*/
#include <xf86drm.h>
-#include <dlfcn.h>
-#include <fcntl.h>
#include "GL/mesa_glinterop.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
#include "main/bufferobj.h"
#include "main/texobj.h"
-#include "dri_screen.h"
-#include "dri_context.h"
+#include "dri_util.h"
+
+#include "dri_helpers.h"
#include "dri_drawable.h"
#include "dri_query_renderer.h"
-#include "dri2_buffer.h"
+
+#ifndef DRM_FORMAT_MOD_INVALID
+#define DRM_FORMAT_MOD_INVALID ((1ULL<<56) - 1)
+#endif
+
+struct dri2_buffer
+{
+ __DRIbuffer base;
+ struct pipe_resource *resource;
+};
+
+static inline struct dri2_buffer *
+dri2_buffer(__DRIbuffer * driBufferPriv)
+{
+ return (struct dri2_buffer *) driBufferPriv;
+}
+
+static const int fourcc_formats[] = {
+ __DRI_IMAGE_FOURCC_ARGB2101010,
+ __DRI_IMAGE_FOURCC_XRGB2101010,
+ __DRI_IMAGE_FOURCC_ABGR2101010,
+ __DRI_IMAGE_FOURCC_XBGR2101010,
+ __DRI_IMAGE_FOURCC_ARGB8888,
+ __DRI_IMAGE_FOURCC_ABGR8888,
+ __DRI_IMAGE_FOURCC_SARGB8888,
+ __DRI_IMAGE_FOURCC_XRGB8888,
+ __DRI_IMAGE_FOURCC_XBGR8888,
+ __DRI_IMAGE_FOURCC_ARGB1555,
+ __DRI_IMAGE_FOURCC_RGB565,
+ __DRI_IMAGE_FOURCC_R8,
+ __DRI_IMAGE_FOURCC_R16,
+ __DRI_IMAGE_FOURCC_GR88,
+ __DRI_IMAGE_FOURCC_GR1616,
+ __DRI_IMAGE_FOURCC_YUV410,
+ __DRI_IMAGE_FOURCC_YUV411,
+ __DRI_IMAGE_FOURCC_YUV420,
+ __DRI_IMAGE_FOURCC_YUV422,
+ __DRI_IMAGE_FOURCC_YUV444,
+ __DRI_IMAGE_FOURCC_YVU410,
+ __DRI_IMAGE_FOURCC_YVU411,
+ __DRI_IMAGE_FOURCC_YVU420,
+ __DRI_IMAGE_FOURCC_YVU422,
+ __DRI_IMAGE_FOURCC_YVU444,
+ __DRI_IMAGE_FOURCC_NV12,
+ __DRI_IMAGE_FOURCC_NV16,
+ __DRI_IMAGE_FOURCC_YUYV
+};
static int convert_fourcc(int format, int *dri_components_p)
{
int dri_components;
switch(format) {
+ case __DRI_IMAGE_FOURCC_ARGB1555:
+ format = __DRI_IMAGE_FORMAT_ARGB1555;
+ dri_components = __DRI_IMAGE_COMPONENTS_RGBA;
+ break;
case __DRI_IMAGE_FOURCC_RGB565:
format = __DRI_IMAGE_FORMAT_RGB565;
dri_components = __DRI_IMAGE_COMPONENTS_RGB;
format = __DRI_IMAGE_FORMAT_XBGR8888;
dri_components = __DRI_IMAGE_COMPONENTS_RGB;
break;
+ case __DRI_IMAGE_FOURCC_ARGB2101010:
+ format = __DRI_IMAGE_FORMAT_ARGB2101010;
+ dri_components = __DRI_IMAGE_COMPONENTS_RGBA;
+ break;
+ case __DRI_IMAGE_FOURCC_XRGB2101010:
+ format = __DRI_IMAGE_FORMAT_XRGB2101010;
+ dri_components = __DRI_IMAGE_COMPONENTS_RGB;
+ break;
+ case __DRI_IMAGE_FOURCC_ABGR2101010:
+ format = __DRI_IMAGE_FORMAT_ABGR2101010;
+ dri_components = __DRI_IMAGE_COMPONENTS_RGBA;
+ break;
+ case __DRI_IMAGE_FOURCC_XBGR2101010:
+ format = __DRI_IMAGE_FORMAT_XBGR2101010;
+ dri_components = __DRI_IMAGE_COMPONENTS_RGB;
+ break;
case __DRI_IMAGE_FOURCC_R8:
format = __DRI_IMAGE_FORMAT_R8;
dri_components = __DRI_IMAGE_COMPONENTS_R;
format = __DRI_IMAGE_FORMAT_GR88;
dri_components = __DRI_IMAGE_COMPONENTS_RG;
break;
+ case __DRI_IMAGE_FOURCC_R16:
+ format = __DRI_IMAGE_FORMAT_R16;
+ dri_components = __DRI_IMAGE_COMPONENTS_R;
+ break;
+ case __DRI_IMAGE_FOURCC_GR1616:
+ format = __DRI_IMAGE_FORMAT_GR1616;
+ dri_components = __DRI_IMAGE_COMPONENTS_RG;
+ break;
+ case __DRI_IMAGE_FOURCC_YUYV:
+ format = __DRI_IMAGE_FORMAT_YUYV;
+ dri_components = __DRI_IMAGE_COMPONENTS_Y_XUXV;
+ break;
/*
* For multi-planar YUV formats, we return the format of the first
* plane only. Since there is only one caller which supports multi-
static int convert_to_fourcc(int format)
{
switch(format) {
+ case __DRI_IMAGE_FORMAT_ARGB1555:
+ format = __DRI_IMAGE_FOURCC_ARGB1555;
+ break;
case __DRI_IMAGE_FORMAT_RGB565:
format = __DRI_IMAGE_FOURCC_RGB565;
break;
case __DRI_IMAGE_FORMAT_XBGR8888:
format = __DRI_IMAGE_FOURCC_XBGR8888;
break;
+ case __DRI_IMAGE_FORMAT_ARGB2101010:
+ format = __DRI_IMAGE_FOURCC_ARGB2101010;
+ break;
+ case __DRI_IMAGE_FORMAT_XRGB2101010:
+ format = __DRI_IMAGE_FOURCC_XRGB2101010;
+ break;
+ case __DRI_IMAGE_FORMAT_ABGR2101010:
+ format = __DRI_IMAGE_FOURCC_ABGR2101010;
+ break;
+ case __DRI_IMAGE_FORMAT_XBGR2101010:
+ format = __DRI_IMAGE_FOURCC_XBGR2101010;
+ break;
case __DRI_IMAGE_FORMAT_R8:
format = __DRI_IMAGE_FOURCC_R8;
break;
enum pipe_format pf;
switch (format) {
+ case __DRI_IMAGE_FORMAT_ARGB1555:
+ pf = PIPE_FORMAT_B5G5R5A1_UNORM;
+ break;
case __DRI_IMAGE_FORMAT_RGB565:
pf = PIPE_FORMAT_B5G6R5_UNORM;
break;
case __DRI_IMAGE_FORMAT_ARGB8888:
pf = PIPE_FORMAT_BGRA8888_UNORM;
break;
+ case __DRI_IMAGE_FORMAT_XBGR8888:
+ pf = PIPE_FORMAT_RGBX8888_UNORM;
+ break;
case __DRI_IMAGE_FORMAT_ABGR8888:
pf = PIPE_FORMAT_RGBA8888_UNORM;
break;
+ case __DRI_IMAGE_FORMAT_XRGB2101010:
+ pf = PIPE_FORMAT_B10G10R10X2_UNORM;
+ break;
+ case __DRI_IMAGE_FORMAT_ARGB2101010:
+ pf = PIPE_FORMAT_B10G10R10A2_UNORM;
+ break;
+ case __DRI_IMAGE_FORMAT_XBGR2101010:
+ pf = PIPE_FORMAT_R10G10B10X2_UNORM;
+ break;
+ case __DRI_IMAGE_FORMAT_ABGR2101010:
+ pf = PIPE_FORMAT_R10G10B10A2_UNORM;
+ break;
case __DRI_IMAGE_FORMAT_R8:
pf = PIPE_FORMAT_R8_UNORM;
break;
case __DRI_IMAGE_FORMAT_GR88:
pf = PIPE_FORMAT_RG88_UNORM;
break;
+ case __DRI_IMAGE_FORMAT_R16:
+ pf = PIPE_FORMAT_R16_UNORM;
+ break;
+ case __DRI_IMAGE_FORMAT_GR1616:
+ pf = PIPE_FORMAT_R16G16_UNORM;
+ break;
+ case __DRI_IMAGE_FORMAT_YUYV:
+ pf = PIPE_FORMAT_YUYV;
+ break;
default:
pf = PIPE_FORMAT_NONE;
break;
return pf;
}
+static enum pipe_format fourcc_to_pipe_format(int fourcc)
+{
+ enum pipe_format pf;
+
+ switch (fourcc) {
+ case __DRI_IMAGE_FOURCC_R8:
+ pf = PIPE_FORMAT_R8_UNORM;
+ break;
+ case __DRI_IMAGE_FOURCC_GR88:
+ pf = PIPE_FORMAT_RG88_UNORM;
+ break;
+ case __DRI_IMAGE_FOURCC_ARGB1555:
+ pf = PIPE_FORMAT_B5G5R5A1_UNORM;
+ break;
+ case __DRI_IMAGE_FOURCC_R16:
+ pf = PIPE_FORMAT_R16_UNORM;
+ break;
+ case __DRI_IMAGE_FOURCC_GR1616:
+ pf = PIPE_FORMAT_RG1616_UNORM;
+ break;
+ case __DRI_IMAGE_FOURCC_RGB565:
+ pf = PIPE_FORMAT_B5G6R5_UNORM;
+ break;
+ case __DRI_IMAGE_FOURCC_ARGB8888:
+ pf = PIPE_FORMAT_BGRA8888_UNORM;
+ break;
+ case __DRI_IMAGE_FOURCC_XRGB8888:
+ pf = PIPE_FORMAT_BGRX8888_UNORM;
+ break;
+ case __DRI_IMAGE_FOURCC_ABGR8888:
+ pf = PIPE_FORMAT_RGBA8888_UNORM;
+ break;
+ case __DRI_IMAGE_FOURCC_XBGR8888:
+ pf = PIPE_FORMAT_RGBX8888_UNORM;
+ break;
+ case __DRI_IMAGE_FOURCC_ARGB2101010:
+ pf = PIPE_FORMAT_B10G10R10A2_UNORM;
+ break;
+ case __DRI_IMAGE_FOURCC_XRGB2101010:
+ pf = PIPE_FORMAT_B10G10R10X2_UNORM;
+ break;
+ case __DRI_IMAGE_FOURCC_ABGR2101010:
+ pf = PIPE_FORMAT_R10G10B10A2_UNORM;
+ break;
+ case __DRI_IMAGE_FOURCC_XBGR2101010:
+ pf = PIPE_FORMAT_R10G10B10X2_UNORM;
+ break;
+
+ case __DRI_IMAGE_FOURCC_NV12:
+ pf = PIPE_FORMAT_NV12;
+ break;
+ case __DRI_IMAGE_FOURCC_YUYV:
+ pf = PIPE_FORMAT_YUYV;
+ break;
+ case __DRI_IMAGE_FOURCC_YUV420:
+ case __DRI_IMAGE_FOURCC_YVU420:
+ pf = PIPE_FORMAT_YV12;
+ break;
+
+ case __DRI_IMAGE_FOURCC_SARGB8888:
+ case __DRI_IMAGE_FOURCC_YUV410:
+ case __DRI_IMAGE_FOURCC_YUV411:
+ case __DRI_IMAGE_FOURCC_YUV422:
+ case __DRI_IMAGE_FOURCC_YUV444:
+ case __DRI_IMAGE_FOURCC_NV16:
+ case __DRI_IMAGE_FOURCC_YVU410:
+ case __DRI_IMAGE_FOURCC_YVU411:
+ case __DRI_IMAGE_FOURCC_YVU422:
+ case __DRI_IMAGE_FOURCC_YVU444:
+ default:
+ pf = PIPE_FORMAT_NONE;
+ }
+
+ return pf;
+}
+
/**
* DRI2 flush extension.
*/
* may occur as the stvis->color_format.
*/
switch(format) {
+ case PIPE_FORMAT_B10G10R10A2_UNORM:
+ case PIPE_FORMAT_R10G10B10A2_UNORM:
case PIPE_FORMAT_BGRA8888_UNORM:
+ case PIPE_FORMAT_RGBA8888_UNORM:
depth = 32;
break;
+ case PIPE_FORMAT_R10G10B10X2_UNORM:
+ case PIPE_FORMAT_B10G10R10X2_UNORM:
+ depth = 30;
+ break;
case PIPE_FORMAT_BGRX8888_UNORM:
+ case PIPE_FORMAT_RGBX8888_UNORM:
depth = 24;
break;
case PIPE_FORMAT_B5G6R5_UNORM:
}
switch (pf) {
+ case PIPE_FORMAT_B5G5R5A1_UNORM:
+ image_format = __DRI_IMAGE_FORMAT_ARGB1555;
+ break;
case PIPE_FORMAT_B5G6R5_UNORM:
image_format = __DRI_IMAGE_FORMAT_RGB565;
break;
case PIPE_FORMAT_BGRA8888_UNORM:
image_format = __DRI_IMAGE_FORMAT_ARGB8888;
break;
+ case PIPE_FORMAT_RGBX8888_UNORM:
+ image_format = __DRI_IMAGE_FORMAT_XBGR8888;
+ break;
case PIPE_FORMAT_RGBA8888_UNORM:
image_format = __DRI_IMAGE_FORMAT_ABGR8888;
break;
+ case PIPE_FORMAT_B10G10R10X2_UNORM:
+ image_format = __DRI_IMAGE_FORMAT_XRGB2101010;
+ break;
+ case PIPE_FORMAT_B10G10R10A2_UNORM:
+ image_format = __DRI_IMAGE_FORMAT_ARGB2101010;
+ break;
+ case PIPE_FORMAT_R10G10B10X2_UNORM:
+ image_format = __DRI_IMAGE_FORMAT_XBGR2101010;
+ break;
+ case PIPE_FORMAT_R10G10B10A2_UNORM:
+ image_format = __DRI_IMAGE_FORMAT_ABGR2101010;
+ break;
default:
image_format = __DRI_IMAGE_FORMAT_NONE;
break;
case 32:
pf = PIPE_FORMAT_BGRA8888_UNORM;
break;
+ case 30:
+ pf = PIPE_FORMAT_B10G10R10X2_UNORM;
+ break;
case 24:
pf = PIPE_FORMAT_BGRX8888_UNORM;
break;
memset(&whandle, 0, sizeof(whandle));
if (screen->can_share_buffer)
- whandle.type = DRM_API_HANDLE_TYPE_SHARED;
+ whandle.type = WINSYS_HANDLE_TYPE_SHARED;
else
- whandle.type = DRM_API_HANDLE_TYPE_KMS;
+ whandle.type = WINSYS_HANDLE_TYPE_KMS;
screen->base.screen->resource_get_handle(screen->base.screen, NULL,
buffer->resource, &whandle,
- PIPE_HANDLE_USAGE_EXPLICIT_FLUSH | PIPE_HANDLE_USAGE_READ);
+ PIPE_HANDLE_USAGE_EXPLICIT_FLUSH);
buffer->base.attachment = attachment;
buffer->base.name = whandle.handle;
whandle.handle = buf->name;
whandle.stride = buf->pitch;
whandle.offset = 0;
+ whandle.modifier = DRM_FORMAT_MOD_INVALID;
if (screen->can_share_buffer)
- whandle.type = DRM_API_HANDLE_TYPE_SHARED;
+ whandle.type = WINSYS_HANDLE_TYPE_SHARED;
else
- whandle.type = DRM_API_HANDLE_TYPE_KMS;
+ whandle.type = WINSYS_HANDLE_TYPE_KMS;
drawable->textures[statt] =
screen->base.screen->resource_from_handle(screen->base.screen,
&templ, &whandle,
- PIPE_HANDLE_USAGE_EXPLICIT_FLUSH | PIPE_HANDLE_USAGE_READ);
+ PIPE_HANDLE_USAGE_EXPLICIT_FLUSH);
assert(drawable->textures[statt]);
}
}
if (drawable->textures[statt]) {
templ.format = drawable->textures[statt]->format;
- templ.bind = drawable->textures[statt]->bind & ~PIPE_BIND_SCANOUT;
+ templ.bind = drawable->textures[statt]->bind &
+ ~(PIPE_BIND_SCANOUT | PIPE_BIND_SHARED);
templ.nr_samples = drawable->stvis.samples;
+ templ.nr_storage_samples = drawable->stvis.samples;
/* Try to reuse the resource.
* (the other resource parameters should be constant)
if (format) {
templ.format = format;
- templ.bind = bind;
+ templ.bind = bind & ~PIPE_BIND_SHARED;
if (drawable->stvis.samples > 1) {
templ.nr_samples = drawable->stvis.samples;
+ templ.nr_storage_samples = drawable->stvis.samples;
zsbuf = &drawable->msaa_textures[statt];
}
else {
templ.nr_samples = 0;
+ templ.nr_storage_samples = 0;
zsbuf = &drawable->textures[statt];
}
}
}
+/**
+ * The struct dri_drawable flush_swapbuffers callback
+ */
+static void
+dri2_flush_swapbuffers(struct dri_context *ctx,
+ struct dri_drawable *drawable)
+{
+ __DRIdrawable *dri_drawable = drawable->dPriv;
+ const __DRIimageLoaderExtension *image = drawable->sPriv->image.loader;
+
+ if (image && image->base.version >= 3 && image->flushSwapBuffers) {
+ image->flushSwapBuffers(dri_drawable, dri_drawable->loaderPrivate);
+ }
+}
+
static void
dri2_update_tex_buffer(struct dri_drawable *drawable,
struct dri_context *ctx,
/* no-op */
}
-static __DRIimage *
-dri2_lookup_egl_image(struct dri_screen *screen, void *handle)
-{
- const __DRIimageLookupExtension *loader = screen->sPriv->dri2.image;
- __DRIimage *img;
-
- if (!loader->lookupEGLImage)
- return NULL;
-
- img = loader->lookupEGLImage(screen->sPriv,
- handle, screen->sPriv->loaderPrivate);
-
- return img;
-}
-
static __DRIimage *
dri2_create_image_from_winsys(__DRIscreen *_screen,
int width, int height, int format,
struct pipe_screen *pscreen = screen->base.screen;
__DRIimage *img;
struct pipe_resource templ;
- unsigned tex_usage;
+ unsigned tex_usage = 0;
enum pipe_format pf;
int i;
- tex_usage = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
-
pf = dri2_format_to_pipe_format (format);
if (pf == PIPE_FORMAT_NONE)
return NULL;
+ if (pscreen->is_format_supported(pscreen, pf, screen->target, 0, 0,
+ PIPE_BIND_RENDER_TARGET))
+ tex_usage |= PIPE_BIND_RENDER_TARGET;
+ if (pscreen->is_format_supported(pscreen, pf, screen->target, 0, 0,
+ PIPE_BIND_SAMPLER_VIEW))
+ tex_usage |= PIPE_BIND_SAMPLER_VIEW;
+
img = CALLOC_STRUCT(__DRIimageRec);
if (!img)
return NULL;
}
tex = pscreen->resource_from_handle(pscreen,
- &templ, &whandle[i], PIPE_HANDLE_USAGE_READ_WRITE);
+ &templ, &whandle[i], PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE);
if (!tex) {
pipe_resource_reference(&img->texture, NULL);
FREE(img);
enum pipe_format pf;
memset(&whandle, 0, sizeof(whandle));
- whandle.type = DRM_API_HANDLE_TYPE_SHARED;
+ whandle.type = WINSYS_HANDLE_TYPE_SHARED;
whandle.handle = name;
+ whandle.modifier = DRM_FORMAT_MOD_INVALID;
pf = dri2_format_to_pipe_format (format);
if (pf == PIPE_FORMAT_NONE)
static __DRIimage *
dri2_create_image_from_fd(__DRIscreen *_screen,
int width, int height, int fourcc,
- int *fds, int num_fds, int *strides,
- int *offsets, unsigned *error,
+ uint64_t modifier, int *fds, int num_fds,
+ int *strides, int *offsets, unsigned *error,
int *dri_components, void *loaderPrivate)
{
struct winsys_handle whandles[3];
goto exit;
}
- whandles[i].type = DRM_API_HANDLE_TYPE_FD;
+ whandles[i].type = WINSYS_HANDLE_TYPE_FD;
whandles[i].handle = (unsigned)fds[i];
whandles[i].stride = (unsigned)strides[i];
whandles[i].offset = (unsigned)offsets[i];
+ whandles[i].modifier = modifier;
}
if (fourcc == __DRI_IMAGE_FOURCC_YVU420) {
}
static __DRIimage *
-dri2_create_image_from_renderbuffer(__DRIcontext *context,
- int renderbuffer, void *loaderPrivate)
-{
- struct dri_context *ctx = dri_context(context);
-
- if (!ctx->st->get_resource_for_egl_image)
- return NULL;
-
- /* TODO */
- return NULL;
-}
-
-static __DRIimage *
-dri2_create_image(__DRIscreen *_screen,
- int width, int height, int format,
- unsigned int use, void *loaderPrivate)
+dri2_create_image_common(__DRIscreen *_screen,
+ int width, int height,
+ int format, unsigned int use,
+ const uint64_t *modifiers,
+ const unsigned count,
+ void *loaderPrivate)
{
struct dri_screen *screen = dri_screen(_screen);
__DRIimage *img;
unsigned tex_usage;
enum pipe_format pf;
+ /* createImageWithModifiers doesn't supply usage, and we should not get
+ * here with both modifiers and a usage flag.
+ */
+ assert(!(use && (modifiers != NULL)));
+
tex_usage = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
+
if (use & __DRI_IMAGE_USE_SCANOUT)
tex_usage |= PIPE_BIND_SCANOUT;
if (use & __DRI_IMAGE_USE_SHARE)
templ.depth0 = 1;
templ.array_size = 1;
- img->texture = screen->base.screen->resource_create(screen->base.screen, &templ);
+ if (modifiers)
+ img->texture =
+ screen->base.screen
+ ->resource_create_with_modifiers(screen->base.screen,
+ &templ,
+ modifiers,
+ count);
+ else
+ img->texture =
+ screen->base.screen->resource_create(screen->base.screen, &templ);
if (!img->texture) {
FREE(img);
return NULL;
return img;
}
+static __DRIimage *
+dri2_create_image(__DRIscreen *_screen,
+ int width, int height, int format,
+ unsigned int use, void *loaderPrivate)
+{
+ return dri2_create_image_common(_screen, width, height, format, use,
+ NULL /* modifiers */, 0 /* count */,
+ loaderPrivate);
+}
+
+static __DRIimage *
+dri2_create_image_with_modifiers(__DRIscreen *dri_screen,
+ int width, int height, int format,
+ const uint64_t *modifiers,
+ const unsigned count,
+ void *loaderPrivate)
+{
+ return dri2_create_image_common(dri_screen, width, height, format,
+ 0 /* use */, modifiers, count,
+ loaderPrivate);
+}
+
static GLboolean
dri2_query_image(__DRIimage *image, int attrib, int *value)
{
unsigned usage;
if (image->use & __DRI_IMAGE_USE_BACKBUFFER)
- usage = PIPE_HANDLE_USAGE_EXPLICIT_FLUSH | PIPE_HANDLE_USAGE_READ;
+ usage = PIPE_HANDLE_USAGE_EXPLICIT_FLUSH;
else
- usage = PIPE_HANDLE_USAGE_READ_WRITE;
+ usage = PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE;
memset(&whandle, 0, sizeof(whandle));
switch (attrib) {
case __DRI_IMAGE_ATTRIB_STRIDE:
- whandle.type = DRM_API_HANDLE_TYPE_KMS;
- image->texture->screen->resource_get_handle(image->texture->screen,
- NULL, image->texture, &whandle, usage);
+ whandle.type = WINSYS_HANDLE_TYPE_KMS;
+ if (!image->texture->screen->resource_get_handle(image->texture->screen,
+ NULL, image->texture, &whandle, usage))
+ return GL_FALSE;
*value = whandle.stride;
return GL_TRUE;
+ case __DRI_IMAGE_ATTRIB_OFFSET:
+ whandle.type = WINSYS_HANDLE_TYPE_KMS;
+ if (!image->texture->screen->resource_get_handle(image->texture->screen,
+ NULL, image->texture, &whandle, usage))
+ return GL_FALSE;
+ *value = whandle.offset;
+ return GL_TRUE;
case __DRI_IMAGE_ATTRIB_HANDLE:
- whandle.type = DRM_API_HANDLE_TYPE_KMS;
- image->texture->screen->resource_get_handle(image->texture->screen,
- NULL, image->texture, &whandle, usage);
+ whandle.type = WINSYS_HANDLE_TYPE_KMS;
+ if (!image->texture->screen->resource_get_handle(image->texture->screen,
+ NULL, image->texture, &whandle, usage))
+ return GL_FALSE;
*value = whandle.handle;
return GL_TRUE;
case __DRI_IMAGE_ATTRIB_NAME:
- whandle.type = DRM_API_HANDLE_TYPE_SHARED;
- image->texture->screen->resource_get_handle(image->texture->screen,
- NULL, image->texture, &whandle, usage);
+ whandle.type = WINSYS_HANDLE_TYPE_SHARED;
+ if (!image->texture->screen->resource_get_handle(image->texture->screen,
+ NULL, image->texture, &whandle, usage))
+ return GL_FALSE;
*value = whandle.handle;
return GL_TRUE;
case __DRI_IMAGE_ATTRIB_FD:
- whandle.type= DRM_API_HANDLE_TYPE_FD;
+ whandle.type= WINSYS_HANDLE_TYPE_FD;
if (!image->texture->screen->resource_get_handle(image->texture->screen,
NULL, image->texture, &whandle, usage))
return GL_FALSE;
return GL_TRUE;
case __DRI_IMAGE_ATTRIB_FOURCC:
*value = convert_to_fourcc(image->dri_format);
- return GL_TRUE;
+ return *value != -1;
case __DRI_IMAGE_ATTRIB_NUM_PLANES:
*value = 1;
return GL_TRUE;
+ case __DRI_IMAGE_ATTRIB_MODIFIER_UPPER:
+ whandle.type = WINSYS_HANDLE_TYPE_KMS;
+ whandle.modifier = DRM_FORMAT_MOD_INVALID;
+ if (!image->texture->screen->resource_get_handle(image->texture->screen,
+ NULL, image->texture, &whandle, usage))
+ return GL_FALSE;
+ if (whandle.modifier == DRM_FORMAT_MOD_INVALID)
+ return GL_FALSE;
+ *value = (whandle.modifier >> 32) & 0xffffffff;
+ return GL_TRUE;
+ case __DRI_IMAGE_ATTRIB_MODIFIER_LOWER:
+ whandle.type = WINSYS_HANDLE_TYPE_KMS;
+ whandle.modifier = DRM_FORMAT_MOD_INVALID;
+ if (!image->texture->screen->resource_get_handle(image->texture->screen,
+ NULL, image->texture, &whandle, usage))
+ return GL_FALSE;
+ if (whandle.modifier == DRM_FORMAT_MOD_INVALID)
+ return GL_FALSE;
+ *value = whandle.modifier & 0xffffffff;
+ return GL_TRUE;
default:
return GL_FALSE;
}
static GLboolean
dri2_validate_usage(__DRIimage *image, unsigned int use)
{
- /*
- * Gallium drivers are bad at adding usages to the resources
- * once opened again in another process, which is the main use
- * case for this, so we have to lie.
+ if (!image || !image->texture)
+ return false;
+
+ struct pipe_screen *screen = image->texture->screen;
+ if (!screen->check_resource_capability)
+ return true;
+
+ /* We don't want to check these:
+ * __DRI_IMAGE_USE_SHARE (all images are shareable)
+ * __DRI_IMAGE_USE_BACKBUFFER (all images support this)
*/
- if (image != NULL)
- return GL_TRUE;
- else
- return GL_FALSE;
+ unsigned bind = 0;
+ if (use & __DRI_IMAGE_USE_SCANOUT)
+ bind |= PIPE_BIND_SCANOUT;
+ if (use & __DRI_IMAGE_USE_LINEAR)
+ bind |= PIPE_BIND_LINEAR;
+ if (use & __DRI_IMAGE_USE_CURSOR)
+ bind |= PIPE_BIND_CURSOR;
+
+ if (!bind)
+ return true;
+
+ return screen->check_resource_capability(screen, image->texture, bind);
}
static __DRIimage *
return NULL;
memset(&whandle, 0, sizeof(whandle));
- whandle.type = DRM_API_HANDLE_TYPE_SHARED;
+ whandle.type = WINSYS_HANDLE_TYPE_SHARED;
whandle.handle = names[0];
whandle.stride = strides[0];
whandle.offset = offsets[0];
+ whandle.modifier = DRM_FORMAT_MOD_INVALID;
img = dri2_create_image_from_winsys(screen, width, height, format,
1, &whandle, loaderPrivate);
}
static __DRIimage *
-dri2_create_from_texture(__DRIcontext *context, int target, unsigned texture,
- int depth, int level, unsigned *error,
- void *loaderPrivate)
+dri2_from_fds(__DRIscreen *screen, int width, int height, int fourcc,
+ int *fds, int num_fds, int *strides, int *offsets,
+ void *loaderPrivate)
{
__DRIimage *img;
- struct gl_context *ctx = ((struct st_context *)dri_context(context)->st)->ctx;
- struct gl_texture_object *obj;
- struct pipe_resource *tex;
- GLuint face = 0;
-
- obj = _mesa_lookup_texture(ctx, texture);
- if (!obj || obj->Target != target) {
- *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
- return NULL;
- }
+ int dri_components;
- tex = st_get_texobj_resource(obj);
- if (!tex) {
- *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
+ img = dri2_create_image_from_fd(screen, width, height, fourcc,
+ DRM_FORMAT_MOD_INVALID, fds, num_fds,
+ strides, offsets, NULL,
+ &dri_components, loaderPrivate);
+ if (img == NULL)
return NULL;
- }
- if (target == GL_TEXTURE_CUBE_MAP)
- face = depth;
+ img->dri_components = dri_components;
+ return img;
+}
- _mesa_test_texobj_completeness(ctx, obj);
- if (!obj->_BaseComplete || (level > 0 && !obj->_MipmapComplete)) {
- *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
- return NULL;
- }
+static boolean
+dri2_query_dma_buf_formats(__DRIscreen *_screen, int max, int *formats,
+ int *count)
+{
+ struct dri_screen *screen = dri_screen(_screen);
+ struct pipe_screen *pscreen = screen->base.screen;
+ int i, j;
- if (level < obj->BaseLevel || level > obj->_MaxLevel) {
- *error = __DRI_IMAGE_ERROR_BAD_MATCH;
- return NULL;
- }
+ for (i = 0, j = 0; (i < ARRAY_SIZE(fourcc_formats)) &&
+ (j < max || max == 0); i++) {
+ enum pipe_format format = fourcc_to_pipe_format(fourcc_formats[i]);
- if (target == GL_TEXTURE_3D && obj->Image[face][level]->Depth < depth) {
- *error = __DRI_IMAGE_ERROR_BAD_MATCH;
- return NULL;
- }
+ /* The sRGB format is not a real FourCC as defined by drm_fourcc.h, so we
+ * must not leak it out to clients.
+ */
+ if (fourcc_formats[i] == __DRI_IMAGE_FOURCC_SARGB8888)
+ continue;
- img = CALLOC_STRUCT(__DRIimageRec);
- if (!img) {
- *error = __DRI_IMAGE_ERROR_BAD_ALLOC;
- return NULL;
+ if (pscreen->is_format_supported(pscreen, format, screen->target, 0, 0,
+ PIPE_BIND_RENDER_TARGET) ||
+ pscreen->is_format_supported(pscreen, format, screen->target, 0, 0,
+ PIPE_BIND_SAMPLER_VIEW)) {
+ if (j < max)
+ formats[j] = fourcc_formats[i];
+ j++;
+ }
}
+ *count = j;
+ return true;
+}
- img->level = level;
- img->layer = depth;
- img->dri_format = driGLFormatToImageFormat(obj->Image[face][level]->TexFormat);
-
- img->loader_private = loaderPrivate;
-
- if (img->dri_format == __DRI_IMAGE_FORMAT_NONE) {
- *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
- free(img);
- return NULL;
+static boolean
+dri2_query_dma_buf_modifiers(__DRIscreen *_screen, int fourcc, int max,
+ uint64_t *modifiers, unsigned int *external_only,
+ int *count)
+{
+ struct dri_screen *screen = dri_screen(_screen);
+ struct pipe_screen *pscreen = screen->base.screen;
+ enum pipe_format format = fourcc_to_pipe_format(fourcc);
+
+ if (pscreen->query_dmabuf_modifiers != NULL &&
+ (pscreen->is_format_supported(pscreen, format, screen->target, 0, 0,
+ PIPE_BIND_RENDER_TARGET) ||
+ pscreen->is_format_supported(pscreen, format, screen->target, 0, 0,
+ PIPE_BIND_SAMPLER_VIEW))) {
+ pscreen->query_dmabuf_modifiers(pscreen, format, max, modifiers,
+ external_only, count);
+ return true;
}
-
- pipe_resource_reference(&img->texture, tex);
-
- *error = __DRI_IMAGE_ERROR_SUCCESS;
- return img;
+ return false;
}
static __DRIimage *
-dri2_from_fds(__DRIscreen *screen, int width, int height, int fourcc,
- int *fds, int num_fds, int *strides, int *offsets,
- void *loaderPrivate)
+dri2_from_dma_bufs(__DRIscreen *screen,
+ int width, int height, int fourcc,
+ int *fds, int num_fds,
+ int *strides, int *offsets,
+ enum __DRIYUVColorSpace yuv_color_space,
+ enum __DRISampleRange sample_range,
+ enum __DRIChromaSiting horizontal_siting,
+ enum __DRIChromaSiting vertical_siting,
+ unsigned *error,
+ void *loaderPrivate)
{
__DRIimage *img;
int dri_components;
img = dri2_create_image_from_fd(screen, width, height, fourcc,
- fds, num_fds, strides, offsets, NULL,
+ DRM_FORMAT_MOD_INVALID, fds, num_fds,
+ strides, offsets, error,
&dri_components, loaderPrivate);
if (img == NULL)
return NULL;
+ img->yuv_color_space = yuv_color_space;
+ img->sample_range = sample_range;
+ img->horizontal_siting = horizontal_siting;
+ img->vertical_siting = vertical_siting;
img->dri_components = dri_components;
+
+ *error = __DRI_IMAGE_ERROR_SUCCESS;
return img;
}
static __DRIimage *
-dri2_from_dma_bufs(__DRIscreen *screen,
- int width, int height, int fourcc,
- int *fds, int num_fds,
- int *strides, int *offsets,
- enum __DRIYUVColorSpace yuv_color_space,
- enum __DRISampleRange sample_range,
- enum __DRIChromaSiting horizontal_siting,
- enum __DRIChromaSiting vertical_siting,
- unsigned *error,
- void *loaderPrivate)
+dri2_from_dma_bufs2(__DRIscreen *screen,
+ int width, int height, int fourcc,
+ uint64_t modifier, int *fds, int num_fds,
+ int *strides, int *offsets,
+ enum __DRIYUVColorSpace yuv_color_space,
+ enum __DRISampleRange sample_range,
+ enum __DRIChromaSiting horizontal_siting,
+ enum __DRIChromaSiting vertical_siting,
+ unsigned *error,
+ void *loaderPrivate)
{
__DRIimage *img;
int dri_components;
img = dri2_create_image_from_fd(screen, width, height, fourcc,
- fds, num_fds, strides, offsets, error,
- &dri_components, loaderPrivate);
+ modifier, fds, num_fds, strides, offsets,
+ error, &dri_components, loaderPrivate);
if (img == NULL)
return NULL;
pipe_transfer_unmap(pipe, (struct pipe_transfer *)data);
}
-static void
-dri2_destroy_image(__DRIimage *img)
-{
- pipe_resource_reference(&img->texture, NULL);
- FREE(img);
-}
-
static int
dri2_get_capabilities(__DRIscreen *_screen)
{
/* The extension is modified during runtime if DRI_PRIME is detected */
static __DRIimageExtension dri2ImageExtension = {
- .base = { __DRI_IMAGE, 12 },
+ .base = { __DRI_IMAGE, 17 },
.createImageFromName = dri2_create_image_from_name,
.createImageFromRenderbuffer = dri2_create_image_from_renderbuffer,
.getCapabilities = dri2_get_capabilities,
.mapImage = dri2_map_image,
.unmapImage = dri2_unmap_image,
-};
-
-
-static bool
-dri2_is_opencl_interop_loaded_locked(struct dri_screen *screen)
-{
- return screen->opencl_dri_event_add_ref &&
- screen->opencl_dri_event_release &&
- screen->opencl_dri_event_wait &&
- screen->opencl_dri_event_get_fence;
-}
-
-static bool
-dri2_load_opencl_interop(struct dri_screen *screen)
-{
-#if defined(RTLD_DEFAULT)
- bool success;
-
- mtx_lock(&screen->opencl_func_mutex);
-
- if (dri2_is_opencl_interop_loaded_locked(screen)) {
- mtx_unlock(&screen->opencl_func_mutex);
- return true;
- }
-
- screen->opencl_dri_event_add_ref =
- dlsym(RTLD_DEFAULT, "opencl_dri_event_add_ref");
- screen->opencl_dri_event_release =
- dlsym(RTLD_DEFAULT, "opencl_dri_event_release");
- screen->opencl_dri_event_wait =
- dlsym(RTLD_DEFAULT, "opencl_dri_event_wait");
- screen->opencl_dri_event_get_fence =
- dlsym(RTLD_DEFAULT, "opencl_dri_event_get_fence");
-
- success = dri2_is_opencl_interop_loaded_locked(screen);
- mtx_unlock(&screen->opencl_func_mutex);
- return success;
-#else
- return false;
-#endif
-}
-
-struct dri2_fence {
- struct dri_screen *driscreen;
- struct pipe_fence_handle *pipe_fence;
- void *cl_event;
-};
-
-static unsigned dri2_fence_get_caps(__DRIscreen *_screen)
-{
- struct dri_screen *driscreen = dri_screen(_screen);
- struct pipe_screen *screen = driscreen->base.screen;
- unsigned caps = 0;
-
- if (screen->get_param(screen, PIPE_CAP_NATIVE_FENCE_FD))
- caps |= __DRI_FENCE_CAP_NATIVE_FD;
-
- return caps;
-}
-
-static void *
-dri2_create_fence(__DRIcontext *_ctx)
-{
- struct pipe_context *ctx = dri_context(_ctx)->st->pipe;
- struct dri2_fence *fence = CALLOC_STRUCT(dri2_fence);
-
- if (!fence)
- return NULL;
-
- ctx->flush(ctx, &fence->pipe_fence, 0);
-
- if (!fence->pipe_fence) {
- FREE(fence);
- return NULL;
- }
-
- fence->driscreen = dri_screen(_ctx->driScreenPriv);
- return fence;
-}
-
-static void *
-dri2_create_fence_fd(__DRIcontext *_ctx, int fd)
-{
- struct pipe_context *ctx = dri_context(_ctx)->st->pipe;
- struct dri2_fence *fence = CALLOC_STRUCT(dri2_fence);
-
- if (fd == -1) {
- /* exporting driver created fence, flush: */
- ctx->flush(ctx, &fence->pipe_fence,
- PIPE_FLUSH_DEFERRED | PIPE_FLUSH_FENCE_FD);
- } else {
- /* importing a foreign fence fd: */
- ctx->create_fence_fd(ctx, &fence->pipe_fence, fd);
- }
- if (!fence->pipe_fence) {
- FREE(fence);
- return NULL;
- }
-
- fence->driscreen = dri_screen(_ctx->driScreenPriv);
- return fence;
-}
-
-static int
-dri2_get_fence_fd(__DRIscreen *_screen, void *_fence)
-{
- struct dri_screen *driscreen = dri_screen(_screen);
- struct pipe_screen *screen = driscreen->base.screen;
- struct dri2_fence *fence = (struct dri2_fence*)_fence;
-
- return screen->fence_get_fd(screen, fence->pipe_fence);
-}
-
-static void *
-dri2_get_fence_from_cl_event(__DRIscreen *_screen, intptr_t cl_event)
-{
- struct dri_screen *driscreen = dri_screen(_screen);
- struct dri2_fence *fence;
-
- if (!dri2_load_opencl_interop(driscreen))
- return NULL;
-
- fence = CALLOC_STRUCT(dri2_fence);
- if (!fence)
- return NULL;
-
- fence->cl_event = (void*)cl_event;
-
- if (!driscreen->opencl_dri_event_add_ref(fence->cl_event)) {
- free(fence);
- return NULL;
- }
-
- fence->driscreen = driscreen;
- return fence;
-}
-
-static void
-dri2_destroy_fence(__DRIscreen *_screen, void *_fence)
-{
- struct dri_screen *driscreen = dri_screen(_screen);
- struct pipe_screen *screen = driscreen->base.screen;
- struct dri2_fence *fence = (struct dri2_fence*)_fence;
-
- if (fence->pipe_fence)
- screen->fence_reference(screen, &fence->pipe_fence, NULL);
- else if (fence->cl_event)
- driscreen->opencl_dri_event_release(fence->cl_event);
- else
- assert(0);
-
- FREE(fence);
-}
-
-static GLboolean
-dri2_client_wait_sync(__DRIcontext *_ctx, void *_fence, unsigned flags,
- uint64_t timeout)
-{
- struct dri2_fence *fence = (struct dri2_fence*)_fence;
- struct dri_screen *driscreen = fence->driscreen;
- struct pipe_screen *screen = driscreen->base.screen;
-
- /* No need to flush. The context was flushed when the fence was created. */
-
- if (fence->pipe_fence)
- return screen->fence_finish(screen, NULL, fence->pipe_fence, timeout);
- else if (fence->cl_event) {
- struct pipe_fence_handle *pipe_fence =
- driscreen->opencl_dri_event_get_fence(fence->cl_event);
-
- if (pipe_fence)
- return screen->fence_finish(screen, NULL, pipe_fence, timeout);
- else
- return driscreen->opencl_dri_event_wait(fence->cl_event, timeout);
- }
- else {
- assert(0);
- return false;
- }
-}
-
-static void
-dri2_server_wait_sync(__DRIcontext *_ctx, void *_fence, unsigned flags)
-{
- struct pipe_context *ctx = dri_context(_ctx)->st->pipe;
- struct dri2_fence *fence = (struct dri2_fence*)_fence;
-
- if (ctx->fence_server_sync)
- ctx->fence_server_sync(ctx, fence->pipe_fence);
-}
-
-static __DRI2fenceExtension dri2FenceExtension = {
- .base = { __DRI2_FENCE, 2 },
-
- .create_fence = dri2_create_fence,
- .get_fence_from_cl_event = dri2_get_fence_from_cl_event,
- .destroy_fence = dri2_destroy_fence,
- .client_wait_sync = dri2_client_wait_sync,
- .server_wait_sync = dri2_server_wait_sync,
- .get_capabilities = dri2_fence_get_caps,
- .create_fence_fd = dri2_create_fence_fd,
- .get_fence_fd = dri2_get_fence_fd,
+ .createImageWithModifiers = NULL,
+ .createImageFromDmaBufs2 = NULL,
+ .queryDmaBufFormats = NULL,
+ .queryDmaBufModifiers = NULL,
+ .queryDmaBufFormatModifierAttribs = NULL,
+ .createImageFromRenderbuffer2 = dri2_create_image_from_renderbuffer2,
};
static const __DRIrobustnessExtension dri2Robustness = {
return MESA_GLINTEROP_INVALID_MIP_LEVEL;
/* Validate the OpenGL object and get pipe_resource. */
- mtx_lock(&ctx->Shared->Mutex);
+ simple_mtx_lock(&ctx->Shared->Mutex);
if (target == GL_ARRAY_BUFFER) {
/* Buffer objects.
* the size of the buffer is 0."
*/
if (!buf || buf->Size == 0) {
- mtx_unlock(&ctx->Shared->Mutex);
+ simple_mtx_unlock(&ctx->Shared->Mutex);
return MESA_GLINTEROP_INVALID_OBJECT;
}
res = st_buffer_object(buf)->buffer;
if (!res) {
/* this shouldn't happen */
- mtx_unlock(&ctx->Shared->Mutex);
+ simple_mtx_unlock(&ctx->Shared->Mutex);
return MESA_GLINTEROP_INVALID_OBJECT;
}
* object or if the width or height of renderbuffer is zero."
*/
if (!rb || rb->Width == 0 || rb->Height == 0) {
- mtx_unlock(&ctx->Shared->Mutex);
+ simple_mtx_unlock(&ctx->Shared->Mutex);
return MESA_GLINTEROP_INVALID_OBJECT;
}
* renderbuffer object."
*/
if (rb->NumSamples > 1) {
- mtx_unlock(&ctx->Shared->Mutex);
+ simple_mtx_unlock(&ctx->Shared->Mutex);
return MESA_GLINTEROP_INVALID_OPERATION;
}
*/
res = st_renderbuffer(rb)->texture;
if (!res) {
- mtx_unlock(&ctx->Shared->Mutex);
+ simple_mtx_unlock(&ctx->Shared->Mutex);
return MESA_GLINTEROP_OUT_OF_RESOURCES;
}
obj->Target != target ||
!obj->_BaseComplete ||
(in->miplevel > 0 && !obj->_MipmapComplete)) {
- mtx_unlock(&ctx->Shared->Mutex);
+ simple_mtx_unlock(&ctx->Shared->Mutex);
return MESA_GLINTEROP_INVALID_OBJECT;
}
- /* From OpenCL 2.0 SDK, clCreateFromGLTexture:
- * "CL_INVALID_MIP_LEVEL if miplevel is less than the value of
- * levelbase (for OpenGL implementations) or zero (for OpenGL ES
- * implementations); or greater than the value of q (for both OpenGL
- * and OpenGL ES). levelbase and q are defined for the texture in
- * section 3.8.10 (Texture Completeness) of the OpenGL 2.1
- * specification and section 3.7.10 of the OpenGL ES 2.0."
- */
- if (in->miplevel < obj->BaseLevel || in->miplevel > obj->_MaxLevel) {
- mtx_unlock(&ctx->Shared->Mutex);
- return MESA_GLINTEROP_INVALID_MIP_LEVEL;
- }
-
- if (!st_finalize_texture(ctx, st->pipe, obj, 0)) {
- mtx_unlock(&ctx->Shared->Mutex);
- return MESA_GLINTEROP_OUT_OF_RESOURCES;
- }
+ if (target == GL_TEXTURE_BUFFER) {
+ struct st_buffer_object *stBuf =
+ st_buffer_object(obj->BufferObject);
- res = st_get_texobj_resource(obj);
- if (!res) {
- /* Incomplete texture buffer object? This shouldn't really occur. */
- mtx_unlock(&ctx->Shared->Mutex);
- return MESA_GLINTEROP_INVALID_OBJECT;
- }
+ if (!stBuf || !stBuf->buffer) {
+ /* this shouldn't happen */
+ simple_mtx_unlock(&ctx->Shared->Mutex);
+ return MESA_GLINTEROP_INVALID_OBJECT;
+ }
+ res = stBuf->buffer;
- if (target == GL_TEXTURE_BUFFER) {
out->internal_format = obj->BufferObjectFormat;
out->buf_offset = obj->BufferOffset;
out->buf_size = obj->BufferSize == -1 ? obj->BufferObject->Size :
obj->BufferObject->UsageHistory |= USAGE_DISABLE_MINMAX_CACHE;
} else {
+ /* From OpenCL 2.0 SDK, clCreateFromGLTexture:
+ * "CL_INVALID_MIP_LEVEL if miplevel is less than the value of
+ * levelbase (for OpenGL implementations) or zero (for OpenGL ES
+ * implementations); or greater than the value of q (for both OpenGL
+ * and OpenGL ES). levelbase and q are defined for the texture in
+ * section 3.8.10 (Texture Completeness) of the OpenGL 2.1
+ * specification and section 3.7.10 of the OpenGL ES 2.0."
+ */
+ if (in->miplevel < obj->BaseLevel || in->miplevel > obj->_MaxLevel) {
+ simple_mtx_unlock(&ctx->Shared->Mutex);
+ return MESA_GLINTEROP_INVALID_MIP_LEVEL;
+ }
+
+ if (!st_finalize_texture(ctx, st->pipe, obj, 0)) {
+ simple_mtx_unlock(&ctx->Shared->Mutex);
+ return MESA_GLINTEROP_OUT_OF_RESOURCES;
+ }
+
+ res = st_get_texobj_resource(obj);
+ if (!res) {
+ /* Incomplete texture buffer object? This shouldn't really occur. */
+ simple_mtx_unlock(&ctx->Shared->Mutex);
+ return MESA_GLINTEROP_INVALID_OBJECT;
+ }
+
out->internal_format = obj->Image[0][0]->InternalFormat;
out->view_minlevel = obj->MinLevel;
out->view_numlevels = obj->NumLevels;
/* Get the handle. */
switch (in->access) {
- case MESA_GLINTEROP_ACCESS_READ_WRITE:
- usage = PIPE_HANDLE_USAGE_READ_WRITE;
- break;
case MESA_GLINTEROP_ACCESS_READ_ONLY:
- usage = PIPE_HANDLE_USAGE_READ;
+ usage = 0;
break;
+ case MESA_GLINTEROP_ACCESS_READ_WRITE:
case MESA_GLINTEROP_ACCESS_WRITE_ONLY:
- usage = PIPE_HANDLE_USAGE_WRITE;
+ usage = PIPE_HANDLE_USAGE_SHADER_WRITE;
break;
default:
usage = 0;
}
memset(&whandle, 0, sizeof(whandle));
- whandle.type = DRM_API_HANDLE_TYPE_FD;
+ whandle.type = WINSYS_HANDLE_TYPE_FD;
success = screen->resource_get_handle(screen, st->pipe, res, &whandle,
usage);
- mtx_unlock(&ctx->Shared->Mutex);
+ simple_mtx_unlock(&ctx->Shared->Mutex);
if (!success)
return MESA_GLINTEROP_OUT_OF_HOST_MEMORY;
.export_object = dri2_interop_export_object
};
+/**
+ * \brief the DRI2ConfigQueryExtension configQueryb method
+ */
+static int
+dri2GalliumConfigQueryb(__DRIscreen *sPriv, const char *var,
+ unsigned char *val)
+{
+ struct dri_screen *screen = dri_screen(sPriv);
+
+ if (!driCheckOption(&screen->dev->option_cache, var, DRI_BOOL))
+ return dri2ConfigQueryExtension.configQueryb(sPriv, var, val);
+
+ *val = driQueryOptionb(&screen->dev->option_cache, var);
+
+ return 0;
+}
+
+/**
+ * \brief the DRI2ConfigQueryExtension configQueryi method
+ */
+static int
+dri2GalliumConfigQueryi(__DRIscreen *sPriv, const char *var, int *val)
+{
+ struct dri_screen *screen = dri_screen(sPriv);
+
+ if (!driCheckOption(&screen->dev->option_cache, var, DRI_INT) &&
+ !driCheckOption(&screen->dev->option_cache, var, DRI_ENUM))
+ return dri2ConfigQueryExtension.configQueryi(sPriv, var, val);
+
+ *val = driQueryOptioni(&screen->dev->option_cache, var);
+
+ return 0;
+}
+
+/**
+ * \brief the DRI2ConfigQueryExtension configQueryf method
+ */
+static int
+dri2GalliumConfigQueryf(__DRIscreen *sPriv, const char *var, float *val)
+{
+ struct dri_screen *screen = dri_screen(sPriv);
+
+ if (!driCheckOption(&screen->dev->option_cache, var, DRI_FLOAT))
+ return dri2ConfigQueryExtension.configQueryf(sPriv, var, val);
+
+ *val = driQueryOptionf(&screen->dev->option_cache, var);
+
+ return 0;
+}
+
+/**
+ * \brief the DRI2ConfigQueryExtension struct.
+ *
+ * We first query the driver option cache. Then the dri2 option cache.
+ */
+static const __DRI2configQueryExtension dri2GalliumConfigQueryExtension = {
+ .base = { __DRI2_CONFIG_QUERY, 1 },
+
+ .configQueryb = dri2GalliumConfigQueryb,
+ .configQueryi = dri2GalliumConfigQueryi,
+ .configQueryf = dri2GalliumConfigQueryf,
+};
+
/*
* Backend function init_screen.
*/
&dri2FlushExtension.base,
&dri2ImageExtension.base,
&dri2RendererQueryExtension.base,
- &dri2ConfigQueryExtension.base,
+ &dri2GalliumConfigQueryExtension.base,
&dri2ThrottleExtension.base,
&dri2FenceExtension.base,
&dri2InteropExtension.base,
+ &dri2NoErrorExtension.base,
NULL
};
&dri2FlushExtension.base,
&dri2ImageExtension.base,
&dri2RendererQueryExtension.base,
- &dri2ConfigQueryExtension.base,
+ &dri2GalliumConfigQueryExtension.base,
&dri2ThrottleExtension.base,
&dri2FenceExtension.base,
&dri2InteropExtension.base,
&dri2Robustness.base,
+ &dri2NoErrorExtension.base,
NULL
};
struct pipe_screen *pscreen = NULL;
const struct drm_conf_ret *throttle_ret;
const struct drm_conf_ret *dmabuf_ret;
- int fd;
screen = CALLOC_STRUCT(dri_screen);
if (!screen)
sPriv->driverPrivate = (void *)screen;
- if (screen->fd < 0 || (fd = fcntl(screen->fd, F_DUPFD_CLOEXEC, 3)) < 0)
- goto free_screen;
+ if (pipe_loader_drm_probe_fd(&screen->dev, screen->fd)) {
+ dri_init_options(screen);
- if (pipe_loader_drm_probe_fd(&screen->dev, fd))
pscreen = pipe_loader_create_screen(screen->dev);
+ }
if (!pscreen)
goto release_pipe;
screen->default_throttle_frames = throttle_ret->val.val_int;
}
+ if (pscreen->resource_create_with_modifiers)
+ dri2ImageExtension.createImageWithModifiers =
+ dri2_create_image_with_modifiers;
+
if (dmabuf_ret && dmabuf_ret->val.val_bool) {
uint64_t cap;
(cap & DRM_PRIME_CAP_IMPORT)) {
dri2ImageExtension.createImageFromFds = dri2_from_fds;
dri2ImageExtension.createImageFromDmaBufs = dri2_from_dma_bufs;
+ dri2ImageExtension.createImageFromDmaBufs2 = dri2_from_dma_bufs2;
+ if (pscreen->query_dmabuf_modifiers) {
+ dri2ImageExtension.queryDmaBufFormats = dri2_query_dma_buf_formats;
+ dri2ImageExtension.queryDmaBufModifiers =
+ dri2_query_dma_buf_modifiers;
+ }
}
}
else
sPriv->extensions = dri_screen_extensions;
- configs = dri_init_screen_helper(screen, pscreen, screen->dev->driver_name);
+ configs = dri_init_screen_helper(screen, pscreen);
if (!configs)
goto destroy_screen;
release_pipe:
if (screen->dev)
pipe_loader_release(&screen->dev, 1);
- else
- close(fd);
-free_screen:
FREE(screen);
return NULL;
}
struct dri_screen *screen;
struct pipe_screen *pscreen = NULL;
uint64_t cap;
- int fd;
screen = CALLOC_STRUCT(dri_screen);
if (!screen)
sPriv->driverPrivate = (void *)screen;
- if (screen->fd < 0 || (fd = fcntl(screen->fd, F_DUPFD_CLOEXEC, 3)) < 0)
- goto free_screen;
-
- if (pipe_loader_sw_probe_kms(&screen->dev, fd))
+ if (pipe_loader_sw_probe_kms(&screen->dev, screen->fd)) {
+ dri_init_options(screen);
pscreen = pipe_loader_create_screen(screen->dev);
+ }
if (!pscreen)
goto release_pipe;
+ if (pscreen->resource_create_with_modifiers)
+ dri2ImageExtension.createImageWithModifiers =
+ dri2_create_image_with_modifiers;
+
if (drmGetCap(sPriv->fd, DRM_CAP_PRIME, &cap) == 0 &&
(cap & DRM_PRIME_CAP_IMPORT)) {
dri2ImageExtension.createImageFromFds = dri2_from_fds;
dri2ImageExtension.createImageFromDmaBufs = dri2_from_dma_bufs;
+ dri2ImageExtension.createImageFromDmaBufs2 = dri2_from_dma_bufs2;
+ if (pscreen->query_dmabuf_modifiers) {
+ dri2ImageExtension.queryDmaBufFormats = dri2_query_dma_buf_formats;
+ dri2ImageExtension.queryDmaBufModifiers = dri2_query_dma_buf_modifiers;
+ }
}
sPriv->extensions = dri_screen_extensions;
- configs = dri_init_screen_helper(screen, pscreen, "swrast");
+ configs = dri_init_screen_helper(screen, pscreen);
if (!configs)
goto destroy_screen;
release_pipe:
if (screen->dev)
pipe_loader_release(&screen->dev, 1);
- else
- close(fd);
-free_screen:
FREE(screen);
#endif // GALLIUM_SOFTPIPE
return NULL;
drawable->allocate_textures = dri2_allocate_textures;
drawable->flush_frontbuffer = dri2_flush_frontbuffer;
drawable->update_tex_buffer = dri2_update_tex_buffer;
+ drawable->flush_swapbuffers = dri2_flush_swapbuffers;
return TRUE;
}
&driImageDriverExtension.base,
&driDRI2Extension.base,
&gallium_config_options.base,
- &dri2FenceExtension.base,
NULL
};