From 6d48779c7e5c9002d1bec4b1266ca05a474218ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 14 Feb 2008 22:12:51 -0500 Subject: Add TTM buffer object based texture from pixmap implementation. Currently only implemented for intel hw. --- src/mesa/drivers/dri/intel/intel_mipmap_tree.c | 93 +++++++++++++++++++++----- src/mesa/drivers/dri/intel/intel_mipmap_tree.h | 10 +++ src/mesa/drivers/dri/intel/intel_screen.c | 6 ++ src/mesa/drivers/dri/intel/intel_tex.h | 3 + src/mesa/drivers/dri/intel/intel_tex_image.c | 67 +++++++++++++++++++ 5 files changed, 162 insertions(+), 17 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c index 97a82fe..d446b2b 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c @@ -49,17 +49,15 @@ target_to_target(GLenum target) } } -struct intel_mipmap_tree * -intel_miptree_create(struct intel_context *intel, - GLenum target, - GLenum internal_format, - GLuint first_level, - GLuint last_level, - GLuint width0, - GLuint height0, - GLuint depth0, - GLuint cpp, - GLuint compress_byte) +static struct intel_mipmap_tree * +intel_miptree_create_internal(struct intel_context *intel, + GLenum target, + GLenum internal_format, + GLuint first_level, + GLuint last_level, + GLuint width0, + GLuint height0, + GLuint depth0, GLuint cpp, GLuint compress_byte) { GLboolean ok; struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1); @@ -89,20 +87,81 @@ intel_miptree_create(struct intel_context *intel, ok = brw_miptree_layout(intel, mt); #endif - if (ok) { - assert (mt->pitch); - - mt->region = intel_region_alloc(intel, - mt->cpp, mt->pitch, mt->total_height); + if (!ok) { + free(mt); + return NULL; } + return mt; +} + +struct intel_mipmap_tree * +intel_miptree_create(struct intel_context *intel, + GLenum target, + GLenum internal_format, + GLuint first_level, + GLuint last_level, + GLuint width0, + GLuint height0, + GLuint depth0, GLuint cpp, GLuint compress_byte) +{ + struct intel_mipmap_tree *mt; + + mt = intel_miptree_create_internal(intel, target, internal_format, + first_level, last_level, width0, + height0, depth0, cpp, compress_byte); + if (!mt) + return NULL; + + assert (mt->pitch); + mt->region = intel_region_alloc(intel, + mt->cpp, mt->pitch, mt->total_height); + if (!mt->region) { + free(mt); + return NULL; + } + + return mt; +} + +struct intel_mipmap_tree * +intel_miptree_create_for_region(struct intel_context *intel, + GLenum target, + GLenum internal_format, + GLuint first_level, + GLuint last_level, + struct intel_region *region, + GLuint depth0, + GLuint compress_byte) +{ + struct intel_mipmap_tree *mt; + + mt = intel_miptree_create_internal(intel, target, internal_format, + first_level, last_level, + region->pitch, region->height, depth0, + region->cpp, compress_byte); + if (!mt) + return mt; +#if 0 + if (mt->pitch != region->pitch) { + fprintf(stderr, + "region pitch (%d) doesn't match mipmap tree pitch (%d)\n", + region->pitch, mt->pitch); free(mt); return NULL; } +#else + /* The mipmap tree pitch is aligned to 64 bytes to make sure render + * to texture works, but we don't need that for texturing from a + * pixmap. Just override it here. */ + mt->pitch = region->pitch; +#endif + + mt->region = region; return mt; -} + } /** * intel_miptree_pitch_align: diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h index e3b31f9..3c1a6ff 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h @@ -124,6 +124,16 @@ struct intel_mipmap_tree *intel_miptree_create(struct intel_context *intel, GLuint cpp, GLuint compress_byte); +struct intel_mipmap_tree * +intel_miptree_create_for_region(struct intel_context *intel, + GLenum target, + GLenum internal_format, + GLuint first_level, + GLuint last_level, + struct intel_region *region, + GLuint depth0, + GLuint compress_byte); + int intel_miptree_pitch_align (struct intel_context *intel, struct intel_mipmap_tree *mt, int pitch); diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index 7e0c520..2392c2c 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -398,6 +398,11 @@ static const __DRItexOffsetExtension intelTexOffsetExtension = { intelSetTexOffset, }; +static const __DRItexBufferExtension intelTexBufferExtension = { + { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION }, + intelSetTexBuffer, +}; + static const __DRIextension *intelExtensions[] = { &driReadDrawableExtension, &driCopySubBufferExtension.base, @@ -405,6 +410,7 @@ static const __DRIextension *intelExtensions[] = { &driFrameTrackingExtension.base, &driMediaStreamCounterExtension.base, &intelTexOffsetExtension.base, + &intelTexBufferExtension.base, NULL }; diff --git a/src/mesa/drivers/dri/intel/intel_tex.h b/src/mesa/drivers/dri/intel/intel_tex.h index 2973e0c..d1055be 100644 --- a/src/mesa/drivers/dri/intel/intel_tex.h +++ b/src/mesa/drivers/dri/intel/intel_tex.h @@ -137,6 +137,9 @@ void intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, void intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname, unsigned long long offset, GLint depth, GLuint pitch); +void intelSetTexBuffer(__DRIcontext *pDRICtx, + GLint target, unsigned long handle, + GLint cpp, GLuint pitch, GLuint height); GLuint intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit); diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index 0500829..4cbc453 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -14,6 +14,7 @@ #include "texformat.h" #include "texobj.h" #include "texstore.h" +#include "teximage.h" #include "intel_context.h" #include "intel_mipmap_tree.h" @@ -692,3 +693,69 @@ intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname, if (offset) intelObj->textureOffset = offset; } + +void +intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, + unsigned long handle, GLint cpp, GLuint pitch, GLuint height) +{ + __DRIcontextPrivate *driContext = pDRICtx->private; + struct intel_context *intel = driContext->driverPrivate; + struct intel_texture_object *intelObj; + struct intel_texture_image *intelImage; + struct intel_mipmap_tree *mt; + struct intel_region *region; + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + int level = 0; + + /* FIXME: type, format, internalFormat */ + int type = GL_BGRA; + int format = GL_UNSIGNED_BYTE; + int internalFormat = (cpp == 3 ? 3 : 4); + cpp = 4; + pitch /= 4; + + texUnit = &intel->ctx.Texture.Unit[intel->ctx.Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(&intel->ctx, texUnit, target); + intelObj = intel_texture_object(texObj); + + if (!intelObj) + return; + + region = intel_region_alloc_for_handle(intel, cpp, pitch, height, + 0, handle); + + mt = intel_miptree_create_for_region(intel, target, + internalFormat, + 0, 0, region, 1, 0); + if (mt == NULL) + return; + + _mesa_lock_texture(&intel->ctx, texObj); + + if (intelObj->mt) + intel_miptree_release(intel, &intelObj->mt); + + intelObj->mt = mt; + texImage = _mesa_get_tex_image(&intel->ctx, texObj, target, level); + _mesa_init_teximage_fields(&intel->ctx, target, texImage, + pitch, height, 1, + 0, internalFormat); + + intelImage = intel_texture_image(texImage); + intelImage->face = target_to_face(target); + intelImage->level = level; + texImage->TexFormat = intelChooseTextureFormat(&intel->ctx, internalFormat, + type, format); + _mesa_set_fetch_functions(texImage, 2); + texImage->RowStride = pitch; + intel_miptree_reference(&intelImage->mt, intelObj->mt); + + if (!intel_miptree_match_image(intelObj->mt, &intelImage->base, + intelImage->face, intelImage->level)) { + fprintf(stderr, "miptree doesn't match image\n"); + } + + _mesa_unlock_texture(&intel->ctx, texObj); +} -- cgit v1.1