From 7915151f2d05e175d00e739e9a3fead922e60096 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Tue, 6 Apr 2010 18:55:40 +0800 Subject: [PATCH] st/dri: Implement DRI image extension. --- .../state_trackers/dri/common/dri_st_api.c | 26 +++++ .../state_trackers/dri/common/dri_st_api.h | 9 ++ src/gallium/state_trackers/dri/drm/dri2.c | 105 ++++++++++++++++++ src/gallium/state_trackers/dri/drm/dri2.h | 3 + 4 files changed, 143 insertions(+) diff --git a/src/gallium/state_trackers/dri/common/dri_st_api.c b/src/gallium/state_trackers/dri/common/dri_st_api.c index 1a5259c68ba..561e6aa3b62 100644 --- a/src/gallium/state_trackers/dri/common/dri_st_api.c +++ b/src/gallium/state_trackers/dri/common/dri_st_api.c @@ -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(); } diff --git a/src/gallium/state_trackers/dri/common/dri_st_api.h b/src/gallium/state_trackers/dri/common/dri_st_api.h index 99a217bfa79..f41c1c6674c 100644 --- a/src/gallium/state_trackers/dri/common/dri_st_api.h +++ b/src/gallium/state_trackers/dri/common/dri_st_api.h @@ -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); diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c index c632f0fe4f3..420ff0ee59e 100644 --- a/src/gallium/state_trackers/dri/drm/dri2.c +++ b/src/gallium/state_trackers/dri/drm/dri2.c @@ -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 }; diff --git a/src/gallium/state_trackers/dri/drm/dri2.h b/src/gallium/state_trackers/dri/drm/dri2.h index 379963431fb..5b28850000b 100644 --- a/src/gallium/state_trackers/dri/drm/dri2.h +++ b/src/gallium/state_trackers/dri/drm/dri2.h @@ -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 */ -- 2.30.2