Initial revision

This commit is contained in:
Stephane Marchesin 2006-02-23 12:55:56 +00:00
commit 0abf3937ce
22 changed files with 2343 additions and 0 deletions

View file

@ -0,0 +1,30 @@
# src/mesa/drivers/dri/nouveau/Makefile
TOP = ../../../../..
include $(TOP)/configs/current
LIBNAME = nouveau_dri.so
MINIGLX_SOURCES =
DRIVER_SOURCES = \
nouveau_context.c \
nouveau_driver.c \
nouveau_fifo.c \
nouveau_ioctl.c \
nouveau_lock.c \
nouveau_span.c \
nouveau_tex.c \
nouveau_tris.c \
nv40_tris.c
C_SOURCES = \
$(COMMON_SOURCES) \
$(DRIVER_SOURCES)
ASM_SOURCES =
include ../Makefile.template
symlinks:

View file

@ -0,0 +1,209 @@
/**************************************************************************
Copyright 2006 Stephane Marchesin
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
on the rights to use, copy, modify, merge, publish, distribute, sub
license, and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
#include "glheader.h"
#include "context.h"
#include "simple_list.h"
#include "imports.h"
#include "matrix.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "array_cache/acache.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
#include "drivers/common/driverfuncs.h"
#include "nouveau_context.h"
#include "nouveau_ioctl.h"
#include "nouveau_driver.h"
//#include "nouveau_state.h"
#include "nouveau_span.h"
#include "nouveau_tex.h"
#include "nv40_tris.h"
#include "vblank.h"
#include "utils.h"
#include "texmem.h"
#include "xmlpool.h" /* for symbolic values of enum-type options */
#ifndef NOUVEAU_DEBUG
int NOUVEAU_DEBUG = 0;
#endif
static const struct dri_debug_control debug_control[] =
{
{ NULL, 0 }
};
/* Create the device specific context.
*/
GLboolean nouveauCreateContext( const __GLcontextModes *glVisual,
__DRIcontextPrivate *driContextPriv,
void *sharedContextPrivate )
{
GLcontext *ctx, *shareCtx;
__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
struct dd_function_table functions;
nouveauContextPtr nmesa;
nouveauScreenPtr screen;
int i;
/* Allocate the context */
nmesa = (nouveauContextPtr) CALLOC( sizeof(*nmesa) );
if ( !nmesa )
return GL_FALSE;
/* Init default driver functions then plug in our Radeon-specific functions
* (the texture functions are especially important)
*/
_mesa_init_driver_functions( &functions );
nouveauDriverInitFunctions( &functions );
nouveauIoctlInitFunctions( &functions );
nouveauTexInitFunctions( &functions );
/* Allocate the Mesa context */
if (sharedContextPrivate)
shareCtx = ((nouveauContextPtr) sharedContextPrivate)->glCtx;
else
shareCtx = NULL;
nmesa->glCtx = _mesa_create_context(glVisual, shareCtx,
&functions, (void *) nmesa);
if (!nmesa->glCtx) {
FREE(nmesa);
return GL_FALSE;
}
driContextPriv->driverPrivate = nmesa;
ctx = nmesa->glCtx;
nmesa->driContext = driContextPriv;
nmesa->driScreen = sPriv;
nmesa->driDrawable = NULL;
nmesa->hHWContext = driContextPriv->hHWContext;
nmesa->driHwLock = &sPriv->pSAREA->lock;
nmesa->driFd = sPriv->fd;
nmesa->screen = (nouveauScreenPtr)(sPriv->private);
screen=nmesa->screen;
/* Parse configuration files */
driParseConfigFiles (&nmesa->optionCache, &screen->optionCache,
screen->driScreen->myNum, "nouveau");
nmesa->sarea = (drm_nouveau_sarea_t *)((char *)sPriv->pSAREA +
screen->sarea_priv_offset);
nmesa->current_primitive = -1;
/* Initialize the swrast */
_swrast_CreateContext( ctx );
_ac_CreateContext( ctx );
_tnl_CreateContext( ctx );
_swsetup_CreateContext( ctx );
switch(nmesa->screen->card_type)
{
case NV_03:
case NV_04:
case NV_05:
case NV_10:
case NV_20:
case NV_30:
default:
break;
case NV_40:
case G_70:
nv40TriInitFunctions( ctx );
break;
}
nouveauDDInitStateFuncs( ctx );
nouveauSpanInitFunctions( ctx );
nouveauDDInitState( nmesa );
driContextPriv->driverPrivate = (void *)nmesa;
NOUVEAU_DEBUG = driParseDebugString( getenv( "NOUVEAU_DEBUG" ),
debug_control );
if (driQueryOptionb(&nmesa->optionCache, "no_rast")) {
fprintf(stderr, "disabling 3D acceleration\n");
FALLBACK(nmesa, NOUVEAU_FALLBACK_DISABLE, 1);
}
return GL_TRUE;
}
/* Destroy the device specific context. */
void nouveauDestroyContext( __DRIcontextPrivate *driContextPriv )
{
nouveauContextPtr nmesa = (nouveauContextPtr) driContextPriv->driverPrivate;
assert(nmesa);
if ( nmesa ) {
/* free the option cache */
driDestroyOptionCache (&nmesa->optionCache);
FREE( nmesa );
}
}
/* Force the context `c' to be the current context and associate with it
* buffer `b'.
*/
GLboolean nouveauMakeCurrent( __DRIcontextPrivate *driContextPriv,
__DRIdrawablePrivate *driDrawPriv,
__DRIdrawablePrivate *driReadPriv )
{
if ( driContextPriv ) {
GET_CURRENT_CONTEXT(ctx);
nouveauContextPtr oldNOUVEAUCtx = ctx ? NOUVEAU_CONTEXT(ctx) : NULL;
nouveauContextPtr newNOUVEAUCtx = (nouveauContextPtr) driContextPriv->driverPrivate;
driDrawableInitVBlank( driDrawPriv, newNOUVEAUCtx->vblank_flags );
newNOUVEAUCtx->driDrawable = driDrawPriv;
_mesa_make_current( newNOUVEAUCtx->glCtx,
(GLframebuffer *) driDrawPriv->driverPrivate,
(GLframebuffer *) driReadPriv->driverPrivate );
} else {
_mesa_make_current( NULL, NULL, NULL );
}
return GL_TRUE;
}
/* Force the context `c' to be unbound from its buffer.
*/
GLboolean nouveauUnbindContext( __DRIcontextPrivate *driContextPriv )
{
return GL_TRUE;
}

View file

