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

Rémi Denis-Courmont remi at remlab.net
Tue Aug 27 16:00:53 CEST 2013


   Hello,

I think all three patches should be merged.

More comments in-line...

On Tue, 27 Aug 2013 09:38:33 -0400, David R Robison
<drrobison at openroadsconsulting.com> wrote:
> @@ -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")

Most probably too long for the GUI.

> +#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 RW data => re-entrancy hell => bad idea.

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

Named initializer, please. No need for memset().

> +
> +    // 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");

And indeed, this seems not reentrant.

> +
> +    // 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;

Left over??

>       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() );

Please wrap and indent long lines.

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

Indent.

>       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);
> +    }
> +*/

More left over?

> +
>       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);
> +*/

Ditto?

>       SwapBuffers(vd->sys->hGLDC);
>   }

-- 
Rémi Denis-Courmont
Sent from my collocated server



More information about the vlc-devel mailing list