/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c,v 1.14 2002/10/30 12:51:30 alanh Exp $ */
/*
 * Copyright 2001 by Alan Hourihane.
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Alan Hourihane not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Alan Hourihane makes no representations
 * about the suitability of this software for any purpose.  It is provided
 * "as is" without express or implied warranty.
 *
 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 *
 * Authors:  Alan Hourihane, <alanh@tungstengraphics.com>
 *
 * 3DLabs Gamma driver
 */

#include "gamma_context.h"
#include "gamma_vb.h"
#include "context.h"
#include "matrix.h"
#include "glint_dri.h"

#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
#include "vbo/vbo.h"

static GLboolean 
gammaInitDriver(__DRIscreenPrivate *sPriv)
{
    sPriv->private = (void *) gammaCreateScreen( sPriv );

    if (!sPriv->private) {
	gammaDestroyScreen( sPriv );
	return GL_FALSE;
    }

    return GL_TRUE;
}

static void 
gammaDestroyContext(__DRIcontextPrivate *driContextPriv)
{
    gammaContextPtr gmesa = (gammaContextPtr)driContextPriv->driverPrivate;

    if (gmesa) {
      _swsetup_DestroyContext( gmesa->glCtx );
      _tnl_DestroyContext( gmesa->glCtx );
      _vbo_DestroyContext( gmesa->glCtx );
      _swrast_DestroyContext( gmesa->glCtx );

      gammaFreeVB( gmesa->glCtx );

      /* free the Mesa context */
      gmesa->glCtx->DriverCtx = NULL;
      _mesa_destroy_context(gmesa->glCtx);

      FREE(gmesa);
      driContextPriv->driverPrivate = NULL;
    }
}


static GLboolean
gammaCreateBuffer( __DRIscreenPrivate *driScrnPriv,
                   __DRIdrawablePrivate *driDrawPriv,
                   const __GLcontextModes *mesaVis,
                   GLboolean isPixmap )
{
   if (isPixmap) {
      return GL_FALSE; /* not implemented */
   }
   else {
      driDrawPriv->driverPrivate = (void *) 
         _mesa_create_framebuffer(mesaVis,
                                  GL_FALSE,  /* software depth buffer? */
                                  mesaVis->stencilBits > 0,
                                  mesaVis->accumRedBits > 0,
                                  mesaVis->alphaBits > 0
                                  );
      return (driDrawPriv->driverPrivate != NULL);
   }
}


static void
gammaDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
{
   _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)));
}

static void
gammaSwapBuffers( __DRIdrawablePrivate *dPriv )
{
   if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
    gammaContextPtr gmesa;
    __DRIscreenPrivate *driScrnPriv;
    GLcontext *ctx;

    gmesa = (gammaContextPtr) dPriv->driContextPriv->driverPrivate;
    ctx = gmesa->glCtx;
    driScrnPriv = gmesa->driScreen;

    _mesa_notifySwapBuffers(ctx);

    VALIDATE_DRAWABLE_INFO(gmesa);

    /* Flush any partially filled buffers */
    FLUSH_DMA_BUFFER(gmesa);

    DRM_SPINLOCK(&driScrnPriv->pSAREA->drawable_lock,
		     driScrnPriv->drawLockID);
    VALIDATE_DRAWABLE_INFO_NO_LOCK(gmesa);

    if (gmesa->EnabledFlags & GAMMA_BACK_BUFFER) {
	int src, dst, x0, y0, x1, h;
	int i;
	int nRect = dPriv->numClipRects;
	drm_clip_rect_t *pRect = dPriv->pClipRects;
	__DRIscreenPrivate *driScrnPriv = gmesa->driScreen;
   	GLINTDRIPtr gDRIPriv = (GLINTDRIPtr)driScrnPriv->pDevPriv;

	CHECK_DMA_BUFFER(gmesa, 2);
	WRITE(gmesa->buf, FBReadMode, (gmesa->FBReadMode |
					 FBReadSrcEnable));
	WRITE(gmesa->buf, LBWriteMode, LBWriteModeDisable);

	for (i = 0; i < nRect; i++, pRect++) {
	    x0 = pRect->x1;
	    x1 = pRect->x2;
	    h  = pRect->y2 - pRect->y1;

	    y0 = driScrnPriv->fbHeight - (pRect->y1+h);
	    if (gDRIPriv->numMultiDevices == 2) 
	    	src = (y0/2)*driScrnPriv->fbWidth+x0;
	    else
	    	src = y0*driScrnPriv->fbWidth+x0;

	    y0 += driScrnPriv->fbHeight;
	    if (gDRIPriv->numMultiDevices == 2) 
	    	dst = (y0/2)*driScrnPriv->fbWidth+x0;
	    else
	    	dst = y0*driScrnPriv->fbWidth+x0;

	    CHECK_DMA_BUFFER(gmesa, 9);
	    WRITE(gmesa->buf, StartXDom,       x0<<16);   /* X0dest */
	    WRITE(gmesa->buf, StartY,          y0<<16);   /* Y0dest */
	    WRITE(gmesa->buf, StartXSub,       x1<<16);   /* X1dest */
	    WRITE(gmesa->buf, GLINTCount,      h);        /* H */
	    WRITE(gmesa->buf, dY,              1<<16);    /* ydir */
	    WRITE(gmesa->buf, dXDom,           0<<16);
	    WRITE(gmesa->buf, dXSub,           0<<16);
	    WRITE(gmesa->buf, FBSourceOffset, (dst-src));
	    WRITE(gmesa->buf, Render,          0x00040048); /* NOT_DONE */
	}

	/*
	** NOTE: FBSourceOffset (above) is backwards from what is
	** described in the manual (i.e., dst-src instead of src-dst)
	** due to our using the bottom-left window origin instead of the
	** top-left window origin.
	*/

	/* Restore FBReadMode */
	CHECK_DMA_BUFFER(gmesa, 2);
	WRITE(gmesa->buf, FBReadMode, (gmesa->FBReadMode |
				       gmesa->AB_FBReadMode));
	WRITE(gmesa->buf, LBWriteMode, LBWriteModeEnable);
    }

    if (gmesa->EnabledFlags & GAMMA_BACK_BUFFER)
        PROCESS_DMA_BUFFER_TOP_HALF(gmesa);

    DRM_SPINUNLOCK(&driScrnPriv->pSAREA->drawable_lock,
		       driScrnPriv->drawLockID);
    VALIDATE_DRAWABLE_INFO_NO_LOCK_POST(gmesa);

    if (gmesa->EnabledFlags & GAMMA_BACK_BUFFER)
        PROCESS_DMA_BUFFER_BOTTOM_HALF(gmesa);
  } else {
    _mesa_problem(NULL, "gammaSwapBuffers: drawable has no context!\n");
  }
}

