Stop trying to specify texture or renderbuffer objects for unsupported EGL images. Generate the error codes specified in the OES_EGL_image extension.
Signed-off-by: Philipp Zabel <p.za...@pengutronix.de> --- EGLImageTargetTexture2D and EGLImageTargetRenderbuffer would call the pipe driver's create_surface callback without ever checking that the given EGL image is actually compatible with the chosen target texture or renderbuffer. This patch adds a call to the pipe driver's is_format_supported callback and generates an INVALID_OPERATION error for unsupported EGL images. If the EGL image handle does not describe a valid EGL image, an INVALID_VALUE error is generated. --- src/mesa/state_tracker/st_cb_eglimage.c | 53 +++++++++++++++++++++++++++++++-- src/mesa/state_tracker/st_manager.c | 27 ++++++----------- src/mesa/state_tracker/st_manager.h | 4 ++- 3 files changed, 63 insertions(+), 21 deletions(-) diff --git a/src/mesa/state_tracker/st_cb_eglimage.c b/src/mesa/state_tracker/st_cb_eglimage.c index c425154..6810e24 100644 --- a/src/mesa/state_tracker/st_cb_eglimage.c +++ b/src/mesa/state_tracker/st_cb_eglimage.c @@ -25,6 +25,7 @@ * Chia-I Wu <o...@lunarg.com> */ +#include "main/errors.h" #include "main/texobj.h" #include "main/teximage.h" #include "util/u_inlines.h" @@ -74,10 +75,34 @@ st_egl_image_target_renderbuffer_storage(struct gl_context *ctx, GLeglImageOES image_handle) { struct st_context *st = st_context(ctx); + struct st_manager *smapi = + (struct st_manager *) st->iface.st_context_private; struct st_renderbuffer *strb = st_renderbuffer(rb); + struct pipe_screen *screen = st->pipe->screen; + struct st_egl_image stimg; struct pipe_surface *ps; - ps = st_manager_get_egl_image_surface(st, (void *) image_handle); + if (!smapi || !smapi->get_egl_image) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glEGLImageTargetRenderbufferStorage"); + return NULL; + } + + memset(&stimg, 0, sizeof(stimg)); + if (!smapi->get_egl_image(smapi, (void *) image_handle, &stimg)) { + /* image_handle does not refer to a valid EGL image object */ + _mesa_error(ctx, GL_INVALID_VALUE, "glEGLImageTargetRenderbufferStorage"); + return NULL; + } + + if (!screen->is_format_supported(screen, stimg.format, PIPE_TEXTURE_2D, + stimg.texture->nr_samples, + PIPE_BIND_RENDER_TARGET)) { + /* unable to specify a texture object using the specified EGL image */ + _mesa_error(ctx, GL_INVALID_OPERATION, "glEGLImageTargetRenderbufferStorage"); + return NULL; + } + + ps = st_manager_get_egl_image_surface(st, &stimg); if (ps) { strb->Base.Width = ps->width; strb->Base.Height = ps->height; @@ -160,9 +185,33 @@ st_egl_image_target_texture_2d(struct gl_context *ctx, GLenum target, GLeglImageOES image_handle) { struct st_context *st = st_context(ctx); + struct st_manager *smapi = + (struct st_manager *) st->iface.st_context_private; + struct pipe_screen *screen = st->pipe->screen; + struct st_egl_image stimg; struct pipe_surface *ps; - ps = st_manager_get_egl_image_surface(st, (void *) image_handle); + if (!smapi || !smapi->get_egl_image) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glEGLImageTargetTexture2D"); + return NULL; + } + + memset(&stimg, 0, sizeof(stimg)); + if (!smapi->get_egl_image(smapi, (void *) image_handle, &stimg)) { + /* image_handle does not refer to a valid EGL image object */ + _mesa_error(ctx, GL_INVALID_VALUE, "glEGLImageTargetTexture2D"); + return NULL; + } + + if (!screen->is_format_supported(screen, stimg.format, PIPE_TEXTURE_2D, + stimg.texture->nr_samples, + PIPE_BIND_SAMPLER_VIEW)) { + /* unable to specify a texture object using the specified EGL image */ + _mesa_error(ctx, GL_INVALID_OPERATION, "glEGLImageTargetTexture2D"); + return NULL; + } + + ps = st_manager_get_egl_image_surface(st, &stimg); if (ps) { st_bind_surface(ctx, target, texObj, texImage, ps); pipe_surface_reference(&ps, NULL); diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c index dad408a..8f16da1 100644 --- a/src/mesa/state_tracker/st_manager.c +++ b/src/mesa/state_tracker/st_manager.c @@ -862,27 +862,18 @@ st_manager_flush_frontbuffer(struct st_context *st) * FIXME: I think this should operate on resources, not surfaces */ struct pipe_surface * -st_manager_get_egl_image_surface(struct st_context *st, void *eglimg) +st_manager_get_egl_image_surface(struct st_context *st, + struct st_egl_image *stimg) { - struct st_manager *smapi = - (struct st_manager *) st->iface.st_context_private; - struct st_egl_image stimg; struct pipe_surface *ps, surf_tmpl; - if (!smapi || !smapi->get_egl_image) - return NULL; - - memset(&stimg, 0, sizeof(stimg)); - if (!smapi->get_egl_image(smapi, eglimg, &stimg)) - return NULL; - - u_surface_default_template(&surf_tmpl, stimg.texture); - surf_tmpl.format = stimg.format; - surf_tmpl.u.tex.level = stimg.level; - surf_tmpl.u.tex.first_layer = stimg.layer; - surf_tmpl.u.tex.last_layer = stimg.layer; - ps = st->pipe->create_surface(st->pipe, stimg.texture, &surf_tmpl); - pipe_resource_reference(&stimg.texture, NULL); + u_surface_default_template(&surf_tmpl, stimg->texture); + surf_tmpl.format = stimg->format; + surf_tmpl.u.tex.level = stimg->level; + surf_tmpl.u.tex.first_layer = stimg->layer; + surf_tmpl.u.tex.last_layer = stimg->layer; + ps = st->pipe->create_surface(st->pipe, stimg->texture, &surf_tmpl); + pipe_resource_reference(&stimg->texture, NULL); return ps; } diff --git a/src/mesa/state_tracker/st_manager.h b/src/mesa/state_tracker/st_manager.h index bbb9b0f..8490c56 100644 --- a/src/mesa/state_tracker/st_manager.h +++ b/src/mesa/state_tracker/st_manager.h @@ -33,9 +33,11 @@ #include "pipe/p_compiler.h" struct st_context; +struct st_egl_image; struct pipe_surface * -st_manager_get_egl_image_surface(struct st_context *st, void *eglimg); +st_manager_get_egl_image_surface(struct st_context *st, + struct st_egl_image *stimg); void st_manager_flush_frontbuffer(struct st_context *st); -- 2.1.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev