Add TTM buffer object based texture from pixmap implementation.
Currently only implemented for intel hw.
This commit is contained in:
parent
5961ed5fbc
commit
6d48779c7e
|
@ -64,6 +64,7 @@ typedef struct __DRIallocateExtensionRec __DRIallocateExtension;
|
||||||
typedef struct __DRIframeTrackingExtensionRec __DRIframeTrackingExtension;
|
typedef struct __DRIframeTrackingExtensionRec __DRIframeTrackingExtension;
|
||||||
typedef struct __DRImediaStreamCounterExtensionRec __DRImediaStreamCounterExtension;
|
typedef struct __DRImediaStreamCounterExtensionRec __DRImediaStreamCounterExtension;
|
||||||
typedef struct __DRItexOffsetExtensionRec __DRItexOffsetExtension;
|
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...
|
* Macros for building symbol and strings. Standard CPP two step...
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -49,17 +49,15 @@ target_to_target(GLenum target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct intel_mipmap_tree *
|
static struct intel_mipmap_tree *
|
||||||
intel_miptree_create(struct intel_context *intel,
|
intel_miptree_create_internal(struct intel_context *intel,
|
||||||
GLenum target,
|
GLenum target,
|
||||||
GLenum internal_format,
|
GLenum internal_format,
|
||||||
GLuint first_level,
|
GLuint first_level,
|
||||||
GLuint last_level,
|
GLuint last_level,
|
||||||
GLuint width0,
|
GLuint width0,
|
||||||
GLuint height0,
|
GLuint height0,
|
||||||
GLuint depth0,
|
GLuint depth0, GLuint cpp, GLuint compress_byte)
|
||||||
GLuint cpp,
|
|
||||||
GLuint compress_byte)
|
|
||||||
{
|
{
|
||||||
GLboolean ok;
|
GLboolean ok;
|
||||||
struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1);
|
struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1);
|
||||||
|
@ -89,12 +87,35 @@ intel_miptree_create(struct intel_context *intel,
|
||||||
ok = brw_miptree_layout(intel, mt);
|
ok = brw_miptree_layout(intel, mt);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ok) {
|
if (!ok) {
|
||||||
assert (mt->pitch);
|
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->region = intel_region_alloc(intel,
|
||||||
mt->cpp, mt->pitch, mt->total_height);
|
mt->cpp, mt->pitch, mt->total_height);
|
||||||
}
|
|
||||||
|
|
||||||
if (!mt->region) {
|
if (!mt->region) {
|
||||||
free(mt);
|
free(mt);
|
||||||
|
@ -104,6 +125,44 @@ intel_miptree_create(struct intel_context *intel,
|
||||||
return mt;
|
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:
|
* intel_miptree_pitch_align:
|
||||||
*
|
*
|
||||||
|
|
|
@ -124,6 +124,16 @@ struct intel_mipmap_tree *intel_miptree_create(struct intel_context *intel,
|
||||||
GLuint cpp,
|
GLuint cpp,
|
||||||
GLuint compress_byte);
|
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,
|
int intel_miptree_pitch_align (struct intel_context *intel,
|
||||||
struct intel_mipmap_tree *mt,
|
struct intel_mipmap_tree *mt,
|
||||||
int pitch);
|
int pitch);
|
||||||
|
|
|
@ -398,6 +398,11 @@ static const __DRItexOffsetExtension intelTexOffsetExtension = {
|
||||||
intelSetTexOffset,
|
intelSetTexOffset,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const __DRItexBufferExtension intelTexBufferExtension = {
|
||||||
|
{ __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
|
||||||
|
intelSetTexBuffer,
|
||||||
|
};
|
||||||
|
|
||||||
static const __DRIextension *intelExtensions[] = {
|
static const __DRIextension *intelExtensions[] = {
|
||||||
&driReadDrawableExtension,
|
&driReadDrawableExtension,
|
||||||
&driCopySubBufferExtension.base,
|
&driCopySubBufferExtension.base,
|
||||||
|
@ -405,6 +410,7 @@ static const __DRIextension *intelExtensions[] = {
|
||||||
&driFrameTrackingExtension.base,
|
&driFrameTrackingExtension.base,
|
||||||
&driMediaStreamCounterExtension.base,
|
&driMediaStreamCounterExtension.base,
|
||||||
&intelTexOffsetExtension.base,
|
&intelTexOffsetExtension.base,
|
||||||
|
&intelTexBufferExtension.base,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -137,6 +137,9 @@ void intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
|
||||||
|
|
||||||
void intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname,
|
void intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname,
|
||||||
unsigned long long offset, GLint depth, GLuint pitch);
|
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);
|
GLuint intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit);
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "texformat.h"
|
#include "texformat.h"
|
||||||
#include "texobj.h"
|
#include "texobj.h"
|
||||||
#include "texstore.h"
|
#include "texstore.h"
|
||||||
|
#include "teximage.h"
|
||||||
|
|
||||||
#include "intel_context.h"
|
#include "intel_context.h"
|
||||||
#include "intel_mipmap_tree.h"
|
#include "intel_mipmap_tree.h"
|
||||||
|
@ -692,3 +693,69 @@ intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname,
|
||||||
if (offset)
|
if (offset)
|
||||||
intelObj->textureOffset = 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);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue