On Mon, Oct 24, 2016 at 8:48 PM, Christian König <deathsim...@vodafone.de> wrote:
> Nice work, have you been able to fix all the issues you mentioned on your > last mail? > > Yes, it fixes all the known issues. But I have only tested it on my system. > Additional to that make sure that this set also keeps DRI2 working, in > patch #2 it looks like you call the new function without checking if it's > available or not. > Keep in mind that we possible compile both DRI2 and DRI3 into the driver, > but it can happen that we fallback to DRI2 on runtime. > > I missed this case, it will won't work if we fallback to DRI2 on runtime I will send a v2 to take care of this. Regards, Nayan. > Regards, > Christian. > > > Am 24.10.2016 um 15:55 schrieb Nayan Deshmukh: > >> Suggested-by: Leo Liu <leo....@amd.com> >> Signed-off-by: Nayan Deshmukh <nayan26deshm...@gmail.com> >> --- >> src/gallium/auxiliary/vl/vl_winsys.h | 4 ++ >> src/gallium/auxiliary/vl/vl_winsys_dri3.c | 89 >> +++++++++++++++++++++++++++---- >> 2 files changed, 83 insertions(+), 10 deletions(-) >> >> diff --git a/src/gallium/auxiliary/vl/vl_winsys.h >> b/src/gallium/auxiliary/vl/vl_winsys.h >> index 26db9f2..7c56b48 100644 >> --- a/src/gallium/auxiliary/vl/vl_winsys.h >> +++ b/src/gallium/auxiliary/vl/vl_winsys.h >> @@ -59,6 +59,10 @@ struct vl_screen >> void * >> (*get_private)(struct vl_screen *vscreen); >> + void >> + (*set_output_texture)(struct vl_screen *vscreen, struct pipe_resource >> *buffer, >> + uint32_t width, uint32_t height); >> + >> struct pipe_screen *pscreen; >> struct pipe_loader_device *dev; >> }; >> diff --git a/src/gallium/auxiliary/vl/vl_winsys_dri3.c >> b/src/gallium/auxiliary/vl/vl_winsys_dri3.c >> index 2929928..44d6f4c 100644 >> --- a/src/gallium/auxiliary/vl/vl_winsys_dri3.c >> +++ b/src/gallium/auxiliary/vl/vl_winsys_dri3.c >> @@ -56,6 +56,7 @@ struct vl_dri3_buffer >> struct xshmfence *shm_fence; >> bool busy; >> + bool is_external_texture; >> uint32_t width, height, pitch; >> }; >> @@ -71,6 +72,9 @@ struct vl_dri3_screen >> xcb_special_event_t *special_event; >> struct pipe_context *pipe; >> + struct pipe_resource *output_texture; >> + uint32_t output_texture_width; >> + uint32_t output_texture_height; >> struct vl_dri3_buffer *back_buffers[BACK_BUFFER_NUM]; >> int cur_back; >> @@ -105,7 +109,8 @@ dri3_free_back_buffer(struct vl_dri3_screen *scrn, >> xcb_free_pixmap(scrn->conn, buffer->pixmap); >> xcb_sync_destroy_fence(scrn->conn, buffer->sync_fence); >> xshmfence_unmap_shm(buffer->shm_fence); >> - pipe_resource_reference(&buffer->texture, NULL); >> + if (!buffer->is_external_texture) >> + pipe_resource_reference(&buffer->texture, NULL); >> if (buffer->linear_texture) >> pipe_resource_reference(&buffer->linear_texture, NULL); >> FREE(buffer); >> @@ -236,13 +241,24 @@ dri3_alloc_back_buffer(struct vl_dri3_screen *scrn) >> templ.format = PIPE_FORMAT_B8G8R8X8_UNORM; >> templ.target = PIPE_TEXTURE_2D; >> templ.last_level = 0; >> - templ.width0 = scrn->width; >> - templ.height0 = scrn->height; >> + if (scrn->output_texture) { >> + templ.width0 = (scrn->output_texture_width) ? >> + scrn->output_texture_width : >> + scrn->output_texture->width0; >> + templ.height0 = (scrn->output_texture_height) ? >> + scrn->output_texture_height : >> + scrn->output_texture->height0; >> + } else { >> + templ.width0 = scrn->width; >> + templ.height0 = scrn->height; >> + } >> templ.depth0 = 1; >> templ.array_size = 1; >> if (scrn->is_different_gpu) { >> - buffer->texture = scrn->base.pscreen->resource_c >> reate(scrn->base.pscreen, >> + buffer->texture = (scrn->output_texture) ? >> + scrn->output_texture : >> + scrn->base.pscreen->resource_c >> reate(scrn->base.pscreen, >> &templ); >> if (!buffer->texture) >> goto unmap_shm; >> @@ -257,7 +273,9 @@ dri3_alloc_back_buffer(struct vl_dri3_screen *scrn) >> goto no_linear_texture; >> } else { >> templ.bind |= PIPE_BIND_SCANOUT | PIPE_BIND_SHARED; >> - buffer->texture = scrn->base.pscreen->resource_c >> reate(scrn->base.pscreen, >> + buffer->texture = (scrn->output_texture) ? >> + scrn->output_texture : >> + scrn->base.pscreen->resource_c >> reate(scrn->base.pscreen, >> &templ); >> if (!buffer->texture) >> goto unmap_shm; >> @@ -271,11 +289,20 @@ dri3_alloc_back_buffer(struct vl_dri3_screen *scrn) >> usage); >> buffer_fd = whandle.handle; >> buffer->pitch = whandle.stride; >> + buffer->width = templ.width0; >> + buffer->height = templ.height0; >> + buffer->is_external_texture = (scrn->output_texture) ? >> + true : >> + false; >> + scrn->output_texture = NULL; >> + scrn->output_texture_width = 0; >> + scrn->output_texture_height = 0; >> + >> xcb_dri3_pixmap_from_buffer(scrn->conn, >> (pixmap = xcb_generate_id(scrn->conn)), >> scrn->drawable, >> 0, >> - scrn->width, scrn->height, buffer->pitch, >> + buffer->width, buffer->height, >> buffer->pitch, >> scrn->depth, 32, >> buffer_fd); >> xcb_dri3_fence_from_fd(scrn->conn, >> @@ -287,8 +314,6 @@ dri3_alloc_back_buffer(struct vl_dri3_screen *scrn) >> buffer->pixmap = pixmap; >> buffer->sync_fence = sync_fence; >> buffer->shm_fence = shm_fence; >> - buffer->width = scrn->width; >> - buffer->height = scrn->height; >> xshmfence_trigger(buffer->shm_fence); >> @@ -310,6 +335,7 @@ dri3_get_back_buffer(struct vl_dri3_screen *scrn) >> { >> struct vl_dri3_buffer *buffer; >> struct pipe_resource *texture = NULL; >> + bool allocate_new_buffer = false; >> assert(scrn); >> @@ -318,8 +344,30 @@ dri3_get_back_buffer(struct vl_dri3_screen *scrn) >> return NULL; >> buffer = scrn->back_buffers[scrn->cur_back]; >> - if (!buffer || buffer->width != scrn->width || >> - buffer->height != scrn->height) { >> + /* This is normal case when our buffer is smaller >> + * than the screen this will be same for external >> + * texture >> + */ >> + if (!buffer || buffer->width < scrn->width || >> + buffer->height < scrn->height) >> + allocate_new_buffer = true; >> + >> + /* If we were using a external texture buffer and >> + * the texture is not provided then we need a new >> + * buffer >> + */ >> + if (buffer && buffer->is_external_texture && >> + !scrn->output_texture) >> + allocate_new_buffer = true; >> + >> + /* In case of a single gpu we need to get the >> + * handle and pixmap for the texture that is set >> + */ >> + if (buffer && buffer->is_external_texture && >> + !scrn->is_different_gpu) >> + allocate_new_buffer = true; >> + >> + if (allocate_new_buffer) { >> struct vl_dri3_buffer *new_buffer; >> new_buffer = dri3_alloc_back_buffer(scrn); >> @@ -332,6 +380,13 @@ dri3_get_back_buffer(struct vl_dri3_screen *scrn) >> vl_compositor_reset_dirty_area(&scrn->dirty_areas[scrn->cur_ >> back]); >> buffer = new_buffer; >> scrn->back_buffers[scrn->cur_back] = buffer; >> + } else if (buffer->is_external_texture) { >> + /* In case of different gpu we can reuse the linear >> + * texture so we only need to set the external >> + * texture for copying >> + */ >> + buffer->texture = scrn->output_texture; >> + scrn->output_texture = NULL; >> } >> pipe_resource_reference(&texture, buffer->texture); >> @@ -627,6 +682,19 @@ vl_dri3_screen_get_private(struct vl_screen >> *vscreen) >> } >> static void >> +vl_dri3_screen_set_output_texture(struct vl_screen *vscreen, struct >> pipe_resource *buffer, >> + uint32_t width, uint32_t height) >> +{ >> + struct vl_dri3_screen *scrn = (struct vl_dri3_screen *)vscreen; >> + >> + assert(scrn); >> + >> + scrn->output_texture = buffer; >> + scrn->output_texture_width = width; >> + scrn->output_texture_height = height; >> +} >> + >> +static void >> vl_dri3_screen_destroy(struct vl_screen *vscreen) >> { >> struct vl_dri3_screen *scrn = (struct vl_dri3_screen *)vscreen; >> @@ -744,6 +812,7 @@ vl_dri3_screen_create(Display *display, int screen) >> scrn->base.set_next_timestamp = vl_dri3_screen_set_next_timestamp; >> scrn->base.get_private = vl_dri3_screen_get_private; >> scrn->base.pscreen->flush_frontbuffer = vl_dri3_flush_frontbuffer; >> + scrn->base.set_output_texture = vl_dri3_screen_set_output_texture; >> return &scrn->base; >> >> > > >
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev