[Mesa-dev] [PATCH 1/3] vl/dri3: handle the case of different GPU(v4.2)

Mike Lothian mike at fireburn.co.uk
Tue Sep 20 13:36:18 UTC 2016


Here's what I currently have:

fireburn at axion ~ $ DRI_PRIME=1 vainfo
libva info: VA-API version 0.39.3
libva info: va_getDriverName() returns 0
libva info: Trying to open /usr/lib64/va/drivers/i965_drv_video.so
libva info: Found init function __vaDriverInit_0_39
libva info: va_openDriver() returns 0
vainfo: VA-API version: 0.39 (libva 1.7.2)
vainfo: Driver version: Intel i965 driver for Intel(R) Skylake - 1.7.2
vainfo: Supported profile and entrypoints
      VAProfileMPEG2Simple            : VAEntrypointVLD
      VAProfileMPEG2Simple            : VAEntrypointEncSlice
      VAProfileMPEG2Main              : VAEntrypointVLD
      VAProfileMPEG2Main              : VAEntrypointEncSlice
      VAProfileH264ConstrainedBaseline: VAEntrypointVLD
      VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice
      VAProfileH264ConstrainedBaseline: VAEntrypointEncSliceLP
      VAProfileH264Main               : VAEntrypointVLD
      VAProfileH264Main               : VAEntrypointEncSlice
      VAProfileH264Main               : VAEntrypointEncSliceLP
      VAProfileH264High               : VAEntrypointVLD
      VAProfileH264High               : VAEntrypointEncSlice
      VAProfileH264High               : VAEntrypointEncSliceLP
      VAProfileH264MultiviewHigh      : VAEntrypointVLD
      VAProfileH264MultiviewHigh      : VAEntrypointEncSlice
      VAProfileH264StereoHigh         : VAEntrypointVLD
      VAProfileH264StereoHigh         : VAEntrypointEncSlice
      VAProfileVC1Simple              : VAEntrypointVLD
      VAProfileVC1Main                : VAEntrypointVLD
      VAProfileVC1Advanced            : VAEntrypointVLD
      VAProfileNone                   : VAEntrypointVideoProc
      VAProfileJPEGBaseline           : VAEntrypointVLD
      VAProfileJPEGBaseline           : VAEntrypointEncPicture
      VAProfileVP8Version0_3          : VAEntrypointVLD
      VAProfileVP8Version0_3          : VAEntrypointEncSlice
      VAProfileHEVCMain               : VAEntrypointVLD
      VAProfileHEVCMain               : VAEntrypointEncSlice


which picks up the i965 driver despite the DRI_PRIME=1 paramerter being fed
in - I have to manually specify LIBVA_DRIVER_NAME=radeonsi in order to get
it to get the details out of vainfo - the same goes for vdpauinfo

fireburn at axion ~ $ LIBVA_DRIVER_NAME=radeonsi DRI_PRIME=1 vainfo
libva info: VA-API version 0.39.3
libva info: va_getDriverName() returns 0
libva info: User requested driver 'radeonsi'
libva info: Trying to open /usr/lib64/va/drivers/radeonsi_drv_video.so
libva info: Found init function __vaDriverInit_0_39
libva info: va_openDriver() returns 0
vainfo: VA-API version: 0.39 (libva 1.7.2)
vainfo: Driver version: mesa gallium vaapi
vainfo: Supported profile and entrypoints
      VAProfileMPEG2Simple            : VAEntrypointVLD
      VAProfileMPEG2Main              : VAEntrypointVLD
      VAProfileVC1Simple              : VAEntrypointVLD
      VAProfileVC1Main                : VAEntrypointVLD
      VAProfileVC1Advanced            : VAEntrypointVLD
      VAProfileH264Baseline           : VAEntrypointVLD
      VAProfileH264Baseline           : VAEntrypointEncSlice
      VAProfileH264Main               : VAEntrypointVLD
      VAProfileH264Main               : VAEntrypointEncSlice
      VAProfileH264High               : VAEntrypointVLD
      VAProfileH264High               : VAEntrypointEncSlice
      VAProfileNone                   : VAEntrypointVideoProc


