#include "main/bufferobj.h"
#include "main/texobj.h"
-#include "dri_screen.h"
-#include "dri_context.h"
+#include "dri_helpers.h"
#include "dri_drawable.h"
-#include "dri_extensions.h"
#include "dri_query_renderer.h"
#include "dri2_buffer.h"
+#ifndef DRM_FORMAT_MOD_INVALID
+#define DRM_FORMAT_MOD_INVALID ((1ULL<<56) - 1)
+#endif
+
+static const int fourcc_formats[] = {
+ __DRI_IMAGE_FOURCC_ARGB2101010,
+ __DRI_IMAGE_FOURCC_XRGB2101010,
+ __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;
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_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-
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_R8:
format = __DRI_IMAGE_FOURCC_R8;
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_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_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_BGRA8888_UNORM:
+ case PIPE_FORMAT_RGBA8888_UNORM:
depth = 32;
break;
+ 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:
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;
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;
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;
/* Try to reuse the resource.
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;
}
}
+/**
+ * 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,
memset(&whandle, 0, sizeof(whandle));
whandle.type = DRM_API_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];
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)
{
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);
+ 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 = DRM_API_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);
+ 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);
+ 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:
case __DRI_IMAGE_ATTRIB_NUM_PLANES:
*value = 1;
return GL_TRUE;
+ case __DRI_IMAGE_ATTRIB_MODIFIER_UPPER:
+ whandle.type = DRM_API_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 = DRM_API_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 *
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);
return img;
}
-static __DRIimage *
-dri2_create_from_texture(__DRIcontext *context, int target, unsigned texture,
- int depth, int level, unsigned *error,
- 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;
- }
-
- tex = st_get_texobj_resource(obj);
- if (!tex) {
- *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
- return NULL;
- }
-
- if (target == GL_TEXTURE_CUBE_MAP)
- face = depth;
-
- _mesa_test_texobj_completeness(ctx, obj);
- if (!obj->_BaseComplete || (level > 0 && !obj->_MipmapComplete)) {
- *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
- return NULL;
- }
-
- if (level < obj->BaseLevel || level > obj->_MaxLevel) {
- *error = __DRI_IMAGE_ERROR_BAD_MATCH;
- return NULL;
- }
-
- if (target == GL_TEXTURE_3D && obj->Image[face][level]->Depth < depth) {
- *error = __DRI_IMAGE_ERROR_BAD_MATCH;
- return NULL;
- }
-
- img = CALLOC_STRUCT(__DRIimageRec);
- if (!img) {
- *error = __DRI_IMAGE_ERROR_BAD_ALLOC;
- return NULL;
- }
-
- 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;
- }
-
- pipe_resource_reference(&img->texture, tex);
-
- *error = __DRI_IMAGE_ERROR_SUCCESS;
- return img;
-}
-
static __DRIimage *
dri2_from_fds(__DRIscreen *screen, int width, int height, int fourcc,
int *fds, int num_fds, int *strides, int *offsets,
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, NULL,
&dri_components, loaderPrivate);
if (img == NULL)
return NULL;
return img;
}
+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;
+ const unsigned bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
+ int i, j;
+
+ for (i = 0, j = 0; (i < ARRAY_SIZE(fourcc_formats)) &&
+ (j < max || max == 0); i++) {
+ if (pscreen->is_format_supported(pscreen,
+ fourcc_to_pipe_format(
+ fourcc_formats[i]),
+ screen->target,
+ 0, bind)) {
+ if (j < max)
+ formats[j] = fourcc_formats[i];
+ j++;
+ }
+ }
+ *count = j;
+ return true;
+}
+
+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);
+ const unsigned usage = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
+
+ if (pscreen->query_dmabuf_modifiers != NULL &&
+ pscreen->is_format_supported(pscreen, format, screen->target, 0, usage)) {
+ pscreen->query_dmabuf_modifiers(pscreen, format, max, modifiers,
+ external_only, count);
+ return true;
+ }
+ return false;
+}
+
static __DRIimage *
dri2_from_dma_bufs(__DRIscreen *screen,
int width, int height, int fourcc,
int dri_components;
img = dri2_create_image_from_fd(screen, width, height, fourcc,
- fds, num_fds, strides, offsets, error,
+ DRM_FORMAT_MOD_INVALID, fds, num_fds,
+ strides, offsets, error,
&dri_components, loaderPrivate);
if (img == NULL)
return NULL;
return img;
}
+static __DRIimage *
+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,
+ modifier, 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 void
dri2_blit_image(__DRIcontext *context, __DRIimage *dst, __DRIimage *src,
int dstx0, int dsty0, int dstwidth, int dstheight,
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,
+ .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;
}
* 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);
+ simple_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);
+ 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. */
- mtx_unlock(&ctx->Shared->Mutex);
+ simple_mtx_unlock(&ctx->Shared->Mutex);
return MESA_GLINTEROP_INVALID_OBJECT;
}
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;
{
struct dri_screen *screen = dri_screen(sPriv);
- if (!driCheckOption(&screen->optionCache, var, DRI_BOOL))
+ if (!driCheckOption(&screen->dev->option_cache, var, DRI_BOOL))
return dri2ConfigQueryExtension.configQueryb(sPriv, var, val);
- *val = driQueryOptionb(&screen->optionCache, var);
+ *val = driQueryOptionb(&screen->dev->option_cache, var);
return 0;
}
{
struct dri_screen *screen = dri_screen(sPriv);
- if (!driCheckOption(&screen->optionCache, var, DRI_INT) &&
- !driCheckOption(&screen->optionCache, var, DRI_ENUM))
+ 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->optionCache, var);
+ *val = driQueryOptioni(&screen->dev->option_cache, var);
return 0;
}
{
struct dri_screen *screen = dri_screen(sPriv);
- if (!driCheckOption(&screen->optionCache, var, DRI_FLOAT))
+ if (!driCheckOption(&screen->dev->option_cache, var, DRI_FLOAT))
return dri2ConfigQueryExtension.configQueryf(sPriv, var, val);
- *val = driQueryOptionf(&screen->optionCache, var);
+ *val = driQueryOptionf(&screen->dev->option_cache, var);
return 0;
}
&dri2ThrottleExtension.base,
&dri2FenceExtension.base,
&dri2InteropExtension.base,
+ &dri2NoErrorExtension.base,
+ &dri2FlushControlExtension.base,
NULL
};
&dri2FlushExtension.base,
&dri2ImageExtension.base,
&dri2RendererQueryExtension.base,
- &dri2ConfigQueryExtension.base,
+ &dri2GalliumConfigQueryExtension.base,
&dri2ThrottleExtension.base,
&dri2FenceExtension.base,
&dri2InteropExtension.base,
&dri2Robustness.base,
+ &dri2NoErrorExtension.base,
+ &dri2FlushControlExtension.base,
NULL
};
if (screen->fd < 0 || (fd = fcntl(screen->fd, F_DUPFD_CLOEXEC, 3)) < 0)
goto free_screen;
- if (pipe_loader_drm_probe_fd(&screen->dev, fd))
+
+ if (pipe_loader_drm_probe_fd(&screen->dev, fd)) {
+ dri_init_options(screen);
+
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;
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, 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;
+ 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;
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
};