static GLboolean 
gammaMakeCurrent(__DRIcontextPrivate *driContextPriv,
		 __DRIdrawablePrivate *driDrawPriv,
		 __DRIdrawablePrivate *driReadPriv)
{
    if (driContextPriv) {
	GET_CURRENT_CONTEXT(ctx);
	gammaContextPtr oldGammaCtx = ctx ? GAMMA_CONTEXT(ctx) : NULL;
	gammaContextPtr newGammaCtx = (gammaContextPtr) driContextPriv->driverPrivate;

	if ( newGammaCtx != oldGammaCtx ) {
	    newGammaCtx->dirty = ~0;
	}

	if (newGammaCtx->driDrawable != driDrawPriv) {
	    newGammaCtx->driDrawable = driDrawPriv;
	    gammaUpdateWindow ( newGammaCtx->glCtx );
	    gammaUpdateViewportOffset( newGammaCtx->glCtx );
	}

#if 0
	newGammaCtx->Window &= ~W_GIDMask;
	newGammaCtx->Window |= (driDrawPriv->index << 5);
	CHECK_DMA_BUFFER(newGammaCtx,1);
	WRITE(newGammaCtx->buf, GLINTWindow, newGammaCtx->Window);
#endif

newGammaCtx->new_state |= GAMMA_NEW_WINDOW; /* FIXME */

	_mesa_make_current2( newGammaCtx->glCtx, 
			  (GLframebuffer *) driDrawPriv->driverPrivate,
			  (GLframebuffer *) driReadPriv->driverPrivate );
    } else {
	_mesa_make_current( 0, 0 );
    }
    return GL_TRUE;
}


static GLboolean 
gammaUnbindContext( __DRIcontextPrivate *driContextPriv )
{
   return GL_TRUE;
}

const struct __DriverAPIRec driDriverAPI = {
   gammaInitDriver,
   gammaDestroyScreen,
   gammaCreateContext,
   gammaDestroyContext,
   gammaCreateBuffer,
   gammaDestroyBuffer,
   gammaSwapBuffers,
   gammaMakeCurrent,
   gammaUnbindContext
};



/*
 * This is the bootstrap function for the driver.
 * The __driCreateScreen name is the symbol that libGL.so fetches.
 * Return:  pointer to a __DRIscreenPrivate.
 */
void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
                        int numConfigs, __GLXvisualConfig *config)
{
   __DRIscreenPrivate *psp;
   psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &gammaAPI);
   return (void *) psp;
}