@ -0,0 +1,129 @@
/**************************************************************************
Copyright 2006 Stephane Marchesin
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
on the rights to use, copy, modify, merge, publish, distribute, sub
license, and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
#ifndef __NOUVEAU_CONTEXT_H__
#define __NOUVEAU_CONTEXT_H__
#include "dri_util.h"
#include "drm.h"
#include "nouveau_drm.h"
#include "mtypes.h"
#include "tnl/t_vertex.h"
#include "nouveau_reg.h"
#include "nouveau_screen.h"
#include "xmlconfig.h"
typedef struct nouveau_fifo_t{
u_int32_t* buffer;
u_int32_t current;
u_int32_t put;
u_int32_t free;
u_int32_t max;
}
nouveau_fifo;
#define TAG(x) nouveau##x
#include "tnl_dd/t_dd_vertex.h"
#undef TAG
typedef void (*nouveau_tri_func)( struct nouveau_context*,
nouveauVertex *,
nouveauVertex *,
nouveauVertex * );
typedef void (*nouveau_line_func)( struct nouveau_context*,
nouveauVertex *,
nouveauVertex * );
typedef void (*nouveau_point_func)( struct nouveau_context*,
nouveauVertex * );
typedef struct nouveau_context {
/* Mesa context */
GLcontext *glCtx;
/* The per-context fifo */
nouveau_fifo fifo;
/* The fifo control regs */
volatile unsigned char* fifo_mmio;
/* The read-only regs */
volatile unsigned char* mmio;
/* The drawing fallbacks */
nouveau_tri_func* draw_tri;
nouveau_line_func* draw_line;
nouveau_point_func* draw_point;
/* Cliprects information */
GLuint numClipRects;
drm_clip_rect_t *pClipRects;
/* The rendering context information */
GLenum current_primitive; /* the current primitive enum */
GLuint render_inputs; /* the current render inputs */
nouveauScreenRec *screen;
drm_nouveau_sarea_t *sarea;
__DRIcontextPrivate *driContext; /* DRI context */
__DRIscreenPrivate *driScreen; /* DRI screen */
__DRIdrawablePrivate *driDrawable; /* DRI drawable bound to this ctx */
drm_context_t hHWContext;
drm_hw_lock_t *driHwLock;
int driFd;
/* Configuration cache */
driOptionCache optionCache;
}nouveauContextRec, *nouveauContextPtr;
#define NOUVEAU_CONTEXT(ctx) ((nouveauContextPtr)(ctx->DriverCtx))
extern GLboolean nouveauCreateContext( const __GLcontextModes *glVisual,
__DRIcontextPrivate *driContextPriv,
void *sharedContextPrivate );
extern void nouveauDestroyContext( __DRIcontextPrivate * );
extern GLboolean nouveauMakeCurrent( __DRIcontextPrivate *driContextPriv,
__DRIdrawablePrivate *driDrawPriv,
__DRIdrawablePrivate *driReadPriv );
extern GLboolean nouveauUnbindContext( __DRIcontextPrivate *driContextPriv );
#endif /* __NOUVEAU_CONTEXT_H__ */

View file

@ -0,0 +1,145 @@
/**************************************************************************
Copyright 2006 Stephane Marchesin
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
on the rights to use, copy, modify, merge, publish, distribute, sub
license, and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
#include "nouveau_context.h"
#include "nouveau_ioctl.h"
//#include "nouveau_state.h"
#include "nouveau_driver.h"
#include "swrast/swrast.h"
#include "context.h"
#include "framebuffer.h"
#include "utils.h"
/* Return the width and height of the current color buffer */
static void nouveauGetBufferSize( GLframebuffer *buffer,
GLuint *width, GLuint *height )
{
GET_CURRENT_CONTEXT(ctx);
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
LOCK_HARDWARE( nmesa );
*width = nmesa->driDrawable->w;
*height = nmesa->driDrawable->h;
UNLOCK_HARDWARE( nmesa );
}
/* glGetString */
static const GLubyte *nouveauGetString( GLcontext *ctx, GLenum name )
{
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
static char buffer[128];
const char * card_name = "Unknown";
GLuint agp_mode = 0;
switch ( name ) {
case GL_VENDOR:
return (GLubyte *)DRIVER_AUTHOR;
case GL_RENDERER:
switch(nmesa->screen->card_type)
{
case NV_03:
card_name="Riva 128";
break;
case NV_04:
card_name="TNT";
break;
case NV_05:
card_name="TNT2";
break;
case NV_10:
card_name="GeForce 1/2/4Mx";
break;
case NV_20:
card_name="GeForce 3/4Ti";
break;
case NV_30:
card_name="GeForce FX 5x00";
break;
case NV_40:
card_name="GeForce FX 6x00";
break;
case G_70:
card_name="GeForce FX 7x00";
break;
default:
break;
}
switch(nmesa->screen->bus_type)
{
case NV_PCI:
case NV_PCIE:
default:
agp_mode=0;
break;
case NV_AGP:
nmesa->screen->agp_mode;
break;
}
driGetRendererString( buffer, card_name, DRIVER_DATE,
agp_mode );
return (GLubyte *)buffer;
default:
return NULL;
}
}
/* glFlush */
static void nouveauFlush( GLcontext *ctx )
{
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
FIRE_RING( nmesa );
}
/* glFinish */
static void nouveauFinish( GLcontext *ctx )
{
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
nouveauFlush( ctx );
nouveauWaitForIdle( nmesa );
}
/* glClear */
static void nouveauClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
GLint cx, GLint cy, GLint cw, GLint ch )
{
// XXX we really should do something here...
}
void nouveauDriverInitFunctions( struct dd_function_table *functions )
{
functions->GetBufferSize = nouveauGetBufferSize;
functions->ResizeBuffers = _mesa_resize_framebuffer;
functions->GetString = nouveauGetString;
functions->Flush = nouveauFlush;
functions->Finish = nouveauFinish;
functions->Clear = nouveauClear;
}

View file

@ -0,0 +1,39 @@
/**************************************************************************
Copyright 2006 Stephane Marchesin
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
on the rights to use, copy, modify, merge, publish, distribute, sub
license, and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
#ifndef __NOUVEAU_DRIVER_H__
#define __NOUVEAU_DRIVER_H__
#define DRIVER_DATE "20060219"
#define DRIVER_AUTHOR "Stephane Marchesin"
extern void nouveauDriverInitFunctions( struct dd_function_table *functions );
#endif /* __NOUVEAU_DRIVER_H__ */

View file

@ -0,0 +1,96 @@
/**************************************************************************
Copyright 2006 Stephane Marchesin
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
on the rights to use, copy, modify, merge, publish, distribute, sub
license, and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
#include "nouveau_fifo.h"
#include "vblank.h"
#define RING_SKIPS 8
void WAIT_RING(nouveauContextPtr nmesa,u_int32_t size)
{
u_int32_t fifo_get;
while(nmesa->fifo.free < size+1) {
fifo_get = NV_FIFO_READ(NV03_FIFO_REGS_DMAGET);
if(nmesa->fifo.put >= fifo_get) {
nmesa->fifo.free = nmesa->fifo.max - nmesa->fifo.current;
if(nmesa->fifo.free < size+1) {
OUT_RING(NV03_FIFO_CMD_REWIND); \
if(fifo_get <= RING_SKIPS) {
if(nmesa->fifo.put <= RING_SKIPS) /* corner case - will be idle */
NV_FIFO_WRITE(NV03_FIFO_REGS_DMAPUT, RING_SKIPS + 1);
do { fifo_get = NV_FIFO_READ(NV03_FIFO_REGS_DMAGET); }
while(fifo_get <= RING_SKIPS);
}
NV03_FIFO_REGS_DMAPUT(NV03_FIFO_REGS_DMAPUT, RING_SKIPS);
nmesa->fifo.current = nmesa->fifo.put = RING_SKIPS;
nmesa->fifo.free = fifo_get - (RING_SKIPS + 1);
}
} else
nmesa->fifo.free = fifo_get - nmesa->fifo.current - 1;
}
}
/*
* Wait for the card to be idle
* XXX we should also wait for an empty fifo
*/
void nouveauWaitForIdleLocked(nouveauContextPtr *nmesa)
{
int i,status;
for(i=0;i<1000000;i++) /* 1 second */
{
switch(nmesa->screen->card_type)
{
case NV_03:
status=NV_READ(NV03_STATUS);
break;
case NV_04:
case NV_05:
case NV_10:
case NV_20:
case NV_30:
case NV_40:
case G_70:
default:
status=NV_READ(NV04_STATUS);
break;
}
if (status)
return 0;
DO_USLEEP(1);
}
}
void nouveauWaitForIdle(nouveauContextPtr *nmesa)
{
LOCK_HARDWARE(nmesa);
nouveauWaitForIdleLocked(nmesa);
UNLOCK_HARDWARE(nmesa);
}

