[vlc-devel] [PATCH 3/3] nVidia affinity

David R Robison drrobison at openroadsconsulting.com
Tue Aug 27 15:38:33 CEST 2013


---
  modules/video_output/msw/glwin32.c |  114 
++++++++++++++++++++++++++++++++++--
  1 file changed, 110 insertions(+), 4 deletions(-)
  mode change 100644 => 100755 modules/video_output/msw/glwin32.c

diff --git a/modules/video_output/msw/glwin32.c 
b/modules/video_output/msw/glwin32.c
old mode 100644
new mode 100755
index 89360c1..259615e
--- 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_("Set the nVidia affinity to this 
adapter number")
+#define HW_NVIDIA_AFFINITY_LONGTEXT N_(\
+    "Identifies nVidia addapter number to use for hardware acceleration.")
+
  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 HDC AffinityHDC;
+
+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;
+    AffinityHDC = wglCreateAffinityDCNV(GpuMask);
+    if (AffinityHDC == NULL) {
+        msg_Warn(vd, "Could not create nVidia afinity DV %d", 
GetLastError() );
+        return;
+    }
+    SetPixelFormat(AffinityHDC, ChoosePixelFormat(AffinityHDC, &pfd), 
&pfd);
+}
+
  /**
   * It creates an OpenGL vout display.
   */
@@ -89,7 +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);

      /* Set the pixel format for the DC */
@@ -98,6 +177,7 @@ static int Open(vlc_object_t *object)
      pfd.nSize = sizeof(pfd);
      pfd.nVersion = 1;
      pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | 
PFD_DOUBLEBUFFER;
+    //pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
      pfd.iPixelType = PFD_TYPE_RGBA;
      pfd.cColorBits = 24;
      pfd.cDepthBits = 16;
@@ -106,10 +186,11 @@ 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((AffinityHDC != NULL) ? AffinityHDC : 
sys->hGLDC);
+    if (!wglMakeCurrent(sys->hGLDC, sys->hGLRC)) msg_Warn(vd, 
"wglMakeCurrent failed = %d", GetLastError() );

      const char *extensions = (const char*)glGetString(GL_EXTENSIONS);
+    msg_Dbg(vd, "GL Extensions = %s", extensions );
  #ifdef WGL_EXT_swap_control
      if (HasExtension(extensions, "WGL_EXT_swap_control")) {
          PFNWGLSWAPINTERVALEXTPROC SwapIntervalEXT = 
(PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
@@ -169,9 +250,10 @@ static void Close(vlc_object_t *object)
          wglMakeCurrent(NULL, NULL);
      if (sys->hGLRC)
          wglDeleteContext(sys->hGLRC);
+    if (AffinityHDC)
+    wglDeleteDCNV(AffinityHDC);
      if (sys->hGLDC)
          ReleaseDC(sys->hvideownd, sys->hGLDC);
-
      CommonClean(vd);

      free(sys);
@@ -191,6 +273,25 @@ static void Prepare(vout_display_t *vd, picture_t 
*picture, subpicture_t *subpic
  {
      vout_display_sys_t *sys = vd->sys;

+    // Create a Frame Buffer Object & bind it
+/*
+    if (glGenFramebuffersEXT == NULL || glBindFramebufferEXT == NULL) {
+        msg_Dbg(vd, "OpenGL Frame Buffer extensions do not seem to be 
present" );
+    } else {
+        const int width  = sys->rect_dest.right  - sys->rect_dest.left;
+        const int height = sys->rect_dest.bottom - sys->rect_dest.top;
+msg_Dbg("Image %d %d", width, height);
+        glGenFramebuffersEXT(1, &MyFBO);
+        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, MyFBO);
+        glGenRenderbuffersEXT(1, &MyRBO);
+        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, MyRBO);
+        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA8, width, 
height);
+        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, 
GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, MyRBO);
+        int rc = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+        if (rc != GL_FRAMEBUFFER_COMPLETE_EXT) msg_Warn(vd, "Could not 
create FBO: %d", rc);
+    }
+*/
+
      vout_display_opengl_Prepare(sys->vgl, picture, subpicture);
  }

@@ -237,6 +338,11 @@ static void Swap(vlc_gl_t *gl)
  {
      vout_display_t *vd = gl->sys;

+/*
+    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+    glDeleteFramebuffersEXT(1, &MyFBO);
+    glDeleteRenderbuffersEXT(1, &MyRBO);
+*/
      SwapBuffers(vd->sys->hGLDC);
  }

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