st/dri: Implement DRI image extension.
This commit is contained in:
@@ -224,6 +224,31 @@ _dri_put_st_api(void)
|
||||
}
|
||||
}
|
||||
|
||||
static boolean
|
||||
dri_st_manager_get_egl_image(struct st_manager *smapi,
|
||||
struct st_egl_image *stimg)
|
||||
{
|
||||
__DRIimage *img = NULL;
|
||||
|
||||
#ifndef __NOT_HAVE_DRM_H
|
||||
if (!__dri1_api_hooks) {
|
||||
struct dri_context *ctx = (struct dri_context *)
|
||||
stimg->stctxi->st_manager_private;
|
||||
img = dri2_lookup_egl_image(ctx, stimg->egl_image);
|
||||
}
|
||||
#endif
|
||||
if (!img)
|
||||
return FALSE;
|
||||
|
||||
stimg->texture = NULL;
|
||||
pipe_texture_reference(&stimg->texture, img->texture);
|
||||
stimg->face = img->face;
|
||||
stimg->level = img->level;
|
||||
stimg->zslice = img->zslice;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a state tracker manager from the given screen.
|
||||
*/
|
||||
@@ -235,6 +260,7 @@ dri_create_st_manager(struct dri_screen *screen)
|
||||
smapi = CALLOC_STRUCT(st_manager);
|
||||
if (smapi) {
|
||||
smapi->screen = screen->pipe_screen;
|
||||
smapi->get_egl_image = dri_st_manager_get_egl_image;
|
||||
_dri_get_st_api();
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,15 @@
|
||||
struct dri_screen;
|
||||
struct dri_drawable;
|
||||
|
||||
struct __DRIimageRec {
|
||||
struct pipe_texture *texture;
|
||||
unsigned face;
|
||||
unsigned level;
|
||||
unsigned zslice;
|
||||
|
||||
void *loader_private;
|
||||
};
|
||||
|
||||
struct st_api *
|
||||
dri_get_st_api(void);
|
||||
|
||||
|
||||
@@ -352,6 +352,110 @@ dri2_flush_frontbuffer(struct dri_drawable *drawable,
|
||||
}
|
||||
}
|
||||
|
||||
__DRIimage *
|
||||
dri2_lookup_egl_image(struct dri_context *ctx, void *handle)
|
||||
{
|
||||
__DRIimageLookupExtension *loader = ctx->sPriv->dri2.image;
|
||||
__DRIimage *img;
|
||||
|
||||
if (!loader->lookupEGLImage)
|
||||
return NULL;
|
||||
|
||||
img = loader->lookupEGLImage(ctx->cPriv, handle, ctx->cPriv->loaderPrivate);
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
static __DRIimage *
|
||||
dri2_create_image_from_name(__DRIcontext *context,
|
||||
int width, int height, int format,
|
||||
int name, int pitch, void *loaderPrivate)
|
||||
{
|
||||
struct dri_screen *screen = dri_screen(context->driScreenPriv);
|
||||
__DRIimage *img;
|
||||
struct pipe_texture templ;
|
||||
struct winsys_handle whandle;
|
||||
unsigned tex_usage;
|
||||
enum pipe_format pf;
|
||||
|
||||
tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET | PIPE_TEXTURE_USAGE_SAMPLER;
|
||||
|
||||
switch (format) {
|
||||
case __DRI_IMAGE_FORMAT_RGB565:
|
||||
pf = PIPE_FORMAT_B5G6R5_UNORM;
|
||||
break;
|
||||
case __DRI_IMAGE_FORMAT_XRGB8888:
|
||||
pf = PIPE_FORMAT_B8G8R8X8_UNORM;
|
||||
break;
|
||||
case __DRI_IMAGE_FORMAT_ARGB8888:
|
||||
pf = PIPE_FORMAT_B8G8R8A8_UNORM;
|
||||
break;
|
||||
default:
|
||||
pf = PIPE_FORMAT_NONE;
|
||||
break;
|
||||
}
|
||||
if (pf == PIPE_FORMAT_NONE)
|
||||
return NULL;
|
||||
|
||||
img = CALLOC_STRUCT(__DRIimageRec);
|
||||
if (!img)
|
||||
return NULL;
|
||||
|
||||
memset(&templ, 0, sizeof(templ));
|
||||
templ.tex_usage = tex_usage;
|
||||
templ.format = pf;
|
||||
templ.target = PIPE_TEXTURE_2D;
|
||||
templ.last_level = 0;
|
||||
templ.width0 = width;
|
||||
templ.height0 = height;
|
||||
templ.depth0 = 1;
|
||||
|
||||
memset(&whandle, 0, sizeof(whandle));
|
||||
whandle.handle = name;
|
||||
whandle.stride = pitch * util_format_get_blocksize(pf);
|
||||
|
||||
img->texture = screen->pipe_screen->texture_from_handle(screen->pipe_screen,
|
||||
&templ, &whandle);
|
||||
if (!img->texture) {
|
||||
FREE(img);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
img->face = 0;
|
||||
img->level = 0;
|
||||
img->zslice = 0;
|
||||
img->loader_private = loaderPrivate;
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
static __DRIimage *
|
||||
dri2_create_image_from_renderbuffer(__DRIcontext *context,
|
||||
int renderbuffer, void *loaderPrivate)
|
||||
{
|
||||
struct dri_context *ctx = dri_context(context->driverPrivate);
|
||||
|
||||
if (!ctx->st->get_resource_for_egl_image)
|
||||
return NULL;
|
||||
|
||||
/* TODO */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
dri2_destroy_image(__DRIimage *img)
|
||||
{
|
||||
pipe_texture_reference(&img->texture, NULL);
|
||||
FREE(img);
|
||||
}
|
||||
|
||||
static struct __DRIimageExtensionRec dri2ImageExtension = {
|
||||
{ __DRI_IMAGE, __DRI_IMAGE_VERSION },
|
||||
dri2_create_image_from_name,
|
||||
dri2_create_image_from_renderbuffer,
|
||||
dri2_destroy_image,
|
||||
};
|
||||
|
||||
/*
|
||||
* Backend function init_screen.
|
||||
*/
|
||||
@@ -364,6 +468,7 @@ static const __DRIextension *dri_screen_extensions[] = {
|
||||
&driMediaStreamCounterExtension.base,
|
||||
&dri2TexBufferExtension.base,
|
||||
&dri2FlushExtension.base,
|
||||
&dri2ImageExtension.base,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
@@ -43,4 +43,7 @@ dri2_allocate_textures(struct dri_drawable *drawable,
|
||||
const enum st_attachment_type *statts,
|
||||
unsigned count);
|
||||
|
||||
__DRIimage *
|
||||
dri2_lookup_egl_image(struct dri_context *ctx, void *handle);
|
||||
|
||||
#endif /* DRI2_H */
|
||||
|
||||
Reference in New Issue
Block a user