summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2010-04-06 18:55:40 +0800
committerChia-I Wu <[email protected]>2010-04-06 19:32:27 +0800
commit7915151f2d05e175d00e739e9a3fead922e60096 (patch)
treee66147a7201ffe5c65723ffc2031e562517b58d5 /src
parent216c76c820339729a6c17237cf4d1478a1e9e2be (diff)
st/dri: Implement DRI image extension.
Diffstat (limited to 'src')
-rw-r--r--src/gallium/state_trackers/dri/common/dri_st_api.c26
-rw-r--r--src/gallium/state_trackers/dri/common/dri_st_api.h9
-rw-r--r--src/gallium/state_trackers/dri/drm/dri2.c105
-rw-r--r--src/gallium/state_trackers/dri/drm/dri2.h3
4 files changed, 143 insertions, 0 deletions
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 */