#define WL_HIDE_DEPRECATED
+#include <stdbool.h>
#include <stdint.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#endif
#include "egl_dri2.h"
-#include "../util/u_atomic.h"
+#include "util/u_atomic.h"
+
+/* The kernel header drm_fourcc.h defines the DRM formats below. We duplicate
+ * some of the definitions here so that building Mesa won't bleeding-edge
+ * kernel headers.
+ */
+#ifndef DRM_FORMAT_R8
+#define DRM_FORMAT_R8 fourcc_code('R', '8', ' ', ' ') /* [7:0] R */
+#endif
+
+#ifndef DRM_FORMAT_RG88
+#define DRM_FORMAT_RG88 fourcc_code('R', 'G', '8', '8') /* [15:0] R:G 8:8 little endian */
+#endif
+
+#ifndef DRM_FORMAT_GR88
+#define DRM_FORMAT_GR88 fourcc_code('G', 'R', '8', '8') /* [15:0] G:R 8:8 little endian */
+#endif
const __DRIuseInvalidateExtension use_invalidate = {
.base = { __DRI_USE_INVALIDATE, 1 }
0, /* __DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE */
};
+const __DRIconfig *
+dri2_get_dri_config(struct dri2_egl_config *conf, EGLint surface_type,
+ EGLenum colorspace)
+{
+ const bool srgb = colorspace == EGL_GL_COLORSPACE_SRGB_KHR;
+
+ return surface_type == EGL_WINDOW_BIT ? conf->dri_double_config[srgb] :
+ conf->dri_single_config[srgb];
+}
+
static EGLBoolean
dri2_match_config(const _EGLConfig *conf, const _EGLConfig *criteria)
{
struct dri2_egl_display *dri2_dpy;
_EGLConfig base;
unsigned int attrib, value, double_buffer;
+ bool srgb = false;
EGLint key, bind_to_texture_rgb, bind_to_texture_rgba;
unsigned int dri_masks[4] = { 0, 0, 0, 0 };
_EGLConfig *matching_config;
return NULL;
break;
+ case __DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE:
+ srgb = value != 0;
+ if (!disp->Extensions.KHR_gl_colorspace && srgb)
+ return NULL;
+ break;
+
default:
key = dri2_to_egl_attribute_map[attrib];
if (key != 0)
if (num_configs == 1) {
conf = (struct dri2_egl_config *) matching_config;
- if (double_buffer && !conf->dri_double_config)
- conf->dri_double_config = dri_config;
- else if (!double_buffer && !conf->dri_single_config)
- conf->dri_single_config = dri_config;
+ if (double_buffer && !conf->dri_double_config[srgb])
+ conf->dri_double_config[srgb] = dri_config;
+ else if (!double_buffer && !conf->dri_single_config[srgb])
+ conf->dri_single_config[srgb] = dri_config;
else
/* a similar config type is already added (unlikely) => discard */
return NULL;
}
else if (num_configs == 0) {
- conf = malloc(sizeof *conf);
+ conf = calloc(1, sizeof *conf);
if (conf == NULL)
return NULL;
+ if (double_buffer)
+ conf->dri_double_config[srgb] = dri_config;
+ else
+ conf->dri_single_config[srgb] = dri_config;
+
memcpy(&conf->base, &base, sizeof base);
- if (double_buffer) {
- conf->dri_double_config = dri_config;
- conf->dri_single_config = NULL;
- } else {
- conf->dri_single_config = dri_config;
- conf->dri_double_config = NULL;
- }
conf->base.SurfaceType = 0;
conf->base.ConfigID = config_id;
int offset;
};
+static struct dri2_extension_match dri3_driver_extensions[] = {
+ { __DRI_CORE, 1, offsetof(struct dri2_egl_display, core) },
+ { __DRI_IMAGE_DRIVER, 1, offsetof(struct dri2_egl_display, image_driver) },
+ { NULL, 0, 0 }
+};
+
static struct dri2_extension_match dri2_driver_extensions[] = {
{ __DRI_CORE, 1, offsetof(struct dri2_egl_display, core) },
{ __DRI_DRI2, 2, offsetof(struct dri2_egl_display, dri2) },
void *field;
for (i = 0; extensions[i]; i++) {
- _eglLog(_EGL_DEBUG, "DRI2: found extension `%s'", extensions[i]->name);
+ _eglLog(_EGL_DEBUG, "found extension `%s'", extensions[i]->name);
for (j = 0; matches[j].name; j++) {
if (strcmp(extensions[i]->name, matches[j].name) == 0 &&
extensions[i]->version >= matches[j].version) {
field = ((char *) dri2_dpy + matches[j].offset);
*(const __DRIextension **) field = extensions[i];
- _eglLog(_EGL_INFO, "DRI2: found extension %s version %d",
+ _eglLog(_EGL_INFO, "found extension %s version %d",
extensions[i]->name, extensions[i]->version);
}
}
for (j = 0; matches[j].name; j++) {
field = ((char *) dri2_dpy + matches[j].offset);
if (*(const __DRIextension **) field == NULL) {
- _eglLog(_EGL_WARNING, "DRI2: did not find extension %s version %d",
+ _eglLog(_EGL_WARNING, "did not find extension %s version %d",
matches[j].name, matches[j].version);
ret = EGL_FALSE;
}
return extensions;
}
+EGLBoolean
+dri2_load_driver_dri3(_EGLDisplay *disp)
+{
+ struct dri2_egl_display *dri2_dpy = disp->DriverData;
+ const __DRIextension **extensions;
+
+ extensions = dri2_open_driver(disp);
+ if (!extensions)
+ return EGL_FALSE;
+
+ if (!dri2_bind_extensions(dri2_dpy, dri3_driver_extensions, extensions)) {
+ dlclose(dri2_dpy->driver);
+ return EGL_FALSE;
+ }
+ dri2_dpy->driver_extensions = extensions;
+
+ return EGL_TRUE;
+}
+
EGLBoolean
dri2_load_driver(_EGLDisplay *disp)
{
return EGL_TRUE;
}
+static unsigned
+dri2_renderer_query_integer(struct dri2_egl_display *dri2_dpy, int param)
+{
+ const __DRI2rendererQueryExtension *rendererQuery = dri2_dpy->rendererQuery;
+ unsigned int value = 0;
+
+ if (!rendererQuery ||
+ rendererQuery->queryInteger(dri2_dpy->dri_screen, param, &value) == -1)
+ return 0;
+
+ return value;
+}
+
void
dri2_setup_screen(_EGLDisplay *disp)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
unsigned int api_mask;
- if (dri2_dpy->dri2) {
+ if (dri2_dpy->image_driver) {
+ api_mask = dri2_dpy->image_driver->getAPIMask(dri2_dpy->dri_screen);
+ } else if (dri2_dpy->dri2) {
api_mask = dri2_dpy->dri2->getAPIMask(dri2_dpy->dri_screen);
} else {
assert(dri2_dpy->swrast);
if (api_mask & (1 << __DRI_API_GLES3))
disp->ClientAPIs |= EGL_OPENGL_ES3_BIT_KHR;
- assert(dri2_dpy->dri2 || dri2_dpy->swrast);
+ assert(dri2_dpy->image_driver || dri2_dpy->dri2 || dri2_dpy->swrast);
disp->Extensions.KHR_surfaceless_context = EGL_TRUE;
disp->Extensions.MESA_configless_context = EGL_TRUE;
- if (dri2_dpy->dri2 && dri2_dpy->dri2->base.version >= 3) {
+ if (dri2_renderer_query_integer(dri2_dpy,
+ __DRI2_RENDERER_HAS_FRAMEBUFFER_SRGB))
+ disp->Extensions.KHR_gl_colorspace = EGL_TRUE;
+
+ if (dri2_dpy->image_driver ||
+ (dri2_dpy->dri2 && dri2_dpy->dri2->base.version >= 3) ||
+ (dri2_dpy->swrast && dri2_dpy->swrast->base.version >= 3)) {
disp->Extensions.KHR_create_context = EGL_TRUE;
if (dri2_dpy->robustness)
disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE;
disp->Extensions.KHR_gl_texture_cubemap_image = EGL_TRUE;
}
+ if (dri2_renderer_query_integer(dri2_dpy,
+ __DRI2_RENDERER_HAS_TEXTURE_3D))
+ disp->Extensions.KHR_gl_texture_3D_image = EGL_TRUE;
#ifdef HAVE_LIBDRM
if (dri2_dpy->image->base.version >= 8 &&
dri2_dpy->image->createImageFromDmaBufs) {
dri2_dpy = disp->DriverData;
- if (dri2_dpy->dri2) {
+ if (dri2_dpy->image_driver) {
+ dri2_dpy->dri_screen =
+ dri2_dpy->image_driver->createNewScreen2(0, dri2_dpy->fd,
+ dri2_dpy->extensions,
+ dri2_dpy->driver_extensions,
+ &dri2_dpy->driver_configs,
+ disp);
+ } else if (dri2_dpy->dri2) {
if (dri2_dpy->dri2->base.version >= 4) {
dri2_dpy->dri_screen =
dri2_dpy->dri2->createNewScreen2(0, dri2_dpy->fd,
extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen);
- if (dri2_dpy->dri2) {
+ if (dri2_dpy->image_driver || dri2_dpy->dri2) {
if (!dri2_bind_extensions(dri2_dpy, dri2_core_extensions, extensions))
goto cleanup_dri_screen;
} else {
if (strcmp(extensions[i]->name, __DRI2_FENCE) == 0) {
dri2_dpy->fence = (__DRI2fenceExtension *) extensions[i];
}
+ if (strcmp(extensions[i]->name, __DRI2_RENDERER_QUERY) == 0) {
+ dri2_dpy->rendererQuery = (__DRI2rendererQueryExtension *) extensions[i];
+ }
}
dri2_setup_screen(disp);
if (dri2_dpy->own_dri_screen)
dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
- if (dri2_dpy->fd)
+ if (dri2_dpy->fd >= 0)
close(dri2_dpy->fd);
if (dri2_dpy->driver)
dlclose(dri2_dpy->driver);
_eglError(egl_error, "dri2_create_context");
}
+static bool
+dri2_fill_context_attribs(struct dri2_egl_context *dri2_ctx,
+ struct dri2_egl_display *dri2_dpy,
+ uint32_t *ctx_attribs,
+ unsigned *num_attribs)
+{
+ int pos = 0;
+
+ assert(*num_attribs >= 8);
+
+ ctx_attribs[pos++] = __DRI_CTX_ATTRIB_MAJOR_VERSION;
+ ctx_attribs[pos++] = dri2_ctx->base.ClientMajorVersion;
+ ctx_attribs[pos++] = __DRI_CTX_ATTRIB_MINOR_VERSION;
+ ctx_attribs[pos++] = dri2_ctx->base.ClientMinorVersion;
+
+ if (dri2_ctx->base.Flags != 0) {
+ /* If the implementation doesn't support the __DRI2_ROBUSTNESS
+ * extension, don't even try to send it the robust-access flag.
+ * It may explode. Instead, generate the required EGL error here.
+ */
+ if ((dri2_ctx->base.Flags & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) != 0
+ && !dri2_dpy->robustness) {
+ _eglError(EGL_BAD_MATCH, "eglCreateContext");
+ return false;
+ }
+
+ ctx_attribs[pos++] = __DRI_CTX_ATTRIB_FLAGS;
+ ctx_attribs[pos++] = dri2_ctx->base.Flags;
+ }
+
+ if (dri2_ctx->base.ResetNotificationStrategy != EGL_NO_RESET_NOTIFICATION_KHR) {
+ /* If the implementation doesn't support the __DRI2_ROBUSTNESS
+ * extension, don't even try to send it a reset strategy. It may
+ * explode. Instead, generate the required EGL error here.
+ */
+ if (!dri2_dpy->robustness) {
+ _eglError(EGL_BAD_CONFIG, "eglCreateContext");
+ return false;
+ }
+
+ ctx_attribs[pos++] = __DRI_CTX_ATTRIB_RESET_STRATEGY;
+ ctx_attribs[pos++] = __DRI_CTX_RESET_LOSE_CONTEXT;
+ }
+
+ *num_attribs = pos;
+
+ return true;
+}
+
/**
* Called via eglCreateContext(), drv->API.CreateContext().
*/
* doubleBufferMode check in
* src/mesa/main/context.c:check_compatible()
*/
- if (dri2_config->dri_double_config)
- dri_config = dri2_config->dri_double_config;
+ if (dri2_config->dri_double_config[0])
+ dri_config = dri2_config->dri_double_config[0];
else
- dri_config = dri2_config->dri_single_config;
+ dri_config = dri2_config->dri_single_config[0];
/* EGL_WINDOW_BIT is set only when there is a dri_double_config. This
* makes sure the back buffer will always be used.
else
dri_config = NULL;
- if (dri2_dpy->dri2) {
+ if (dri2_dpy->image_driver) {
+ unsigned error;
+ unsigned num_attribs = 8;
+ uint32_t ctx_attribs[8];
+
+ if (!dri2_fill_context_attribs(dri2_ctx, dri2_dpy, ctx_attribs,
+ &num_attribs))
+ goto cleanup;
+
+ dri2_ctx->dri_context =
+ dri2_dpy->image_driver->createContextAttribs(dri2_dpy->dri_screen,
+ api,
+ dri_config,
+ shared,
+ num_attribs / 2,
+ ctx_attribs,
+ & error,
+ dri2_ctx);
+ dri2_create_context_attribs_error(error);
+ } else if (dri2_dpy->dri2) {
if (dri2_dpy->dri2->base.version >= 3) {
unsigned error;
- unsigned num_attribs = 0;
+ unsigned num_attribs = 8;
uint32_t ctx_attribs[8];
- ctx_attribs[num_attribs++] = __DRI_CTX_ATTRIB_MAJOR_VERSION;
- ctx_attribs[num_attribs++] = dri2_ctx->base.ClientMajorVersion;
- ctx_attribs[num_attribs++] = __DRI_CTX_ATTRIB_MINOR_VERSION;
- ctx_attribs[num_attribs++] = dri2_ctx->base.ClientMinorVersion;
-
- if (dri2_ctx->base.Flags != 0) {
- /* If the implementation doesn't support the __DRI2_ROBUSTNESS
- * extension, don't even try to send it the robust-access flag.
- * It may explode. Instead, generate the required EGL error here.
- */
- if ((dri2_ctx->base.Flags & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) != 0
- && !dri2_dpy->robustness) {
- _eglError(EGL_BAD_MATCH, "eglCreateContext");
- goto cleanup;
- }
-
- ctx_attribs[num_attribs++] = __DRI_CTX_ATTRIB_FLAGS;
- ctx_attribs[num_attribs++] = dri2_ctx->base.Flags;
- }
-
- if (dri2_ctx->base.ResetNotificationStrategy != EGL_NO_RESET_NOTIFICATION_KHR) {
- /* If the implementation doesn't support the __DRI2_ROBUSTNESS
- * extension, don't even try to send it a reset strategy. It may
- * explode. Instead, generate the required EGL error here.
- */
- if (!dri2_dpy->robustness) {
- _eglError(EGL_BAD_CONFIG, "eglCreateContext");
- goto cleanup;
- }
-
- ctx_attribs[num_attribs++] = __DRI_CTX_ATTRIB_RESET_STRATEGY;
- ctx_attribs[num_attribs++] = __DRI_CTX_RESET_LOSE_CONTEXT;
- }
-
- assert(num_attribs <= ARRAY_SIZE(ctx_attribs));
+ if (!dri2_fill_context_attribs(dri2_ctx, dri2_dpy, ctx_attribs,
+ &num_attribs))
+ goto cleanup;
dri2_ctx->dri_context =
dri2_dpy->dri2->createContextAttribs(dri2_dpy->dri_screen,
}
} else {
assert(dri2_dpy->swrast);
- dri2_ctx->dri_context =
- dri2_dpy->swrast->createNewContextForAPI(dri2_dpy->dri_screen,
- api,
- dri_config,
- shared,
- dri2_ctx);
+ if (dri2_dpy->swrast->base.version >= 3) {
+ unsigned error;
+ unsigned num_attribs = 8;
+ uint32_t ctx_attribs[8];
+
+ if (!dri2_fill_context_attribs(dri2_ctx, dri2_dpy, ctx_attribs,
+ &num_attribs))
+ goto cleanup;
+
+ dri2_ctx->dri_context =
+ dri2_dpy->swrast->createContextAttribs(dri2_dpy->dri_screen,
+ api,
+ dri_config,
+ shared,
+ num_attribs / 2,
+ ctx_attribs,
+ & error,
+ dri2_ctx);
+ dri2_create_context_attribs_error(error);
+ } else {
+ dri2_ctx->dri_context =
+ dri2_dpy->swrast->createNewContextForAPI(dri2_dpy->dri_screen,
+ api,
+ dri_config,
+ shared,
+ dri2_ctx);
+ }
}
if (!dri2_ctx->dri_context)
{
struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv);
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
- struct dri2_egl_surface *dri2_dsurf = dri2_egl_surface(dsurf);
- struct dri2_egl_surface *dri2_rsurf = dri2_egl_surface(rsurf);
struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
_EGLContext *old_ctx;
_EGLSurface *old_dsurf, *old_rsurf;
+ _EGLSurface *tmp_dsurf, *tmp_rsurf;
__DRIdrawable *ddraw, *rdraw;
__DRIcontext *cctx;
if (old_ctx && dri2_drv->glFlush)
dri2_drv->glFlush();
- ddraw = (dri2_dsurf) ? dri2_dsurf->dri_drawable : NULL;
- rdraw = (dri2_rsurf) ? dri2_rsurf->dri_drawable : NULL;
+ ddraw = (dsurf) ? dri2_dpy->vtbl->get_dri_drawable(dsurf) : NULL;
+ rdraw = (rsurf) ? dri2_dpy->vtbl->get_dri_drawable(rsurf) : NULL;
cctx = (dri2_ctx) ? dri2_ctx->dri_context : NULL;
if (old_ctx) {
return EGL_TRUE;
} else {
/* undo the previous _eglBindContext */
- _eglBindContext(old_ctx, old_dsurf, old_rsurf, &ctx, &dsurf, &rsurf);
+ _eglBindContext(old_ctx, old_dsurf, old_rsurf, &ctx, &tmp_dsurf, &tmp_rsurf);
assert(&dri2_ctx->base == ctx &&
- &dri2_dsurf->base == dsurf &&
- &dri2_rsurf->base == rsurf);
+ tmp_dsurf == dsurf &&
+ tmp_rsurf == rsurf);
_eglPutSurface(dsurf);
_eglPutSurface(rsurf);
}
}
+__DRIdrawable *
+dri2_surface_get_dri_drawable(_EGLSurface *surf)
+{
+ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
+
+ return dri2_surf->dri_drawable;
+}
+
/*
* Called from eglGetProcAddress() via drv->API.GetProcAddress().
*/
dri2_flush_drawable_for_swapbuffers(_EGLDisplay *disp, _EGLSurface *draw)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
- struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
+ __DRIdrawable *dri_drawable = dri2_dpy->vtbl->get_dri_drawable(draw);
if (dri2_dpy->flush) {
if (dri2_dpy->flush->base.version >= 4) {
* after calling eglSwapBuffers."
*/
dri2_dpy->flush->flush_with_flags(dri2_ctx->dri_context,
- dri2_surf->dri_drawable,
+ dri_drawable,
__DRI2_FLUSH_DRAWABLE |
__DRI2_FLUSH_INVALIDATE_ANCILLARY,
__DRI2_THROTTLE_SWAPBUFFER);
} else {
- dri2_dpy->flush->flush(dri2_surf->dri_drawable);
+ dri2_dpy->flush->flush(dri_drawable);
}
}
}
dri2_wait_client(_EGLDriver *drv, _EGLDisplay *disp, _EGLContext *ctx)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
- struct dri2_egl_surface *dri2_surf = dri2_egl_surface(ctx->DrawSurface);
+ _EGLSurface *surf = ctx->DrawSurface;
+ __DRIdrawable *dri_drawable = dri2_dpy->vtbl->get_dri_drawable(surf);
(void) drv;
* we need to copy fake to real here.*/
if (dri2_dpy->flush != NULL)
- dri2_dpy->flush->flush(dri2_surf->dri_drawable);
+ dri2_dpy->flush->flush(dri_drawable);
return EGL_TRUE;
}
_EGLDisplay *disp, _EGLSurface *surf, EGLint buffer)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
- struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
struct dri2_egl_context *dri2_ctx;
_EGLContext *ctx;
GLint format, target;
+ __DRIdrawable *dri_drawable = dri2_dpy->vtbl->get_dri_drawable(surf);
ctx = _eglGetCurrentContext();
dri2_ctx = dri2_egl_context(ctx);
if (!_eglBindTexImage(drv, disp, surf, buffer))
return EGL_FALSE;
- switch (dri2_surf->base.TextureFormat) {
+ switch (surf->TextureFormat) {
case EGL_TEXTURE_RGB:
format = __DRI_TEXTURE_FORMAT_RGB;
break;
format = __DRI_TEXTURE_FORMAT_RGBA;
}
- switch (dri2_surf->base.TextureTarget) {
+ switch (surf->TextureTarget) {
case EGL_TEXTURE_2D:
target = GL_TEXTURE_2D;
break;
(*dri2_dpy->tex_buffer->setTexBuffer2)(dri2_ctx->dri_context,
target, format,
- dri2_surf->dri_drawable);
+ dri_drawable);
return EGL_TRUE;
}
_EGLDisplay *disp, _EGLSurface *surf, EGLint buffer)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
- struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
struct dri2_egl_context *dri2_ctx;
_EGLContext *ctx;
GLint target;
+ __DRIdrawable *dri_drawable = dri2_dpy->vtbl->get_dri_drawable(surf);
ctx = _eglGetCurrentContext();
dri2_ctx = dri2_egl_context(ctx);
if (!_eglReleaseTexImage(drv, disp, surf, buffer))
return EGL_FALSE;
- switch (dri2_surf->base.TextureTarget) {
+ switch (surf->TextureTarget) {
case EGL_TEXTURE_2D:
target = GL_TEXTURE_2D;
break;
dri2_dpy->tex_buffer->releaseTexBuffer != NULL) {
(*dri2_dpy->tex_buffer->releaseTexBuffer)(dri2_ctx->dri_context,
target,
- dri2_surf->dri_drawable);
+ dri_drawable);
}
return EGL_TRUE;
return dri2_create_image_from_dri(disp, dri_image);
}
-#ifdef HAVE_LIBDRM
-static _EGLImage *
-dri2_create_image_mesa_drm_buffer(_EGLDisplay *disp, _EGLContext *ctx,
- EGLClientBuffer buffer, const EGLint *attr_list)
-{
- struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
- EGLint format, name, pitch, err;
- _EGLImageAttribs attrs;
- __DRIimage *dri_image;
-
- name = (EGLint) (uintptr_t) buffer;
-
- err = _eglParseImageAttribList(&attrs, disp, attr_list);
- if (err != EGL_SUCCESS)
- return NULL;
-
- if (attrs.Width <= 0 || attrs.Height <= 0 ||
- attrs.DRMBufferStrideMESA <= 0) {
- _eglError(EGL_BAD_PARAMETER,
- "bad width, height or stride");
- return NULL;
- }
-
- switch (attrs.DRMBufferFormatMESA) {
- case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA:
- format = __DRI_IMAGE_FORMAT_ARGB8888;
- pitch = attrs.DRMBufferStrideMESA;
- break;
- default:
- _eglError(EGL_BAD_PARAMETER,
- "dri2_create_image_khr: unsupported pixmap depth");
- return NULL;
- }
-
- dri_image =
- dri2_dpy->image->createImageFromName(dri2_dpy->dri_screen,
- attrs.Width,
- attrs.Height,
- format,
- name,
- pitch,
- NULL);
-
- return dri2_create_image_from_dri(disp, dri_image);
-}
-#endif
-
#ifdef HAVE_WAYLAND_PLATFORM
/* This structure describes how a wl_buffer maps to one or more
egl_error = EGL_BAD_PARAMETER;
break;
+ case __DRI_IMAGE_ERROR_BAD_ACCESS:
+ egl_error = EGL_BAD_ACCESS;
+ break;
+
default:
assert(0);
egl_error = EGL_BAD_MATCH;
}
#ifdef HAVE_LIBDRM
+static _EGLImage *
+dri2_create_image_mesa_drm_buffer(_EGLDisplay *disp, _EGLContext *ctx,
+ EGLClientBuffer buffer, const EGLint *attr_list)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ EGLint format, name, pitch, err;
+ _EGLImageAttribs attrs;
+ __DRIimage *dri_image;
+
+ name = (EGLint) (uintptr_t) buffer;
+
+ err = _eglParseImageAttribList(&attrs, disp, attr_list);
+ if (err != EGL_SUCCESS)
+ return NULL;
+
+ if (attrs.Width <= 0 || attrs.Height <= 0 ||
+ attrs.DRMBufferStrideMESA <= 0) {
+ _eglError(EGL_BAD_PARAMETER,
+ "bad width, height or stride");
+ return NULL;
+ }
+
+ switch (attrs.DRMBufferFormatMESA) {
+ case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA:
+ format = __DRI_IMAGE_FORMAT_ARGB8888;
+ pitch = attrs.DRMBufferStrideMESA;
+ break;
+ default:
+ _eglError(EGL_BAD_PARAMETER,
+ "dri2_create_image_khr: unsupported pixmap depth");
+ return NULL;
+ }
+
+ dri_image =
+ dri2_dpy->image->createImageFromName(dri2_dpy->dri_screen,
+ attrs.Width,
+ attrs.Height,
+ format,
+ name,
+ pitch,
+ NULL);
+
+ return dri2_create_image_from_dri(disp, dri_image);
+}
+
static EGLBoolean
dri2_check_dma_buf_attribs(const _EGLImageAttribs *attrs)
{
unsigned i, plane_n;
switch (attrs->DMABufFourCC.Value) {
+ case DRM_FORMAT_R8:
+ case DRM_FORMAT_RG88:
+ case DRM_FORMAT_GR88:
case DRM_FORMAT_RGB332:
case DRM_FORMAT_BGR233:
case DRM_FORMAT_XRGB4444:
return res;
}
-#endif
-
-_EGLImage *
-dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
- _EGLContext *ctx, EGLenum target,
- EGLClientBuffer buffer, const EGLint *attr_list)
-{
- (void) drv;
-
- switch (target) {
- case EGL_GL_TEXTURE_2D_KHR:
- case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
- case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
- case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
- case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
- case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
- case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
- return dri2_create_image_khr_texture(disp, ctx, target, buffer, attr_list);
- case EGL_GL_TEXTURE_3D_KHR:
- if (disp->Extensions.KHR_gl_texture_3D_image) {
- return dri2_create_image_khr_texture(disp, ctx, target, buffer, attr_list);
- }
- else {
- _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
- return EGL_NO_IMAGE_KHR;
- }
- case EGL_GL_RENDERBUFFER_KHR:
- return dri2_create_image_khr_renderbuffer(disp, ctx, buffer, attr_list);
-#ifdef HAVE_LIBDRM
- case EGL_DRM_BUFFER_MESA:
- return dri2_create_image_mesa_drm_buffer(disp, ctx, buffer, attr_list);
-#endif
-#ifdef HAVE_WAYLAND_PLATFORM
- case EGL_WAYLAND_BUFFER_WL:
- return dri2_create_image_wayland_wl_buffer(disp, ctx, buffer, attr_list);
-#endif
-#ifdef HAVE_LIBDRM
- case EGL_LINUX_DMA_BUF_EXT:
- return dri2_create_image_dma_buf(disp, ctx, buffer, attr_list);
-#endif
- default:
- _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
- return EGL_NO_IMAGE_KHR;
- }
-}
-
-static EGLBoolean
-dri2_destroy_image_khr(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *image)
-{
- struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
- struct dri2_egl_image *dri2_img = dri2_egl_image(image);
-
- (void) drv;
-
- dri2_dpy->image->destroyImage(dri2_img->dri_image);
- free(dri2_img);
-
- return EGL_TRUE;
-}
-
-#ifdef HAVE_LIBDRM
static _EGLImage *
dri2_create_drm_image_mesa(_EGLDriver *drv, _EGLDisplay *disp,
const EGLint *attr_list)
return EGL_TRUE;
}
+
#endif
+_EGLImage *
+dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
+ _EGLContext *ctx, EGLenum target,
+ EGLClientBuffer buffer, const EGLint *attr_list)
+{
+ (void) drv;
+
+ switch (target) {
+ case EGL_GL_TEXTURE_2D_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
+ return dri2_create_image_khr_texture(disp, ctx, target, buffer, attr_list);
+ case EGL_GL_TEXTURE_3D_KHR:
+ if (disp->Extensions.KHR_gl_texture_3D_image) {
+ return dri2_create_image_khr_texture(disp, ctx, target, buffer, attr_list);
+ }
+ else {
+ _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
+ return EGL_NO_IMAGE_KHR;
+ }
+ case EGL_GL_RENDERBUFFER_KHR:
+ return dri2_create_image_khr_renderbuffer(disp, ctx, buffer, attr_list);
+#ifdef HAVE_LIBDRM
+ case EGL_DRM_BUFFER_MESA:
+ return dri2_create_image_mesa_drm_buffer(disp, ctx, buffer, attr_list);
+ case EGL_LINUX_DMA_BUF_EXT:
+ return dri2_create_image_dma_buf(disp, ctx, buffer, attr_list);
+#endif
+#ifdef HAVE_WAYLAND_PLATFORM
+ case EGL_WAYLAND_BUFFER_WL:
+ return dri2_create_image_wayland_wl_buffer(disp, ctx, buffer, attr_list);
+#endif
+ default:
+ _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
+ return EGL_NO_IMAGE_KHR;
+ }
+}
+
+static EGLBoolean
+dri2_destroy_image_khr(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *image)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct dri2_egl_image *dri2_img = dri2_egl_image(image);
+
+ (void) drv;
+
+ dri2_dpy->image->destroyImage(dri2_img->dri_image);
+ free(dri2_img);
+
+ return EGL_TRUE;
+}
+
#ifdef HAVE_WAYLAND_PLATFORM
static void
wl_drm_callbacks.authenticate =
(int(*)(void *, uint32_t)) dri2_dpy->vtbl->authenticate;
-#ifdef HAVE_LIBDRM
if (drmGetCap(dri2_dpy->fd, DRM_CAP_PRIME, &cap) == 0 &&
cap == (DRM_PRIME_CAP_IMPORT | DRM_PRIME_CAP_EXPORT) &&
dri2_dpy->image->base.version >= 7 &&
dri2_dpy->image->createImageFromFds != NULL)
flags |= WAYLAND_DRM_PRIME;
-#endif
dri2_dpy->wl_server_drm =
wayland_drm_init(wl_dpy, dri2_dpy->device_name,
unsigned wait_flags = 0;
EGLint ret = EGL_CONDITION_SATISFIED_KHR;
- if (flags & EGL_SYNC_FLUSH_COMMANDS_BIT_KHR)
+ /* The EGL_KHR_fence_sync spec states:
+ *
+ * "If no context is current for the bound API,
+ * the EGL_SYNC_FLUSH_COMMANDS_BIT_KHR bit is ignored.
+ */
+ if (dri2_ctx && flags & EGL_SYNC_FLUSH_COMMANDS_BIT_KHR)
wait_flags |= __DRI2_FENCE_FLAG_FLUSH_COMMANDS;
/* the sync object should take a reference while waiting */
dri2_egl_ref_sync(dri2_sync);
- if (dri2_dpy->fence->client_wait_sync(dri2_ctx->dri_context,
+ if (dri2_dpy->fence->client_wait_sync(dri2_ctx ? dri2_ctx->dri_context : NULL,
dri2_sync->fence, wait_flags,
timeout))
dri2_sync->base.SyncStatus = EGL_SIGNALED_KHR;
dri2_load(_EGLDriver *drv)
{
struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv);
-#ifdef HAVE_SHARED_GLAPI
#ifdef HAVE_ANDROID_PLATFORM
const char *libname = "libglapi.so";
#elif defined(__APPLE__)
const char *libname = "libglapi.0.dylib";
#else
const char *libname = "libglapi.so.0";
-#endif
-#else
- /*
- * Both libGL.so and libglapi.so are glapi providers. There is no way to
- * tell which one to load.
- */
- const char *libname = NULL;
#endif
void *handle;