[vlc-devel] [PATCH] nVidia affinity

David R Robison drrobison at openroadsconsulting.com
Thu Aug 29 20:02:47 CEST 2013


We are finishing our testing of these final changes but I wanted to 
submit the patch to see of there is anything else I need to change. I 
believe I have incorporated all the requested changes and comments.
David


---
  modules/video_output/Modules.am    |    2 +-
  modules/video_output/msw/common.h  |    2 +
  modules/video_output/msw/glwin32.c |  101 
+++++++++++++++++++++++++++++++++++-
  5 files changed, 104 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..2d50a38 100644
--- a/modules/video_output/msw/common.h
+++ b/modules/video_output/msw/common.h
@@ -174,6 +174,8 @@ struct vout_display_sys_t
          RGBQUAD    blue;
      };
  #endif
+
+    HDC affinityHDC; // DC for the selected GPU
  };

  /*****************************************************************************
diff --git a/modules/video_output/msw/glwin32.c 
b/modules/video_output/msw/glwin32.c
index 89360c1..d1826d2 100644
--- a/modules/video_output/msw/glwin32.c
+++ b/modules/video_output/msw/glwin32.c
@@ -38,6 +38,8 @@
  #   define MONITOR_DEFAULTTONEAREST 2
  #endif

+#define GLEW_NO_GLU
+#define GLEW_STATIC
  #include "../opengl.h"
  #include <GL/wglew.h>
  #include "common.h"
@@ -48,11 +50,18 @@
  static int  Open (vlc_object_t *);
  static void Close(vlc_object_t *);

+#define HW_GPU_AFFINITY_TEXT N_("GPU affinity")
+#define HW_GPU_AFFINITY_LONGTEXT N_(\
+    "select GPU affinity.")
+
  vlc_module_begin()
      set_category(CAT_VIDEO)
      set_subcategory(SUBCAT_VIDEO_VOUT)
      set_shortname("OpenGL")
      set_description(N_("OpenGL video output"))
+
+    add_integer("gpu-affinity", -1, HW_GPU_AFFINITY_TEXT, 
HW_GPU_AFFINITY_LONGTEXT, true)
+
      set_capability("vout display", 160)
      add_shortcut("glwin32", "opengl")
      set_callbacks(Open, Close)
@@ -70,6 +79,85 @@ static void           Manage (vout_display_t *);
  static void           Swap   (vlc_gl_t *);
  static void          *OurGetProcAddress(vlc_gl_t *, const char *);

+/* Create an GPU Affinity DC */
+static void CreateGPUAffinityDC(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;
+
+    /* create a temporary GL context */
+    HDC winDC = GetDC(vd->sys->hvideownd);
+    SetPixelFormat(winDC, ChoosePixelFormat(winDC, &pfd), &pfd);
+    HGLRC hGLRC = wglCreateContext(winDC);
+    wglMakeCurrent(winDC, hGLRC);
+
+    /* Initialize the neccessary function pointers */
+    PFNWGLENUMGPUSNVPROC fncEnumGpusNV = 
(PFNWGLENUMGPUSNVPROC)wglGetProcAddress("wglEnumGpusNV");
+    PFNWGLCREATEAFFINITYDCNVPROC fncCreateAffinityDCNV = 
(PFNWGLCREATEAFFINITYDCNVPROC)wglGetProcAddress("wglCreateAffinityDCNV");
+
+    /* delete the temporary GL context */
+    wglDeleteContext(hGLRC);
+
+    /* see if we have the extensions */
+    if (!fncEnumGpusNV || !fncCreateAffinityDCNV) return;
+
+    /* find the graphics card */
+    HGPUNV GpuMask[2];
+    GpuMask[0] = NULL;
+    GpuMask[1] = NULL;
+    HGPUNV hGPU;
+    if (!fncEnumGpusNV(nVidiaAffinity, &hGPU)) return;
+
+    /* make the affinity DC */
+    GpuMask[0] = hGPU;
+    vd->sys->affinityHDC = fncCreateAffinityDCNV(GpuMask);
+    if (vd->sys->affinityHDC == NULL) return;
+    SetPixelFormat(vd->sys->affinityHDC,
+        ChoosePixelFormat(vd->sys->affinityHDC, &pfd), &pfd);
+
+    msg_Dbg( vd, "GPU affinity set to adapter: %d",
+                     nVidiaAffinity );
+}
+
+/* Destroy an GPU Affinity DC */
+static void DestroyGPUAffinityDC(vout_display_t *vd) {
+    if (vd->sys->affinityHDC == NULL) return;
+
+    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;
+
+    /* create a temporary GL context */
+    HDC winDC = GetDC(vd->sys->hvideownd);
+    SetPixelFormat(winDC, ChoosePixelFormat(winDC, &pfd), &pfd);
+    HGLRC hGLRC = wglCreateContext(winDC);
+    wglMakeCurrent(winDC, hGLRC);
+
+    /* Initialize the neccessary function pointers */
+    PFNWGLDELETEDCNVPROC fncDeleteDCNV = 
(PFNWGLDELETEDCNVPROC)wglGetProcAddress("wglDeleteDCNV");
+
+    /* delete the temporary GL context */
+    wglDeleteContext(hGLRC);
+
+    /* see if we have the extensions */
+    if (!fncDeleteDCNV) return;
+
+    /* delete the affinity DC */
+    fncDeleteDCNV(vd->sys->affinityHDC);
+}
+
  /**
   * It creates an OpenGL vout display.
   */
@@ -89,6 +177,10 @@ static int Open(vlc_object_t *object)

      EventThreadUpdateTitle(sys->event, VOUT_TITLE " (OpenGL output)");

+    /* process selected GPU affinities */
+    int nVidiaAffinity = var_GetInteger(vd, "gpu-affinity");
+    if (nVidiaAffinity >= 0) CreateGPUAffinityDC(vd, nVidiaAffinity);
+
      /* */
      sys->hGLDC = GetDC(sys->hvideownd);

@@ -105,8 +197,12 @@ static int Open(vlc_object_t *object)
      SetPixelFormat(sys->hGLDC,
                     ChoosePixelFormat(sys->hGLDC, &pfd), &pfd);

-    /* Create and enable the render context */
-    sys->hGLRC = wglCreateContext(sys->hGLDC);
+    /*
+     * Create and enable the render context
+     * For GPU affinity, attach the window DC
+     * to the GPU affinity DC
+     */
+    sys->hGLRC = wglCreateContext((sys->affinityHDC != NULL) ? 
sys->affinityHDC : sys->hGLDC);
      wglMakeCurrent(sys->hGLDC, sys->hGLRC);

      const char *extensions = (const char*)glGetString(GL_EXTENSIONS);
@@ -171,6 +267,7 @@ static void Close(vlc_object_t *object)
          wglDeleteContext(sys->hGLRC);
      if (sys->hGLDC)
          ReleaseDC(sys->hvideownd, sys->hGLDC);
+    DestroyGPUAffinityDC(vd);

      CommonClean(vd);

-- 
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