summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristian Høgsberg <[email protected]>2008-02-14 22:12:51 -0500
committerKristian Høgsberg <[email protected]>2008-02-14 22:12:51 -0500
commit6d48779c7e5c9002d1bec4b1266ca05a474218ef (patch)
tree11e77add8301b85d43151d66dc62ded2bf4e50df
parent5961ed5fbc6c76476ff8f76d21a7113673563068 (diff)
Add TTM buffer object based texture from pixmap implementation.
Currently only implemented for intel hw.
-rw-r--r--include/GL/internal/dri_interface.h20
-rw-r--r--src/mesa/drivers/dri/intel/intel_mipmap_tree.c93
-rw-r--r--src/mesa/drivers/dri/intel/intel_mipmap_tree.h10
-rw-r--r--src/mesa/drivers/dri/intel/intel_screen.c6
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex.h3
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_image.c67
6 files changed, 182 insertions, 17 deletions
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 50f1d1a765c..b83aff18f97 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -64,6 +64,7 @@ typedef struct __DRIallocateExtensionRec __DRIallocateExtension;
typedef struct __DRIframeTrackingExtensionRec __DRIframeTrackingExtension;
typedef struct __DRImediaStreamCounterExtensionRec __DRImediaStreamCounterExtension;
typedef struct __DRItexOffsetExtensionRec __DRItexOffsetExtension;
+typedef struct __DRItexBufferExtensionRec __DRItexBufferExtension;
/*@}*/
@@ -221,6 +222,25 @@ struct __DRItexOffsetExtensionRec {
};
+#define __DRI_TEX_BUFFER "DRI_TexBuffer"
+#define __DRI_TEX_BUFFER_VERSION 1
+struct __DRItexBufferExtensionRec {
+ __DRIextension base;
+
+ /**
+ * Method to override base texture image with a DRM memory manager
+ * buffer object. The depth passed in allows e.g. to ignore the
+ * alpha channel of texture images where the non-alpha components
+ * don't occupy a whole texel.
+ *
+ * For GLX_EXT_texture_from_pixmap with AIGLX.
+ */
+ void (*setTexBuffer)(__DRIcontext *pDRICtx,
+ GLint target, unsigned long handle,
+ GLint cpp, GLuint pitch, GLuint height);
+};
+
+
/**
* Macros for building symbol and strings. Standard CPP two step...
*/
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
index 97a82fe9d0f..d446b2b392a 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 e3b31f9c6e5..3c1a6ffa2a8 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 7e0c52005de..2392c2c49cc 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 2973e0ceb9f..d1055be93e6 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 0500829f4b6..4cbc453c704 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);
+}