View file

@ -0,0 +1,96 @@
/**************************************************************************
Copyright 2006 Stephane Marchesin
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
on the rights to use, copy, modify, merge, publish, distribute, sub
license, and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
#ifndef __NOUVEAU_FIFO_H__
#define __NOUVEAU_FIFO_H__
#include "nouveau_context.h"
#define NV_READ(reg) *(volatile u_int32_t *)(nmesa->mmio + (reg))
#define NV_FIFO_READ(reg) *(volatile u_int32_t *)(nmesa->fifo_mmio + (reg))
#define NV_FIFO_WRITE(reg,value) *(volatile u_int32_t *)(nmesa->fifo_mmio + (reg)) = value;
/*
* Ring/fifo interface
*
* - Begin a ring section with BEGIN_RING_SIZE (if you know the full size in advance)
* - Begin a ring section with BEGIN_RING_PRIM otherwise (and then finish with FINISH_RING_PRIM)
* - Output stuff to the ring with either OUT_RINGp (outputs a raw mem chunk), OUT_RING (1 uint32_t) or OUT_RINGf (1 float)
* - RING_AVAILABLE returns the available fifo (in uint32_ts)
* - RING_AHEAD returns how much ahead of the last submission point we are
* - FIRE_RING fire whatever we have that wasn't fired before
* - WAIT_RING waits for size (in uint32_ts) to be available in the fifo
*/
#define OUT_RINGp(ptr,sz) do{ \
memcpy(nmesa->fifo.buffer+nmesa->fifo.current,ptr,sz); \
nmesa->fifo.current+=sz; \
}while(0)
#define OUT_RING(n) do { \
nmesa->fifo.buffer[nmesa->fifo.current++]=n; \
}while(0)
#define OUT_RINGf(n) do { \
*((float*)(nmesa->fifo.buffer+nmesa->fifo.current++))=n; \
}while(0)
extern void WAIT_RING(nouveauContextPtr nmesa,u_int32_t size);
#define BEGIN_RING_PRIM(subchannel,tag,size) do { \
if (nmesa->fifo.free<size) \
WAIT_RING(nmesa,(size)); \
OUT_RING( ((subchannel) << 13) | (tag)); \
}while(0)
#define FINISH_RING_PRIM() do{ \
nmesa->fifo.buffer[nmesa->fifo.put]|=((nmesa->fifo.current-nmesa->fifo.put) << 18); \
}while(0)
#define BEGIN_RING_SIZE(subchannel,tag,size) do { \
if (nmesa->fifo.free<size) \
WAIT_RING(nmesa,(size)); \
OUT_RING( (size<<18) | ((subchannel) << 13) | (tag)); \
}while(0)
#define RING_AVAILABLE() (nmesa->fifo.free-1)
#define RING_AHEAD() ((nmesa->fifo.put<=nmesa->fifo.current)?(nmesa->fifo.current-nmesa->fifo.put):nmesa->fifo.max-nmesa->fifo.put+nmesa->fifo.current)
#define FIRE_RING() do { \
if (nmesa->fifo.current!=nmesa->fifo.put) {\
nmesa->fifo.put=nmesa->fifo.current;\
NV_FIFO_WRITE(NV03_FIFO_REGS_DMAPUT,nmesa->fifo.put);\
}\
}while(0)
#endif /* __NOUVEAU_FIFO_H__ */

View file

@ -0,0 +1,53 @@
/**************************************************************************
Copyright 2006 Stephane Marchesin
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
on the rights to use, copy, modify, merge, publish, distribute, sub
license, and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
#include "nouveau_ioctl.h"
#include "nouveau_context.h"
#include "nouveau_msg.h"
// here we call the fifo initialization ioctl and fill in stuff accordingly
void nouveauIoctlInitFifo()
{
int ret;
int fifo_num;
__DRIscreenPrivate *sPriv;
drm_nouveau_fifo_init_t fifo_init;
fifo_init.fifo_num=&fifo_num;
ret = drmCommandWriteRead(sPriv->fd, DRM_NOUVEAU_FIFO_INIT, &fifo_init, sizeof(fifo_init));
if (ret)
FATAL("Fifo initialization ioctl failed (returned %d)\n",ret);
MESSAGE("Fifo init ok. Got number %d\n",fifo_num);
// XXX needs more stuff
}
void nouveauIoctlInitFunctions( struct dd_function_table *functions )
{
// nothing for now
}

View file

@ -0,0 +1,33 @@
/**************************************************************************
Copyright 2006 Stephane Marchesin
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
on the rights to use, copy, modify, merge, publish, distribute, sub
license, and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
#ifndef __NOUVEAU_IOCTL_H__
#define __NOUVEAU_IOCTL_H__
extern void nouveauIoctlInitFunctions( struct dd_function_table *functions );
#endif /* __NOUVEAU_IOCTL_H__ */

View file

@ -0,0 +1,64 @@
/**************************************************************************
Copyright 2006 Stephane Marchesin
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
on the rights to use, copy, modify, merge, publish, distribute, sub
license, and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
#include "nouveau_context.h"
#include "nouveau_lock.h"
#include "drirenderbuffer.h"
/* Update the hardware state. This is called if another context has
* grabbed the hardware lock, which includes the X server. This
* function also updates the driver's window state after the X server
* moves, resizes or restacks a window -- the change will be reflected
* in the drawable position and clip rects. Since the X server grabs
* the hardware lock when it changes the window state, this routine will
* automatically be called after such a change.
*/
void nouveauGetLock( nouveauContextPtr nmesa, GLuint flags )
{
__DRIdrawablePrivate *dPriv = nmesa->driDrawable;
__DRIscreenPrivate *sPriv = nmesa->driScreen;
drm_nouveau_sarea_t *sarea = nmesa->sarea;
int i;
drmGetLock( nmesa->driFd, nmesa->hHWContext, flags );
/* The window might have moved, so we might need to get new clip
* rects.
*
* NOTE: This releases and regrabs the hw lock to allow the X server
* to respond to the DRI protocol request for new drawable info.
* Since the hardware state depends on having the latest drawable
* clip rects, all state checking must be done _after_ this call.
*/
DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv );
nmesa->numClipRects = dPriv->numClipRects;
nmesa->pClipRects = dPriv->pClipRects;
}

View file

@ -0,0 +1,69 @@
/**************************************************************************
Copyright 2006 Stephane Marchesin
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
on the rights to use, copy, modify, merge, publish, distribute, sub
license, and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
#ifndef __NOUVEAU_LOCK_H__
#define __NOUVEAU_LOCK_H__
#include "nouveau_context.h"
extern void nouveauGetLock( nouveauContextPtr nmesa, GLuint flags );
/*
* !!! We may want to separate locks from locks with validation. This
* could be used to improve performance for those things commands that
* do not do any drawing !!!
*/
/* Lock the hardware and validate our state.
*/
#define LOCK_HARDWARE( nmesa ) \
do { \
char __ret = 0; \
DEBUG_CHECK_LOCK(); \
DRM_CAS( nmesa->driHwLock, nmesa->hHWContext, \
(DRM_LOCK_HELD | nmesa->hHWContext), __ret ); \
if ( __ret ) \
nouveauGetLock( nmesa, 0 ); \
DEBUG_LOCK(); \
} while (0)
/* Unlock the hardware.
*/
#define UNLOCK_HARDWARE( nmesa ) \
do { \
DRM_UNLOCK( nmesa->driFd, \
nmesa->driHwLock, \
nmesa->hHWContext ); \
DEBUG_RESET(); \
} while (0)
#define DEBUG_LOCK()
#define DEBUG_RESET()
#define DEBUG_CHECK_LOCK()
#endif /* __NOUVEAU_LOCK_H__ */

