diff --git a/src/mesa/state_tracker/st_vdpau.c b/src/mesa/state_tracker/st_vdpau.c index bfc6adf7f77..a3e6de287a3 100644 --- a/src/mesa/state_tracker/st_vdpau.c +++ b/src/mesa/state_tracker/st_vdpau.c @@ -185,6 +185,7 @@ st_vdpau_map_surface(struct gl_context *ctx, GLenum target, GLenum access, const void *vdpSurface, GLuint index) { struct st_context *st = st_context(ctx); + struct pipe_screen *screen = st->pipe->screen; struct st_texture_object *stObj = st_texture_object(texObj); struct st_texture_image *stImage = st_texture_image(texImage); @@ -213,10 +219,32 @@ st_vdpau_map_surface(struct gl_context *ctx, GLenum target, GLenum access, } /* do we have different screen objects ? */ - if (res->screen != st->pipe->screen) { - _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV"); + if (res->screen != screen) { + struct pipe_resource *new_res = NULL; + struct winsys_handle whandle = { .type = WINSYS_HANDLE_TYPE_FD }; + + if (res->screen->resource_get_handle(res->screen, NULL, res, &whandle, 0)) { + struct pipe_resource templ = *res; + + templ.target = PIPE_TEXTURE_2D; + templ.last_level = 0; + templ.depth0 = 1; + templ.array_size = 1; + templ.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET; + templ.usage = PIPE_USAGE_DEFAULT; + new_res = screen->resource_from_handle(screen, &templ, &whandle, 0); + close(whandle.handle); + } + pipe_resource_reference(&res, NULL); - return; + + if (!new_res) { + _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUMapSurfacesNV"); + return; + } + + res = new_res; + layer_override = 0; } /* switch to surface based */