Currently only implemented for intel hw.
typedef struct __DRIframeTrackingExtensionRec __DRIframeTrackingExtension;
typedef struct __DRImediaStreamCounterExtensionRec __DRImediaStreamCounterExtension;
typedef struct __DRItexOffsetExtensionRec __DRItexOffsetExtension;
+typedef struct __DRItexBufferExtensionRec __DRItexBufferExtension;
/*@}*/
};
+#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...
*/
}
}
-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);
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:
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);
intelSetTexOffset,
};
+static const __DRItexBufferExtension intelTexBufferExtension = {
+ { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
+ intelSetTexBuffer,
+};
+
static const __DRIextension *intelExtensions[] = {
&driReadDrawableExtension,
&driCopySubBufferExtension.base,
&driFrameTrackingExtension.base,
&driMediaStreamCounterExtension.base,
&intelTexOffsetExtension.base,
+ &intelTexBufferExtension.base,
NULL
};
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);
#include "texformat.h"
#include "texobj.h"
#include "texstore.h"
+#include "teximage.h"
#include "intel_context.h"
#include "intel_mipmap_tree.h"
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);
+}