[vlc-devel] [PATCH] nVidia affinity

David Robison drrobison at openroadsconsulting.com
Tue Sep 3 20:12:18 CEST 2013


Here is the patch. Hopefully the format is correct:

>From eb9e88a077dc2e56011abbd2ce161ef6825ff68a Mon Sep 17 00:00:00 2001
From: Ludovic Fauvet <etix at videolan.org>
Date: Wed, 28 Aug 2013 17:27:12 +0200
Subject: [PATCH] GPU Afinity

---
 modules/video_output/msw/common.h  |    2 +
 modules/video_output/msw/glwin32.c |   98 +++++++++++++++++++++++++++++++++++-
 6 files changed, 115 insertions(+), 6 deletions(-)

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..deb7cc1 100644
--- a/modules/video_output/msw/glwin32.c
+++ b/modules/video_output/msw/glwin32.c
@@ -38,6 +38,7 @@
 #   define MONITOR_DEFAULTTONEAREST 2
 #endif
 
+#define GLEW_STATIC
 #include "../opengl.h"
 #include <GL/wglew.h>
 #include "common.h"
@@ -48,11 +49,16 @@
 static int  Open (vlc_object_t *);
 static void Close(vlc_object_t *);
 
+#define HW_GPU_AFFINITY_TEXT N_("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_TEXT, true)
+
     set_capability("vout display", 160)
     add_shortcut("glwin32", "opengl")
     set_callbacks(Open, Close)
@@ -70,6 +76,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 +174,10 @@ static int Open(vlc_object_t *object)
 
     EventThreadUpdateTitle(sys->event, VOUT_TITLE " (OpenGL output)");
 
+    /* process selected GPU affinity */
+    int nVidiaAffinity = var_InheritInteger(vd, "gpu-affinity");
+    if (nVidiaAffinity >= 0) CreateGPUAffinityDC(vd, nVidiaAffinity);
+
     /* */
     sys->hGLDC = GetDC(sys->hvideownd);
 
@@ -105,8 +194,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 +264,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