diff options
author | David Reveman <c99drn@cs.umu.se> | 2005-06-10 12:30:39 +0000 |
---|---|---|
committer | David Reveman <c99drn@cs.umu.se> | 2005-06-10 12:30:39 +0000 |
commit | 521916d0074901db58ab6b9edab52373da28bdb3 (patch) | |
tree | 763641f3e70165cf80acb3d3ff789290bcca3e30 /hw/xgl | |
parent | bdb3eb86f02e233b6aeef0995ea9afeaa7b035ac (diff) |
New implementation of GLX_MESA_render_texture
Diffstat (limited to 'hw/xgl')
-rw-r--r-- | hw/xgl/xglglx.c | 356 |
1 files changed, 198 insertions, 158 deletions
diff --git a/hw/xgl/xglglx.c b/hw/xgl/xglglx.c index 09900e7ea..20e2cb098 100644 --- a/hw/xgl/xglglx.c +++ b/hw/xgl/xglglx.c @@ -78,6 +78,10 @@ typedef __GLinterface *(*GLXCreateContextProc) (__GLimports *imports, __GLinterface *shareGC); typedef void (*GLXCreateBufferProc) (__GLXdrawablePrivate *glxPriv); typedef GLboolean (*GLXSwapBuffersProc) (__GLXdrawablePrivate *glxPriv); +typedef int (*GLXBindBuffersProc) (__GLXdrawablePrivate *glxPriv, + int buffer); +typedef int (*GLXReleaseBuffersProc) (__GLXdrawablePrivate *glxPriv, + int buffer); typedef struct _xglGLXScreenInfo { GLXScreenProbeProc screenProbe; @@ -97,18 +101,20 @@ typedef GLboolean (*GLResizeBuffersProc) (__GLdrawableBuffer *buffer, typedef void (*GLFreeBuffersProc) (__GLdrawablePrivate *glPriv); typedef struct _xglGLBuffer { - GLXSwapBuffersProc swapBuffers; - GLResizeBuffersProc resizeBuffers; - GLFreeBuffersProc freeBuffers; - ScreenPtr pScreen; - DrawablePtr pDrawable; - glitz_surface_t *backSurface; - PixmapPtr pPixmap; - GCPtr pGC; - RegionRec damage; - void *private; - int xOff, yOff; - int yFlip; + GLXSwapBuffersProc swapBuffers; + GLXBindBuffersProc bindBuffers; + GLXReleaseBuffersProc releaseBuffers; + GLResizeBuffersProc resizeBuffers; + GLFreeBuffersProc freeBuffers; + ScreenPtr pScreen; + DrawablePtr pDrawable; + glitz_surface_t *backSurface; + PixmapPtr pPixmap; + GCPtr pGC; + RegionRec damage; + void *private; + int xOff, yOff; + int yFlip; } xglGLBufferRec, *xglGLBufferPtr; typedef int xglGLXVisualConfigRec, *xglGLXVisualConfigPtr; @@ -3388,136 +3394,6 @@ xglNoOpPointParameterivNV (GLenum pname, const GLint *params) {} static void 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 = { xglNoOpActiveTextureARB, xglNoOpClientActiveTextureARB, @@ -3561,10 +3437,7 @@ __glProcTableEXT __glNoOpRenderTableEXT = { xglNoOpSecondaryColorPointerEXT, xglNoOpPointParameteriNV, xglNoOpPointParameterivNV, - xglNoOpActiveStencilFaceEXT, - xglXBindTexImageMESA, - xglXReleaseTexImageMESA, - xglXQueryDrawableMESA + xglNoOpActiveStencilFaceEXT }; static void @@ -4490,6 +4363,125 @@ xglResizeBuffers (__GLdrawableBuffer *buffer, 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 xglFreeBuffers (__GLdrawablePrivate *glPriv) { @@ -4529,7 +4521,11 @@ xglCreateBuffer (__GLXdrawablePrivate *glxPriv) pBufferPriv->pGC = NULL; pBufferPriv->backSurface = NULL; - pBufferPriv->swapBuffers = NULL; + pBufferPriv->swapBuffers = NULL; + + pBufferPriv->bindBuffers = NULL; + pBufferPriv->releaseBuffers = NULL; + pBufferPriv->resizeBuffers = NULL; pBufferPriv->private = NULL; pBufferPriv->freeBuffers = NULL; @@ -4554,17 +4550,17 @@ xglCreateBuffer (__GLXdrawablePrivate *glxPriv) glitz_surface_reference (pScreenPriv->backSurface); } } - else if (0) /*pScreenPriv->features & - GLITZ_FEATURE_FRAMEBUFFER_OBJECT_MASK) */ + else if (0) /* pScreenPriv->features & + GLITZ_FEATURE_FRAMEBUFFER_OBJECT_MASK) */ { pBufferPriv->pDrawable = pDrawable; if (glxPriv->pGlxVisual->doubleBuffer) { int depth = pDrawable->depth; - + pBufferPriv->backSurface = - glitz_surface_create (pScreenPriv->drawable, + glitz_surface_create (pScreenPriv->drawable, pScreenPriv->pixmapFormats[depth].format, pDrawable->width, pDrawable->height, 0, NULL); @@ -4576,20 +4572,64 @@ xglCreateBuffer (__GLXdrawablePrivate *glxPriv) { (*screenInfoPriv.createBuffer) (glxPriv); - /* wrap the swap buffers routine */ + /* Wrap the swap buffers routine */ 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->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->bindBuffers = xglBindBuffers; + glxPriv->releaseBuffers = xglReleaseBuffers; glPriv->frontBuffer.resize = xglResizeBuffers; - glPriv->private = (void *) pBufferPriv; - glPriv->freePrivate = xglFreeBuffers; + + glPriv->private = (void *) pBufferPriv; + glPriv->freePrivate = xglFreeBuffers; } static Bool |