New implementation of GLX_MESA_render_texture
This commit is contained in:
parent
bdb3eb86f0
commit
521916d007
356
hw/xgl/xglglx.c
356
hw/xgl/xglglx.c
|
@ -78,6 +78,10 @@ typedef __GLinterface *(*GLXCreateContextProc) (__GLimports *imports,
|
||||||
__GLinterface *shareGC);
|
__GLinterface *shareGC);
|
||||||
typedef void (*GLXCreateBufferProc) (__GLXdrawablePrivate *glxPriv);
|
typedef void (*GLXCreateBufferProc) (__GLXdrawablePrivate *glxPriv);
|
||||||
typedef GLboolean (*GLXSwapBuffersProc) (__GLXdrawablePrivate *glxPriv);
|
typedef GLboolean (*GLXSwapBuffersProc) (__GLXdrawablePrivate *glxPriv);
|
||||||
|
typedef int (*GLXBindBuffersProc) (__GLXdrawablePrivate *glxPriv,
|
||||||
|
int buffer);
|
||||||
|
typedef int (*GLXReleaseBuffersProc) (__GLXdrawablePrivate *glxPriv,
|
||||||
|
int buffer);
|
||||||
|
|
||||||
typedef struct _xglGLXScreenInfo {
|
typedef struct _xglGLXScreenInfo {
|
||||||
GLXScreenProbeProc screenProbe;
|
GLXScreenProbeProc screenProbe;
|
||||||
|
@ -97,18 +101,20 @@ typedef GLboolean (*GLResizeBuffersProc) (__GLdrawableBuffer *buffer,
|
||||||
typedef void (*GLFreeBuffersProc) (__GLdrawablePrivate *glPriv);
|
typedef void (*GLFreeBuffersProc) (__GLdrawablePrivate *glPriv);
|
||||||
|
|
||||||
typedef struct _xglGLBuffer {
|
typedef struct _xglGLBuffer {
|
||||||
GLXSwapBuffersProc swapBuffers;
|
GLXSwapBuffersProc swapBuffers;
|
||||||
GLResizeBuffersProc resizeBuffers;
|
GLXBindBuffersProc bindBuffers;
|
||||||
GLFreeBuffersProc freeBuffers;
|
GLXReleaseBuffersProc releaseBuffers;
|
||||||
ScreenPtr pScreen;
|
GLResizeBuffersProc resizeBuffers;
|
||||||
DrawablePtr pDrawable;
|
GLFreeBuffersProc freeBuffers;
|
||||||
glitz_surface_t *backSurface;
|
ScreenPtr pScreen;
|
||||||
PixmapPtr pPixmap;
|
DrawablePtr pDrawable;
|
||||||
GCPtr pGC;
|
glitz_surface_t *backSurface;
|
||||||
RegionRec damage;
|
PixmapPtr pPixmap;
|
||||||
void *private;
|
GCPtr pGC;
|
||||||
int xOff, yOff;
|
RegionRec damage;
|
||||||
int yFlip;
|
void *private;
|
||||||
|
int xOff, yOff;
|
||||||
|
int yFlip;
|
||||||
} xglGLBufferRec, *xglGLBufferPtr;
|
} xglGLBufferRec, *xglGLBufferPtr;
|
||||||
|
|
||||||
typedef int xglGLXVisualConfigRec, *xglGLXVisualConfigPtr;
|
typedef int xglGLXVisualConfigRec, *xglGLXVisualConfigPtr;
|
||||||
|
@ -3388,136 +3394,6 @@ xglNoOpPointParameterivNV (GLenum pname, const GLint *params) {}
|
||||||
static void
|
static void
|
||||||
xglNoOpActiveStencilFaceEXT (GLenum face) {}
|
xglNoOpActiveStencilFaceEXT (GLenum face) {}
|
||||||
|
|
||||||
|
|
||||||
/* GL_MESA_render_texture */
|
|
||||||
#define GLX_TEXTURE_TARGET_MESA 0x1
|
|
||||||
#define GLX_TEXTURE_2D_MESA 0x2
|
|
||||||
#define GLX_TEXTURE_RECTANGLE_MESA 0x3
|
|
||||||
#define GLX_NO_TEXTURE_MESA 0x4
|
|
||||||
#define GLX_FRONT_LEFT_MESA 0x5
|
|
||||||
static int
|
|
||||||
xglXBindTexImageMESA (DrawablePtr pDrawable,
|
|
||||||
int buffer)
|
|
||||||
{
|
|
||||||
if (buffer != GLX_FRONT_LEFT_MESA)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (pDrawable->type != DRAWABLE_WINDOW)
|
|
||||||
{
|
|
||||||
xglGLContextPtr pContext = cctx;
|
|
||||||
xglTexUnitPtr pTexUnit = &cctx->attrib.texUnits[cctx->activeTexUnit];
|
|
||||||
xglTexObjPtr pTexObj = NULL;
|
|
||||||
|
|
||||||
if (xglSyncSurface (pDrawable))
|
|
||||||
{
|
|
||||||
glitz_point_fixed_t point = { 1 << 16 , 1 << 16 };
|
|
||||||
|
|
||||||
XGL_DRAWABLE_PIXMAP (pDrawable);
|
|
||||||
XGL_PIXMAP_PRIV (pPixmap);
|
|
||||||
|
|
||||||
/* FIXME: doesn't work with 1x1 textures */
|
|
||||||
glitz_surface_translate_point (pPixmapPriv->surface,
|
|
||||||
&point, &point);
|
|
||||||
if (point.x > (1 << 16) || point.y > (1 << 16))
|
|
||||||
pTexObj = pTexUnit->pRect;
|
|
||||||
else
|
|
||||||
pTexObj = pTexUnit->p2D;
|
|
||||||
|
|
||||||
if (pTexObj)
|
|
||||||
{
|
|
||||||
pPixmap->refcnt++;
|
|
||||||
|
|
||||||
if (pTexObj->pPixmap)
|
|
||||||
(*pDrawable->pScreen->DestroyPixmap) (pTexObj->pPixmap);
|
|
||||||
|
|
||||||
pTexObj->pPixmap = pPixmap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pContext != cctx)
|
|
||||||
xglSetCurrentContext (pContext);
|
|
||||||
|
|
||||||
if (pTexObj)
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
static int
|
|
||||||
xglXReleaseTexImageMESA (DrawablePtr pDrawable,
|
|
||||||
int buffer)
|
|
||||||
{
|
|
||||||
xglTexObjPtr pTexObj;
|
|
||||||
|
|
||||||
XGL_DRAWABLE_PIXMAP (pDrawable);
|
|
||||||
|
|
||||||
if (buffer != GLX_FRONT_LEFT_MESA)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
pTexObj = cctx->attrib.texUnits[cctx->activeTexUnit].p2D;
|
|
||||||
if (pTexObj && pTexObj->pPixmap == pPixmap)
|
|
||||||
{
|
|
||||||
(*pDrawable->pScreen->DestroyPixmap) (pTexObj->pPixmap);
|
|
||||||
pTexObj->pPixmap = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pTexObj = cctx->attrib.texUnits[cctx->activeTexUnit].pRect;
|
|
||||||
if (pTexObj && pTexObj->pPixmap == pPixmap)
|
|
||||||
{
|
|
||||||
(*pDrawable->pScreen->DestroyPixmap) (pTexObj->pPixmap);
|
|
||||||
pTexObj->pPixmap = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
static int
|
|
||||||
xglXQueryDrawableMESA (DrawablePtr pDrawable,
|
|
||||||
int attribute,
|
|
||||||
unsigned int *value)
|
|
||||||
{
|
|
||||||
switch (attribute) {
|
|
||||||
case GLX_TEXTURE_TARGET_MESA:
|
|
||||||
if (pDrawable->type != DRAWABLE_WINDOW)
|
|
||||||
{
|
|
||||||
glitz_point_fixed_t point = { 1 << 16 , 1 << 16 };
|
|
||||||
xglGLContextPtr pContext = cctx;
|
|
||||||
|
|
||||||
XGL_DRAWABLE_PIXMAP (pDrawable);
|
|
||||||
|
|
||||||
if (xglCreatePixmapSurface (pPixmap))
|
|
||||||
{
|
|
||||||
XGL_PIXMAP_PRIV (pPixmap);
|
|
||||||
|
|
||||||
/* FIXME: doesn't work for 1x1 textures */
|
|
||||||
glitz_surface_translate_point (pPixmapPriv->surface,
|
|
||||||
&point, &point);
|
|
||||||
if (point.x > (1 << 16) || point.y > (1 << 16))
|
|
||||||
*value = GLX_TEXTURE_RECTANGLE_MESA;
|
|
||||||
else
|
|
||||||
*value = GLX_TEXTURE_2D_MESA;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
*value = GLX_NO_TEXTURE_MESA;
|
|
||||||
|
|
||||||
if (pContext != cctx)
|
|
||||||
xglSetCurrentContext (pContext);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
*value = GLX_NO_TEXTURE_MESA;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
*value = 0;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
__glProcTableEXT __glNoOpRenderTableEXT = {
|
__glProcTableEXT __glNoOpRenderTableEXT = {
|
||||||
xglNoOpActiveTextureARB,
|
xglNoOpActiveTextureARB,
|
||||||
xglNoOpClientActiveTextureARB,
|
xglNoOpClientActiveTextureARB,
|
||||||
|
@ -3561,10 +3437,7 @@ __glProcTableEXT __glNoOpRenderTableEXT = {
|
||||||
xglNoOpSecondaryColorPointerEXT,
|
xglNoOpSecondaryColorPointerEXT,
|
||||||
xglNoOpPointParameteriNV,
|
xglNoOpPointParameteriNV,
|
||||||
xglNoOpPointParameterivNV,
|
xglNoOpPointParameterivNV,
|
||||||
xglNoOpActiveStencilFaceEXT,
|
xglNoOpActiveStencilFaceEXT
|
||||||
xglXBindTexImageMESA,
|
|
||||||
xglXReleaseTexImageMESA,
|
|
||||||
xglXQueryDrawableMESA
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -4490,6 +4363,125 @@ xglResizeBuffers (__GLdrawableBuffer *buffer,
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
xglBindBuffers (__GLXdrawablePrivate *glxPriv,
|
||||||
|
int buffer)
|
||||||
|
{
|
||||||
|
__GLdrawablePrivate *glPriv = &glxPriv->glPriv;
|
||||||
|
xglGLBufferPtr pBufferPriv = glPriv->private;
|
||||||
|
|
||||||
|
if (cctx)
|
||||||
|
{
|
||||||
|
xglTexUnitPtr pTexUnit = &cctx->attrib.texUnits[cctx->activeTexUnit];
|
||||||
|
xglTexObjPtr pTexObj = NULL;
|
||||||
|
DrawablePtr pDrawable;
|
||||||
|
|
||||||
|
/* XXX: front left buffer is only supported so far */
|
||||||
|
if (buffer != GLX_FRONT_LEFT_EXT)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Must be a GLXpixmap */
|
||||||
|
if (!glxPriv->pGlxPixmap)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
pDrawable = glxPriv->pGlxPixmap->pDraw;
|
||||||
|
|
||||||
|
switch (glxPriv->texTarget) {
|
||||||
|
case GLX_TEXTURE_RECTANGLE_EXT:
|
||||||
|
pTexObj = pTexUnit->pRect;
|
||||||
|
break;
|
||||||
|
case GLX_TEXTURE_2D_EXT:
|
||||||
|
pTexObj = pTexUnit->p2D;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pTexObj)
|
||||||
|
{
|
||||||
|
XGL_DRAWABLE_PIXMAP (pDrawable);
|
||||||
|
|
||||||
|
pPixmap->refcnt++;
|
||||||
|
|
||||||
|
if (pTexObj->pPixmap)
|
||||||
|
(*pDrawable->pScreen->DestroyPixmap) (pTexObj->pPixmap);
|
||||||
|
|
||||||
|
pTexObj->pPixmap = pPixmap;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pBufferPriv->private)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
glPriv->private = pBufferPriv->private;
|
||||||
|
status = (*pBufferPriv->bindBuffers) (glxPriv, buffer);
|
||||||
|
glPriv->private = pBufferPriv;
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
xglReleaseBuffers (__GLXdrawablePrivate *glxPriv,
|
||||||
|
int buffer)
|
||||||
|
{
|
||||||
|
__GLdrawablePrivate *glPriv = &glxPriv->glPriv;
|
||||||
|
xglGLBufferPtr pBufferPriv = glPriv->private;
|
||||||
|
|
||||||
|
if (cctx)
|
||||||
|
{
|
||||||
|
xglTexObjPtr pTexObj;
|
||||||
|
|
||||||
|
/* XXX: front left buffer is only supported so far */
|
||||||
|
if (buffer != GLX_FRONT_LEFT_EXT)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Must be a GLXpixmap */
|
||||||
|
if (glxPriv->pGlxPixmap)
|
||||||
|
{
|
||||||
|
DrawablePtr pDrawable = glxPriv->pGlxPixmap->pDraw;
|
||||||
|
|
||||||
|
XGL_DRAWABLE_PIXMAP (pDrawable);
|
||||||
|
|
||||||
|
pTexObj = cctx->attrib.texUnits[cctx->activeTexUnit].p2D;
|
||||||
|
if (pTexObj && pTexObj->pPixmap == pPixmap)
|
||||||
|
{
|
||||||
|
(*pDrawable->pScreen->DestroyPixmap) (pTexObj->pPixmap);
|
||||||
|
pTexObj->pPixmap = NULL;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pTexObj = cctx->attrib.texUnits[cctx->activeTexUnit].pRect;
|
||||||
|
if (pTexObj && pTexObj->pPixmap == pPixmap)
|
||||||
|
{
|
||||||
|
(*pDrawable->pScreen->DestroyPixmap) (pTexObj->pPixmap);
|
||||||
|
pTexObj->pPixmap = NULL;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pBufferPriv->private)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
glPriv->private = pBufferPriv->private;
|
||||||
|
status = (*pBufferPriv->releaseBuffers) (glxPriv, buffer);
|
||||||
|
glPriv->private = pBufferPriv;
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xglFreeBuffers (__GLdrawablePrivate *glPriv)
|
xglFreeBuffers (__GLdrawablePrivate *glPriv)
|
||||||
{
|
{
|
||||||
|
@ -4529,7 +4521,11 @@ xglCreateBuffer (__GLXdrawablePrivate *glxPriv)
|
||||||
pBufferPriv->pGC = NULL;
|
pBufferPriv->pGC = NULL;
|
||||||
pBufferPriv->backSurface = NULL;
|
pBufferPriv->backSurface = NULL;
|
||||||
|
|
||||||
pBufferPriv->swapBuffers = NULL;
|
pBufferPriv->swapBuffers = NULL;
|
||||||
|
|
||||||
|
pBufferPriv->bindBuffers = NULL;
|
||||||
|
pBufferPriv->releaseBuffers = NULL;
|
||||||
|
|
||||||
pBufferPriv->resizeBuffers = NULL;
|
pBufferPriv->resizeBuffers = NULL;
|
||||||
pBufferPriv->private = NULL;
|
pBufferPriv->private = NULL;
|
||||||
pBufferPriv->freeBuffers = NULL;
|
pBufferPriv->freeBuffers = NULL;
|
||||||
|
@ -4554,17 +4550,17 @@ xglCreateBuffer (__GLXdrawablePrivate *glxPriv)
|
||||||
glitz_surface_reference (pScreenPriv->backSurface);
|
glitz_surface_reference (pScreenPriv->backSurface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (0) /*pScreenPriv->features &
|
else if (0) /* pScreenPriv->features &
|
||||||
GLITZ_FEATURE_FRAMEBUFFER_OBJECT_MASK) */
|
GLITZ_FEATURE_FRAMEBUFFER_OBJECT_MASK) */
|
||||||
{
|
{
|
||||||
pBufferPriv->pDrawable = pDrawable;
|
pBufferPriv->pDrawable = pDrawable;
|
||||||
|
|
||||||
if (glxPriv->pGlxVisual->doubleBuffer)
|
if (glxPriv->pGlxVisual->doubleBuffer)
|
||||||
{
|
{
|
||||||
int depth = pDrawable->depth;
|
int depth = pDrawable->depth;
|
||||||
|
|
||||||
pBufferPriv->backSurface =
|
pBufferPriv->backSurface =
|
||||||
glitz_surface_create (pScreenPriv->drawable,
|
glitz_surface_create (pScreenPriv->drawable,
|
||||||
pScreenPriv->pixmapFormats[depth].format,
|
pScreenPriv->pixmapFormats[depth].format,
|
||||||
pDrawable->width, pDrawable->height,
|
pDrawable->width, pDrawable->height,
|
||||||
0, NULL);
|
0, NULL);
|
||||||
|
@ -4576,20 +4572,64 @@ xglCreateBuffer (__GLXdrawablePrivate *glxPriv)
|
||||||
{
|
{
|
||||||
(*screenInfoPriv.createBuffer) (glxPriv);
|
(*screenInfoPriv.createBuffer) (glxPriv);
|
||||||
|
|
||||||
/* wrap the swap buffers routine */
|
/* Wrap the swap buffers routine */
|
||||||
pBufferPriv->swapBuffers = glxPriv->swapBuffers;
|
pBufferPriv->swapBuffers = glxPriv->swapBuffers;
|
||||||
|
|
||||||
/* wrap the front buffer's resize routine and freePrivate */
|
/* Wrap the render texture routines */
|
||||||
|
pBufferPriv->bindBuffers = glxPriv->bindBuffers;
|
||||||
|
pBufferPriv->releaseBuffers = glxPriv->releaseBuffers;
|
||||||
|
|
||||||
|
/* Wrap the front buffer's resize routine */
|
||||||
pBufferPriv->resizeBuffers = glPriv->frontBuffer.resize;
|
pBufferPriv->resizeBuffers = glPriv->frontBuffer.resize;
|
||||||
pBufferPriv->freeBuffers = glPriv->freePrivate;
|
|
||||||
pBufferPriv->private = glPriv->private;
|
/* Save Xgl's private buffer structure */
|
||||||
|
pBufferPriv->freeBuffers = glPriv->freePrivate;
|
||||||
|
pBufferPriv->private = glPriv->private;
|
||||||
|
}
|
||||||
|
|
||||||
|
glxPriv->texTarget = GLX_NO_TEXTURE_EXT;
|
||||||
|
|
||||||
|
/* We enable render texture for all GLXPixmaps right now. Eventually, this
|
||||||
|
should only be enabled when fbconfig attribute GLX_RENDER_TEXTURE_RGB or
|
||||||
|
GLX_RENDER_TEXTURE_RGBA is set to TRUE. */
|
||||||
|
if (pDrawable->type != DRAWABLE_WINDOW)
|
||||||
|
{
|
||||||
|
/* GL_ARB_texture_rectangle is required for sane texture coordinates.
|
||||||
|
GL_ARB_texture_border_clamp is required right now as glitz will
|
||||||
|
emulate it when missing, which means a 1 pixel translucent black
|
||||||
|
border inside textures, that cannot be exposed to clients. */
|
||||||
|
if (pScreenPriv->features &
|
||||||
|
(GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK |
|
||||||
|
GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK))
|
||||||
|
{
|
||||||
|
glitz_point_fixed_t point = { 1 << 16 , 1 << 16 };
|
||||||
|
|
||||||
|
XGL_DRAWABLE_PIXMAP (pDrawable);
|
||||||
|
|
||||||
|
if (xglCreatePixmapSurface (pPixmap))
|
||||||
|
{
|
||||||
|
XGL_PIXMAP_PRIV (pPixmap);
|
||||||
|
|
||||||
|
/* FIXME: doesn't work for 1x1 textures */
|
||||||
|
glitz_surface_translate_point (pPixmapPriv->surface,
|
||||||
|
&point, &point);
|
||||||
|
if (point.x > (1 << 16) || point.y > (1 << 16))
|
||||||
|
glxPriv->texTarget = GLX_TEXTURE_RECTANGLE_EXT;
|
||||||
|
else
|
||||||
|
glxPriv->texTarget = GLX_TEXTURE_2D_EXT;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glxPriv->swapBuffers = xglSwapBuffers;
|
glxPriv->swapBuffers = xglSwapBuffers;
|
||||||
|
|
||||||
|
glxPriv->bindBuffers = xglBindBuffers;
|
||||||
|
glxPriv->releaseBuffers = xglReleaseBuffers;
|
||||||
|
|
||||||
glPriv->frontBuffer.resize = xglResizeBuffers;
|
glPriv->frontBuffer.resize = xglResizeBuffers;
|
||||||
glPriv->private = (void *) pBufferPriv;
|
|
||||||
glPriv->freePrivate = xglFreeBuffers;
|
glPriv->private = (void *) pBufferPriv;
|
||||||
|
glPriv->freePrivate = xglFreeBuffers;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
|
|
Loading…
Reference in New Issue