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 __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...
|
||||
*/
|
||||
|
|
|
@ -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:
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue