/*
 * Copyright 2002 by Alan Hourihane, Sychdyn, North Wales, UK.
 *
 * 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@fairlite.demon.co.uk>
 *
 * Trident CyberBladeXP driver.
 *
 */
#ifndef _TRIDENT_CONTEXT_H_
#define _TRIDENT_CONTEXT_H_

#include "dri_util.h"
#include "main/macros.h"
#include "main/mtypes.h"
#include "drm.h"
#include "main/mm.h"

#define SUBPIXEL_X (0.0F)
#define SUBPIXEL_Y (0.125F)

#define _TRIDENT_NEW_VERTEX (_NEW_TEXTURE |		\
			   _DD_NEW_TRI_UNFILLED |	\
			   _DD_NEW_TRI_LIGHT_TWOSIDE)

#define TRIDENT_FALLBACK_TEXTURE	0x01
#define TRIDENT_FALLBACK_DRAW_BUFFER	0x02

#define TRIDENT_NEW_CLIP		0x01

#define TRIDENT_UPLOAD_COMMAND_D	0x00000001
#define TRIDENT_UPLOAD_CONTEXT		0x04000000
#define TRIDENT_UPLOAD_CLIPRECTS	0x80000000

#define TAG(x) trident##x
#include "tnl_dd/t_dd_vertex.h"
#undef TAG

/* these require that base be dword-aligned */
static INLINE void MMIO_OUT32(unsigned char *base, unsigned int offset,
                              unsigned int val)
{
    unsigned int *addr = (unsigned int *)(base + offset);
    *addr = val;
}

static INLINE unsigned int MMIO_IN32(unsigned char *base, unsigned int offset)
{
    unsigned int *addr = (unsigned int *)(base + offset);
    return *addr;
}

#define MMIO_OUT8(base, offset, val) *((base) + (offset)) = (val)
#define MMIO_IN8(base, offset) *((base) + (offset))

struct trident_context;
typedef struct trident_context tridentContextRec;
typedef struct trident_context *tridentContextPtr;

typedef void (*trident_quad_func)( tridentContextPtr, 
				 const tridentVertex *, 
				 const tridentVertex *,
				 const tridentVertex *,
				 const tridentVertex * );
typedef void (*trident_tri_func)( tridentContextPtr, 
				const tridentVertex *, 
				const tridentVertex *,
				const tridentVertex * );
typedef void (*trident_line_func)( tridentContextPtr, 
				 const tridentVertex *, 
				 const tridentVertex * );
typedef void (*trident_point_func)( tridentContextPtr, 
				  const tridentVertex * );

typedef struct {
   drm_handle_t handle;			/* Handle to the DRM region */
   drmSize size;			/* Size of the DRM region */
   unsigned char *map;			/* Mapping of the DRM region */
} tridentRegionRec, *tridentRegionPtr;

typedef struct {
    __DRIscreenPrivate *driScreen; /* Back pointer to DRI screen */

    drmBufMapPtr buffers;

    unsigned int frontOffset;
    unsigned int frontPitch;
    unsigned int backOffset;
    unsigned int backPitch;
    unsigned int depthOffset;
    unsigned int depthPitch;
    unsigned int width;
    unsigned int height;
    unsigned int cpp;

#if 0
    unsigned int sarea_priv_offset;
#endif

    tridentRegionRec mmio;
} tridentScreenRec, *tridentScreenPtr;

/**
 * tridentRenderbuffer, derived from Mesa's gl_renderbuffer
 */
typedef struct {
   struct gl_renderbuffer Base;
   /* XXX per-window info should go here */
   int foo, bar;
} tridentRenderbuffer;


struct trident_context {
	GLcontext 		*glCtx;		/* Mesa context */

	__DRIcontextPrivate	*driContext;
	__DRIscreenPrivate	*driScreen;
	__DRIdrawablePrivate	*driDrawable;

	GLuint 			new_gl_state;
	GLuint 			new_state;
	GLuint 			dirty;

#if 0
  	drm_trident_sarea_t	*sarea; 
#endif

        /* Temporaries for translating away float colors:
	 */
        struct gl_client_array UbyteColor;
        struct gl_client_array UbyteSecondaryColor;

   	/* Mirrors of some DRI state
    	 */
	int lastStamp;		        /* mirror driDrawable->lastStamp */

   	drm_context_t hHWContext;
   	drmLock *driHwLock;
   	int driFd;

   	tridentScreenPtr tridentScreen;	/* Screen private DRI data */

  	/* Visual, drawable, cliprect and scissor information
    	 */
   	GLenum DrawBuffer;
   	GLint drawOffset, drawPitch;
   	GLint drawX, drawY;             /* origin of drawable in draw buffer */
   	GLint readOffset, readPitch;

   	GLuint numClipRects;		/* Cliprects for the draw buffer */
   	drm_clip_rect_t *pClipRects;

   	GLint scissor;
   	drm_clip_rect_t ScissorRect;	/* Current software scissor */

   	GLuint Fallback;
	GLuint RenderIndex;
	GLuint SetupNewInputs;
	GLuint SetupIndex;
	GLfloat hw_viewport[16];
	GLfloat	depth_scale;
	GLuint vertex_format;
	GLuint vertex_size;
	GLuint vertex_stride_shift;
	GLubyte *verts;

	GLint tmu_source[2];

	GLuint hw_primitive;
	GLenum render_primitive;

   	trident_point_func    draw_point;
   	trident_line_func     draw_line;
   	trident_tri_func      draw_tri;
   	trident_quad_func     draw_quad;

#if 0
   	gammaTextureObjectPtr CurrentTexObj[2];
   	struct gamma_texture_object_t TexObjList;
   	struct gamma_texture_object_t SwappedOut; 
	GLenum TexEnvImageFmt[2];

	struct mem_block *texHeap;

   	int lastSwap;
   	int texAge;
   	int ctxAge;
   	int dirtyAge;
        int lastStamp;
#endif

	/* Chip state */
	
	int	commandD;

	/* Context State */
	
	int	ClearColor;
};

void tridentDDInitExtensions( GLcontext *ctx );
void tridentDDInitDriverFuncs( GLcontext *ctx );
void tridentDDInitSpanFuncs( GLcontext *ctx );
void tridentDDInitState( tridentContextPtr tmesa );
void tridentInitHW( tridentContextPtr tmesa );
void tridentDDInitStateFuncs( GLcontext *ctx );
void tridentDDInitTextureFuncs( GLcontext *ctx );
void tridentDDInitTriFuncs( GLcontext *ctx );

extern void tridentBuildVertices( GLcontext *ctx, 
				GLuint start, 
				GLuint count,
				GLuint newinputs );
extern void tridentInitVB( GLcontext *ctx );
extern void tridentCopyBuffer( const __DRIdrawablePrivate *dPriv );
extern void tridentFallback( tridentContextPtr tmesa, GLuint bit,
                             GLboolean mode );
extern void tridentCheckTexSizes( GLcontext *ctx );
extern void tridentChooseVertexState( GLcontext *ctx );
extern void tridentDDUpdateHWState( GLcontext *ctx );
extern void tridentUploadHwStateLocked( tridentContextPtr tmesa );

#define TRIDENT_CONTEXT(ctx)		((tridentContextPtr)(ctx->DriverCtx))

#endif /* _TRIDENT_CONTEXT_H_ */
