diff options
22 files changed, 2343 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile new file mode 100644 index 00000000000..02632c49cf2 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -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: diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c new file mode 100644 index 00000000000..1a8dc6a6c4d --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -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; +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h new file mode 100644 index 00000000000..d287439fcf9 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -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__ */ + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_driver.c b/src/mesa/drivers/dri/nouveau/nouveau_driver.c new file mode 100644 index 00000000000..165fc4929fa --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_driver.c @@ -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; +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_driver.h b/src/mesa/drivers/dri/nouveau/nouveau_driver.h new file mode 100644 index 00000000000..e1541aa3c57 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_driver.h @@ -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__ */ + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c new file mode 100644 index 00000000000..a330d5268b7 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c @@ -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); +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h new file mode 100644 index 00000000000..6a21687551b --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h @@ -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__ */ + + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_ioctl.c b/src/mesa/drivers/dri/nouveau/nouveau_ioctl.c new file mode 100644 index 00000000000..959c5f465bd --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_ioctl.c @@ -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 +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_ioctl.h b/src/mesa/drivers/dri/nouveau/nouveau_ioctl.h new file mode 100644 index 00000000000..e6a9a7e2495 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_ioctl.h @@ -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__ */ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_lock.c b/src/mesa/drivers/dri/nouveau/nouveau_lock.c new file mode 100644 index 00000000000..1bd2ee4ca98 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_lock.c @@ -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; + +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_lock.h b/src/mesa/drivers/dri/nouveau/nouveau_lock.h new file mode 100644 index 00000000000..38bb0014258 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_lock.h @@ -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__ */ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_msg.h b/src/mesa/drivers/dri/nouveau/nouveau_msg.h new file mode 100644 index 00000000000..7b8f89e7745 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_msg.h @@ -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 <[email protected]> + * Nicolai Haehnle <[email protected]> + */ + + +#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__ */ + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_reg.h b/src/mesa/drivers/dri/nouveau/nouveau_reg.h new file mode 100644 index 00000000000..8b936a5ceca --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_reg.h @@ -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)) + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.h b/src/mesa/drivers/dri/nouveau/nouveau_screen.h new file mode 100644 index 00000000000..b8e8bfc22ab --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.h @@ -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__ */ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_span.c b/src/mesa/drivers/dri/nouveau/nouveau_span.c new file mode 100644 index 00000000000..f990a8907ea --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_span.c @@ -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); + } + } +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_span.h b/src/mesa/drivers/dri/nouveau/nouveau_span.h new file mode 100644 index 00000000000..f5e5733ba88 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_span.h @@ -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__ */ + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_tex.c b/src/mesa/drivers/dri/nouveau/nouveau_tex.c new file mode 100644 index 00000000000..e3160b2d3d5 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_tex.c @@ -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(); +*/ +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_tex.h b/src/mesa/drivers/dri/nouveau/nouveau_tex.h new file mode 100644 index 00000000000..c415dc2a6bb --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_tex.h @@ -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__ */ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_tris.c b/src/mesa/drivers/dri/nouveau/nouveau_tris.c new file mode 100644 index 00000000000..770776390b9 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_tris.c @@ -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 ); +} + + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_tris.h b/src/mesa/drivers/dri/nouveau/nouveau_tris.h new file mode 100644 index 00000000000..4d9de538d71 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_tris.h @@ -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__ */ + + diff --git a/src/mesa/drivers/dri/nouveau/nv40_tris.c b/src/mesa/drivers/dri/nouveau/nv40_tris.c new file mode 100644 index 00000000000..6550928c2fc --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv40_tris.c @@ -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; + +} + diff --git a/src/mesa/drivers/dri/nouveau/nv40_tris.h b/src/mesa/drivers/dri/nouveau/nv40_tris.h new file mode 100644 index 00000000000..92f18965393 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv40_tris.h @@ -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__ */ + |