View file

@ -0,0 +1,69 @@
/*
Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
Copyright 2006 Stephane Marchesin. All Rights Reserved
The Weather Channel (TM) funded Tungsten Graphics to develop the
initial release of the Radeon 8500 driver under the XFree86 license.
This notice must be preserved.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
/*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
* Nicolai Haehnle <prefect_@gmx.net>
*/
#ifndef __NOUVEAU_MSG_H__
#define __NOUVEAU_MSG_H__
#define WARN_ONCE(a, ...) do {\
static int warn##__LINE__=1;\
if(warn##__LINE__){\
fprintf(stderr, "*********************************WARN_ONCE*********************************\n");\
fprintf(stderr, "File %s function %s line %d\n", __FILE__, __FUNCTION__, __LINE__);\
fprintf(stderr, a, ## __VA_ARGS__);\
fprintf(stderr, "***************************************************************************\n");\
warn##__LINE__=0;\
} \
}while(0)
#define MESSAGE(a, ...) do{\
fprintf(stderr, "************************************INFO***********************************\n");\
fprintf(stderr, "File %s function %s line %d\n", __FILE__, __FUNCTION__, __LINE__); \
fprintf(stderr, a, ## __VA_ARGS__);\
fprintf(stderr, "***************************************************************************\n");\
exit(0);\
}while(0)
#define FATAL(a, ...) do{\
fprintf(stderr, "***********************************FATAL***********************************\n");\
fprintf(stderr, "File %s function %s line %d\n", __FILE__, __FUNCTION__, __LINE__); \
fprintf(stderr, a, ## __VA_ARGS__);\
fprintf(stderr, "***************************************************************************\n");\
exit(0);\
}while(0)
#endif /* __NOUVEAU_MSG_H__ */

View file

@ -0,0 +1,60 @@
/**************************************************************************
Copyright 2006 Stephane Marchesin
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
on the rights to use, copy, modify, merge, publish, distribute, sub
license, and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
#define NV03_BOOT_0 0x00100000
# define NV03_BOOT_0_RAM_AMOUNT 0x00000003
# define NV03_BOOT_0_RAM_AMOUNT_8MB 0x00000000
# define NV03_BOOT_0_RAM_AMOUNT_2MB 0x00000001
# define NV03_BOOT_0_RAM_AMOUNT_4MB 0x00000002
# define NV03_BOOT_0_RAM_AMOUNT_8MB_SDRAM 0x00000003
# define NV04_BOOT_0_RAM_AMOUNT_32MB 0x00000000
# define NV04_BOOT_0_RAM_AMOUNT_4MB 0x00000001
# define NV04_BOOT_0_RAM_AMOUNT_8MB 0x00000002
# define NV04_BOOT_0_RAM_AMOUNT_16MB 0x00000003
#define NV04_FIFO_DATA 0x0010020c
# define NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK 0xfff00000
# define NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT 20
#define NV03_STATUS 0x004006b0
#define NV04_STATUS 0x00400700
#define NV03_FIFO_SIZE 0x8000
// NV10 maybe has 12 fifos
// NV40 probably has 16 fifos
#define NV03_FIFO_NUMBER 8
#define NV03_FIFO_REGS_SIZE 0x10000
# define NV03_FIFO_REGS_DMAPUT 0x00000040
# define NV03_FIFO_REGS_DMAGET 0x00000044
/* Fifo commands. These are not regs, neither masks */
#define NV03_FIFO_CMD_JUMP 0x20000000
#define NV03_FIFO_CMD_JUMP_OFFSET_MASK 0x1ffffffc
#define NV03_FIFO_CMD_REWIND (NV03_FIFO_CMD_JUMP | (0 & NV03_FIFO_CMD_JUMP_OFFSET_MASK))

View file

@ -0,0 +1,55 @@
/**************************************************************************
Copyright 2006 Stephane Marchesin
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
on the rights to use, copy, modify, merge, publish, distribute, sub
license, and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
#ifndef __NOUVEAU_SCREEN_H__
#define __NOUVEAU_SCREEN_H__
#include "xmlconfig.h"
typedef struct {
u_int32_t card_type;
u_int32_t bus_type;
u_int32_t agp_mode;
GLuint frontOffset;
GLuint frontPitch;
GLuint backOffset;
GLuint backPitch;
GLuint depthOffset;
GLuint depthPitch;
GLuint spanOffset;
__DRIscreenPrivate *driScreen;
/* Configuration cache with default values for all contexts */
driOptionCache optionCache;
} nouveauScreenRec, *nouveauScreenPtr;
#endif /* __NOUVEAU_SCREEN_H__ */

View file

@ -0,0 +1,121 @@
/**************************************************************************
Copyright 2006 Stephane Marchesin
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
on the rights to use, copy, modify, merge, publish, distribute, sub
license, and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
#include "nouveau_context.h"
#include "nouveau_span.h"
#include "nouveau_fifo.h"
#include "swrast/swrast.h"
#define HAVE_HW_DEPTH_SPANS 0
#define HAVE_HW_DEPTH_PIXELS 0
#define HAVE_HW_STENCIL_SPANS 0
#define HAVE_HW_STENCIL_PIXELS 0
#define LOCAL_VARS \
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); \
__DRIscreenPrivate *sPriv = nmesa->driScreen; \
__DRIdrawablePrivate *dPriv = nmesa->driDrawable; \
driRenderbuffer *drb = (driRenderbuffer *) rb; \
GLuint height = dPriv->h; \
GLuint p; \
(void) p;
#define Y_FLIP( _y ) (height - _y - 1)
#define HW_LOCK()
#define HW_UNLOCK()
/* ================================================================
* Color buffers
*/
/* RGB565 */
#define SPANTMP_PIXEL_FMT GL_RGB
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
#define TAG(x) nouveau##x##_RGB565
#define TAG2(x,y) nouveau##x##_RGB565##y
#define GET_PTR(X,Y) (sPriv->pFB + drb->flippedOffset \
+ ((dPriv->y + (Y)) * drb->flippedPitch + (dPriv->x + (X))) * drb->cpp)
#include "spantmp2.h"
/* ARGB8888 */
#define SPANTMP_PIXEL_FMT GL_BGRA
#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
#define TAG(x) nouveau##x##_ARGB8888
#define TAG2(x,y) nouveau##x##_ARGB8888##y
#define GET_PTR(X,Y) (sPriv->pFB + drb->flippedOffset \
+ ((dPriv->y + (Y)) * drb->flippedPitch + (dPriv->x + (X))) * drb->cpp)
#include "spantmp2.h"
static void
nouveauSpanRenderStart( GLcontext *ctx )
{
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
FIRE_RING();
LOCK_HARDWARE(nmesa);
nouveauWaitForIdleLocked( nmesa );
}
static void
nouveauSpanRenderFinish( GLcontext *ctx )
{
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
_swrast_flush( ctx );
nouveauWaitForIdleLocked( nmesa );
UNLOCK_HARDWARE( nmesa );
}
void nouveauSpanInitFunctions( GLcontext *ctx )
{
struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
swdd->SpanRenderStart = nouveauSpanRenderStart;
swdd->SpanRenderFinish = nouveauSpanRenderFinish;
}
/**
* Plug in the Get/Put routines for the given driRenderbuffer.
*/
void
nouveauSpanSetFunctions(driRenderbuffer *drb, const GLvisual *vis)
{
if (drb->Base.InternalFormat == GL_RGBA) {
if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) {
nouveauInitPointers_RGB565(&drb->Base);
}
else {
nouveauInitPointers_ARGB8888(&drb->Base);
}
}
}

View file

@ -0,0 +1,38 @@
/**************************************************************************
Copyright 2006 Stephane Marchesin
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
on the rights to use, copy, modify, merge, publish, distribute, sub
license, and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
#ifndef __NOUVEAU_SPAN_H__
#define __NOUVEAU_SPAN_H__
#include "drirenderbuffer.h"
extern void nouveauSpanInitFunctions( GLcontext *ctx );
extern void nouveauSpanSetFunctions(driRenderbuffer *rb, const GLvisual *vis);
#endif /* __NOUVEAU_SPAN_H__ */

View file

@ -0,0 +1,49 @@
/**************************************************************************
Copyright 2006 Stephane Marchesin
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
on the rights to use, copy, modify, merge, publish, distribute, sub
license, and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
#include "nouveau_tex.h"
// XXX needs some love
void nouveauInitTextureFuncs( struct dd_function_table *functions )
{
/*
functions->TexEnv = nouveauTexEnv;
functions->ChooseTextureFormat = nouveauChooseTextureFormat;
functions->TexImage1D = nouveauTexImage1D;
functions->TexSubImage1D = nouveauTexSubImage1D;
functions->TexImage2D = nouveauTexImage2D;
functions->TexSubImage2D = nouveauTexSubImage2D;
functions->TexParameter = nouveauTexParameter;
functions->BindTexture = nouveauBindTexture;
functions->NewTextureObject = nouveauNewTextureObject;
functions->DeleteTexture = nouveauDeleteTexture;
functions->IsTextureResident = driIsTextureResident;
driInitTextureFormats();
*/
}

View file

@ -0,0 +1,33 @@
/**************************************************************************
Copyright 2006 Stephane Marchesin
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
on the rights to use, copy, modify, merge, publish, distribute, sub
license, and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
#ifndef __NOUVEAU_TEX_H__
#define __NOUVEAU_TEX_H__
extern void nouveauTexInitFunctions( struct dd_function_table *functions );
#endif /* __NOUVEAU_TEX_H__ */

View file

@ -0,0 +1,126 @@
/**************************************************************************
Copyright 2006 Stephane Marchesin
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
on the rights to use, copy, modify, merge, publish, distribute, sub
license, and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
#include "nouveau_context.h"
/* Common tri functions */
/* The fallbacks */
void nouveau_fallback_tri(struct nouveau_context *nmesa,
nouveauVertex *v0,
nouveauVertex *v1,
nouveauVertex *v2)
{
GLcontext *ctx = nmesa->glCtx;
SWvertex v[3];
_swsetup_Translate(ctx, v0, &v[0]);
_swsetup_Translate(ctx, v1, &v[1]);
_swsetup_Translate(ctx, v2, &v[2]);
nouveauSpanRenderStart( ctx );
_swrast_Triangle(ctx, &v[0], &v[1], &v[2]);
nouveauSpanRenderFinish( ctx );
}
void nouveau_fallback_line(struct nouveau_context *nmesa,
nouveauVertex *v0,
nouveauVertex *v1)
{
GLcontext *ctx = nmesa->glCtx;
SWvertex v[2];
_swsetup_Translate(ctx, v0, &v[0]);
_swsetup_Translate(ctx, v1, &v[1]);
nouveauSpanRenderStart( ctx );
_swrast_Line(ctx, &v[0], &v[1]);
nouveauSpanRenderFinish( ctx );
}
void nouveau_fallback_point(struct nouveau_context *nmesa,
nouveauVertex *v0)
{
GLcontext *ctx = nmesa->glCtx;
SWvertex v[1];
_swsetup_Translate(ctx, v0, &v[0]);
nouveauSpanRenderStart( ctx );
_swrast_Point(ctx, &v[0]);
nouveauSpanRenderFinish( ctx );
}
void nouveauFallback(struct nouveau_context *nmesa, GLuint bit, GLboolean mode)
{
GLcontext *ctx = nmesa->glCtx;
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLuint oldfallback = nmesa->Fallback;
if (mode) {
nmesa->Fallback |= bit;
if (oldfallback == 0) {
nv40FinishPrimitive(nmesa);
_swsetup_Wakeup(ctx);
nmesa->renderIndex = ~0;
}
}
else {
nmesa->Fallback &= ~bit;
if (oldfallback == bit) {
_swrast_flush( ctx );
tnl->Driver.Render.Start = nouveauRenderStart;
tnl->Driver.Render.PrimitiveNotify = nouveauRenderPrimitive;
tnl->Driver.Render.Finish = nouveauRenderFinish;
tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
tnl->Driver.Render.CopyPV = _tnl_copy_pv;
tnl->Driver.Render.Interp = _tnl_interp;
tnl->Driver.Render.ResetLineStipple = nouveauResetLineStipple;
_tnl_invalidate_vertex_state( ctx, ~0 );
_tnl_invalidate_vertices( ctx, ~0 );
_tnl_install_attrs( ctx,
nmesa->vertex_attrs,
nmesa->vertex_attr_count,
nmesa->ViewportMatrix.m, 0 );
}
}
}
void nouveauRunPipeline( GLcontext *ctx )
{
struct nouveau_context *vmesa = NOUVEAU_CONTEXT(ctx);
if (vmesa->newState) {
vmesa->newRenderState |= vmesa->newState;
nouveauValidateState( ctx );
}
_tnl_run_pipeline( ctx );
}

View file

@ -0,0 +1,52 @@
/**************************************************************************
Copyright 2006 Stephane Marchesin
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
on the rights to use, copy, modify, merge, publish, distribute, sub
license, and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
#ifndef __NOUVEAU_TRIS_H__
#define __NOUVEAU_TRIS_H__
#include "nouveau_context.h"
extern void nouveau_fallback_tri(struct nouveau_context *nmesa,
nouveauVertex *v0,
nouveauVertex *v1,
nouveauVertex *v2);
extern void nouveau_fallback_line(struct nouveau_context *nmesa,
nouveauVertex *v0,
nouveauVertex *v1);
extern void nouveau_fallback_point(struct nouveau_context *nmesa,
nouveauVertex *v0);
extern void nouveauFallback(struct nouveau_context *nmesa, GLuint bit, GLboolean mode);
extern void nouveauRunPipeline( GLcontext *ctx );
#endif /* __NOUVEAU_TRIS_H__ */

View file

@ -0,0 +1,738 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
* Copyright 2006 Stephane Marchesin. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sub license,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <stdio.h>
#include <math.h>
#include "glheader.h"
#include "context.h"
#include "mtypes.h"
#include "macros.h"
#include "colormac.h"
#include "enums.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "tnl/t_context.h"
#include "tnl/t_pipeline.h"
#include "nouveau_tris.h"
#include "nv40_tris.h"
#include "nouveau_context.h"
#include "nouveau_state.h"
#include "nouveau_span.h"
#include "nouveau_ioctl.h"
#include "nouveau_3d_reg.h"
#include "nouveau_tex.h"
/* hack for now */
#define channel 1
/***********************************************************************
* Emit primitives as inline vertices *
***********************************************************************/
#define LINE_FALLBACK (0)
#define POINT_FALLBACK (0)
#define TRI_FALLBACK (0)
#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK)
#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
#define COPY_DWORDS(vb, vertsize, v) \
do { \
int j; \
for (j = 0; j < vertsize; j++) \
vb[j] = ((GLuint *)v)[j]; \
vb += vertsize; \
} while (0)
#endif
/* the free room we want before we start a vertex batch */
#define NV40_MIN_PRIM_SIZE (32/4)
static inline void nv40StartPrimitive(struct nouveau_context* nmesa)
{
BEGIN_RING_SIZE(channel,0x1808,1);
OUT_RING(nmesa->current_primitive);
BEGIN_RING_PRIM(channel,0x1818,NV40_MIN_PRIM_SIZE);
}
static inline void nv40FinishPrimitive(struct nouveau_context *nmesa)
{
FINISH_RING_PRIM();
BEGIN_RING_SIZE(channel,0x1808,1);
OUT_RING(0x0);
FIRE_RING();
}
static inline void nv40ExtendPrimitive(struct nouveau_context* nmesa, int size)
{
/* when the fifo has enough stuff (2048 bytes) or there is not enough room, fire */
if ((RING_AHEAD()>=2048/4)||(RING_AVAILABLE()<size/4))
{
nv40FinishPrimitive(nmesa);
nv40StartPrimitive(nmesa);
}
/* make sure there's enough room. if not, wait */
if (RING_AVAILABLE()<size/4)
{
WAIT_RING(nmesa,size);
}
}
static inline void nv40_draw_quad(struct nouveau_context *nmesa,
nouveauVertexPtr v0,
nouveauVertexPtr v1,
nouveauVertexPtr v2,
nouveauVertexPtr v3)
{
GLuint vertsize = nmesa->vertexSize;
GLuint *vb = nv40ExtendPrimitive(nmesa, 4 * 4 * vertsize);
COPY_DWORDS(vb, vertsize, v0);
COPY_DWORDS(vb, vertsize, v1);
COPY_DWORDS(vb, vertsize, v2);
COPY_DWORDS(vb, vertsize, v3);
}
static inline void nv40_draw_triangle(struct nouveau_context *nmesa,
nouveauVertexPtr v0,
nouveauVertexPtr v1,
nouveauVertexPtr v2)
{
GLuint vertsize = nmesa->vertexSize;
GLuint *vb = nv40ExtendPrimitive(nmesa, 3 * 4 * vertsize);
COPY_DWORDS(vb, vertsize, v0);
COPY_DWORDS(vb, vertsize, v1);
COPY_DWORDS(vb, vertsize, v2);
}
static inline void nouveau_draw_line(struct nouveau_context *nmesa,
nouveauVertexPtr v0,
nouveauVertexPtr v1)
{
GLuint vertsize = nmesa->vertexSize;
GLuint *vb = nv40ExtendPrimitive(nmesa, 2 * 4 * vertsize);
COPY_DWORDS(vb, vertsize, v0);
COPY_DWORDS(vb, vertsize, v1);
}
static inline void nouveau_draw_point(struct nouveau_context *nmesa,
nouveauVertexPtr v0)
{
GLuint vertsize = nmesa->vertexSize;
GLuint *vb = nv40ExtendPrimitive(nmesa, 4 * vertsize);
COPY_DWORDS(vb, vertsize, v0);
}
/***********************************************************************
* Macros for nouveau_dd_tritmp.h to draw basic primitives *
***********************************************************************/
#define TRI(a, b, c) \
do { \
if (DO_FALLBACK) \
nmesa->draw_tri(nmesa, a, b, c); \
else \
nouveau_draw_triangle(nmesa, a, b, c); \
} while (0)
#define QUAD(a, b, c, d) \
do { \
if (DO_FALLBACK) { \
nmesa->draw_tri(nmesa, a, b, d); \
nmesa->draw_tri(nmesa, b, c, d); \
} \
else \
nouveau_draw_quad(nmesa, a, b, c, d); \
} while (0)
#define LINE(v0, v1) \
do { \
if (DO_FALLBACK) \
nmesa->draw_line(nmesa, v0, v1); \
else \
nouveau_draw_line(nmesa, v0, v1); \
} while (0)
#define POINT(v0) \
do { \
if (DO_FALLBACK) \
nmesa->draw_point(nmesa, v0); \
else \
nouveau_draw_point(nmesa, v0); \
} while (0)
/***********************************************************************
* Build render functions from dd templates *
***********************************************************************/
#define NOUVEAU_OFFSET_BIT 0x01
#define NOUVEAU_TWOSIDE_BIT 0x02
#define NOUVEAU_UNFILLED_BIT 0x04
#define NOUVEAU_FALLBACK_BIT 0x08
#define NOUVEAU_MAX_TRIFUNC 0x10
static struct {
tnl_points_func points;
tnl_line_func line;
tnl_triangle_func triangle;
tnl_quad_func quad;
} rast_tab[NOUVEAU_MAX_TRIFUNC + 1];
#define DO_FALLBACK (IND & NOUVEAU_FALLBACK_BIT)
#define DO_OFFSET (IND & NOUVEAU_OFFSET_BIT)
#define DO_UNFILLED (IND & NOUVEAU_UNFILLED_BIT)
#define DO_TWOSIDE (IND & NOUVEAU_TWOSIDE_BIT)
#define DO_FLAT 0
#define DO_TRI 1
#define DO_QUAD 1
#define DO_LINE 1
#define DO_POINTS 1
#define DO_FULL_QUAD 1
#define HAVE_RGBA 1
#define HAVE_SPEC 1
#define HAVE_BACK_COLORS 0
#define HAVE_HW_FLATSHADE 1
#define VERTEX nouveauVertex
#define TAB rast_tab
/* Only used to pull back colors into vertices (ie, we know color is
* floating point).
*/
#define NOUVEAU_COLOR(dst, src) \
do { \
dst[0] = src[2]; \
dst[1] = src[1]; \
dst[2] = src[0]; \
dst[3] = src[3]; \
} while (0)
#define NOUVEAU_SPEC(dst, src) \
do { \
dst[0] = src[2]; \
dst[1] = src[1]; \
dst[2] = src[0]; \
} while (0)
#define DEPTH_SCALE nmesa->polygon_offset_scale
#define UNFILLED_TRI unfilled_tri
#define UNFILLED_QUAD unfilled_quad
#define VERT_X(_v) _v->v.x
#define VERT_Y(_v) _v->v.y
#define VERT_Z(_v) _v->v.z
#define AREA_IS_CCW(a) (a > 0)
#define GET_VERTEX(e) (nmesa->verts + (e * nmesa->vertexSize * sizeof(int)))
#define VERT_SET_RGBA( v, c ) \
do { \
nouveau_color_t *color = (nouveau_color_t *)&((v)->ui[coloroffset]); \
UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \
UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \
UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \
UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]); \
} while (0)
#define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
#define VERT_SET_SPEC( v, c ) \
do { \
if (specoffset) { \
nouveau_color_t *color = (nouveau_color_t *)&((v)->ui[specoffset]); \
UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \
UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \
UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \
} \
} while (0)
#define VERT_COPY_SPEC( v0, v1 ) \
do { \
if (specoffset) { \
v0->ub4[specoffset][0] = v1->ub4[specoffset][0]; \
v0->ub4[specoffset][1] = v1->ub4[specoffset][1]; \
v0->ub4[specoffset][2] = v1->ub4[specoffset][2]; \
} \
} while (0)
#define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset]
#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
#define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->ui[specoffset]
#define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx]
#define LOCAL_VARS(n) \
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); \
GLuint color[n], spec[n]; \
GLuint coloroffset = nmesa->coloroffset; \
GLuint specoffset = nmesa->specoffset; \
(void)color; (void)spec; (void)coloroffset; (void)specoffset;
/***********************************************************************
* Helpers for rendering unfilled primitives *
***********************************************************************/
#define RASTERIZE(x) nv40RasterPrimitive( ctx, x, x )
#define RENDER_PRIMITIVE nmesa->renderPrimitive
#define TAG(x) x
#define IND NOUVEAU_FALLBACK_BIT
#include "tnl_dd/t_dd_unfilled.h"
#undef IND
#undef RASTERIZE
/***********************************************************************
* Generate GL render functions *
***********************************************************************/
#define RASTERIZE(x)
#define IND (0)
#define TAG(x) x
#include "tnl_dd/t_dd_tritmp.h"
#define IND (NOUVEAU_OFFSET_BIT)
#define TAG(x) x##_offset
#include "tnl_dd/t_dd_tritmp.h"
#define IND (NOUVEAU_TWOSIDE_BIT)
#define TAG(x) x##_twoside
#include "tnl_dd/t_dd_tritmp.h"
#define IND (NOUVEAU_TWOSIDE_BIT|NOUVEAU_OFFSET_BIT)
#define TAG(x) x##_twoside_offset
#include "tnl_dd/t_dd_tritmp.h"
#define IND (NOUVEAU_UNFILLED_BIT)
#define TAG(x) x##_unfilled
#include "tnl_dd/t_dd_tritmp.h"
#define IND (NOUVEAU_OFFSET_BIT|NOUVEAU_UNFILLED_BIT)
#define TAG(x) x##_offset_unfilled
#include "tnl_dd/t_dd_tritmp.h"
#define IND (NOUVEAU_TWOSIDE_BIT|NOUVEAU_UNFILLED_BIT)
#define TAG(x) x##_twoside_unfilled
#include "tnl_dd/t_dd_tritmp.h"
#define IND (NOUVEAU_TWOSIDE_BIT|NOUVEAU_OFFSET_BIT|NOUVEAU_UNFILLED_BIT)
#define TAG(x) x##_twoside_offset_unfilled
#include "tnl_dd/t_dd_tritmp.h"
#define IND (NOUVEAU_FALLBACK_BIT)
#define TAG(x) x##_fallback
#include "tnl_dd/t_dd_tritmp.h"
#define IND (NOUVEAU_OFFSET_BIT|NOUVEAU_FALLBACK_BIT)
#define TAG(x) x##_offset_fallback
#include "tnl_dd/t_dd_tritmp.h"
#define IND (NOUVEAU_TWOSIDE_BIT|NOUVEAU_FALLBACK_BIT)
#define TAG(x) x##_twoside_fallback
#include "tnl_dd/t_dd_tritmp.h"
#define IND (NOUVEAU_TWOSIDE_BIT|NOUVEAU_OFFSET_BIT|NOUVEAU_FALLBACK_BIT)
#define TAG(x) x##_twoside_offset_fallback
#include "tnl_dd/t_dd_tritmp.h"
#define IND (NOUVEAU_UNFILLED_BIT|NOUVEAU_FALLBACK_BIT)
#define TAG(x) x##_unfilled_fallback
#include "tnl_dd/t_dd_tritmp.h"
#define IND (NOUVEAU_OFFSET_BIT|NOUVEAU_UNFILLED_BIT|NOUVEAU_FALLBACK_BIT)
#define TAG(x) x##_offset_unfilled_fallback
#include "tnl_dd/t_dd_tritmp.h"
#define IND (NOUVEAU_TWOSIDE_BIT|NOUVEAU_UNFILLED_BIT|NOUVEAU_FALLBACK_BIT)
#define TAG(x) x##_twoside_unfilled_fallback
#include "tnl_dd/t_dd_tritmp.h"
#define IND (NOUVEAU_TWOSIDE_BIT|NOUVEAU_OFFSET_BIT|NOUVEAU_UNFILLED_BIT| \
NOUVEAU_FALLBACK_BIT)
#define TAG(x) x##_twoside_offset_unfilled_fallback
#include "tnl_dd/t_dd_tritmp.h"
/* Catchall case for flat, separate specular triangles */
#undef DO_FALLBACK
#undef DO_OFFSET
#undef DO_UNFILLED
#undef DO_TWOSIDE
#undef DO_FLAT
#define DO_FALLBACK (0)
#define DO_OFFSET (ctx->_TriangleCaps & DD_TRI_OFFSET)
#define DO_UNFILLED (ctx->_TriangleCaps & DD_TRI_UNFILLED)
#define DO_TWOSIDE (ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE)
#define DO_FLAT 1
#define TAG(x) x##_flat_specular
#define IND NOUVEAU_MAX_TRIFUNC
#include "tnl_dd/t_dd_tritmp.h"
static void init_rast_tab(void)
{
init();
init_offset();
init_twoside();
init_twoside_offset();
init_unfilled();
init_offset_unfilled();
init_twoside_unfilled();
init_twoside_offset_unfilled();
init_fallback();
init_offset_fallback();
init_twoside_fallback();
init_twoside_offset_fallback();
init_unfilled_fallback();
init_offset_unfilled_fallback();
init_twoside_unfilled_fallback();
init_twoside_offset_unfilled_fallback();
init_flat_specular(); /* special! */
}
/**********************************************************************/
/* Render unclipped begin/end objects */
/**********************************************************************/
#define IND 0
#define V(x) (nouveauVertex *)(vertptr + ((x) * vertsize * sizeof(int)))
#define RENDER_POINTS(start, count) \
for (; start < count; start++) POINT(V(ELT(start)));
#define RENDER_LINE(v0, v1) LINE(V(v0), V(v1))
#define RENDER_TRI( v0, v1, v2) TRI( V(v0), V(v1), V(v2))
#define RENDER_QUAD(v0, v1, v2, v3) QUAD(V(v0), V(v1), V(v2), V(v3))
#define INIT(x) nv40RasterPrimitive(ctx, x, x)
#undef LOCAL_VARS
#define LOCAL_VARS \
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); \
GLubyte *vertptr = (GLubyte *)nmesa->verts; \
const GLuint vertsize = nmesa->vertexSize; \
const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
const GLboolean stipple = ctx->Line.StippleFlag; \
(void) elt; (void) stipple;
#define RESET_STIPPLE if ( stipple ) nouveauResetLineStipple( ctx );
#define RESET_OCCLUSION
#define PRESERVE_VB_DEFS
#define ELT(x) x
#define TAG(x) nouveau_##x##_verts
#include "tnl/t_vb_rendertmp.h"
#undef ELT
#undef TAG
#define TAG(x) nouveau_##x##_elts
#define ELT(x) elt[x]
#include "tnl/t_vb_rendertmp.h"
#undef ELT
#undef TAG
#undef NEED_EDGEFLAG_SETUP
#undef EDGEFLAG_GET
#undef EDGEFLAG_SET
#undef RESET_OCCLUSION
/**********************************************************************/
/* Render clipped primitives */
/**********************************************************************/
static void nouveauRenderClippedPoly(GLcontext *ctx, const GLuint *elts,
GLuint n)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
GLuint prim = NOUVEAU_CONTEXT(ctx)->renderPrimitive;
/* Render the new vertices as an unclipped polygon.
*/
{
GLuint *tmp = VB->Elts;
VB->Elts = (GLuint *)elts;
tnl->Driver.Render.PrimTabElts[GL_POLYGON](ctx, 0, n,
PRIM_BEGIN|PRIM_END);
VB->Elts = tmp;
}
/* Restore the render primitive
*/
if (prim != GL_POLYGON &&
prim != GL_POLYGON + 1)
tnl->Driver.Render.PrimitiveNotify( ctx, prim );
}
static void nouveauRenderClippedLine(GLcontext *ctx, GLuint ii, GLuint jj)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
tnl->Driver.Render.Line(ctx, ii, jj);
}
static void nouveauFastRenderClippedPoly(GLcontext *ctx, const GLuint *elts,
GLuint n)
{
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
GLuint vertsize = nmesa->vertexSize;
GLuint *vb = nouveauExtendPrimitive(nmesa, (n - 2) * 3 * 4 * vertsize);
GLubyte *vertptr = (GLubyte *)nmesa->verts;
const GLuint *start = (const GLuint *)V(elts[0]);
int i;
for (i = 2; i < n; i++) {
COPY_DWORDS(vb, vertsize, V(elts[i - 1]));
COPY_DWORDS(vb, vertsize, V(elts[i]));
COPY_DWORDS(vb, vertsize, start);
}
}
/**********************************************************************/
/* Choose render functions */
/**********************************************************************/
#define _NOUVEAU_NEW_VERTEX (_NEW_TEXTURE | \
_DD_NEW_SEPARATE_SPECULAR | \
_DD_NEW_TRI_UNFILLED | \
_DD_NEW_TRI_LIGHT_TWOSIDE | \
_NEW_FOG)
#define _NOUVEAU_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE | \
_DD_NEW_TRI_UNFILLED | \
_DD_NEW_TRI_LIGHT_TWOSIDE | \
_DD_NEW_TRI_OFFSET | \
_DD_NEW_TRI_STIPPLE | \
_NEW_POLYGONSTIPPLE)
static void nv40ChooseRenderState(GLcontext *ctx)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
GLuint flags = ctx->_TriangleCaps;
GLuint index = 0;
nmesa->draw_point = nouveau_draw_point;
nmesa->draw_line = nouveau_draw_line;
nmesa->draw_tri = nouveau_draw_triangle;
if (flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) {
if (flags & DD_TRI_LIGHT_TWOSIDE) index |= NOUVEAU_TWOSIDE_BIT;
if (flags & DD_TRI_OFFSET) index |= NOUVEAU_OFFSET_BIT;
if (flags & DD_TRI_UNFILLED) index |= NOUVEAU_UNFILLED_BIT;
if (flags & ANY_FALLBACK_FLAGS) index |= NOUVEAU_FALLBACK_BIT;
/* Hook in fallbacks for specific primitives.
*/
if (flags & POINT_FALLBACK)
nmesa->draw_point = nouveau_fallback_point;
if (flags & LINE_FALLBACK)
nmesa->draw_line = nouveau_fallback_line;
if (flags & TRI_FALLBACK)
nmesa->draw_tri = nouveau_fallback_tri;
}
if ((flags & DD_SEPARATE_SPECULAR) &&
ctx->Light.ShadeModel == GL_FLAT) {
index = NOUVEAU_MAX_TRIFUNC; /* flat specular */
}
if (nmesa->renderIndex != index) {
nmesa->renderIndex = index;
tnl->Driver.Render.Points = rast_tab[index].points;
tnl->Driver.Render.Line = rast_tab[index].line;
tnl->Driver.Render.Triangle = rast_tab[index].triangle;
tnl->Driver.Render.Quad = rast_tab[index].quad;
if (index == 0) {
tnl->Driver.Render.PrimTabVerts = nouveau_render_tab_verts;
tnl->Driver.Render.PrimTabElts = nouveau_render_tab_elts;
tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */
tnl->Driver.Render.ClippedPolygon = nouveauFastRenderClippedPoly;
}
else {
tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
tnl->Driver.Render.ClippedLine = nouveauRenderClippedLine;
tnl->Driver.Render.ClippedPolygon = nouveauRenderClippedPoly;
}
}
}
static inline void nv40OutputVertexFormat(struct nouveau_context* mesa, GLuint index)
{
/*
* Determine how many inputs we need in the vertex format.
* We need to find & setup the right input "slots"
*
* The hw attribute order matches nv_vertex_program, and _TNL_BIT_*
* also matches this order, so we can take shortcuts...
*/
int i;
int slots=0;
for(i=0;i<16;i++)
if (index&(1<<i))
slots=i+1;
BEGIN_RING_SIZE(channel,0x1740,slots);
for(i=0;i<slots;i++)
if (index&(1<<i))
{
/* XXX for now we only emit 3-sized attributes */
int size=3;
OUR_RING(0x00000002|(size*0x10));
}
else
{
OUR_RING(0x00000002);
}
BEGIN_RING_SIZE(channel,0x1718,1);
OUT_RING(0);
BEGIN_RING_SIZE(channel,0x1718,1);
OUT_RING(0);
BEGIN_RING_SIZE(channel,0x1718,1);
OUT_RING(0);
}
static void nv40ChooseVertexState( GLcontext *ctx )
{
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLuint index = tnl->render_inputs;
if (index!=nmesa->render_inputs)
{
nmesa->render_inputs=index;
nv40OutputVertexFormat(nmesa,index);
}
}
/**********************************************************************/
/* High level hooks for t_vb_render.c */
/**********************************************************************/
static void nv40RenderStart(GLcontext *ctx)
{
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
if (nmesa->newState) {
nmesa->newRenderState |= nmesa->newState;
nouveauValidateState( ctx );
}
if (nmesa->Fallback) {
tnl->Driver.Render.Start(ctx);
return;
}
if (nmesa->newRenderState) {
nv40ChooseVertexState(ctx);
nv40ChooseRenderState(ctx);
nmesa->newRenderState = 0;
}
}
static void nv40RenderFinish(GLcontext *ctx)
{
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
nv40FinishPrimitive(nmesa);
}
/* System to flush dma and emit state changes based on the rasterized
* primitive.
*/
void nv40RasterPrimitive(GLcontext *ctx,
GLenum glprim,
GLenum hwprim)
{
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
assert (!nmesa->newState);
if (hwprim != nmesa->current_primitive)
{
nmesa->current_primitive=hwprim;
}
}
/* Callback for mesa:
*/
static void nv40RenderPrimitive( GLcontext *ctx, GLuint prim )
{
nv40RasterPrimitive( ctx, prim, prim );
}
/**********************************************************************/
/* Initialization. */
/**********************************************************************/
void nouveauInitTriFuncs(GLcontext *ctx)
{
struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
static int firsttime = 1;
if (firsttime) {
init_rast_tab();
firsttime = 0;
}
tnl->Driver.RunPipeline = nouveauRunPipeline;
tnl->Driver.Render.Start = nv40RenderStart;
tnl->Driver.Render.Finish = nv40RenderFinish;
tnl->Driver.Render.PrimitiveNotify = nv40RenderPrimitive;
tnl->Driver.Render.ResetLineStipple = nouveauResetLineStipple;
tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
tnl->Driver.Render.CopyPV = _tnl_copy_pv;
tnl->Driver.Render.Interp = _tnl_interp;
_tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12,
(6 + 2*ctx->Const.MaxTextureUnits) * sizeof(GLfloat) );
nmesa->verts = (GLubyte *)tnl->clipspace.vertex_buf;
}

View file

@ -0,0 +1,39 @@
/**************************************************************************
Copyright 2006 Stephane Marchesin
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
on the rights to use, copy, modify, merge, publish, distribute, sub
license, and/or sell copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
#ifndef __NV40_TRIS_H__
#define __NV40_TRIS_H__
#include "mtypes.h"
extern void nv40TriInitFunctions( GLcontext *ctx );
extern void nv40Fallback( GLcontext *ctx, GLuint bit, GLboolean mode );
#define FALLBACK( nmesa, bit, mode ) nouveauFallback( nmesa->glCtx, bit, mode )
#endif /* __NV40_TRIS_H__ */