*/
#include <xf86drm.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_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
-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
+struct dri2_buffer
+{
+ __DRIbuffer base;
+ struct pipe_resource *resource;
};
-static int convert_fourcc(int format, int *dri_components_p)
+static inline struct dri2_buffer *
+dri2_buffer(__DRIbuffer * driBufferPriv)
{
- int dri_components;
- switch(format) {
- case __DRI_IMAGE_FOURCC_RGB565:
- format = __DRI_IMAGE_FORMAT_RGB565;
- dri_components = __DRI_IMAGE_COMPONENTS_RGB;
- break;
- case __DRI_IMAGE_FOURCC_ARGB8888:
- format = __DRI_IMAGE_FORMAT_ARGB8888;
- dri_components = __DRI_IMAGE_COMPONENTS_RGBA;
- break;
- case __DRI_IMAGE_FOURCC_XRGB8888:
- format = __DRI_IMAGE_FORMAT_XRGB8888;
- dri_components = __DRI_IMAGE_COMPONENTS_RGB;
- break;
- case __DRI_IMAGE_FOURCC_ABGR8888:
- format = __DRI_IMAGE_FORMAT_ABGR8888;
- dri_components = __DRI_IMAGE_COMPONENTS_RGBA;
- break;
- case __DRI_IMAGE_FOURCC_XBGR8888:
- 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;
- break;
- case __DRI_IMAGE_FOURCC_GR88:
- 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-
- * planar YUV it gets to figure out the remaining planes on it's
- * own.
- */
- case __DRI_IMAGE_FOURCC_YUV420:
- case __DRI_IMAGE_FOURCC_YVU420:
- format = __DRI_IMAGE_FORMAT_R8;
- dri_components = __DRI_IMAGE_COMPONENTS_Y_U_V;
- break;
- case __DRI_IMAGE_FOURCC_NV12:
- format = __DRI_IMAGE_FORMAT_R8;
- dri_components = __DRI_IMAGE_COMPONENTS_Y_UV;
- break;
- default:
- return -1;
- }
- *dri_components_p = dri_components;
- return format;
+ return (struct dri2_buffer *) driBufferPriv;
}
-/* NOTE this probably isn't going to do the right thing for YUV images
- * (but I think the same can be said for intel_query_image()). I think
- * only needed for exporting dmabuf's, so I think I won't loose much
- * sleep over it.
- */
-static int convert_to_fourcc(int format)
-{
- switch(format) {
- case __DRI_IMAGE_FORMAT_RGB565:
- format = __DRI_IMAGE_FOURCC_RGB565;
- break;
- case __DRI_IMAGE_FORMAT_ARGB8888:
- format = __DRI_IMAGE_FOURCC_ARGB8888;
- break;
- case __DRI_IMAGE_FORMAT_XRGB8888:
- format = __DRI_IMAGE_FOURCC_XRGB8888;
- break;
- case __DRI_IMAGE_FORMAT_ABGR8888:
- format = __DRI_IMAGE_FOURCC_ABGR8888;
- 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_R8:
- format = __DRI_IMAGE_FOURCC_R8;
- break;
- case __DRI_IMAGE_FORMAT_GR88:
- format = __DRI_IMAGE_FOURCC_GR88;
- break;
- default:
- return -1;
- }
- return format;
-}
+struct dri2_format_mapping {
+ int dri_fourcc;
+ int dri_format;
+ int dri_components;
+ enum pipe_format pipe_format;
+};
-static enum pipe_format dri2_format_to_pipe_format (int format)
-{
- enum pipe_format pf;
+static const struct dri2_format_mapping dri2_format_table[] = {
+ { __DRI_IMAGE_FOURCC_ARGB2101010, __DRI_IMAGE_FORMAT_ARGB2101010,
+ __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_B10G10R10A2_UNORM },
+ { __DRI_IMAGE_FOURCC_XRGB2101010, __DRI_IMAGE_FORMAT_XRGB2101010,
+ __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_B10G10R10X2_UNORM },
+ { __DRI_IMAGE_FOURCC_ABGR2101010, __DRI_IMAGE_FORMAT_ABGR2101010,
+ __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_R10G10B10A2_UNORM },
+ { __DRI_IMAGE_FOURCC_XBGR2101010, __DRI_IMAGE_FORMAT_XBGR2101010,
+ __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_R10G10B10X2_UNORM },
+ { __DRI_IMAGE_FOURCC_ARGB8888, __DRI_IMAGE_FORMAT_ARGB8888,
+ __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_BGRA8888_UNORM },
+ { __DRI_IMAGE_FOURCC_ABGR8888, __DRI_IMAGE_FORMAT_ABGR8888,
+ __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_RGBA8888_UNORM },
+ { __DRI_IMAGE_FOURCC_SARGB8888, __DRI_IMAGE_FORMAT_SARGB8,
+ __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_BGRA8888_SRGB },
+ { __DRI_IMAGE_FOURCC_XRGB8888, __DRI_IMAGE_FORMAT_XRGB8888,
+ __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_BGRX8888_UNORM },
+ { __DRI_IMAGE_FOURCC_XBGR8888, __DRI_IMAGE_FORMAT_XBGR8888,
+ __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_RGBX8888_UNORM },
+ { __DRI_IMAGE_FOURCC_ARGB1555, __DRI_IMAGE_FORMAT_RGB565,
+ __DRI_IMAGE_COMPONENTS_RGBA, PIPE_FORMAT_B5G5R5A1_UNORM },
+ { __DRI_IMAGE_FOURCC_RGB565, __DRI_IMAGE_FORMAT_RGB565,
+ __DRI_IMAGE_COMPONENTS_RGB, PIPE_FORMAT_B5G6R5_UNORM },
+ { __DRI_IMAGE_FOURCC_R8, __DRI_IMAGE_FORMAT_R8,
+ __DRI_IMAGE_COMPONENTS_R, PIPE_FORMAT_R8_UNORM },
+ { __DRI_IMAGE_FOURCC_R16, __DRI_IMAGE_FORMAT_R16,
+ __DRI_IMAGE_COMPONENTS_R, PIPE_FORMAT_R16_UNORM },
+ { __DRI_IMAGE_FOURCC_GR88, __DRI_IMAGE_FORMAT_GR88,
+ __DRI_IMAGE_COMPONENTS_RG, PIPE_FORMAT_RG88_UNORM },
+ { __DRI_IMAGE_FOURCC_GR1616, __DRI_IMAGE_FORMAT_GR88,
+ __DRI_IMAGE_COMPONENTS_RG, PIPE_FORMAT_RG1616_UNORM },
+ { __DRI_IMAGE_FOURCC_YUV420, __DRI_IMAGE_FORMAT_NONE,
+ __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_IYUV },
+ { __DRI_IMAGE_FOURCC_YVU420, __DRI_IMAGE_FORMAT_NONE,
+ __DRI_IMAGE_COMPONENTS_Y_U_V, PIPE_FORMAT_YV12 },
+ { __DRI_IMAGE_FOURCC_NV12, __DRI_IMAGE_FORMAT_NONE,
+ __DRI_IMAGE_COMPONENTS_Y_UV, PIPE_FORMAT_NV12 },
+ { __DRI_IMAGE_FOURCC_YUYV, __DRI_IMAGE_FORMAT_YUYV,
+ __DRI_IMAGE_COMPONENTS_Y_XUXV, PIPE_FORMAT_YUYV },
+};
- switch (format) {
- case __DRI_IMAGE_FORMAT_RGB565:
- pf = PIPE_FORMAT_B5G6R5_UNORM;
- break;
- case __DRI_IMAGE_FORMAT_XRGB8888:
- pf = PIPE_FORMAT_BGRX8888_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_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;
+static const struct dri2_format_mapping *
+dri2_get_mapping_by_fourcc(int fourcc) {
+ for (unsigned i = 0; i < ARRAY_SIZE(dri2_format_table); i++) {
+ if (dri2_format_table[i].dri_fourcc == fourcc)
+ return &dri2_format_table[i];
}
- return pf;
+ return NULL;
}
-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;
+static const struct dri2_format_mapping *
+dri2_get_mapping_by_format(int format) {
+ for (unsigned i = 0; i < ARRAY_SIZE(dri2_format_table); i++) {
+ if (dri2_format_table[i].dri_format == format)
+ return &dri2_format_table[i];
}
- return pf;
+ return NULL;
}
/**
* 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;
}
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_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]);
}
}
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 (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];
}
static __DRIimage *
dri2_create_image_from_winsys(__DRIscreen *_screen,
- int width, int height, int format,
+ int width, int height, enum pipe_format pf,
int num_handles, struct winsys_handle *whandle,
void *loaderPrivate)
{
struct pipe_screen *pscreen = screen->base.screen;
__DRIimage *img;
struct pipe_resource templ;
- unsigned tex_usage;
- enum pipe_format pf;
+ unsigned tex_usage = 0;
int i;
- tex_usage = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
+ 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;
+
+ if (!tex_usage && util_format_is_yuv(pf)) {
+ /* YUV format sampling can be emulated by the Mesa state tracker by
+ * using multiple R8/RG88 samplers. So try to rewrite the pipe format.
+ */
+ pf = PIPE_FORMAT_R8_UNORM;
- pf = dri2_format_to_pipe_format (format);
- if (pf == PIPE_FORMAT_NONE)
+ if (pscreen->is_format_supported(pscreen, pf, screen->target, 0, 0,
+ PIPE_BIND_SAMPLER_VIEW))
+ tex_usage |= PIPE_BIND_SAMPLER_VIEW;
+ }
+
+ if (!tex_usage)
return NULL;
img = CALLOC_STRUCT(__DRIimageRec);
}
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);
img->level = 0;
img->layer = 0;
- img->dri_format = format;
img->use = 0;
img->loader_private = loaderPrivate;
int width, int height, int format,
int name, int pitch, void *loaderPrivate)
{
+ const struct dri2_format_mapping *map = dri2_get_mapping_by_format(format);
struct winsys_handle whandle;
- enum pipe_format pf;
+ __DRIimage *img;
+
+ if (!map)
+ return NULL;
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)
+ whandle.stride = pitch * util_format_get_blocksize(map->pipe_format);
+
+ img = dri2_create_image_from_winsys(_screen, width, height, map->pipe_format,
+ 1, &whandle, loaderPrivate);
+
+ if (!img)
return NULL;
- whandle.stride = pitch * util_format_get_blocksize(pf);
+ img->dri_components = map->dri_components;
+ img->dri_fourcc = map->dri_fourcc;
+ img->dri_format = map->dri_format;
- return dri2_create_image_from_winsys(_screen, width, height, format,
- 1, &whandle, loaderPrivate);
+ return img;
}
static __DRIimage *
int width, int height, int fourcc,
uint64_t modifier, int *fds, int num_fds,
int *strides, int *offsets, unsigned *error,
- int *dri_components, void *loaderPrivate)
+ void *loaderPrivate)
{
struct winsys_handle whandles[3];
- int format;
+ const struct dri2_format_mapping *map = dri2_get_mapping_by_fourcc(fourcc);
__DRIimage *img = NULL;
unsigned err = __DRI_IMAGE_ERROR_SUCCESS;
int expected_num_fds, i;
+ if (!map) {
+ err = __DRI_IMAGE_ERROR_BAD_MATCH;
+ goto exit;
+ }
+
switch (fourcc) {
case __DRI_IMAGE_FOURCC_YUV420:
case __DRI_IMAGE_FOURCC_YVU420:
goto exit;
}
- format = convert_fourcc(fourcc, dri_components);
- if (format == -1) {
- err = __DRI_IMAGE_ERROR_BAD_MATCH;
- goto exit;
- }
-
memset(whandles, 0, sizeof(whandles));
for (i = 0; i < num_fds; i++) {
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[1] = whandles[2];
whandles[2] = tmp;
fourcc = __DRI_IMAGE_FOURCC_YUV420;
+ map = dri2_get_mapping_by_fourcc(fourcc);
}
- img = dri2_create_image_from_winsys(_screen, width, height, format,
+ img = dri2_create_image_from_winsys(_screen, width, height, map->pipe_format,
num_fds, whandles, loaderPrivate);
- if(img == NULL)
+ if(img == NULL) {
err = __DRI_IMAGE_ERROR_BAD_ALLOC;
+ goto exit;
+ }
+
+ img->dri_components = map->dri_components;
+ img->dri_fourcc = fourcc;
+ img->dri_format = map->dri_format;
exit:
if (error)
const unsigned count,
void *loaderPrivate)
{
+ const struct dri2_format_mapping *map = dri2_get_mapping_by_format(format);
struct dri_screen *screen = dri_screen(_screen);
__DRIimage *img;
struct pipe_resource templ;
unsigned tex_usage;
- enum pipe_format pf;
+
+ if (!map)
+ return NULL;
/* createImageWithModifiers doesn't supply usage, and we should not get
* here with both modifiers and a usage flag.
tex_usage |= PIPE_BIND_CURSOR;
}
- pf = dri2_format_to_pipe_format (format);
- if (pf == PIPE_FORMAT_NONE)
- return NULL;
-
img = CALLOC_STRUCT(__DRIimageRec);
if (!img)
return NULL;
memset(&templ, 0, sizeof(templ));
templ.bind = tex_usage;
- templ.format = pf;
+ templ.format = map->pipe_format;
templ.target = PIPE_TEXTURE_2D;
templ.last_level = 0;
templ.width0 = width;
img->level = 0;
img->layer = 0;
img->dri_format = format;
+ img->dri_fourcc = map->dri_fourcc;
img->dri_components = 0;
img->use = use;
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;
+ 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 = DRM_API_HANDLE_TYPE_KMS;
+ 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;
+ 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;
+ 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;
*value = image->dri_components;
return GL_TRUE;
case __DRI_IMAGE_ATTRIB_FOURCC:
- *value = convert_to_fourcc(image->dri_format);
+ if (image->dri_fourcc) {
+ *value = image->dri_fourcc;
+ } else {
+ const struct dri2_format_mapping *map;
+
+ map = dri2_get_mapping_by_format(image->dri_format);
+ if (!map)
+ return GL_FALSE;
+
+ *value = map->dri_fourcc;
+ }
return GL_TRUE;
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.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))
*value = (whandle.modifier >> 32) & 0xffffffff;
return GL_TRUE;
case __DRI_IMAGE_ATTRIB_MODIFIER_LOWER:
- whandle.type = DRM_API_HANDLE_TYPE_KMS;
+ 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))
int *names, int num_names, int *strides, int *offsets,
void *loaderPrivate)
{
+ const struct dri2_format_mapping *map = dri2_get_mapping_by_format(format);
__DRIimage *img;
- int dri_components;
struct winsys_handle whandle;
- if (num_names != 1)
+ if (!map)
return NULL;
- format = convert_fourcc(format, &dri_components);
- if (format == -1)
+ if (num_names != 1)
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,
+ img = dri2_create_image_from_winsys(screen, width, height, map->pipe_format,
1, &whandle, loaderPrivate);
if (img == NULL)
return NULL;
- img->dri_components = dri_components;
+ img->dri_components = map->dri_components;
+ img->dri_fourcc = map->dri_fourcc;
+ img->dri_format = map->pipe_format;
+
return img;
}
int *fds, int num_fds, int *strides, int *offsets,
void *loaderPrivate)
{
- __DRIimage *img;
- int dri_components;
-
- img = dri2_create_image_from_fd(screen, width, height, fourcc,
+ return 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;
-
- img->dri_components = dri_components;
- return img;
+ strides, offsets, NULL, loaderPrivate);
}
static boolean
{
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)) &&
+ for (i = 0, j = 0; (i < ARRAY_SIZE(dri2_format_table)) &&
(j < max || max == 0); i++) {
- if (pscreen->is_format_supported(pscreen,
- fourcc_to_pipe_format(
- fourcc_formats[i]),
- screen->target,
- 0, bind)) {
+ const struct dri2_format_mapping *map = &dri2_format_table[i];
+
+ /* The sRGB format is not a real FourCC as defined by drm_fourcc.h, so we
+ * must not leak it out to clients.
+ */
+ if (dri2_format_table[i].dri_fourcc == __DRI_IMAGE_FOURCC_SARGB8888)
+ continue;
+
+ if (pscreen->is_format_supported(pscreen, map->pipe_format,
+ screen->target, 0, 0,
+ PIPE_BIND_RENDER_TARGET) ||
+ pscreen->is_format_supported(pscreen, map->pipe_format,
+ screen->target, 0, 0,
+ PIPE_BIND_SAMPLER_VIEW)) {
if (j < max)
- formats[j] = fourcc_formats[i];
+ formats[j] = map->dri_fourcc;
j++;
}
}
{
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;
+ const struct dri2_format_mapping *map = dri2_get_mapping_by_fourcc(fourcc);
+ enum pipe_format format;
+
+ if (!map)
+ return false;
+
+ format = map->pipe_format;
if (pscreen->query_dmabuf_modifiers != NULL &&
- pscreen->is_format_supported(pscreen, format, screen->target, 0, usage)) {
+ (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;
void *loaderPrivate)
{
__DRIimage *img;
- int dri_components;
img = dri2_create_image_from_fd(screen, width, height, fourcc,
DRM_FORMAT_MOD_INVALID, fds, num_fds,
- strides, offsets, error,
- &dri_components, loaderPrivate);
+ strides, offsets, error, loaderPrivate);
if (img == NULL)
return NULL;
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;
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);
+ error, loaderPrivate);
if (img == NULL)
return NULL;
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;
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) {
- 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;
- }
+ 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. */
- simple_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);
&dri2FenceExtension.base,
&dri2InteropExtension.base,
&dri2NoErrorExtension.base,
- &dri2FlushControlExtension.base,
NULL
};
&dri2InteropExtension.base,
&dri2Robustness.base,
&dri2NoErrorExtension.base,
- &dri2FlushControlExtension.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, fd)) {
+ if (pipe_loader_drm_probe_fd(&screen->dev, screen->fd)) {
dri_init_options(screen);
pscreen = pipe_loader_create_screen(screen->dev);
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);
}
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;
+ if (pscreen->query_dmabuf_modifiers) {
+ dri2ImageExtension.queryDmaBufFormats = dri2_query_dma_buf_formats;
+ dri2ImageExtension.queryDmaBufModifiers = dri2_query_dma_buf_modifiers;
+ }
}
sPriv->extensions = dri_screen_extensions;
release_pipe:
if (screen->dev)
pipe_loader_release(&screen->dev, 1);
- else
- close(fd);
-free_screen:
FREE(screen);
#endif // GALLIUM_SOFTPIPE
return NULL;