summaryrefslogtreecommitdiff
path: root/lib/mesa/src/gbm/backends
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2016-12-11 08:40:05 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2016-12-11 08:40:05 +0000
commit21ab4c9f31674b113c24177398ed39f29b7cd8e6 (patch)
tree8be392d7a792d9663c2586396be77bfd506f5164 /lib/mesa/src/gbm/backends
parenta8f0a7916e26e550dd2a26e7188835c481978004 (diff)
Import Mesa 13.0.2
Diffstat (limited to 'lib/mesa/src/gbm/backends')
-rw-r--r--lib/mesa/src/gbm/backends/dri/gbm_dri.c112
-rw-r--r--lib/mesa/src/gbm/backends/dri/gbm_driint.h12
2 files changed, 109 insertions, 15 deletions
diff --git a/lib/mesa/src/gbm/backends/dri/gbm_dri.c b/lib/mesa/src/gbm/backends/dri/gbm_dri.c
index 57cdeacdc..88f4428a5 100644
--- a/lib/mesa/src/gbm/backends/dri/gbm_dri.c
+++ b/lib/mesa/src/gbm/backends/dri/gbm_dri.c
@@ -32,6 +32,7 @@
#include <string.h>
#include <errno.h>
#include <limits.h>
+#include <assert.h>
#include <sys/types.h>
#include <unistd.h>
@@ -238,11 +239,13 @@ struct dri_extension_match {
const char *name;
int version;
int offset;
+ int optional;
};
static struct dri_extension_match dri_core_extensions[] = {
{ __DRI2_FLUSH, 1, offsetof(struct gbm_dri_device, flush) },
{ __DRI_IMAGE, 1, offsetof(struct gbm_dri_device, image) },
+ { __DRI2_FENCE, 1, offsetof(struct gbm_dri_device, fence), 1 },
{ NULL, 0, 0 }
};
@@ -278,7 +281,7 @@ dri_bind_extensions(struct gbm_dri_device *dri,
for (j = 0; matches[j].name; j++) {
field = ((char *) dri + matches[j].offset);
- if (*(const __DRIextension **) field == NULL) {
+ if ((*(const __DRIextension **) field == NULL) && !matches[j].optional) {
ret = -1;
}
}
@@ -341,6 +344,15 @@ dri_open_driver(struct gbm_dri_device *dri)
/* not need continue to loop all paths once the driver is found */
if (dri->driver != NULL)
break;
+
+#ifdef ANDROID
+ snprintf(path, sizeof path, "%.*s/gallium_dri.so", len, p);
+ dri->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
+ if (dri->driver == NULL)
+ sprintf("failed to open %s: %s\n", path, dlerror());
+ else
+ break;
+#endif
}
if (dri->driver == NULL) {
@@ -427,19 +439,19 @@ dri_screen_create_dri2(struct gbm_dri_device *dri, char *driver_name)
return ret;
};
- dri->extensions = gbm_dri_screen_extensions;
+ dri->loader_extensions = gbm_dri_screen_extensions;
if (dri->dri2 == NULL)
return -1;
if (dri->dri2->base.version >= 4) {
dri->screen = dri->dri2->createNewScreen2(0, dri->base.base.fd,
- dri->extensions,
+ dri->loader_extensions,
dri->driver_extensions,
&dri->driver_configs, dri);
} else {
dri->screen = dri->dri2->createNewScreen(0, dri->base.base.fd,
- dri->extensions,
+ dri->loader_extensions,
&dri->driver_configs, dri);
}
if (dri->screen == NULL)
@@ -477,17 +489,17 @@ dri_screen_create_swrast(struct gbm_dri_device *dri)
return ret;
}
- dri->extensions = gbm_dri_screen_extensions;
+ dri->loader_extensions = gbm_dri_screen_extensions;
if (dri->swrast == NULL)
return -1;
if (dri->swrast->base.version >= 4) {
- dri->screen = dri->swrast->createNewScreen2(0, dri->extensions,
+ dri->screen = dri->swrast->createNewScreen2(0, dri->loader_extensions,
dri->driver_extensions,
&dri->driver_configs, dri);
} else {
- dri->screen = dri->swrast->createNewScreen(0, dri->extensions,
+ dri->screen = dri->swrast->createNewScreen(0, dri->loader_extensions,
&dri->driver_configs, dri);
}
if (dri->screen == NULL)
@@ -504,7 +516,7 @@ dri_screen_create(struct gbm_dri_device *dri)
{
char *driver_name;
- driver_name = loader_get_driver_for_fd(dri->base.base.fd, 0);
+ driver_name = loader_get_driver_for_fd(dri->base.base.fd);
if (!driver_name)
return -1;
@@ -535,6 +547,7 @@ gbm_dri_is_format_supported(struct gbm_device *gbm,
{
switch (format) {
case GBM_BO_FORMAT_XRGB8888:
+ case GBM_FORMAT_XBGR8888:
case GBM_FORMAT_XRGB8888:
break;
case GBM_BO_FORMAT_ARGB8888:
@@ -578,7 +591,8 @@ gbm_dri_bo_get_fd(struct gbm_bo *_bo)
if (bo->image == NULL)
return -1;
- dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_FD, &fd);
+ if (!dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_FD, &fd))
+ return -1;
return fd;
}
@@ -593,7 +607,7 @@ gbm_dri_bo_destroy(struct gbm_bo *_bo)
if (bo->image != NULL) {
dri->image->destroyImage(bo->image);
} else {
- gbm_dri_bo_unmap(bo);
+ gbm_dri_bo_unmap_dumb(bo);
memset(&arg, 0, sizeof(arg));
arg.handle = bo->handle;
drmIoctl(dri->base.base.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &arg);
@@ -617,6 +631,9 @@ gbm_dri_to_gbm_format(uint32_t dri_format)
case __DRI_IMAGE_FORMAT_ARGB8888:
ret = GBM_FORMAT_ARGB8888;
break;
+ case __DRI_IMAGE_FORMAT_XBGR8888:
+ ret = GBM_FORMAT_XBGR8888;
+ break;
case __DRI_IMAGE_FORMAT_ABGR8888:
ret = GBM_FORMAT_ABGR8888;
break;
@@ -815,7 +832,7 @@ create_dumb(struct gbm_device *gbm,
bo->handle = create_arg.handle;
bo->size = create_arg.size;
- if (gbm_dri_bo_map(bo) == NULL)
+ if (gbm_dri_bo_map_dumb(bo) == NULL)
goto destroy_dumb;
return &bo->base.base;
@@ -853,8 +870,14 @@ gbm_dri_bo_create(struct gbm_device *gbm,
bo->base.base.format = format;
switch (format) {
+ case GBM_FORMAT_R8:
+ dri_format = __DRI_IMAGE_FORMAT_R8;
+ break;
+ case GBM_FORMAT_GR88:
+ dri_format = __DRI_IMAGE_FORMAT_GR88;
+ break;
case GBM_FORMAT_RGB565:
- dri_format =__DRI_IMAGE_FORMAT_RGB565;
+ dri_format = __DRI_IMAGE_FORMAT_RGB565;
break;
case GBM_FORMAT_XRGB8888:
case GBM_BO_FORMAT_XRGB8888:
@@ -867,6 +890,9 @@ gbm_dri_bo_create(struct gbm_device *gbm,
case GBM_FORMAT_ABGR8888:
dri_format = __DRI_IMAGE_FORMAT_ABGR8888;
break;
+ case GBM_FORMAT_XBGR8888:
+ dri_format = __DRI_IMAGE_FORMAT_XBGR8888;
+ break;
case GBM_FORMAT_ARGB2101010:
dri_format = __DRI_IMAGE_FORMAT_ARGB2101010;
break;
@@ -908,6 +934,61 @@ failed:
return NULL;
}
+static void *
+gbm_dri_bo_map(struct gbm_bo *_bo,
+ uint32_t x, uint32_t y,
+ uint32_t width, uint32_t height,
+ uint32_t flags, uint32_t *stride, void **map_data)
+{
+ struct gbm_dri_device *dri = gbm_dri_device(_bo->gbm);
+ struct gbm_dri_bo *bo = gbm_dri_bo(_bo);
+
+ /* If it's a dumb buffer, we already have a mapping */
+ if (bo->map) {
+ *map_data = (char *)bo->map + (bo->base.base.stride * y) + (x * 4);
+ *stride = bo->base.base.stride;
+ return *map_data;
+ }
+
+ if (!dri->image || dri->image->base.version < 12 || !dri->image->mapImage) {
+ errno = ENOSYS;
+ return NULL;
+ }
+
+ mtx_lock(&dri->mutex);
+ if (!dri->context)
+ dri->context = dri->dri2->createNewContext(dri->screen, NULL,
+ NULL, NULL);
+ assert(dri->context);
+ mtx_unlock(&dri->mutex);
+
+ /* GBM flags and DRI flags are the same, so just pass them on */
+ return dri->image->mapImage(dri->context, bo->image, x, y,
+ width, height, flags, (int *)stride,
+ map_data);
+}
+
+static void
+gbm_dri_bo_unmap(struct gbm_bo *_bo, void *map_data)
+{
+ struct gbm_dri_device *dri = gbm_dri_device(_bo->gbm);
+ struct gbm_dri_bo *bo = gbm_dri_bo(_bo);
+
+ /* Check if it's a dumb buffer and check the pointer is in range */
+ if (bo->map) {
+ assert(map_data >= bo->map);
+ assert(map_data < (bo->map + bo->size));
+ return;
+ }
+
+ if (!dri->context || !dri->image ||
+ dri->image->base.version < 12 || !dri->image->unmapImage)
+ return;
+
+ dri->image->unmapImage(dri->context, bo->image, map_data);
+}
+
+
static struct gbm_surface *
gbm_dri_surface_create(struct gbm_device *gbm,
uint32_t width, uint32_t height,
@@ -942,6 +1023,9 @@ dri_destroy(struct gbm_device *gbm)
struct gbm_dri_device *dri = gbm_dri_device(gbm);
unsigned i;
+ if (dri->context)
+ dri->core->destroyContext(dri->context);
+
dri->core->destroyScreen(dri->screen);
for (i = 0; dri->driver_configs[i]; i++)
free((__DRIconfig *) dri->driver_configs[i]);
@@ -965,6 +1049,8 @@ dri_device_create(int fd)
dri->base.base.fd = fd;
dri->base.base.bo_create = gbm_dri_bo_create;
dri->base.base.bo_import = gbm_dri_bo_import;
+ dri->base.base.bo_map = gbm_dri_bo_map;
+ dri->base.base.bo_unmap = gbm_dri_bo_unmap;
dri->base.base.is_format_supported = gbm_dri_is_format_supported;
dri->base.base.bo_write = gbm_dri_bo_write;
dri->base.base.bo_get_fd = gbm_dri_bo_get_fd;
@@ -976,6 +1062,8 @@ dri_device_create(int fd)
dri->base.type = GBM_DRM_DRIVER_TYPE_DRI;
dri->base.base.name = "drm";
+ mtx_init(&dri->mutex, mtx_plain);
+
force_sw = getenv("GBM_ALWAYS_SOFTWARE") != NULL;
if (!force_sw) {
ret = dri_screen_create(dri);
diff --git a/lib/mesa/src/gbm/backends/dri/gbm_driint.h b/lib/mesa/src/gbm/backends/dri/gbm_driint.h
index 3f46effbe..26376efb1 100644
--- a/lib/mesa/src/gbm/backends/dri/gbm_driint.h
+++ b/lib/mesa/src/gbm/backends/dri/gbm_driint.h
@@ -28,8 +28,11 @@
#ifndef _GBM_DRI_INTERNAL_H_
#define _GBM_DRI_INTERNAL_H_
+#include <xf86drm.h>
+#include <string.h>
#include <sys/mman.h>
#include "gbmint.h"
+#include "c11/threads.h"
#include "common_drm.h"
@@ -45,16 +48,19 @@ struct gbm_dri_device {
void *driver;
__DRIscreen *screen;
+ __DRIcontext *context;
+ mtx_t mutex;
const __DRIcoreExtension *core;
const __DRIdri2Extension *dri2;
+ const __DRI2fenceExtension *fence;
const __DRIimageExtension *image;
const __DRIswrastExtension *swrast;
const __DRI2flushExtension *flush;
const __DRIdri2LoaderExtension *loader;
const __DRIconfig **driver_configs;
- const __DRIextension **extensions;
+ const __DRIextension **loader_extensions;
const __DRIextension **driver_extensions;
__DRIimage *(*lookup_image)(__DRIscreen *screen, void *image, void *data);
@@ -130,7 +136,7 @@ gbm_dri_surface(struct gbm_surface *surface)
}
static inline void *
-gbm_dri_bo_map(struct gbm_dri_bo *bo)
+gbm_dri_bo_map_dumb(struct gbm_dri_bo *bo)
{
struct drm_mode_map_dumb map_arg;
int ret;
@@ -159,7 +165,7 @@ gbm_dri_bo_map(struct gbm_dri_bo *bo)
}
static inline void
-gbm_dri_bo_unmap(struct gbm_dri_bo *bo)
+gbm_dri_bo_unmap_dumb(struct gbm_dri_bo *bo)
{
munmap(bo->map, bo->size);
bo->map = NULL;