+static bool
+is_format_supported(struct pipe_screen *screen, enum pipe_format format,
+ unsigned nr_samples, unsigned nr_storage_samples,
+ unsigned usage, bool *native_supported)
+{
+ bool supported = screen->is_format_supported(screen, format, PIPE_TEXTURE_2D,
+ nr_samples, nr_storage_samples,
+ usage);
+ *native_supported = supported;
+
+ /* for sampling, some formats can be emulated.. it doesn't matter that
+ * the surface will have a format that the driver can't cope with because
+ * we'll give it sampler view formats that it can deal with and generate
+ * a shader variant that converts.
+ */
+ if ((usage == PIPE_BIND_SAMPLER_VIEW) && !supported) {
+ switch (format) {
+ case PIPE_FORMAT_IYUV:
+ supported = screen->is_format_supported(screen, PIPE_FORMAT_R8_UNORM,
+ PIPE_TEXTURE_2D, nr_samples,
+ nr_storage_samples, usage);
+ break;
+ case PIPE_FORMAT_NV12:
+ supported = screen->is_format_supported(screen, PIPE_FORMAT_R8_UNORM,
+ PIPE_TEXTURE_2D, nr_samples,
+ nr_storage_samples, usage) &&
+ screen->is_format_supported(screen, PIPE_FORMAT_R8G8_UNORM,
+ PIPE_TEXTURE_2D, nr_samples,
+ nr_storage_samples, usage);
+ break;
+ case PIPE_FORMAT_P016:
+ supported = screen->is_format_supported(screen, PIPE_FORMAT_R16_UNORM,
+ PIPE_TEXTURE_2D, nr_samples,
+ nr_storage_samples, usage) &&
+ screen->is_format_supported(screen, PIPE_FORMAT_R16G16_UNORM,
+ PIPE_TEXTURE_2D, nr_samples,
+ nr_storage_samples, usage);
+ break;
+ case PIPE_FORMAT_YUYV:
+ supported = screen->is_format_supported(screen, PIPE_FORMAT_RG88_UNORM,
+ PIPE_TEXTURE_2D, nr_samples,
+ nr_storage_samples, usage) &&
+ screen->is_format_supported(screen, PIPE_FORMAT_BGRA8888_UNORM,
+ PIPE_TEXTURE_2D, nr_samples,
+ nr_storage_samples, usage);
+ break;
+ case PIPE_FORMAT_UYVY:
+ supported = screen->is_format_supported(screen, PIPE_FORMAT_RG88_UNORM,
+ PIPE_TEXTURE_2D, nr_samples,
+ nr_storage_samples, usage) &&
+ screen->is_format_supported(screen, PIPE_FORMAT_RGBA8888_UNORM,
+ PIPE_TEXTURE_2D, nr_samples,
+ nr_storage_samples, usage);
+ break;
+ case PIPE_FORMAT_AYUV:
+ supported = screen->is_format_supported(screen, PIPE_FORMAT_RGBA8888_UNORM,
+ PIPE_TEXTURE_2D, nr_samples,
+ nr_storage_samples, usage);
+ break;
+ case PIPE_FORMAT_XYUV:
+ supported = screen->is_format_supported(screen, PIPE_FORMAT_RGBX8888_UNORM,
+ PIPE_TEXTURE_2D, nr_samples,
+ nr_storage_samples, usage);
+ break;
+ default:
+ break;
+ }
+ }
+
+ return supported;
+}
+
+/**
+ * Return the gallium texture of an EGLImage.
+ */
+static bool
+st_get_egl_image(struct gl_context *ctx, GLeglImageOES image_handle,
+ unsigned usage, const char *error, struct st_egl_image *out,
+ bool *native_supported)
+{
+ struct st_context *st = st_context(ctx);
+ struct pipe_screen *screen = st->pipe->screen;
+ struct st_manager *smapi =
+ (struct st_manager *) st->iface.st_context_private;
+
+ if (!smapi || !smapi->get_egl_image)
+ return false;
+
+ memset(out, 0, sizeof(*out));
+ if (!smapi->get_egl_image(smapi, (void *) image_handle, out)) {
+ /* image_handle does not refer to a valid EGL image object */
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(image handle not found)", error);
+ return false;
+ }
+
+ if (!is_format_supported(screen, out->format, out->texture->nr_samples,
+ out->texture->nr_storage_samples, usage,
+ native_supported)) {
+ /* unable to specify a texture object using the specified EGL image */
+ pipe_resource_reference(&out->texture, NULL);
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(format not supported)", error);
+ return false;
+ }
+
+ return true;
+}