On Tue, 20 Sep 2016 at 14:13 Nayan Deshmukh <nayan26deshmukh at gmail.com>
wrote:

> Hi Mike,
>
>
> On Tue, Sep 20, 2016 at 5:45 PM, Mike Lothian <mike at fireburn.co.uk> wrote:
>
>> Hi
>>
>> I've just confirmed this works for getting details from vainfo and
>> vdpauinfo using DRI_PRIME=1 without needing to set up offloading with xrandr
>>
>> I do however need to specify the driver still, is that something being
>> worked on? It would be great if it autoselected based on the card running
>> at DRI_PRIME=1 (or x if there's more than one card)
>>
>> I have a prime system and I don't need to specify any drivers in my
> system.
> Though I am not the right person to answer this question.
> Maybe Michel can answer this.
>
> Cheers,
> Nayan
>
>> Cheers
>>
>> Mike
>>
>> On Tue, 20 Sep 2016 at 05:52 Nayan Deshmukh <nayan26deshmukh at gmail.com>
>> wrote:
>>
>>> In case of prime when rendering is done on GPU other then the
>>> server GPU, use a seprate linear buffer for each back buffer
>>> which will be displayed using present extension.
>>>
>>> v2: Use a seprate linear buffer for each back buffer (Michel)
>>> v3: Change variable names and fix coding style (Leo and Emil)
>>> v4: Use PIPE_BIND_SAMPLER_VIEW for back buffer in case when
>>>     a seprate linear buffer is used (Michel)
>>> v4.1: remove empty line
>>> v4.2: destroy the context and handle the case when
>>>       create_context fails (Emil)
>>>
>>> Signed-off-by: Nayan Deshmukh <nayan26deshmukh at gmail.com>
>>> Reviewed-by: Leo Liu <leo.liu at amd.com>
>>> Acked-by: Michel Dänzer <michel.daenzer at amd.com>
>>> ---
>>>  src/gallium/auxiliary/vl/vl_winsys_dri3.c | 66
>>> +++++++++++++++++++++++++------
>>>  1 file changed, 53 insertions(+), 13 deletions(-)
>>>
>>> diff --git a/src/gallium/auxiliary/vl/vl_winsys_dri3.c
>>> b/src/gallium/auxiliary/vl/vl_winsys_dri3.c
>>> index 3d596a6..191a64b 100644
>>> --- a/src/gallium/auxiliary/vl/vl_winsys_dri3.c
>>> +++ b/src/gallium/auxiliary/vl/vl_winsys_dri3.c
>>> @@ -49,6 +49,7 @@
>>>  struct vl_dri3_buffer
>>>  {
>>>     struct pipe_resource *texture;
>>> +   struct pipe_resource *linear_texture;
>>>
>>>     uint32_t pixmap;
>>>     uint32_t sync_fence;
>>> @@ -69,6 +70,8 @@ struct vl_dri3_screen
>>>     xcb_present_event_t eid;
>>>     xcb_special_event_t *special_event;
>>>
>>> +   struct pipe_context *pipe;
>>> +
>>>     struct vl_dri3_buffer *back_buffers[BACK_BUFFER_NUM];
>>>     int cur_back;
>>>
>>> @@ -82,6 +85,7 @@ struct vl_dri3_screen
>>>     int64_t last_ust, ns_frame, last_msc, next_msc;
>>>
>>>     bool flushed;
>>> +   bool is_different_gpu;
>>>  };
>>>
>>>  static void
>>> @@ -102,6 +106,8 @@ dri3_free_back_buffer(struct vl_dri3_screen *scrn,
>>>     xcb_sync_destroy_fence(scrn->conn, buffer->sync_fence);
>>>     xshmfence_unmap_shm(buffer->shm_fence);
>>>     pipe_resource_reference(&buffer->texture, NULL);
>>> +   if (buffer->linear_texture)
>>> +       pipe_resource_reference(&buffer->linear_texture, NULL);
>>>     FREE(buffer);
>>>  }
>>>
>>> @@ -209,7 +215,7 @@ dri3_alloc_back_buffer(struct vl_dri3_screen *scrn)
>>>     xcb_sync_fence_t sync_fence;
>>>     struct xshmfence *shm_fence;
>>>     int buffer_fd, fence_fd;
>>> -   struct pipe_resource templ;
>>> +   struct pipe_resource templ, *pixmap_buffer_texture;
>>>     struct winsys_handle whandle;
>>>     unsigned usage;
>>>
>>> @@ -226,8 +232,7 @@ dri3_alloc_back_buffer(struct vl_dri3_screen *scrn)
>>>        goto close_fd;
>>>
>>>     memset(&templ, 0, sizeof(templ));
>>> -   templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW |
>>> -                PIPE_BIND_SCANOUT | PIPE_BIND_SHARED;
>>> +   templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
>>>     templ.format = PIPE_FORMAT_B8G8R8X8_UNORM;
>>>     templ.target = PIPE_TEXTURE_2D;
>>>     templ.last_level = 0;
>>> @@ -235,16 +240,34 @@ dri3_alloc_back_buffer(struct vl_dri3_screen *scrn)
>>>     templ.height0 = scrn->height;
>>>     templ.depth0 = 1;
>>>     templ.array_size = 1;
>>> -   buffer->texture =
>>> scrn->base.pscreen->resource_create(scrn->base.pscreen,
>>> -                                                         &templ);
>>> -   if (!buffer->texture)
>>> -      goto unmap_shm;
>>>
>>> +   if (scrn->is_different_gpu) {
>>> +      buffer->texture =
>>> scrn->base.pscreen->resource_create(scrn->base.pscreen,
>>> +                                                            &templ);
>>> +      if (!buffer->texture)
>>> +         goto unmap_shm;
>>> +
>>> +      templ.bind |= PIPE_BIND_SCANOUT | PIPE_BIND_SHARED |
>>> +                    PIPE_BIND_LINEAR;
>>> +      buffer->linear_texture =
>>> scrn->base.pscreen->resource_create(scrn->base.pscreen,
>>> +
>>> &templ);
>>> +      pixmap_buffer_texture = buffer->linear_texture;
>>> +
>>> +      if (!buffer->linear_texture)
>>> +         goto no_linear_texture;
>>> +   } else {
>>> +      templ.bind |= PIPE_BIND_SCANOUT | PIPE_BIND_SHARED;
>>> +      buffer->texture =
>>> scrn->base.pscreen->resource_create(scrn->base.pscreen,
>>> +                                                            &templ);
>>> +      if (!buffer->texture)
>>> +         goto unmap_shm;
>>> +      pixmap_buffer_texture = buffer->texture;
>>> +   }
>>>     memset(&whandle, 0, sizeof(whandle));
>>>     whandle.type= DRM_API_HANDLE_TYPE_FD;
>>>     usage = PIPE_HANDLE_USAGE_EXPLICIT_FLUSH | PIPE_HANDLE_USAGE_READ;
>>>     scrn->base.pscreen->resource_get_handle(scrn->base.pscreen, NULL,
>>> -                                           buffer->texture, &whandle,
>>> +                                           pixmap_buffer_texture,
>>> &whandle,
>>>                                             usage);
>>>     buffer_fd = whandle.handle;
>>>     buffer->pitch = whandle.stride;
>>> @@ -271,6 +294,8 @@ dri3_alloc_back_buffer(struct vl_dri3_screen *scrn)
>>>
>>>     return buffer;
>>>
>>> +no_linear_texture:
>>> +   pipe_resource_reference(&buffer->texture, NULL);
>>>  unmap_shm:
>>>     xshmfence_unmap_shm(shm_fence);
>>>  close_fd:
>>> @@ -474,6 +499,7 @@ vl_dri3_flush_frontbuffer(struct pipe_screen *screen,
>>>     struct vl_dri3_screen *scrn = (struct vl_dri3_screen
>>> *)context_private;
>>>     uint32_t options = XCB_PRESENT_OPTION_NONE;
>>>     struct vl_dri3_buffer *back;
>>> +   struct pipe_box src_box;
>>>
>>>     back = scrn->back_buffers[scrn->cur_back];
>>>     if (!back)
>>> @@ -485,6 +511,16 @@ vl_dri3_flush_frontbuffer(struct pipe_screen
>>> *screen,
>>>              return;
>>>     }
>>>
>>> +   if (scrn->is_different_gpu) {
>>> +      u_box_origin_2d(scrn->width, scrn->height, &src_box);
>>> +      scrn->pipe->resource_copy_region(scrn->pipe,
>>> +                                       back->linear_texture,
>>> +                                       0, 0, 0, 0,
>>> +                                       back->texture,
>>> +                                       0, &src_box);
>>> +
>>> +      scrn->pipe->flush(scrn->pipe, NULL, 0);
>>> +   }
>>>     xshmfence_reset(back->shm_fence);
>>>     back->busy = true;
>>>
>>> @@ -622,6 +658,7 @@ vl_dri3_screen_destroy(struct vl_screen *vscreen)
>>>        xcb_discard_reply(scrn->conn, cookie.sequence);
>>>        xcb_unregister_for_special_event(scrn->conn, scrn->special_event);
>>>     }
>>> +   scrn->pipe->destroy(scrn->pipe);
>>>     scrn->base.pscreen->destroy(scrn->base.pscreen);
>>>     pipe_loader_release(&scrn->base.dev, 1);
>>>     FREE(scrn);
>>> @@ -638,7 +675,6 @@ vl_dri3_screen_create(Display *display, int screen)
>>>     xcb_dri3_open_reply_t *open_reply;
>>>     xcb_get_geometry_cookie_t geom_cookie;
>>>     xcb_get_geometry_reply_t *geom_reply;
>>> -   int is_different_gpu;
>>>     int fd;
>>>
>>>     assert(display);
>>> @@ -677,10 +713,7 @@ vl_dri3_screen_create(Display *display, int screen)
>>>     fcntl(fd, F_SETFD, FD_CLOEXEC);
>>>     free(open_reply);
>>>
>>> -   fd = loader_get_user_preferred_fd(fd, &is_different_gpu);
>>> -   /* TODO support different GPU */
>>> -   if (is_different_gpu)
>>> -      goto close_fd;
>>> +   fd = loader_get_user_preferred_fd(fd, &scrn->is_different_gpu);
>>>
>>>     geom_cookie = xcb_get_geometry(scrn->conn, RootWindow(display,
>>> screen));
>>>     geom_reply = xcb_get_geometry_reply(scrn->conn, geom_cookie, NULL);
>>> @@ -699,6 +732,11 @@ vl_dri3_screen_create(Display *display, int screen)
>>>     if (!scrn->base.pscreen)
>>>        goto release_pipe;
>>>
>>> +   scrn->pipe = scrn->base.pscreen->context_create(scrn->base.pscreen,
>>> +                                                   &scrn->base, 0);
>>> +   if (!scrn->pipe)
>>> +       goto no_context;
>>> +
>>>     scrn->base.destroy = vl_dri3_screen_destroy;
>>>     scrn->base.texture_from_drawable =
>>> vl_dri3_screen_texture_from_drawable;
>>>     scrn->base.get_dirty_area = vl_dri3_screen_get_dirty_area;
>>> @@ -709,6 +747,8 @@ vl_dri3_screen_create(Display *display, int screen)
>>>
>>>     return &scrn->base;
>>>
>>> +no_context:
>>> +   scrn->base.pscreen->destroy(scrn->base.pscreen);
>>>  release_pipe:
>>>     if (scrn->base.dev) {
>>>        pipe_loader_release(&scrn->base.dev, 1);
>>> --
>>> 2.7.4
>>>
>>> _______________________________________________
>>> mesa-dev mailing list
>>> mesa-dev at lists.freedesktop.org
>>> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20160920/52d18783/attachment-0001.html>


More information about the mesa-dev mailing list