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) Cheers Mike On Tue, 20 Sep 2016 at 05:52 Nayan Deshmukh <nayan26deshm...@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 <nayan26deshm...@gmail.com> > Reviewed-by: Leo Liu <leo....@amd.com> > Acked-by: Michel Dänzer <michel.daen...@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@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev >
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev