[vlc-devel] [PATCH] nVidia affinity
David R Robison
drrobison at openroadsconsulting.com
Wed Aug 28 20:26:28 CEST 2013
I've merged the three patch files into one and incorporated some of the
comments previously made. Here are some further comments:
1) The use of memset in the AssignNVidiaAffinity function is consistent
with its use in the open function. Maybe I misunderstood your comment.
2) The GLEW_STATIC define forces a static compile of the GLEW libraries
rather than using dynamic linking. I could not get it to work without this.
3) Any other comments?
Our appliation embedds 48 VLC windows in a single application using the
VLC SDK. We distribute the different instances across two nVidia cards.
By examining the GPU resource utilization we were able to verify that
the GPU affinity is working. This has allowed us to support more
simultaneous videos than previously when not using GPU affinity.
David
---
modules/video_output/Modules.am | 2 +-
modules/video_output/msw/common.h | 3 ++
modules/video_output/msw/glwin32.c | 87
+++++++++++++++++++++++++++++++++++-
po/nb.po | 2 +-
po/or.po | 2 +-
5 files changed, 91 insertions(+), 5 deletions(-)
diff --git a/modules/video_output/Modules.am
b/modules/video_output/Modules.am
index 7efe10a..649b4b9 100644
--- a/modules/video_output/Modules.am
+++ b/modules/video_output/Modules.am
@@ -118,7 +118,7 @@ endif
libglwin32_plugin_la_SOURCES = msw/glwin32.c opengl.c opengl.h \
msw/common.c msw/common.h msw/events.c msw/events.h
libglwin32_plugin_la_CFLAGS = $(AM_CFLAGS)
-libglwin32_plugin_la_LIBADD = $(AM_LIBADD) -lopengl32 -lgdi32 -lole32
-luuid
+libglwin32_plugin_la_LIBADD = $(AM_LIBADD) -lglew32 -lopengl32 -lgdi32
-lole32 -luuid
libvlc_LTLIBRARIES += $(LTLIBglwin32)
EXTRA_LTLIBRARIES += libglwin32_plugin.la
diff --git a/modules/video_output/msw/common.h
b/modules/video_output/msw/common.h
index 12a4f55..fca9efe 100644
--- a/modules/video_output/msw/common.h
+++ b/modules/video_output/msw/common.h
@@ -174,6 +174,9 @@ struct vout_display_sys_t
RGBQUAD blue;
};
#endif
+
+ // nVidia GPU affinity
+ HDC affinityHDC
};
/*****************************************************************************
diff --git a/modules/video_output/msw/glwin32.c
b/modules/video_output/msw/glwin32.c
index 89360c1..22b69aa 100644
--- a/modules/video_output/msw/glwin32.c
+++ b/modules/video_output/msw/glwin32.c
@@ -23,6 +23,8 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
+#define GLEW_NO_GLU
+#define GLEW_STATIC
#include <vlc_common.h>
#include <vlc_plugin.h>
@@ -48,11 +50,18 @@
static int Open (vlc_object_t *);
static void Close(vlc_object_t *);
+#define HW_NVIDIA_AFFINITY_TEXT N_("nVidia affinity of adapter")
+#define HW_NVIDIA_AFFINITY_LONGTEXT N_(\
+ "nVidia affinity of adapter indexed from 0.")
+
vlc_module_begin()
set_category(CAT_VIDEO)
set_subcategory(SUBCAT_VIDEO_VOUT)
set_shortname("OpenGL")
set_description(N_("OpenGL video output"))
+
+ add_integer("nvidia-affinity", -1, HW_NVIDIA_AFFINITY_TEXT,
HW_NVIDIA_AFFINITY_LONGTEXT, true)
+
set_capability("vout display", 160)
add_shortcut("glwin32", "opengl")
set_callbacks(Open, Close)
@@ -70,6 +79,70 @@ static void Manage (vout_display_t *);
static void Swap (vlc_gl_t *);
static void *OurGetProcAddress(vlc_gl_t *, const char *);
+#undef wglEnumGpusNV
+#undef wglCreateAffinityDCNV
+#undef wglDeleteDCNV
+static PFNWGLENUMGPUSNVPROC wglEnumGpusNV;
+static PFNWGLCREATEAFFINITYDCNVPROC wglCreateAffinityDCNV;
+static PFNWGLDELETEDCNVPROC wglDeleteDCNV;
+
+static void AssignNVidiaAffinity(vout_display_t *vd, UINT nVidiaAffinity) {
+ PIXELFORMATDESCRIPTOR pfd;
+ memset(&pfd, 0, sizeof(pfd));
+ pfd.nSize = sizeof(pfd);
+ pfd.nVersion = 1;
+ pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER;
+ pfd.iPixelType = PFD_TYPE_RGBA;
+ pfd.cColorBits = 24;
+ pfd.cDepthBits = 16;
+ pfd.iLayerType = PFD_MAIN_PLANE;
+
+ /* initialize the wgl context */
+ if (wglEnumGpusNV == NULL) {
+ msg_Dbg(vd, "Initialize wgl context" );
+
+ /* create a temporary GL context */
+ HDC winDC = GetDC(vd->sys->hvideownd);
+ SetPixelFormat(winDC, ChoosePixelFormat(winDC, &pfd), &pfd);
+ HGLRC hGLRC = wglCreateContext(winDC);
+ wglMakeCurrent(winDC, hGLRC);
+
+ /* get function pointers */
+ wglEnumGpusNV =
(PFNWGLENUMGPUSNVPROC)wglGetProcAddress("wglEnumGpusNV");
+ wglCreateAffinityDCNV =
(PFNWGLCREATEAFFINITYDCNVPROC)wglGetProcAddress("wglCreateAffinityDCNV");
+ wglDeleteDCNV =
(PFNWGLDELETEDCNVPROC)wglGetProcAddress("wglDeleteDCNV");
+
+ /* delete the temporary GL context */
+ wglDeleteContext(hGLRC);
+ }
+
+ /* see if we have the extensions */
+ if (!wglEnumGpusNV || !wglCreateAffinityDCNV) {
+ msg_Dbg(vd, "OpenGL nVidia extensions do not seem to be present" );
+ return;
+ }
+
+ /* find the graphics card */
+ HGPUNV GpuMask[2];
+ GpuMask[0] = NULL;
+ GpuMask[1] = NULL;
+ HGPUNV hGPU;
+ if (!wglEnumGpusNV(nVidiaAffinity, &hGPU)) {
+ msg_Warn(vd, "Could not enumerate nVidia adapter %d",
nVidiaAffinity );
+ return;
+ }
+
+ /* make the new context */
+ GpuMask[0] = hGPU;
+ vd->sys->affinityHDC = wglCreateAffinityDCNV(GpuMask);
+ if (vd->sys->affinityHDC == NULL) {
+ msg_Warn(vd, "Could not create nVidia afinity DV %d",
GetLastError() );
+ return;
+ }
+ SetPixelFormat(vd->sys->affinityHDC,
+ ChoosePixelFormat(vd->sys->affinityHDC, &pfd), &pfd);
+}
+
/**
* It creates an OpenGL vout display.
*/
@@ -89,6 +162,13 @@ static int Open(vlc_object_t *object)
EventThreadUpdateTitle(sys->event, VOUT_TITLE " (OpenGL output)");
+ /* process card specific affinities */
+ int nVidiaAffinity = var_InheritInteger(vd, "nvidia-affinity");
+ if (nVidiaAffinity >= 0) {
+ msg_Dbg(vd, "nVidia affinity using adapter %d", nVidiaAffinity );
+ AssignNVidiaAffinity(vd, nVidiaAffinity);
+ }
+
/* */
sys->hGLDC = GetDC(sys->hvideownd);
@@ -106,8 +186,9 @@ static int Open(vlc_object_t *object)
ChoosePixelFormat(sys->hGLDC, &pfd), &pfd);
/* Create and enable the render context */
- sys->hGLRC = wglCreateContext(sys->hGLDC);
- wglMakeCurrent(sys->hGLDC, sys->hGLRC);
+ sys->hGLRC = wglCreateContext((sys->affinityHDC != NULL) ?
sys->affinityHDC : sys->hGLDC);
+ if (!wglMakeCurrent(sys->hGLDC, sys->hGLRC))
+ msg_Warn(vd, "wglMakeCurrent failed = %d", GetLastError() );
const char *extensions = (const char*)glGetString(GL_EXTENSIONS);
#ifdef WGL_EXT_swap_control
@@ -169,6 +250,8 @@ static void Close(vlc_object_t *object)
wglMakeCurrent(NULL, NULL);
if (sys->hGLRC)
wglDeleteContext(sys->hGLRC);
+ if (sys->affinityHDC)
+ wglDeleteDCNV(sys->affinityHDC);
if (sys->hGLDC)
ReleaseDC(sys->hvideownd, sys->hGLDC);
diff --git a/po/nb.po b/po/nb.po
index 94d1b68..e5ab122 100644
--- a/po/nb.po
+++ b/po/nb.po
@@ -17,7 +17,7 @@ msgstr ""
"Last-Translator: bobbaluba <bobbaluba at gmail.com>\n"
"Language-Team: Norwegian Bokmål (Norway)
(http://www.transifex.com/projects/"
"p/vlc-trans/language/nb_NO/)\n"
-"Language: nb_NO\n"
+"Language: nb\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
diff --git a/po/or.po b/po/or.po
index 8d75ea3..4e51c74 100644
--- a/po/or.po
+++ b/po/or.po
@@ -13,7 +13,7 @@ msgstr ""
"Last-Translator: Yaron Shahrabani <sh.yaron at gmail.com>\n"
"Language-Team: Oriya (India)
(http://www.transifex.com/projects/p/vlc-trans/"
"language/or_IN/)\n"
-"Language: or_IN\n"
+"Language: or\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
--
1.7.9.5
This email communication (including any attachments) may contain confidential and/or privileged material intended solely for the individual or entity to which it is addressed.
If you are not the intended recipient, please delete this email immediately.
More information about the vlc-devel
mailing list