Add TTM buffer object based texture from pixmap implementation.

Currently only implemented for intel hw.
This commit is contained in:
Kristian Høgsberg 2008-02-14 22:12:51 -05:00
parent 5961ed5fbc
commit 6d48779c7e
6 changed files with 184 additions and 19 deletions

View File

@ -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...
*/

View File

@ -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,14 +87,7 @@ 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 (!mt->region) {
if (!ok) {
free(mt);
return NULL;
}
@ -104,6 +95,74 @@ intel_miptree_create(struct intel_context *intel,
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:
*

View File

@ -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);

View File

@ -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
};

View File

@ -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);

View File

@ -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);
}