use a linear buffer in case of back buffer v2: Use a seprate linear buffer for each back buffer
Signed-off-by: Nayan Deshmukh <nayan26deshm...@gmail.com> --- src/gallium/auxiliary/vl/vl_winsys_dri3.c | 82 ++++++++++++++++++++++++------- 1 file changed, 63 insertions(+), 19 deletions(-) diff --git a/src/gallium/auxiliary/vl/vl_winsys_dri3.c b/src/gallium/auxiliary/vl/vl_winsys_dri3.c index 3d596a6..e168e36 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_buffer; 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 @@ -209,7 +213,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; struct winsys_handle whandle; unsigned usage; @@ -226,25 +230,49 @@ 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.format = PIPE_FORMAT_B8G8R8X8_UNORM; - templ.target = PIPE_TEXTURE_2D; - templ.last_level = 0; - templ.width0 = scrn->width; - 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) { + templ.format = PIPE_FORMAT_B8G8R8X8_UNORM; + templ.target = PIPE_TEXTURE_2D; + templ.last_level = 0; + templ.width0 = scrn->width; + 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; + + templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW | + PIPE_BIND_SCANOUT | PIPE_BIND_SHARED | PIPE_BIND_LINEAR; + buffer->linear_buffer = scrn->base.pscreen->resource_create(scrn->base.pscreen, + &templ); + pixmap_buffer = buffer->linear_buffer; + + if (!buffer->linear_buffer) + goto no_linear_buffer; + + } else { + templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW | + PIPE_BIND_SCANOUT | PIPE_BIND_SHARED; + templ.format = PIPE_FORMAT_B8G8R8X8_UNORM; + templ.target = PIPE_TEXTURE_2D; + templ.last_level = 0; + templ.width0 = scrn->width; + 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; + pixmap_buffer = 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, &whandle, usage); buffer_fd = whandle.handle; buffer->pitch = whandle.stride; @@ -271,6 +299,8 @@ dri3_alloc_back_buffer(struct vl_dri3_screen *scrn) return buffer; +no_linear_buffer: + pipe_resource_reference(&buffer->texture, NULL); unmap_shm: xshmfence_unmap_shm(shm_fence); close_fd: @@ -474,6 +504,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 +516,17 @@ 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_buffer, + 0, 0, 0, 0, + back->texture, + 0, &src_box); + + } xshmfence_reset(back->shm_fence); back->busy = true; @@ -501,6 +543,7 @@ vl_dri3_flush_frontbuffer(struct pipe_screen *screen, xcb_flush(scrn->conn); + scrn->pipe->flush(scrn->pipe, NULL, 0); scrn->flushed = true; return; @@ -678,9 +721,7 @@ vl_dri3_screen_create(Display *display, int screen) free(open_reply); fd = loader_get_user_preferred_fd(fd, &is_different_gpu); - /* TODO support different GPU */ - if (is_different_gpu) - goto close_fd; + scrn->is_different_gpu = 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 +740,9 @@ 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); + 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; -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev