From 0abf3937ce651d26b18a3ab93ed916f3e7bd04dd Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Thu, 23 Feb 2006 12:55:56 +0000 Subject: Initial revision --- src/mesa/drivers/dri/nouveau/Makefile | 30 + src/mesa/drivers/dri/nouveau/nouveau_context.c | 209 +++++++ src/mesa/drivers/dri/nouveau/nouveau_context.h | 129 +++++ src/mesa/drivers/dri/nouveau/nouveau_driver.c | 145 +++++ src/mesa/drivers/dri/nouveau/nouveau_driver.h | 39 ++ src/mesa/drivers/dri/nouveau/nouveau_fifo.c | 96 ++++ src/mesa/drivers/dri/nouveau/nouveau_fifo.h | 96 ++++ src/mesa/drivers/dri/nouveau/nouveau_ioctl.c | 53 ++ src/mesa/drivers/dri/nouveau/nouveau_ioctl.h | 33 ++ src/mesa/drivers/dri/nouveau/nouveau_lock.c | 64 +++ src/mesa/drivers/dri/nouveau/nouveau_lock.h | 69 +++ src/mesa/drivers/dri/nouveau/nouveau_msg.h | 69 +++ src/mesa/drivers/dri/nouveau/nouveau_reg.h | 60 ++ src/mesa/drivers/dri/nouveau/nouveau_screen.h | 55 ++ src/mesa/drivers/dri/nouveau/nouveau_span.c | 121 ++++ src/mesa/drivers/dri/nouveau/nouveau_span.h | 38 ++ src/mesa/drivers/dri/nouveau/nouveau_tex.c | 49 ++ src/mesa/drivers/dri/nouveau/nouveau_tex.h | 33 ++ src/mesa/drivers/dri/nouveau/nouveau_tris.c | 126 +++++ src/mesa/drivers/dri/nouveau/nouveau_tris.h | 52 ++ src/mesa/drivers/dri/nouveau/nv40_tris.c | 738 +++++++++++++++++++++++++ src/mesa/drivers/dri/nouveau/nv40_tris.h | 39 ++ 22 files changed, 2343 insertions(+) create mode 100644 src/mesa/drivers/dri/nouveau/Makefile create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_context.c create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_context.h create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_driver.c create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_driver.h create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_fifo.c create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_fifo.h create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_ioctl.c create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_ioctl.h create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_lock.c create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_lock.h create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_msg.h create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_reg.h create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_screen.h create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_span.c create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_span.h create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_tex.c create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_tex.h create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_tris.c create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_tris.h create mode 100644 src/mesa/drivers/dri/nouveau/nv40_tris.c create mode 100644 src/mesa/drivers/dri/nouveau/nv40_tris.h (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile new file mode 100644 index 0000000000..02632c49cf --- /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 0000000000..1a8dc6a6c4 --- /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 0000000000..d287439fcf --- /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 0000000000..165fc4929f --- /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 0000000000..e1541aa3c5 --- /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 0000000000..a330d5268b --- /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 0000000000..6a21687551 --- /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.freefifo.buffer[nmesa->fifo.put]|=((nmesa->fifo.current-nmesa->fifo.put) << 18); \ +}while(0) + +#define BEGIN_RING_SIZE(subchannel,tag,size) do { \ + if (nmesa->fifo.freefifo.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 0000000000..959c5f465b --- /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 0000000000..e6a9a7e249 --- /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 0000000000..1bd2ee4ca9 --- /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 0000000000..38bb001425 --- /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 0000000000..7b8f89e774 --- /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 + * Nicolai Haehnle + */ + + +#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 0000000000..8b936a5cec --- /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 0000000000..b8e8bfc22a --- /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 0000000000..f990a8907e --- /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 0000000000..f5e5733ba8 --- /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 0000000000..e3160b2d3d --- /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 0000000000..c415dc2a6b --- /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 0000000000..770776390b --- /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 0000000000..4d9de538d7 --- /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 0000000000..6550928c2f --- /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 +#include + +#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()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<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 0000000000..92f1896539 --- /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__ */ + -- cgit v1.2.3 From 0e7e80ae106689bbd30148835b24e811f40198e9 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Thu, 2 Mar 2006 00:42:37 +0000 Subject: Some small improvements. --- src/mesa/drivers/dri/nouveau/nv40_tris.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv40_tris.c b/src/mesa/drivers/dri/nouveau/nv40_tris.c index 6550928c2f..65180ccdfe 100644 --- a/src/mesa/drivers/dri/nouveau/nv40_tris.c +++ b/src/mesa/drivers/dri/nouveau/nv40_tris.c @@ -70,7 +70,7 @@ } while (0) #endif -/* the free room we want before we start a vertex batch */ +/* the free room we want before we start a vertex batch. this is a performance-tunable */ #define NV40_MIN_PRIM_SIZE (32/4) static inline void nv40StartPrimitive(struct nouveau_context* nmesa) @@ -304,7 +304,20 @@ GLuint specoffset = nmesa->specoffset; \ * Helpers for rendering unfilled primitives * ***********************************************************************/ -#define RASTERIZE(x) nv40RasterPrimitive( ctx, x, x ) +static const GLenum hwPrim[GL_POLYGON+1] = { + GL_POINTS, + GL_LINES, + GL_LINES, + GL_LINES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES +}; + +#define RASTERIZE(x) nv40RasterPrimitive( ctx, x, hwPrim[x] ) #define RENDER_PRIMITIVE nmesa->renderPrimitive #define TAG(x) x #define IND NOUVEAU_FALLBACK_BIT @@ -432,7 +445,7 @@ static void init_rast_tab(void) #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) +#define INIT(x) nv40RasterPrimitive(ctx, x, hwPrim[x]) #undef LOCAL_VARS #define LOCAL_VARS \ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); \ @@ -613,7 +626,8 @@ static inline void nv40OutputVertexFormat(struct nouveau_context* mesa, GLuint i for(i=0;i Date: Fri, 3 Mar 2006 16:08:59 +0000 Subject: rename nv40_tris to nv30_tris. --- src/mesa/drivers/dri/nouveau/Makefile | 2 +- src/mesa/drivers/dri/nouveau/nouveau_context.c | 6 +- src/mesa/drivers/dri/nouveau/nv30_tris.c | 754 +++++++++++++++++++++++++ src/mesa/drivers/dri/nouveau/nv30_tris.h | 39 ++ src/mesa/drivers/dri/nouveau/nv40_tris.c | 752 ------------------------ src/mesa/drivers/dri/nouveau/nv40_tris.h | 39 -- 6 files changed, 797 insertions(+), 795 deletions(-) create mode 100644 src/mesa/drivers/dri/nouveau/nv30_tris.c create mode 100644 src/mesa/drivers/dri/nouveau/nv30_tris.h delete mode 100644 src/mesa/drivers/dri/nouveau/nv40_tris.c delete mode 100644 src/mesa/drivers/dri/nouveau/nv40_tris.h (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile index 02632c49cf..3fd237e080 100644 --- a/src/mesa/drivers/dri/nouveau/Makefile +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -16,7 +16,7 @@ DRIVER_SOURCES = \ nouveau_span.c \ nouveau_tex.c \ nouveau_tris.c \ - nv40_tris.c + nv30_tris.c C_SOURCES = \ $(COMMON_SOURCES) \ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 1a8dc6a6c4..e42aecefe8 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -44,7 +44,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. //#include "nouveau_state.h" #include "nouveau_span.h" #include "nouveau_tex.h" -#include "nv40_tris.h" +#include "nv30_tris.h" #include "vblank.h" #include "utils.h" @@ -133,12 +133,12 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, case NV_05: case NV_10: case NV_20: - case NV_30: default: break; + case NV_30: case NV_40: case G_70: - nv40TriInitFunctions( ctx ); + nv30TriInitFunctions( ctx ); break; } nouveauDDInitStateFuncs( ctx ); diff --git a/src/mesa/drivers/dri/nouveau/nv30_tris.c b/src/mesa/drivers/dri/nouveau/nv30_tris.c new file mode 100644 index 0000000000..c9749a741f --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv30_tris.c @@ -0,0 +1,754 @@ +/* + * 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. + */ + +/* Triangles for NV30, NV40, G70 */ + +#include +#include + +#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 "nv30_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. this is a performance-tunable */ +#define NV30_MIN_PRIM_SIZE (32/4) + +static inline void nv30StartPrimitive(struct nouveau_context* nmesa) +{ + BEGIN_RING_SIZE(channel,0x1808,1); + OUT_RING(nmesa->current_primitive); + BEGIN_RING_PRIM(channel,0x1818,NV30_MIN_PRIM_SIZE); +} + +static inline void nv30FinishPrimitive(struct nouveau_context *nmesa) +{ + FINISH_RING_PRIM(); + BEGIN_RING_SIZE(channel,0x1808,1); + OUT_RING(0x0); + FIRE_RING(); +} + + +static inline void nv30ExtendPrimitive(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()vertexSize; + GLuint *vb = nv30ExtendPrimitive(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 nv30_draw_triangle(struct nouveau_context *nmesa, + nouveauVertexPtr v0, + nouveauVertexPtr v1, + nouveauVertexPtr v2) +{ + GLuint vertsize = nmesa->vertexSize; + GLuint *vb = nv30ExtendPrimitive(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 = nv30ExtendPrimitive(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 = nv30ExtendPrimitive(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 * + ***********************************************************************/ + +static const GLenum hwPrim[GL_POLYGON+1] = { + GL_POINTS, + GL_LINES, + GL_LINES, + GL_LINES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES +}; + +#define RASTERIZE(x) nv30RasterPrimitive( ctx, x, hwPrim[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) nv30RasterPrimitive(ctx, x, hwPrim[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 nv30ChooseRenderState(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 nv30OutputVertexFormat(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<render_inputs; + + if (index!=nmesa->render_inputs) + { + nmesa->render_inputs=index; + nv30OutputVertexFormat(nmesa,index); + } +} + + +/**********************************************************************/ +/* High level hooks for t_vb_render.c */ +/**********************************************************************/ + + +static void nv30RenderStart(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) { + nv30ChooseVertexState(ctx); + nv30ChooseRenderState(ctx); + nmesa->newRenderState = 0; + } +} + +static void nv30RenderFinish(GLcontext *ctx) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + nv30FinishPrimitive(nmesa); +} + + +/* System to flush dma and emit state changes based on the rasterized + * primitive. + */ +void nv30RasterPrimitive(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 nv30RenderPrimitive( GLcontext *ctx, GLuint prim ) +{ + nv30RasterPrimitive( ctx, prim, hwPrim[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 = nv30RenderStart; + tnl->Driver.Render.Finish = nv30RenderFinish; + tnl->Driver.Render.PrimitiveNotify = nv30RenderPrimitive; + 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/nv30_tris.h b/src/mesa/drivers/dri/nouveau/nv30_tris.h new file mode 100644 index 0000000000..92f1896539 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv30_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__ */ + diff --git a/src/mesa/drivers/dri/nouveau/nv40_tris.c b/src/mesa/drivers/dri/nouveau/nv40_tris.c deleted file mode 100644 index 65180ccdfe..0000000000 --- a/src/mesa/drivers/dri/nouveau/nv40_tris.c +++ /dev/null @@ -1,752 +0,0 @@ -/* - * 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 -#include - -#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. this is a performance-tunable */ -#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()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 * - ***********************************************************************/ - -static const GLenum hwPrim[GL_POLYGON+1] = { - GL_POINTS, - GL_LINES, - GL_LINES, - GL_LINES, - GL_TRIANGLES, - GL_TRIANGLES, - GL_TRIANGLES, - GL_TRIANGLES, - GL_TRIANGLES, - GL_TRIANGLES -}; - -#define RASTERIZE(x) nv40RasterPrimitive( ctx, x, hwPrim[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, hwPrim[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<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, hwPrim[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 deleted file mode 100644 index 92f1896539..0000000000 --- a/src/mesa/drivers/dri/nouveau/nv40_tris.h +++ /dev/null @@ -1,39 +0,0 @@ -/************************************************************************** - -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__ */ - -- cgit v1.2.3 From 4af665a843f8f3181b306711a14470a3cfe817fc Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Fri, 3 Mar 2006 16:10:28 +0000 Subject: Rename nouveau_3d_reg.h to nouveau_reg.h --- src/mesa/drivers/dri/nouveau/nv30_tris.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv30_tris.c b/src/mesa/drivers/dri/nouveau/nv30_tris.c index c9749a741f..9853b6bce9 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_tris.c +++ b/src/mesa/drivers/dri/nouveau/nv30_tris.c @@ -46,7 +46,7 @@ #include "nouveau_state.h" #include "nouveau_span.h" #include "nouveau_ioctl.h" -#include "nouveau_3d_reg.h" +#include "nouveau_reg.h" #include "nouveau_tex.h" /* hack for now */ -- cgit v1.2.3 From b9c4b7fc896f7ff3188065526b27707ff6e43c77 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Mon, 6 Mar 2006 01:46:24 +0000 Subject: More work on the nv30 software tcl code --- src/mesa/drivers/dri/nouveau/nouveau_context.h | 6 + src/mesa/drivers/dri/nouveau/nv30_tris.c | 318 ++++++++++++++----------- src/mesa/drivers/dri/nouveau/nv30_tris.h | 10 +- 3 files changed, 191 insertions(+), 143 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index d287439fcf..49e22f8074 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -54,6 +54,7 @@ nouveau_fifo; #include "tnl_dd/t_dd_vertex.h" #undef TAG +struct nouveau_context; typedef void (*nouveau_tri_func)( struct nouveau_context*, nouveauVertex *, @@ -81,6 +82,11 @@ typedef struct nouveau_context { /* The read-only regs */ volatile unsigned char* mmio; + /* State for tris */ + GLuint vertex_size; + GLuint color_offset; + GLuint specular_offset; + /* The drawing fallbacks */ nouveau_tri_func* draw_tri; nouveau_line_func* draw_line; diff --git a/src/mesa/drivers/dri/nouveau/nv30_tris.c b/src/mesa/drivers/dri/nouveau/nv30_tris.c index 9853b6bce9..275536c8e4 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_tris.c +++ b/src/mesa/drivers/dri/nouveau/nv30_tris.c @@ -23,7 +23,7 @@ * DEALINGS IN THE SOFTWARE. */ -/* Triangles for NV30, NV40, G70 */ +/* Software TCL for NV30, NV40, G70 */ #include #include @@ -43,15 +43,18 @@ #include "nouveau_tris.h" #include "nv30_tris.h" #include "nouveau_context.h" -#include "nouveau_state.h" #include "nouveau_span.h" #include "nouveau_ioctl.h" #include "nouveau_reg.h" #include "nouveau_tex.h" +#include "nouveau_fifo.h" -/* hack for now */ +/* XXX hack for now */ #define channel 1 +static void nv30RenderPrimitive( GLcontext *ctx, GLenum prim ); +static void nv30RasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim ); + /*********************************************************************** * Emit primitives as inline vertices * @@ -63,15 +66,6 @@ #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. this is a performance-tunable */ #define NV30_MIN_PRIM_SIZE (32/4) @@ -107,89 +101,90 @@ static inline void nv30ExtendPrimitive(struct nouveau_context* nmesa, int size) } } -static inline void nv30_draw_quad(struct nouveau_context *nmesa, +static inline void nv30_draw_quad(nouveauContextPtr nmesa, nouveauVertexPtr v0, nouveauVertexPtr v1, nouveauVertexPtr v2, nouveauVertexPtr v3) { - GLuint vertsize = nmesa->vertexSize; - GLuint *vb = nv30ExtendPrimitive(nmesa, 4 * 4 * vertsize); + GLuint vertsize = nmesa->vertex_size; + nv30ExtendPrimitive(nmesa, 4 * 4 * vertsize); - COPY_DWORDS(vb, vertsize, v0); - COPY_DWORDS(vb, vertsize, v1); - COPY_DWORDS(vb, vertsize, v2); - COPY_DWORDS(vb, vertsize, v3); + OUT_RINGp(v0,vertsize); + OUT_RINGp(v1,vertsize); + OUT_RINGp(v2,vertsize); + OUT_RINGp(v3,vertsize); } -static inline void nv30_draw_triangle(struct nouveau_context *nmesa, +static inline void nv30_draw_triangle(nouveauContextPtr nmesa, nouveauVertexPtr v0, nouveauVertexPtr v1, nouveauVertexPtr v2) { - GLuint vertsize = nmesa->vertexSize; - GLuint *vb = nv30ExtendPrimitive(nmesa, 3 * 4 * vertsize); + GLuint vertsize = nmesa->vertex_size; + nv30ExtendPrimitive(nmesa, 3 * 4 * vertsize); - COPY_DWORDS(vb, vertsize, v0); - COPY_DWORDS(vb, vertsize, v1); - COPY_DWORDS(vb, vertsize, v2); + OUT_RINGp(v0,vertsize); + OUT_RINGp(v1,vertsize); + OUT_RINGp(v2,vertsize); } -static inline void nouveau_draw_line(struct nouveau_context *nmesa, +static inline void nv30_draw_line(nouveauContextPtr nmesa, nouveauVertexPtr v0, nouveauVertexPtr v1) { - GLuint vertsize = nmesa->vertexSize; - GLuint *vb = nv30ExtendPrimitive(nmesa, 2 * 4 * vertsize); - COPY_DWORDS(vb, vertsize, v0); - COPY_DWORDS(vb, vertsize, v1); + GLuint vertsize = nmesa->vertex_size; + nv30ExtendPrimitive(nmesa, 2 * 4 * vertsize); + OUT_RINGp(v0,vertsize); + OUT_RINGp(v1,vertsize); } -static inline void nouveau_draw_point(struct nouveau_context *nmesa, +static inline void nv30_draw_point(nouveauContextPtr nmesa, nouveauVertexPtr v0) { - GLuint vertsize = nmesa->vertexSize; - GLuint *vb = nv30ExtendPrimitive(nmesa, 4 * vertsize); - COPY_DWORDS(vb, vertsize, v0); + GLuint vertsize = nmesa->vertex_size; + nv30ExtendPrimitive(nmesa, 1 * 4 * vertsize); + OUT_RINGp(v0,vertsize); } + /*********************************************************************** * Macros for nouveau_dd_tritmp.h to draw basic primitives * ***********************************************************************/ -#define TRI(a, b, c) \ - do { \ +#define TRI(a, b, c) \ + do { \ if (DO_FALLBACK) \ - nmesa->draw_tri(nmesa, a, b, c); \ + nmesa->draw_tri(nmesa, a, b, c); \ else \ - nouveau_draw_triangle(nmesa, a, b, c); \ + nv30_draw_triangle(nmesa, a, b, c); \ } while (0) -#define QUAD(a, b, c, d) \ - do { \ +#define QUAD(a, b, c, d) \ + do { \ if (DO_FALLBACK) { \ - nmesa->draw_tri(nmesa, a, b, d); \ - nmesa->draw_tri(nmesa, b, c, d); \ + nmesa->draw_tri(nmesa, a, b, d); \ + nmesa->draw_tri(nmesa, b, c, d); \ } \ else \ - nouveau_draw_quad(nmesa, a, b, c, d); \ + nv30_draw_quad(nmesa, a, b, c, d); \ } while (0) -#define LINE(v0, v1) \ - do { \ +#define LINE(v0, v1) \ + do { \ if (DO_FALLBACK) \ - nmesa->draw_line(nmesa, v0, v1); \ + nmesa->draw_line(nmesa, v0, v1); \ else \ - nouveau_draw_line(nmesa, v0, v1); \ + nv30_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); \ +#define POINT(v0) \ + do { \ + if (DO_FALLBACK) \ + nmesa->draw_point(nmesa, v0); \ + else \ + nv30_draw_point(nmesa, v0); \ } while (0) @@ -230,49 +225,39 @@ static struct { #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 DEPTH_SCALE 1.0 #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 GET_VERTEX(e) (nmesa->verts + (e * nmesa->vertex_size * 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]); \ + nouveau_color_t *color = (nouveau_color_t *)&((v)->f[coloroffset]); \ + color->red=(c)[0]; \ + color->green=(c)[1]; \ + color->blue=(c)[2]; \ + color->alpha=(c)[3]; \ } while (0) -#define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset] - -#define VERT_SET_SPEC( v, c ) \ +#define VERT_COPY_RGBA( v0, v1 ) \ do { \ + if (coloroffset) { \ + v0->f[coloroffset][0] = v1->f[coloroffset][0]; \ + v0->f[coloroffset][1] = v1->f[coloroffset][1]; \ + v0->f[coloroffset][2] = v1->f[coloroffset][2]; \ + v0->f[coloroffset][3] = v1->f[coloroffset][3]; \ + } \ + } while (0) + +#define VERT_SET_SPEC( v, c ) \ + do { \ if (specoffset) { \ - nouveau_color_t *color = (nouveau_color_t *)&((v)->ui[specoffset]); \ + nouveau_color_t *color = (nouveau_color_t *)&((v)->f[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]); \ @@ -281,24 +266,24 @@ static struct { #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]; \ + v0->f[specoffset][0] = v1->f[specoffset][0]; \ + v0->f[specoffset][1] = v1->f[specoffset][1]; \ + v0->f[specoffset][2] = v1->f[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 VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->f[coloroffset] +#define VERT_RESTORE_RGBA( idx ) v[idx]->f[coloroffset] = color[idx] +#define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->f[specoffset] +#define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->f[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; \ +#define LOCAL_VARS(n) \ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); \ +GLuint color[n], spec[n]; \ +GLuint coloroffset = nmesa->color_offset; \ +GLuint specoffset = nmesa->specular_offset; \ (void)color; (void)spec; (void)coloroffset; (void)specoffset; @@ -306,20 +291,20 @@ GLuint specoffset = nmesa->specoffset; \ * Helpers for rendering unfilled primitives * ***********************************************************************/ -static const GLenum hwPrim[GL_POLYGON+1] = { - GL_POINTS, - GL_LINES, - GL_LINES, - GL_LINES, - GL_TRIANGLES, - GL_TRIANGLES, - GL_TRIANGLES, - GL_TRIANGLES, - GL_TRIANGLES, - GL_TRIANGLES +static const GLuint hw_prim[GL_POLYGON+1] = { + GL_POINTS+1, + GL_LINES+1, + GL_LINES+1, + GL_LINES+1, + GL_TRIANGLES+1, + GL_TRIANGLES+1, + GL_TRIANGLES+1, + GL_QUADS+1, + GL_QUADS+1, + GL_TRIANGLES+1 }; -#define RASTERIZE(x) nv30RasterPrimitive( ctx, x, hwPrim[x] ) +#define RASTERIZE(x) nv30RasterPrimitive( ctx, x, hw_prim[x] ) #define RENDER_PRIMITIVE nmesa->renderPrimitive #define TAG(x) x #define IND NOUVEAU_FALLBACK_BIT @@ -447,12 +432,12 @@ static void init_rast_tab(void) #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) nv30RasterPrimitive(ctx, x, hwPrim[x]) +#define INIT(x) nv30RasterPrimitive(ctx, x, hw_prim[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 vertsize = nmesa->vertex_size; \ const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ const GLboolean stipple = ctx->Line.StippleFlag; \ (void) elt; (void) stipple; @@ -515,16 +500,16 @@ 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); + GLuint vertsize = nmesa->vertex_size; + nv30ExtendPrimitive(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); + OUT_RINGp(V(elts[i-1]),vertsize); + OUT_RINGp(V(elts[i]),vertsize); + OUT_RINGp(start,vertsize); } } @@ -548,6 +533,13 @@ static void nouveauFastRenderClippedPoly(GLcontext *ctx, const GLuint *elts, _DD_NEW_TRI_STIPPLE | \ _NEW_POLYGONSTIPPLE) +#define EMIT_ATTR( ATTR, STYLE ) \ +do { \ + nmesa->vertex_attrs[nmesa->vertex_attr_count].attrib = (ATTR); \ + nmesa->vertex_attrs[nmesa->vertex_attr_count].format = (STYLE); \ + nmesa->vertex_attr_count++; \ +} while (0) + static void nv30ChooseRenderState(GLcontext *ctx) { @@ -556,9 +548,9 @@ static void nv30ChooseRenderState(GLcontext *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; + nmesa->draw_point = nv30_draw_point; + nmesa->draw_line = nv30_draw_line; + nmesa->draw_tri = nv30_draw_triangle; if (flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) { if (flags & DD_TRI_LIGHT_TWOSIDE) index |= NOUVEAU_TWOSIDE_BIT; @@ -609,34 +601,84 @@ static void nv30ChooseRenderState(GLcontext *ctx) -static inline void nv30OutputVertexFormat(struct nouveau_context* mesa, GLuint index) +static inline void nv30OutputVertexFormat(struct nouveau_context* nmesa, 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... - */ + GLcontext* ctx=nmesa->glCtx; + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + int attr_size[16]; + int default_attr_size[8]={3,3,3,4,3,1,4,4}; int i; int slots=0; + int total_size=0; + + /* + * Determine attribute sizes + */ + for(i=0;i<8;i++) + { + if (index&(1<TexCoordPtr[i]; + else + attr_size[i]=0; + } + + /* + * Tell t_vertex about the vertex format + */ for(i=0;i<16;i++) + { if (index&(1<color_offset=total_size; + if (i==_TNL_ATTRIB_COLOR1) + nmesa->specular_offset=total_size; + total_size+=attr_size[i]; + } + } + nmesa->vertex_size=total_size; + /* + * Tell the hardware about the vertex format + */ BEGIN_RING_SIZE(channel,0x1740,slots); for(i=0;inewState); - + if (hwprim != nmesa->current_primitive) { nmesa->current_primitive=hwprim; @@ -715,7 +757,7 @@ void nv30RasterPrimitive(GLcontext *ctx, */ static void nv30RenderPrimitive( GLcontext *ctx, GLuint prim ) { - nv30RasterPrimitive( ctx, prim, hwPrim[prim] ); + nv30RasterPrimitive( ctx, prim, hw_prim[prim] ); } diff --git a/src/mesa/drivers/dri/nouveau/nv30_tris.h b/src/mesa/drivers/dri/nouveau/nv30_tris.h index 92f1896539..680b578787 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_tris.h +++ b/src/mesa/drivers/dri/nouveau/nv30_tris.h @@ -26,14 +26,14 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. -#ifndef __NV40_TRIS_H__ -#define __NV40_TRIS_H__ +#ifndef __NV30_TRIS_H__ +#define __NV30_TRIS_H__ #include "mtypes.h" -extern void nv40TriInitFunctions( GLcontext *ctx ); -extern void nv40Fallback( GLcontext *ctx, GLuint bit, GLboolean mode ); +extern void nv30TriInitFunctions( GLcontext *ctx ); +extern void nv30Fallback( GLcontext *ctx, GLuint bit, GLboolean mode ); #define FALLBACK( nmesa, bit, mode ) nouveauFallback( nmesa->glCtx, bit, mode ) -#endif /* __NV40_TRIS_H__ */ +#endif /* __NV30_TRIS_H__ */ -- cgit v1.2.3 From 98e1b13802fb83b504353c14df1d90646eabe111 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Mon, 6 Mar 2006 12:23:24 +0000 Subject: Added some NV20 support - nv_30_tris.c should probably be renamed again. --- src/mesa/drivers/dri/nouveau/nv30_tris.c | 40 ++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 10 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv30_tris.c b/src/mesa/drivers/dri/nouveau/nv30_tris.c index 275536c8e4..6b949bd3b7 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_tris.c +++ b/src/mesa/drivers/dri/nouveau/nv30_tris.c @@ -673,18 +673,38 @@ static inline void nv30OutputVertexFormat(struct nouveau_context* nmesa, GLuint /* * Tell the hardware about the vertex format */ - BEGIN_RING_SIZE(channel,0x1740,slots); - for(i=0;iscreen->card_type) { - int size=attr_size[i]; - OUT_RING(0x00000002|(size*0x10)); + case NV_20: + { + for(i=0;i<16;i++) + { + int size=attr_size[i]; + BEGIN_RING_SIZE(channel,0x1760+i*4,1); + OUT_RING(0x00000002|(size*0x10)); + } + } + break; + case NV_30: + case NV_40: + case G_70: + { + BEGIN_RING_SIZE(channel,0x1740,slots); + for(i=0;i Date: Mon, 6 Mar 2006 15:32:31 +0000 Subject: Cleaned up the software TCL code a bit. Renamed nv30_tris.[c,h] to nv20_swtcl.[c,h]. --- src/mesa/drivers/dri/nouveau/Makefile | 2 +- src/mesa/drivers/dri/nouveau/nouveau_reg.h | 13 +- src/mesa/drivers/dri/nouveau/nv20_swtcl.c | 813 ++++++++++++++++++++++++++++ src/mesa/drivers/dri/nouveau/nv20_swtcl.h | 39 ++ src/mesa/drivers/dri/nouveau/nv30_tris.c | 816 ----------------------------- src/mesa/drivers/dri/nouveau/nv30_tris.h | 39 -- 6 files changed, 865 insertions(+), 857 deletions(-) create mode 100644 src/mesa/drivers/dri/nouveau/nv20_swtcl.c create mode 100644 src/mesa/drivers/dri/nouveau/nv20_swtcl.h delete mode 100644 src/mesa/drivers/dri/nouveau/nv30_tris.c delete mode 100644 src/mesa/drivers/dri/nouveau/nv30_tris.h (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile index 3fd237e080..3e40240e76 100644 --- a/src/mesa/drivers/dri/nouveau/Makefile +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -16,7 +16,7 @@ DRIVER_SOURCES = \ nouveau_span.c \ nouveau_tex.c \ nouveau_tris.c \ - nv30_tris.c + nv20_swtcl.c C_SOURCES = \ $(COMMON_SOURCES) \ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_reg.h b/src/mesa/drivers/dri/nouveau/nouveau_reg.h index 8b936a5cec..4f35283040 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_reg.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_reg.h @@ -1,6 +1,6 @@ /************************************************************************** -Copyright 2006 Stephane Marchesin +Copyright 2006 Stephane Marchesin, Sylvain Munaut All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a @@ -58,3 +58,14 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV03_FIFO_CMD_JUMP_OFFSET_MASK 0x1ffffffc #define NV03_FIFO_CMD_REWIND (NV03_FIFO_CMD_JUMP | (0 & NV03_FIFO_CMD_JUMP_OFFSET_MASK)) +/* Rendering commands */ +#define NV20_PRIMITIVE 0x000017fc +#define NV30_PRIMITIVE 0x00001808 +#define NV20_BEGIN_VERTICES 0x00001818 + +/* Vertex attributes */ +#define NV20_VERTEX_ATTRIBUTE(i) (0x00001760+i*4) +#define NV30_VERTEX_ATTRIBUTES 0x00001740 +#define NV30_UNKNOWN_0 0x00001718 + + diff --git a/src/mesa/drivers/dri/nouveau/nv20_swtcl.c b/src/mesa/drivers/dri/nouveau/nv20_swtcl.c new file mode 100644 index 0000000000..9f1327ba83 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_swtcl.c @@ -0,0 +1,813 @@ +/* + * 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. + */ + +/* Software TCL for NV20, NV30, NV40, G70 */ + +#include +#include + +#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 "nv20_swtcl.h" +#include "nouveau_context.h" +#include "nouveau_span.h" +#include "nouveau_ioctl.h" +#include "nouveau_reg.h" +#include "nouveau_tex.h" +#include "nouveau_fifo.h" + +/* XXX hack for now */ +#define channel 1 + +static void nv20RenderPrimitive( GLcontext *ctx, GLenum prim ); +static void nv20RasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim ); + + +/*********************************************************************** + * 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) + + +/* the free room we want before we start a vertex batch. this is a performance-tunable */ +#define NV20_MIN_PRIM_SIZE (32/4) +/* the size above which we fire the ring. this is a performance-tunable */ +#define NV20_FIRE_SIZE (2048/4) + +static inline void nv20StartPrimitive(struct nouveau_context* nmesa) +{ + if (nmesa->screen->card_type==NV20) + BEGIN_RING_SIZE(channel,NV20_PRIMITIVE,1); + else + BEGIN_RING_SIZE(channel,NV30_PRIMITIVE,1); + OUT_RING(nmesa->current_primitive); + BEGIN_RING_PRIM(channel,NV20_BEGIN_VERTICES,NV20_MIN_PRIM_SIZE); +} + +static inline void nv20FinishPrimitive(struct nouveau_context *nmesa) +{ + FINISH_RING_PRIM(); + if (nmesa->screen->card_type==NV20) + BEGIN_RING_SIZE(channel,NV20_PRIMITIVE,1); + else + BEGIN_RING_SIZE(channel,NV30_PRIMITIVE,1); + OUT_RING(0x0); + FIRE_RING(); +} + + +static inline void nv20ExtendPrimitive(struct nouveau_context* nmesa, int size) +{ + /* when the fifo has enough stuff (2048 bytes) or there is not enough room, fire */ + if ((RING_AHEAD()>=NV20_FIRE_SIZE)||(RING_AVAILABLE()vertex_size; + nv20ExtendPrimitive(nmesa, 4 * 4 * vertsize); + + OUT_RINGp(v0,vertsize); + OUT_RINGp(v1,vertsize); + OUT_RINGp(v2,vertsize); + OUT_RINGp(v3,vertsize); +} + +static inline void nv20_draw_triangle(nouveauContextPtr nmesa, + nouveauVertexPtr v0, + nouveauVertexPtr v1, + nouveauVertexPtr v2) +{ + GLuint vertsize = nmesa->vertex_size; + nv20ExtendPrimitive(nmesa, 3 * 4 * vertsize); + + OUT_RINGp(v0,vertsize); + OUT_RINGp(v1,vertsize); + OUT_RINGp(v2,vertsize); +} + +static inline void nv20_draw_line(nouveauContextPtr nmesa, + nouveauVertexPtr v0, + nouveauVertexPtr v1) +{ + GLuint vertsize = nmesa->vertex_size; + nv20ExtendPrimitive(nmesa, 2 * 4 * vertsize); + OUT_RINGp(v0,vertsize); + OUT_RINGp(v1,vertsize); +} + +static inline void nv20_draw_point(nouveauContextPtr nmesa, + nouveauVertexPtr v0) +{ + GLuint vertsize = nmesa->vertex_size; + nv20ExtendPrimitive(nmesa, 1 * 4 * vertsize); + OUT_RINGp(v0,vertsize); +} + + + +/*********************************************************************** + * 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 \ + nv20_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 \ + nv20_draw_quad(nmesa, a, b, c, d); \ + } while (0) + +#define LINE(v0, v1) \ + do { \ + if (DO_FALLBACK) \ + nmesa->draw_line(nmesa, v0, v1); \ + else \ + nv20_draw_line(nmesa, v0, v1); \ + } while (0) + +#define POINT(v0) \ + do { \ + if (DO_FALLBACK) \ + nmesa->draw_point(nmesa, v0); \ + else \ + nv20_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 + + +#define DEPTH_SCALE 1.0 +#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->vertex_size * sizeof(int))) + +#define VERT_SET_RGBA( v, c ) \ + do { \ + nouveau_color_t *color = (nouveau_color_t *)&((v)->f[coloroffset]); \ + color->red=(c)[0]; \ + color->green=(c)[1]; \ + color->blue=(c)[2]; \ + color->alpha=(c)[3]; \ + } while (0) + +#define VERT_COPY_RGBA( v0, v1 ) \ + do { \ + if (coloroffset) { \ + v0->f[coloroffset][0] = v1->f[coloroffset][0]; \ + v0->f[coloroffset][1] = v1->f[coloroffset][1]; \ + v0->f[coloroffset][2] = v1->f[coloroffset][2]; \ + v0->f[coloroffset][3] = v1->f[coloroffset][3]; \ + } \ + } while (0) + +#define VERT_SET_SPEC( v, c ) \ + do { \ + if (specoffset) { \ + nouveau_color_t *color = (nouveau_color_t *)&((v)->f[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->f[specoffset][0] = v1->f[specoffset][0]; \ + v0->f[specoffset][1] = v1->f[specoffset][1]; \ + v0->f[specoffset][2] = v1->f[specoffset][2]; \ + } \ + } while (0) + + +#define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->f[coloroffset] +#define VERT_RESTORE_RGBA( idx ) v[idx]->f[coloroffset] = color[idx] +#define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->f[specoffset] +#define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->f[specoffset] = spec[idx] + + +#define LOCAL_VARS(n) \ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); \ +GLuint color[n], spec[n]; \ +GLuint coloroffset = nmesa->color_offset; \ +GLuint specoffset = nmesa->specular_offset; \ +(void)color; (void)spec; (void)coloroffset; (void)specoffset; + + +/*********************************************************************** + * Helpers for rendering unfilled primitives * + ***********************************************************************/ + +static const GLuint hw_prim[GL_POLYGON+1] = { + GL_POINTS+1, + GL_LINES+1, + GL_LINES+1, + GL_LINES+1, + GL_TRIANGLES+1, + GL_TRIANGLES+1, + GL_TRIANGLES+1, + GL_QUADS+1, + GL_QUADS+1, + GL_TRIANGLES+1 +}; + +#define RASTERIZE(x) nv20RasterPrimitive( ctx, x, hw_prim[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) nv20RasterPrimitive(ctx, x, hw_prim[x]) +#undef LOCAL_VARS +#define LOCAL_VARS \ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); \ +GLubyte *vertptr = (GLubyte *)nmesa->verts; \ +const GLuint vertsize = nmesa->vertex_size; \ +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->vertex_size; + nv20ExtendPrimitive(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++) { + OUT_RINGp(V(elts[i-1]),vertsize); + OUT_RINGp(V(elts[i]),vertsize); + OUT_RINGp(start,vertsize); + } +} + +/**********************************************************************/ +/* 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) + +#define EMIT_ATTR( ATTR, STYLE ) \ +do { \ + nmesa->vertex_attrs[nmesa->vertex_attr_count].attrib = (ATTR); \ + nmesa->vertex_attrs[nmesa->vertex_attr_count].format = (STYLE); \ + nmesa->vertex_attr_count++; \ +} while (0) + + +static void nv20ChooseRenderState(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLuint flags = ctx->_TriangleCaps; + GLuint index = 0; + + nmesa->draw_point = nv20_draw_point; + nmesa->draw_line = nv20_draw_line; + nmesa->draw_tri = nv20_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 nv20OutputVertexFormat(struct nouveau_context* nmesa, GLuint index) +{ + GLcontext* ctx=nmesa->glCtx; + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + int attr_size[16]; + int default_attr_size[8]={3,3,3,4,3,1,4,4}; + int i; + int slots=0; + int total_size=0; + + /* + * Determine attribute sizes + */ + for(i=0;i<8;i++) + { + if (index&(1<TexCoordPtr[i]; + else + attr_size[i]=0; + } + + /* + * Tell t_vertex about the vertex format + */ + for(i=0;i<16;i++) + { + if (index&(1<color_offset=total_size; + if (i==_TNL_ATTRIB_COLOR1) + nmesa->specular_offset=total_size; + total_size+=attr_size[i]; + } + } + nmesa->vertex_size=total_size; + + /* + * Tell the hardware about the vertex format + */ + if (nmesa->screen->card_type==NV_20) { + for(i=0;i<16;i++) + { + int size=attr_size[i]; + BEGIN_RING_SIZE(channel,NV20_VERTEX_ATTRIBUTE(i),1); + OUT_RING(0x00000002|(size*0x10)); + } + } else { + BEGIN_RING_SIZE(channel,NV30_VERTEX_ATTRIBUTES,slots); + for(i=0;irender_inputs; + + if (index!=nmesa->render_inputs) + { + nmesa->render_inputs=index; + nv20OutputVertexFormat(nmesa,index); + } +} + + +/**********************************************************************/ +/* High level hooks for t_vb_render.c */ +/**********************************************************************/ + + +static void nv20RenderStart(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) { + nv20ChooseVertexState(ctx); + nv20ChooseRenderState(ctx); + nmesa->newRenderState = 0; + } +} + +static void nv20RenderFinish(GLcontext *ctx) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + nv20FinishPrimitive(nmesa); +} + + +/* System to flush dma and emit state changes based on the rasterized + * primitive. + */ +void nv20RasterPrimitive(GLcontext *ctx, + GLenum glprim, + GLuint 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 nv20RenderPrimitive( GLcontext *ctx, GLuint prim ) +{ + nv20RasterPrimitive( ctx, prim, hw_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 = nv20RenderStart; + tnl->Driver.Render.Finish = nv20RenderFinish; + tnl->Driver.Render.PrimitiveNotify = nv20RenderPrimitive; + 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/nv20_swtcl.h b/src/mesa/drivers/dri/nouveau/nv20_swtcl.h new file mode 100644 index 0000000000..ed589d8bcf --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_swtcl.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 __NV20_SWTCL_H__ +#define __NV20_SWTCL_H__ + +#include "mtypes.h" + +extern void nv20TriInitFunctions( GLcontext *ctx ); +extern void nv20Fallback( GLcontext *ctx, GLuint bit, GLboolean mode ); +#define FALLBACK( nmesa, bit, mode ) nouveauFallback( nmesa->glCtx, bit, mode ) + +#endif /* __NV20_SWTCL_H__ */ + diff --git a/src/mesa/drivers/dri/nouveau/nv30_tris.c b/src/mesa/drivers/dri/nouveau/nv30_tris.c deleted file mode 100644 index 6b949bd3b7..0000000000 --- a/src/mesa/drivers/dri/nouveau/nv30_tris.c +++ /dev/null @@ -1,816 +0,0 @@ -/* - * 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. - */ - -/* Software TCL for NV30, NV40, G70 */ - -#include -#include - -#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 "nv30_tris.h" -#include "nouveau_context.h" -#include "nouveau_span.h" -#include "nouveau_ioctl.h" -#include "nouveau_reg.h" -#include "nouveau_tex.h" -#include "nouveau_fifo.h" - -/* XXX hack for now */ -#define channel 1 - -static void nv30RenderPrimitive( GLcontext *ctx, GLenum prim ); -static void nv30RasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim ); - - -/*********************************************************************** - * 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) - - -/* the free room we want before we start a vertex batch. this is a performance-tunable */ -#define NV30_MIN_PRIM_SIZE (32/4) - -static inline void nv30StartPrimitive(struct nouveau_context* nmesa) -{ - BEGIN_RING_SIZE(channel,0x1808,1); - OUT_RING(nmesa->current_primitive); - BEGIN_RING_PRIM(channel,0x1818,NV30_MIN_PRIM_SIZE); -} - -static inline void nv30FinishPrimitive(struct nouveau_context *nmesa) -{ - FINISH_RING_PRIM(); - BEGIN_RING_SIZE(channel,0x1808,1); - OUT_RING(0x0); - FIRE_RING(); -} - - -static inline void nv30ExtendPrimitive(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()vertex_size; - nv30ExtendPrimitive(nmesa, 4 * 4 * vertsize); - - OUT_RINGp(v0,vertsize); - OUT_RINGp(v1,vertsize); - OUT_RINGp(v2,vertsize); - OUT_RINGp(v3,vertsize); -} - -static inline void nv30_draw_triangle(nouveauContextPtr nmesa, - nouveauVertexPtr v0, - nouveauVertexPtr v1, - nouveauVertexPtr v2) -{ - GLuint vertsize = nmesa->vertex_size; - nv30ExtendPrimitive(nmesa, 3 * 4 * vertsize); - - OUT_RINGp(v0,vertsize); - OUT_RINGp(v1,vertsize); - OUT_RINGp(v2,vertsize); -} - -static inline void nv30_draw_line(nouveauContextPtr nmesa, - nouveauVertexPtr v0, - nouveauVertexPtr v1) -{ - GLuint vertsize = nmesa->vertex_size; - nv30ExtendPrimitive(nmesa, 2 * 4 * vertsize); - OUT_RINGp(v0,vertsize); - OUT_RINGp(v1,vertsize); -} - -static inline void nv30_draw_point(nouveauContextPtr nmesa, - nouveauVertexPtr v0) -{ - GLuint vertsize = nmesa->vertex_size; - nv30ExtendPrimitive(nmesa, 1 * 4 * vertsize); - OUT_RINGp(v0,vertsize); -} - - - -/*********************************************************************** - * 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 \ - nv30_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 \ - nv30_draw_quad(nmesa, a, b, c, d); \ - } while (0) - -#define LINE(v0, v1) \ - do { \ - if (DO_FALLBACK) \ - nmesa->draw_line(nmesa, v0, v1); \ - else \ - nv30_draw_line(nmesa, v0, v1); \ - } while (0) - -#define POINT(v0) \ - do { \ - if (DO_FALLBACK) \ - nmesa->draw_point(nmesa, v0); \ - else \ - nv30_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 - - -#define DEPTH_SCALE 1.0 -#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->vertex_size * sizeof(int))) - -#define VERT_SET_RGBA( v, c ) \ - do { \ - nouveau_color_t *color = (nouveau_color_t *)&((v)->f[coloroffset]); \ - color->red=(c)[0]; \ - color->green=(c)[1]; \ - color->blue=(c)[2]; \ - color->alpha=(c)[3]; \ - } while (0) - -#define VERT_COPY_RGBA( v0, v1 ) \ - do { \ - if (coloroffset) { \ - v0->f[coloroffset][0] = v1->f[coloroffset][0]; \ - v0->f[coloroffset][1] = v1->f[coloroffset][1]; \ - v0->f[coloroffset][2] = v1->f[coloroffset][2]; \ - v0->f[coloroffset][3] = v1->f[coloroffset][3]; \ - } \ - } while (0) - -#define VERT_SET_SPEC( v, c ) \ - do { \ - if (specoffset) { \ - nouveau_color_t *color = (nouveau_color_t *)&((v)->f[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->f[specoffset][0] = v1->f[specoffset][0]; \ - v0->f[specoffset][1] = v1->f[specoffset][1]; \ - v0->f[specoffset][2] = v1->f[specoffset][2]; \ - } \ - } while (0) - - -#define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->f[coloroffset] -#define VERT_RESTORE_RGBA( idx ) v[idx]->f[coloroffset] = color[idx] -#define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->f[specoffset] -#define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->f[specoffset] = spec[idx] - - -#define LOCAL_VARS(n) \ - struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); \ -GLuint color[n], spec[n]; \ -GLuint coloroffset = nmesa->color_offset; \ -GLuint specoffset = nmesa->specular_offset; \ -(void)color; (void)spec; (void)coloroffset; (void)specoffset; - - -/*********************************************************************** - * Helpers for rendering unfilled primitives * - ***********************************************************************/ - -static const GLuint hw_prim[GL_POLYGON+1] = { - GL_POINTS+1, - GL_LINES+1, - GL_LINES+1, - GL_LINES+1, - GL_TRIANGLES+1, - GL_TRIANGLES+1, - GL_TRIANGLES+1, - GL_QUADS+1, - GL_QUADS+1, - GL_TRIANGLES+1 -}; - -#define RASTERIZE(x) nv30RasterPrimitive( ctx, x, hw_prim[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) nv30RasterPrimitive(ctx, x, hw_prim[x]) -#undef LOCAL_VARS -#define LOCAL_VARS \ - struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); \ -GLubyte *vertptr = (GLubyte *)nmesa->verts; \ -const GLuint vertsize = nmesa->vertex_size; \ -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->vertex_size; - nv30ExtendPrimitive(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++) { - OUT_RINGp(V(elts[i-1]),vertsize); - OUT_RINGp(V(elts[i]),vertsize); - OUT_RINGp(start,vertsize); - } -} - -/**********************************************************************/ -/* 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) - -#define EMIT_ATTR( ATTR, STYLE ) \ -do { \ - nmesa->vertex_attrs[nmesa->vertex_attr_count].attrib = (ATTR); \ - nmesa->vertex_attrs[nmesa->vertex_attr_count].format = (STYLE); \ - nmesa->vertex_attr_count++; \ -} while (0) - - -static void nv30ChooseRenderState(GLcontext *ctx) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - GLuint flags = ctx->_TriangleCaps; - GLuint index = 0; - - nmesa->draw_point = nv30_draw_point; - nmesa->draw_line = nv30_draw_line; - nmesa->draw_tri = nv30_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 nv30OutputVertexFormat(struct nouveau_context* nmesa, GLuint index) -{ - GLcontext* ctx=nmesa->glCtx; - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - int attr_size[16]; - int default_attr_size[8]={3,3,3,4,3,1,4,4}; - int i; - int slots=0; - int total_size=0; - - /* - * Determine attribute sizes - */ - for(i=0;i<8;i++) - { - if (index&(1<TexCoordPtr[i]; - else - attr_size[i]=0; - } - - /* - * Tell t_vertex about the vertex format - */ - for(i=0;i<16;i++) - { - if (index&(1<color_offset=total_size; - if (i==_TNL_ATTRIB_COLOR1) - nmesa->specular_offset=total_size; - total_size+=attr_size[i]; - } - } - nmesa->vertex_size=total_size; - - /* - * Tell the hardware about the vertex format - */ - switch(nmesa->screen->card_type) - { - case NV_20: - { - for(i=0;i<16;i++) - { - int size=attr_size[i]; - BEGIN_RING_SIZE(channel,0x1760+i*4,1); - OUT_RING(0x00000002|(size*0x10)); - } - } - break; - case NV_30: - case NV_40: - case G_70: - { - BEGIN_RING_SIZE(channel,0x1740,slots); - for(i=0;irender_inputs; - - if (index!=nmesa->render_inputs) - { - nmesa->render_inputs=index; - nv30OutputVertexFormat(nmesa,index); - } -} - - -/**********************************************************************/ -/* High level hooks for t_vb_render.c */ -/**********************************************************************/ - - -static void nv30RenderStart(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) { - nv30ChooseVertexState(ctx); - nv30ChooseRenderState(ctx); - nmesa->newRenderState = 0; - } -} - -static void nv30RenderFinish(GLcontext *ctx) -{ - struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - nv30FinishPrimitive(nmesa); -} - - -/* System to flush dma and emit state changes based on the rasterized - * primitive. - */ -void nv30RasterPrimitive(GLcontext *ctx, - GLenum glprim, - GLuint 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 nv30RenderPrimitive( GLcontext *ctx, GLuint prim ) -{ - nv30RasterPrimitive( ctx, prim, hw_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 = nv30RenderStart; - tnl->Driver.Render.Finish = nv30RenderFinish; - tnl->Driver.Render.PrimitiveNotify = nv30RenderPrimitive; - 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/nv30_tris.h b/src/mesa/drivers/dri/nouveau/nv30_tris.h deleted file mode 100644 index 680b578787..0000000000 --- a/src/mesa/drivers/dri/nouveau/nv30_tris.h +++ /dev/null @@ -1,39 +0,0 @@ -/************************************************************************** - -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 __NV30_TRIS_H__ -#define __NV30_TRIS_H__ - -#include "mtypes.h" - -extern void nv30TriInitFunctions( GLcontext *ctx ); -extern void nv30Fallback( GLcontext *ctx, GLuint bit, GLboolean mode ); -#define FALLBACK( nmesa, bit, mode ) nouveauFallback( nmesa->glCtx, bit, mode ) - -#endif /* __NV30_TRIS_H__ */ - -- cgit v1.2.3 From 2560e65a9aa0479ebb564a2ac5161a1c47507ce0 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Tue, 7 Mar 2006 00:56:30 +0000 Subject: Added a missing field --- src/mesa/drivers/dri/nouveau/nouveau_context.c | 6 +++--- src/mesa/drivers/dri/nouveau/nouveau_screen.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index e42aecefe8..3558b25857 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -44,7 +44,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. //#include "nouveau_state.h" #include "nouveau_span.h" #include "nouveau_tex.h" -#include "nv30_tris.h" +#include "nv20_swtcl.h" #include "vblank.h" #include "utils.h" @@ -132,13 +132,13 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, case NV_04: case NV_05: case NV_10: - case NV_20: default: break; + case NV_20: case NV_30: case NV_40: case G_70: - nv30TriInitFunctions( ctx ); + nv20TriInitFunctions( ctx ); break; } nouveauDDInitStateFuncs( ctx ); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.h b/src/mesa/drivers/dri/nouveau/nouveau_screen.h index b8e8bfc22a..997b05fecd 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.h @@ -45,6 +45,7 @@ typedef struct { GLuint spanOffset; __DRIscreenPrivate *driScreen; + unsigned int sarea_priv_offset; /* Configuration cache with default values for all contexts */ driOptionCache optionCache; -- cgit v1.2.3 From 9ebde216cc3e7a9dbe8090abe976db38f63d4717 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Fri, 10 Mar 2006 01:43:39 +0000 Subject: A little work here and there --- src/mesa/drivers/dri/nouveau/nouveau_fifo.c | 9 +++++---- src/mesa/drivers/dri/nouveau/nouveau_reg.h | 14 ++++++++++---- src/mesa/drivers/dri/nouveau/nv20_swtcl.c | 30 +++++++++++++++++++---------- 3 files changed, 35 insertions(+), 18 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c index a330d5268b..cc77b577ca 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c @@ -26,6 +26,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_fifo.h" +#include "nouveau_lock.h" #include "vblank.h" #define RING_SKIPS 8 @@ -46,7 +47,7 @@ void WAIT_RING(nouveauContextPtr nmesa,u_int32_t size) 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); + NV_FIFO_WRITE(NV03_FIFO_REGS_DMAPUT, RING_SKIPS); nmesa->fifo.current = nmesa->fifo.put = RING_SKIPS; nmesa->fifo.free = fifo_get - (RING_SKIPS + 1); } @@ -59,7 +60,7 @@ void WAIT_RING(nouveauContextPtr nmesa,u_int32_t size) * Wait for the card to be idle * XXX we should also wait for an empty fifo */ -void nouveauWaitForIdleLocked(nouveauContextPtr *nmesa) +void nouveauWaitForIdleLocked(nouveauContextPtr nmesa) { int i,status; @@ -82,12 +83,12 @@ void nouveauWaitForIdleLocked(nouveauContextPtr *nmesa) break; } if (status) - return 0; + return; DO_USLEEP(1); } } -void nouveauWaitForIdle(nouveauContextPtr *nmesa) +void nouveauWaitForIdle(nouveauContextPtr nmesa) { LOCK_HARDWARE(nmesa); nouveauWaitForIdleLocked(nmesa); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_reg.h b/src/mesa/drivers/dri/nouveau/nouveau_reg.h index 4f35283040..5f4b0624ad 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_reg.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_reg.h @@ -58,14 +58,20 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV03_FIFO_CMD_JUMP_OFFSET_MASK 0x1ffffffc #define NV03_FIFO_CMD_REWIND (NV03_FIFO_CMD_JUMP | (0 & NV03_FIFO_CMD_JUMP_OFFSET_MASK)) +/* Vertex attributes */ +#define NV30_UNKNOWN_0 0x00001718 +#define NV30_VERTEX_ATTRIBUTES 0x00001740 +#define NV20_VERTEX_ATTRIBUTE(i) (0x00001760+i*4) +#define NV20_VERTEX_ATTRIBUTE_TYPE_MASK 0x0000000f +#define NV20_VERTEX_ATTRIBUTE_TYPE_FLOAT 0x00000002 +#define NV20_VERTEX_ATTRIBUTE_SIZE_MASK 0x000000f0 + /* Rendering commands */ +#define NV10_PRIMITIVE 0x00000dfc #define NV20_PRIMITIVE 0x000017fc #define NV30_PRIMITIVE 0x00001808 +#define NV10_BEGIN_VERTICES 0x00001800 #define NV20_BEGIN_VERTICES 0x00001818 -/* Vertex attributes */ -#define NV20_VERTEX_ATTRIBUTE(i) (0x00001760+i*4) -#define NV30_VERTEX_ATTRIBUTES 0x00001740 -#define NV30_UNKNOWN_0 0x00001718 diff --git a/src/mesa/drivers/dri/nouveau/nv20_swtcl.c b/src/mesa/drivers/dri/nouveau/nv20_swtcl.c index 9f1327ba83..c493516e2a 100644 --- a/src/mesa/drivers/dri/nouveau/nv20_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv20_swtcl.c @@ -23,7 +23,7 @@ * DEALINGS IN THE SOFTWARE. */ -/* Software TCL for NV20, NV30, NV40, G70 */ +/* Software TCL for NV10, NV20, NV30, NV40, G70 */ #include #include @@ -67,24 +67,32 @@ static void nv20RasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim ); /* the free room we want before we start a vertex batch. this is a performance-tunable */ -#define NV20_MIN_PRIM_SIZE (32/4) +#define NOUVEAU_MIN_PRIM_SIZE (32/4) /* the size above which we fire the ring. this is a performance-tunable */ -#define NV20_FIRE_SIZE (2048/4) +#define NOUVEAU_FIRE_SIZE (2048/4) static inline void nv20StartPrimitive(struct nouveau_context* nmesa) { - if (nmesa->screen->card_type==NV20) + if (nmesa->screen->card_type==NV_10) + BEGIN_RING_SIZE(channel,NV10_PRIMITIVE,1); + else if (nmesa->screen->card_type==NV_20) BEGIN_RING_SIZE(channel,NV20_PRIMITIVE,1); else BEGIN_RING_SIZE(channel,NV30_PRIMITIVE,1); OUT_RING(nmesa->current_primitive); - BEGIN_RING_PRIM(channel,NV20_BEGIN_VERTICES,NV20_MIN_PRIM_SIZE); + + if (nmesa->screen->card_type==NV_10) + BEGIN_RING_PRIM(channel,NV10_BEGIN_VERTICES,NOUVEAU_MIN_PRIM_SIZE); + else + BEGIN_RING_PRIM(channel,NV20_BEGIN_VERTICES,NOUVEAU_MIN_PRIM_SIZE); } static inline void nv20FinishPrimitive(struct nouveau_context *nmesa) { FINISH_RING_PRIM(); - if (nmesa->screen->card_type==NV20) + if (nmesa->screen->card_type==NV_10) + BEGIN_RING_SIZE(channel,NV10_PRIMITIVE,1); + else if (nmesa->screen->card_type==NV_20) BEGIN_RING_SIZE(channel,NV20_PRIMITIVE,1); else BEGIN_RING_SIZE(channel,NV30_PRIMITIVE,1); @@ -96,7 +104,7 @@ static inline void nv20FinishPrimitive(struct nouveau_context *nmesa) static inline void nv20ExtendPrimitive(struct nouveau_context* nmesa, int size) { /* when the fifo has enough stuff (2048 bytes) or there is not enough room, fire */ - if ((RING_AHEAD()>=NV20_FIRE_SIZE)||(RING_AVAILABLE()=NOUVEAU_FIRE_SIZE)||(RING_AVAILABLE()screen->card_type==NV_20) { + if (nmesa->screen->card_type==NV_10) { + // XXX needs some love + } else if (nmesa->screen->card_type==NV_20) { for(i=0;i<16;i++) { int size=attr_size[i]; BEGIN_RING_SIZE(channel,NV20_VERTEX_ATTRIBUTE(i),1); - OUT_RING(0x00000002|(size*0x10)); + OUT_RING(NV20_VERTEX_ATTRIBUTE_TYPE_FLOAT|(size*0x10)); } } else { BEGIN_RING_SIZE(channel,NV30_VERTEX_ATTRIBUTES,slots); for(i=0;i Date: Mon, 13 Mar 2006 11:30:41 +0000 Subject: Cleaned up some code, made more files compile. Renamed nv20_swtcl.* to nv10_swtcl.*, hopefully this is the last rename (this should be, as NV05 really behaves differently). --- src/mesa/drivers/dri/nouveau/Makefile | 2 +- src/mesa/drivers/dri/nouveau/nouveau_context.c | 6 +- src/mesa/drivers/dri/nouveau/nouveau_driver.c | 6 +- src/mesa/drivers/dri/nouveau/nouveau_fifo.h | 1 + src/mesa/drivers/dri/nouveau/nouveau_ioctl.c | 7 +- src/mesa/drivers/dri/nouveau/nouveau_ioctl.h | 3 +- src/mesa/drivers/dri/nouveau/nouveau_tris.c | 1 - src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 822 ++++++++++++++++++++++++ src/mesa/drivers/dri/nouveau/nv10_swtcl.h | 39 ++ src/mesa/drivers/dri/nouveau/nv20_swtcl.c | 823 ------------------------- src/mesa/drivers/dri/nouveau/nv20_swtcl.h | 39 -- 11 files changed, 878 insertions(+), 871 deletions(-) create mode 100644 src/mesa/drivers/dri/nouveau/nv10_swtcl.c create mode 100644 src/mesa/drivers/dri/nouveau/nv10_swtcl.h delete mode 100644 src/mesa/drivers/dri/nouveau/nv20_swtcl.c delete mode 100644 src/mesa/drivers/dri/nouveau/nv20_swtcl.h (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile index 3e40240e76..25c298132c 100644 --- a/src/mesa/drivers/dri/nouveau/Makefile +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -16,7 +16,7 @@ DRIVER_SOURCES = \ nouveau_span.c \ nouveau_tex.c \ nouveau_tris.c \ - nv20_swtcl.c + nv10_swtcl.c C_SOURCES = \ $(COMMON_SOURCES) \ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 3558b25857..b55e52f487 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -44,7 +44,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. //#include "nouveau_state.h" #include "nouveau_span.h" #include "nouveau_tex.h" -#include "nv20_swtcl.h" +#include "nv10_swtcl.h" #include "vblank.h" #include "utils.h" @@ -131,14 +131,14 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, case NV_03: case NV_04: case NV_05: - case NV_10: default: break; + case NV_10: case NV_20: case NV_30: case NV_40: case G_70: - nv20TriInitFunctions( ctx ); + nv10TriInitFunctions( ctx ); break; } nouveauDDInitStateFuncs( ctx ); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_driver.c b/src/mesa/drivers/dri/nouveau/nouveau_driver.c index 165fc4929f..cb996acd89 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_driver.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_driver.c @@ -27,6 +27,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_context.h" #include "nouveau_ioctl.h" //#include "nouveau_state.h" +#include "nouveau_lock.h" +#include "nouveau_fifo.h" #include "nouveau_driver.h" #include "swrast/swrast.h" @@ -100,7 +102,7 @@ static const GLubyte *nouveauGetString( GLcontext *ctx, GLenum name ) agp_mode=0; break; case NV_AGP: - nmesa->screen->agp_mode; + agp_mode=nmesa->screen->agp_mode; break; } driGetRendererString( buffer, card_name, DRIVER_DATE, @@ -115,7 +117,7 @@ static const GLubyte *nouveauGetString( GLcontext *ctx, GLenum name ) static void nouveauFlush( GLcontext *ctx ) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - FIRE_RING( nmesa ); + FIRE_RING(); } /* glFinish */ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h index 6a21687551..bf528a24ca 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h @@ -90,6 +90,7 @@ extern void WAIT_RING(nouveauContextPtr nmesa,u_int32_t size); }\ }while(0) +extern void nouveauWaitForIdle(nouveauContextPtr nmesa); #endif /* __NOUVEAU_FIFO_H__ */ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_ioctl.c b/src/mesa/drivers/dri/nouveau/nouveau_ioctl.c index 959c5f465b..32bdcef06b 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_ioctl.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_ioctl.c @@ -24,6 +24,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +#include +#include "mtypes.h" +#include "macros.h" +#include "dd.h" +#include "swrast/swrast.h" #include "nouveau_ioctl.h" @@ -46,7 +51,7 @@ void nouveauIoctlInitFifo() // XXX needs more stuff } -void nouveauIoctlInitFunctions( struct dd_function_table *functions ) +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 index e6a9a7e249..3147265e90 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_ioctl.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_ioctl.h @@ -28,6 +28,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef __NOUVEAU_IOCTL_H__ #define __NOUVEAU_IOCTL_H__ -extern void nouveauIoctlInitFunctions( struct dd_function_table *functions ); +extern void nouveauIoctlInitFifo(); +extern void nouveauIoctlInitFunctions(struct dd_function_table *functions); #endif /* __NOUVEAU_IOCTL_H__ */ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_tris.c b/src/mesa/drivers/dri/nouveau/nouveau_tris.c index 770776390b..607c811910 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_tris.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_tris.c @@ -117,7 +117,6 @@ void nouveauRunPipeline( GLcontext *ctx ) if (vmesa->newState) { vmesa->newRenderState |= vmesa->newState; - nouveauValidateState( ctx ); } _tnl_run_pipeline( ctx ); diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c new file mode 100644 index 0000000000..0b061876cb --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -0,0 +1,822 @@ +/* + * 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. + */ + +/* Software TCL for NV10, NV20, NV30, NV40, G70 */ + +#include +#include + +#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 "nv10_swtcl.h" +#include "nouveau_context.h" +#include "nouveau_span.h" +#include "nouveau_ioctl.h" +#include "nouveau_reg.h" +#include "nouveau_tex.h" +#include "nouveau_fifo.h" + +/* XXX hack for now */ +#define channel 1 + +static void nv10RenderPrimitive( GLcontext *ctx, GLenum prim ); +static void nv10RasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim ); + + +/*********************************************************************** + * 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) + + +/* the free room we want before we start a vertex batch. this is a performance-tunable */ +#define NOUVEAU_MIN_PRIM_SIZE (32/4) +/* the size above which we fire the ring. this is a performance-tunable */ +#define NOUVEAU_FIRE_SIZE (2048/4) + +static inline void nv10StartPrimitive(struct nouveau_context* nmesa) +{ + if (nmesa->screen->card_type==NV_10) + BEGIN_RING_SIZE(channel,NV10_PRIMITIVE,1); + else if (nmesa->screen->card_type==NV_20) + BEGIN_RING_SIZE(channel,NV20_PRIMITIVE,1); + else + BEGIN_RING_SIZE(channel,NV30_PRIMITIVE,1); + OUT_RING(nmesa->current_primitive); + + if (nmesa->screen->card_type==NV_10) + BEGIN_RING_PRIM(channel,NV10_BEGIN_VERTICES,NOUVEAU_MIN_PRIM_SIZE); + else + BEGIN_RING_PRIM(channel,NV20_BEGIN_VERTICES,NOUVEAU_MIN_PRIM_SIZE); +} + +static inline void nv10FinishPrimitive(struct nouveau_context *nmesa) +{ + FINISH_RING_PRIM(); + if (nmesa->screen->card_type==NV_10) + BEGIN_RING_SIZE(channel,NV10_PRIMITIVE,1); + else if (nmesa->screen->card_type==NV_20) + BEGIN_RING_SIZE(channel,NV20_PRIMITIVE,1); + else + BEGIN_RING_SIZE(channel,NV30_PRIMITIVE,1); + OUT_RING(0x0); + FIRE_RING(); +} + + +static inline void nv10ExtendPrimitive(struct nouveau_context* nmesa, int size) +{ + /* when the fifo has enough stuff (2048 bytes) or there is not enough room, fire */ + if ((RING_AHEAD()>=NOUVEAU_FIRE_SIZE)||(RING_AVAILABLE()vertex_size; + nv10ExtendPrimitive(nmesa, 4 * 4 * vertsize); + + OUT_RINGp(v0,vertsize); + OUT_RINGp(v1,vertsize); + OUT_RINGp(v2,vertsize); + OUT_RINGp(v3,vertsize); +} + +static inline void nv10_draw_triangle(nouveauContextPtr nmesa, + nouveauVertexPtr v0, + nouveauVertexPtr v1, + nouveauVertexPtr v2) +{ + GLuint vertsize = nmesa->vertex_size; + nv10ExtendPrimitive(nmesa, 3 * 4 * vertsize); + + OUT_RINGp(v0,vertsize); + OUT_RINGp(v1,vertsize); + OUT_RINGp(v2,vertsize); +} + +static inline void nv10_draw_line(nouveauContextPtr nmesa, + nouveauVertexPtr v0, + nouveauVertexPtr v1) +{ + GLuint vertsize = nmesa->vertex_size; + nv10ExtendPrimitive(nmesa, 2 * 4 * vertsize); + OUT_RINGp(v0,vertsize); + OUT_RINGp(v1,vertsize); +} + +static inline void nv10_draw_point(nouveauContextPtr nmesa, + nouveauVertexPtr v0) +{ + GLuint vertsize = nmesa->vertex_size; + nv10ExtendPrimitive(nmesa, 1 * 4 * vertsize); + OUT_RINGp(v0,vertsize); +} + + + +/*********************************************************************** + * 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 \ + nv10_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 \ + nv10_draw_quad(nmesa, a, b, c, d); \ + } while (0) + +#define LINE(v0, v1) \ + do { \ + if (DO_FALLBACK) \ + nmesa->draw_line(nmesa, v0, v1); \ + else \ + nv10_draw_line(nmesa, v0, v1); \ + } while (0) + +#define POINT(v0) \ + do { \ + if (DO_FALLBACK) \ + nmesa->draw_point(nmesa, v0); \ + else \ + nv10_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 + + +#define DEPTH_SCALE 1.0 +#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->vertex_size * sizeof(int))) + +#define VERT_SET_RGBA( v, c ) \ + do { \ + nouveau_color_t *color = (nouveau_color_t *)&((v)->f[coloroffset]); \ + color->red=(c)[0]; \ + color->green=(c)[1]; \ + color->blue=(c)[2]; \ + color->alpha=(c)[3]; \ + } while (0) + +#define VERT_COPY_RGBA( v0, v1 ) \ + do { \ + if (coloroffset) { \ + v0->f[coloroffset][0] = v1->f[coloroffset][0]; \ + v0->f[coloroffset][1] = v1->f[coloroffset][1]; \ + v0->f[coloroffset][2] = v1->f[coloroffset][2]; \ + v0->f[coloroffset][3] = v1->f[coloroffset][3]; \ + } \ + } while (0) + +#define VERT_SET_SPEC( v, c ) \ + do { \ + if (specoffset) { \ + nouveau_color_t *color = (nouveau_color_t *)&((v)->f[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->f[specoffset][0] = v1->f[specoffset][0]; \ + v0->f[specoffset][1] = v1->f[specoffset][1]; \ + v0->f[specoffset][2] = v1->f[specoffset][2]; \ + } \ + } while (0) + + +#define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->f[coloroffset] +#define VERT_RESTORE_RGBA( idx ) v[idx]->f[coloroffset] = color[idx] +#define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->f[specoffset] +#define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->f[specoffset] = spec[idx] + + +#define LOCAL_VARS(n) \ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); \ +GLuint color[n], spec[n]; \ +GLuint coloroffset = nmesa->color_offset; \ +GLuint specoffset = nmesa->specular_offset; \ +(void)color; (void)spec; (void)coloroffset; (void)specoffset; + + +/*********************************************************************** + * Helpers for rendering unfilled primitives * + ***********************************************************************/ + +static const GLuint hw_prim[GL_POLYGON+1] = { + GL_POINTS+1, + GL_LINES+1, + GL_LINES+1, + GL_LINES+1, + GL_TRIANGLES+1, + GL_TRIANGLES+1, + GL_TRIANGLES+1, + GL_QUADS+1, + GL_QUADS+1, + GL_TRIANGLES+1 +}; + +#define RASTERIZE(x) nv10RasterPrimitive( ctx, x, hw_prim[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) nv10RasterPrimitive(ctx, x, hw_prim[x]) +#undef LOCAL_VARS +#define LOCAL_VARS \ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); \ +GLubyte *vertptr = (GLubyte *)nmesa->verts; \ +const GLuint vertsize = nmesa->vertex_size; \ +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->vertex_size; + nv10ExtendPrimitive(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++) { + OUT_RINGp(V(elts[i-1]),vertsize); + OUT_RINGp(V(elts[i]),vertsize); + OUT_RINGp(start,vertsize); + } +} + +/**********************************************************************/ +/* 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) + +#define EMIT_ATTR( ATTR, STYLE ) \ +do { \ + nmesa->vertex_attrs[nmesa->vertex_attr_count].attrib = (ATTR); \ + nmesa->vertex_attrs[nmesa->vertex_attr_count].format = (STYLE); \ + nmesa->vertex_attr_count++; \ +} while (0) + + +static void nv10ChooseRenderState(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLuint flags = ctx->_TriangleCaps; + GLuint index = 0; + + nmesa->draw_point = nv10_draw_point; + nmesa->draw_line = nv10_draw_line; + nmesa->draw_tri = nv10_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 nv10OutputVertexFormat(struct nouveau_context* nmesa, GLuint index) +{ + GLcontext* ctx=nmesa->glCtx; + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + int attr_size[16]; + int default_attr_size[8]={3,3,3,4,3,1,4,4}; + int i; + int slots=0; + int total_size=0; + + /* + * Determine attribute sizes + */ + for(i=0;i<8;i++) + { + if (index&(1<TexCoordPtr[i]; + else + attr_size[i]=0; + } + + /* + * Tell t_vertex about the vertex format + */ + for(i=0;i<16;i++) + { + if (index&(1<color_offset=total_size; + if (i==_TNL_ATTRIB_COLOR1) + nmesa->specular_offset=total_size; + total_size+=attr_size[i]; + } + } + nmesa->vertex_size=total_size; + + /* + * Tell the hardware about the vertex format + */ + if (nmesa->screen->card_type==NV_10) { + // XXX needs some love + } else if (nmesa->screen->card_type==NV_20) { + for(i=0;i<16;i++) + { + int size=attr_size[i]; + BEGIN_RING_SIZE(channel,NV20_VERTEX_ATTRIBUTE(i),1); + OUT_RING(NV20_VERTEX_ATTRIBUTE_TYPE_FLOAT|(size*0x10)); + } + } else { + BEGIN_RING_SIZE(channel,NV30_VERTEX_ATTRIBUTES,slots); + for(i=0;irender_inputs; + + if (index!=nmesa->render_inputs) + { + nmesa->render_inputs=index; + nv10OutputVertexFormat(nmesa,index); + } +} + + +/**********************************************************************/ +/* High level hooks for t_vb_render.c */ +/**********************************************************************/ + + +static void nv10RenderStart(GLcontext *ctx) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + + if (nmesa->newState) { + nmesa->newRenderState |= nmesa->newState; + } + + if (nmesa->Fallback) { + tnl->Driver.Render.Start(ctx); + return; + } + + if (nmesa->newRenderState) { + nv10ChooseVertexState(ctx); + nv10ChooseRenderState(ctx); + nmesa->newRenderState = 0; + } +} + +static void nv10RenderFinish(GLcontext *ctx) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + nv10FinishPrimitive(nmesa); +} + + +/* System to flush dma and emit state changes based on the rasterized + * primitive. + */ +void nv10RasterPrimitive(GLcontext *ctx, + GLenum glprim, + GLuint 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 nv10RenderPrimitive( GLcontext *ctx, GLuint prim ) +{ + nv10RasterPrimitive( ctx, prim, hw_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 = nv10RenderStart; + tnl->Driver.Render.Finish = nv10RenderFinish; + tnl->Driver.Render.PrimitiveNotify = nv10RenderPrimitive; + 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/nv10_swtcl.h b/src/mesa/drivers/dri/nouveau/nv10_swtcl.h new file mode 100644 index 0000000000..7b42967dd8 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.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 __NV10_SWTCL_H__ +#define __NV10_SWTCL_H__ + +#include "mtypes.h" + +extern void nv10TriInitFunctions( GLcontext *ctx ); +extern void nv10Fallback( GLcontext *ctx, GLuint bit, GLboolean mode ); +#define FALLBACK( nmesa, bit, mode ) nouveauFallback( nmesa->glCtx, bit, mode ) + +#endif /* __NV10_SWTCL_H__ */ + diff --git a/src/mesa/drivers/dri/nouveau/nv20_swtcl.c b/src/mesa/drivers/dri/nouveau/nv20_swtcl.c deleted file mode 100644 index c493516e2a..0000000000 --- a/src/mesa/drivers/dri/nouveau/nv20_swtcl.c +++ /dev/null @@ -1,823 +0,0 @@ -/* - * 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. - */ - -/* Software TCL for NV10, NV20, NV30, NV40, G70 */ - -#include -#include - -#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 "nv20_swtcl.h" -#include "nouveau_context.h" -#include "nouveau_span.h" -#include "nouveau_ioctl.h" -#include "nouveau_reg.h" -#include "nouveau_tex.h" -#include "nouveau_fifo.h" - -/* XXX hack for now */ -#define channel 1 - -static void nv20RenderPrimitive( GLcontext *ctx, GLenum prim ); -static void nv20RasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim ); - - -/*********************************************************************** - * 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) - - -/* the free room we want before we start a vertex batch. this is a performance-tunable */ -#define NOUVEAU_MIN_PRIM_SIZE (32/4) -/* the size above which we fire the ring. this is a performance-tunable */ -#define NOUVEAU_FIRE_SIZE (2048/4) - -static inline void nv20StartPrimitive(struct nouveau_context* nmesa) -{ - if (nmesa->screen->card_type==NV_10) - BEGIN_RING_SIZE(channel,NV10_PRIMITIVE,1); - else if (nmesa->screen->card_type==NV_20) - BEGIN_RING_SIZE(channel,NV20_PRIMITIVE,1); - else - BEGIN_RING_SIZE(channel,NV30_PRIMITIVE,1); - OUT_RING(nmesa->current_primitive); - - if (nmesa->screen->card_type==NV_10) - BEGIN_RING_PRIM(channel,NV10_BEGIN_VERTICES,NOUVEAU_MIN_PRIM_SIZE); - else - BEGIN_RING_PRIM(channel,NV20_BEGIN_VERTICES,NOUVEAU_MIN_PRIM_SIZE); -} - -static inline void nv20FinishPrimitive(struct nouveau_context *nmesa) -{ - FINISH_RING_PRIM(); - if (nmesa->screen->card_type==NV_10) - BEGIN_RING_SIZE(channel,NV10_PRIMITIVE,1); - else if (nmesa->screen->card_type==NV_20) - BEGIN_RING_SIZE(channel,NV20_PRIMITIVE,1); - else - BEGIN_RING_SIZE(channel,NV30_PRIMITIVE,1); - OUT_RING(0x0); - FIRE_RING(); -} - - -static inline void nv20ExtendPrimitive(struct nouveau_context* nmesa, int size) -{ - /* when the fifo has enough stuff (2048 bytes) or there is not enough room, fire */ - if ((RING_AHEAD()>=NOUVEAU_FIRE_SIZE)||(RING_AVAILABLE()vertex_size; - nv20ExtendPrimitive(nmesa, 4 * 4 * vertsize); - - OUT_RINGp(v0,vertsize); - OUT_RINGp(v1,vertsize); - OUT_RINGp(v2,vertsize); - OUT_RINGp(v3,vertsize); -} - -static inline void nv20_draw_triangle(nouveauContextPtr nmesa, - nouveauVertexPtr v0, - nouveauVertexPtr v1, - nouveauVertexPtr v2) -{ - GLuint vertsize = nmesa->vertex_size; - nv20ExtendPrimitive(nmesa, 3 * 4 * vertsize); - - OUT_RINGp(v0,vertsize); - OUT_RINGp(v1,vertsize); - OUT_RINGp(v2,vertsize); -} - -static inline void nv20_draw_line(nouveauContextPtr nmesa, - nouveauVertexPtr v0, - nouveauVertexPtr v1) -{ - GLuint vertsize = nmesa->vertex_size; - nv20ExtendPrimitive(nmesa, 2 * 4 * vertsize); - OUT_RINGp(v0,vertsize); - OUT_RINGp(v1,vertsize); -} - -static inline void nv20_draw_point(nouveauContextPtr nmesa, - nouveauVertexPtr v0) -{ - GLuint vertsize = nmesa->vertex_size; - nv20ExtendPrimitive(nmesa, 1 * 4 * vertsize); - OUT_RINGp(v0,vertsize); -} - - - -/*********************************************************************** - * 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 \ - nv20_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 \ - nv20_draw_quad(nmesa, a, b, c, d); \ - } while (0) - -#define LINE(v0, v1) \ - do { \ - if (DO_FALLBACK) \ - nmesa->draw_line(nmesa, v0, v1); \ - else \ - nv20_draw_line(nmesa, v0, v1); \ - } while (0) - -#define POINT(v0) \ - do { \ - if (DO_FALLBACK) \ - nmesa->draw_point(nmesa, v0); \ - else \ - nv20_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 - - -#define DEPTH_SCALE 1.0 -#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->vertex_size * sizeof(int))) - -#define VERT_SET_RGBA( v, c ) \ - do { \ - nouveau_color_t *color = (nouveau_color_t *)&((v)->f[coloroffset]); \ - color->red=(c)[0]; \ - color->green=(c)[1]; \ - color->blue=(c)[2]; \ - color->alpha=(c)[3]; \ - } while (0) - -#define VERT_COPY_RGBA( v0, v1 ) \ - do { \ - if (coloroffset) { \ - v0->f[coloroffset][0] = v1->f[coloroffset][0]; \ - v0->f[coloroffset][1] = v1->f[coloroffset][1]; \ - v0->f[coloroffset][2] = v1->f[coloroffset][2]; \ - v0->f[coloroffset][3] = v1->f[coloroffset][3]; \ - } \ - } while (0) - -#define VERT_SET_SPEC( v, c ) \ - do { \ - if (specoffset) { \ - nouveau_color_t *color = (nouveau_color_t *)&((v)->f[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->f[specoffset][0] = v1->f[specoffset][0]; \ - v0->f[specoffset][1] = v1->f[specoffset][1]; \ - v0->f[specoffset][2] = v1->f[specoffset][2]; \ - } \ - } while (0) - - -#define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->f[coloroffset] -#define VERT_RESTORE_RGBA( idx ) v[idx]->f[coloroffset] = color[idx] -#define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->f[specoffset] -#define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->f[specoffset] = spec[idx] - - -#define LOCAL_VARS(n) \ - struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); \ -GLuint color[n], spec[n]; \ -GLuint coloroffset = nmesa->color_offset; \ -GLuint specoffset = nmesa->specular_offset; \ -(void)color; (void)spec; (void)coloroffset; (void)specoffset; - - -/*********************************************************************** - * Helpers for rendering unfilled primitives * - ***********************************************************************/ - -static const GLuint hw_prim[GL_POLYGON+1] = { - GL_POINTS+1, - GL_LINES+1, - GL_LINES+1, - GL_LINES+1, - GL_TRIANGLES+1, - GL_TRIANGLES+1, - GL_TRIANGLES+1, - GL_QUADS+1, - GL_QUADS+1, - GL_TRIANGLES+1 -}; - -#define RASTERIZE(x) nv20RasterPrimitive( ctx, x, hw_prim[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) nv20RasterPrimitive(ctx, x, hw_prim[x]) -#undef LOCAL_VARS -#define LOCAL_VARS \ - struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); \ -GLubyte *vertptr = (GLubyte *)nmesa->verts; \ -const GLuint vertsize = nmesa->vertex_size; \ -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->vertex_size; - nv20ExtendPrimitive(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++) { - OUT_RINGp(V(elts[i-1]),vertsize); - OUT_RINGp(V(elts[i]),vertsize); - OUT_RINGp(start,vertsize); - } -} - -/**********************************************************************/ -/* 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) - -#define EMIT_ATTR( ATTR, STYLE ) \ -do { \ - nmesa->vertex_attrs[nmesa->vertex_attr_count].attrib = (ATTR); \ - nmesa->vertex_attrs[nmesa->vertex_attr_count].format = (STYLE); \ - nmesa->vertex_attr_count++; \ -} while (0) - - -static void nv20ChooseRenderState(GLcontext *ctx) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - GLuint flags = ctx->_TriangleCaps; - GLuint index = 0; - - nmesa->draw_point = nv20_draw_point; - nmesa->draw_line = nv20_draw_line; - nmesa->draw_tri = nv20_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 nv20OutputVertexFormat(struct nouveau_context* nmesa, GLuint index) -{ - GLcontext* ctx=nmesa->glCtx; - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - int attr_size[16]; - int default_attr_size[8]={3,3,3,4,3,1,4,4}; - int i; - int slots=0; - int total_size=0; - - /* - * Determine attribute sizes - */ - for(i=0;i<8;i++) - { - if (index&(1<TexCoordPtr[i]; - else - attr_size[i]=0; - } - - /* - * Tell t_vertex about the vertex format - */ - for(i=0;i<16;i++) - { - if (index&(1<color_offset=total_size; - if (i==_TNL_ATTRIB_COLOR1) - nmesa->specular_offset=total_size; - total_size+=attr_size[i]; - } - } - nmesa->vertex_size=total_size; - - /* - * Tell the hardware about the vertex format - */ - if (nmesa->screen->card_type==NV_10) { - // XXX needs some love - } else if (nmesa->screen->card_type==NV_20) { - for(i=0;i<16;i++) - { - int size=attr_size[i]; - BEGIN_RING_SIZE(channel,NV20_VERTEX_ATTRIBUTE(i),1); - OUT_RING(NV20_VERTEX_ATTRIBUTE_TYPE_FLOAT|(size*0x10)); - } - } else { - BEGIN_RING_SIZE(channel,NV30_VERTEX_ATTRIBUTES,slots); - for(i=0;irender_inputs; - - if (index!=nmesa->render_inputs) - { - nmesa->render_inputs=index; - nv20OutputVertexFormat(nmesa,index); - } -} - - -/**********************************************************************/ -/* High level hooks for t_vb_render.c */ -/**********************************************************************/ - - -static void nv20RenderStart(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) { - nv20ChooseVertexState(ctx); - nv20ChooseRenderState(ctx); - nmesa->newRenderState = 0; - } -} - -static void nv20RenderFinish(GLcontext *ctx) -{ - struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - nv20FinishPrimitive(nmesa); -} - - -/* System to flush dma and emit state changes based on the rasterized - * primitive. - */ -void nv20RasterPrimitive(GLcontext *ctx, - GLenum glprim, - GLuint 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 nv20RenderPrimitive( GLcontext *ctx, GLuint prim ) -{ - nv20RasterPrimitive( ctx, prim, hw_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 = nv20RenderStart; - tnl->Driver.Render.Finish = nv20RenderFinish; - tnl->Driver.Render.PrimitiveNotify = nv20RenderPrimitive; - 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/nv20_swtcl.h b/src/mesa/drivers/dri/nouveau/nv20_swtcl.h deleted file mode 100644 index ed589d8bcf..0000000000 --- a/src/mesa/drivers/dri/nouveau/nv20_swtcl.h +++ /dev/null @@ -1,39 +0,0 @@ -/************************************************************************** - -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 __NV20_SWTCL_H__ -#define __NV20_SWTCL_H__ - -#include "mtypes.h" - -extern void nv20TriInitFunctions( GLcontext *ctx ); -extern void nv20Fallback( GLcontext *ctx, GLuint bit, GLboolean mode ); -#define FALLBACK( nmesa, bit, mode ) nouveauFallback( nmesa->glCtx, bit, mode ) - -#endif /* __NV20_SWTCL_H__ */ - -- cgit v1.2.3 From f799745f50ff2e61f535816d623e643cc1eac944 Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Thu, 13 Apr 2006 17:03:51 +0000 Subject: Some compile fixes. --- src/mesa/drivers/dri/nouveau/nouveau_context.c | 2 ++ src/mesa/drivers/dri/nouveau/nouveau_context.h | 2 ++ src/mesa/drivers/dri/nouveau/nouveau_tris.c | 2 ++ src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 1 + 4 files changed, 7 insertions(+) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index b55e52f487..9e025a5231 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -55,6 +55,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. int NOUVEAU_DEBUG = 0; #endif +#define NOUVEAU_FALLBACK_DISABLE 1 + static const struct dri_debug_control debug_control[] = { { NULL, 0 } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 49e22f8074..83ac2fd455 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -113,6 +113,8 @@ typedef struct nouveau_context { /* Configuration cache */ driOptionCache optionCache; + + uint32_t vblank_flags; }nouveauContextRec, *nouveauContextPtr; #define NOUVEAU_CONTEXT(ctx) ((nouveauContextPtr)(ctx->DriverCtx)) diff --git a/src/mesa/drivers/dri/nouveau/nouveau_tris.c b/src/mesa/drivers/dri/nouveau/nouveau_tris.c index 607c811910..3a48393662 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_tris.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_tris.c @@ -25,6 +25,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ #include "nouveau_context.h" +#include "nouveau_tris.h" +#include /* Common tri functions */ diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 0b061876cb..3eafde39a7 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -56,6 +56,7 @@ static void nv10RenderPrimitive( GLcontext *ctx, GLenum prim ); static void nv10RasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim ); + /*********************************************************************** * Emit primitives as inline vertices * ***********************************************************************/ -- cgit v1.2.3 From 5fd11335f655e27515d9bf92fef5d9a8cd4f6bb5 Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Fri, 14 Apr 2006 17:39:43 +0000 Subject: Added the beginnings of state (not much there yet). Fixed some includes. --- src/mesa/drivers/dri/nouveau/Makefile | 1 + src/mesa/drivers/dri/nouveau/nouveau_context.h | 3 + src/mesa/drivers/dri/nouveau/nouveau_state.c | 140 +++++++++++++++++++++++++ src/mesa/drivers/dri/nouveau/nouveau_state.h | 42 ++++++++ src/mesa/drivers/dri/nouveau/nouveau_tris.c | 5 +- 5 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_state.c create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_state.h (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile index 25c298132c..fc51205019 100644 --- a/src/mesa/drivers/dri/nouveau/Makefile +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -14,6 +14,7 @@ DRIVER_SOURCES = \ nouveau_ioctl.c \ nouveau_lock.c \ nouveau_span.c \ + nouveau_state.c \ nouveau_tex.c \ nouveau_tris.c \ nv10_swtcl.c diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 83ac2fd455..c2929a16a8 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -115,6 +115,9 @@ typedef struct nouveau_context { driOptionCache optionCache; uint32_t vblank_flags; + + GLfloat viewport[16]; + }nouveauContextRec, *nouveauContextPtr; #define NOUVEAU_CONTEXT(ctx) ((nouveauContextPtr)(ctx->DriverCtx)) diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c new file mode 100644 index 0000000000..c88b33b884 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -0,0 +1,140 @@ +/************************************************************************** + +Copyright 2006 Jeremy Kolb +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_state.h" +#include "nouveau_ioctl.h" +#include "nouveau_tris.h" + +#include "swrast/swrast.h" +#include "array_cache/acache.h" +#include "tnl/tnl.h" +#include "swrast_setup/swrast_setup.h" + +#include "tnl/t_pipeline.h" + +static void nouveauCalcViewport(GLcontext *ctx) +{ + /* Calculate the Viewport Matrix */ + +/* Taken from the intel driver + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + const GLfloat *v = ctx->Viewport._WindowMap.m; + GLfloat *m = nmesa->ViewportMatrix.m; + GLint h = 0; + + if (nmesa->driDrawable) + h = nmesa->driDrawable->h + SUBPIXEL_Y; + + m[MAT_SX] = v[MAT_SX]; + m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X; + m[MAT_SY] = - v[MAT_SY]; + m[MAT_TY] = - v[MAT_TY] + h; + m[MAT_SZ] = v[MAT_SZ] * nmesa->depth_scale; + m[MAT_TZ] = v[MAT_TZ] * nmesa->depth_scale; +*/ +} + +static nouveauViewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + /* + * Need to send (at least on an nv35 the following: + * cons = 4 (this may be bytes per pixel) + * + * The viewport: + * 445 0x0000bee0 {size: 0x0 channel: 0x1 cmd: 0x00009ee0} <-- VIEWPORT_SETUP/HEADER ? + * 446 0x00000000 {size: 0x0 channel: 0x0 cmd: 0x00000000} <-- x * cons + * 447 0x00000c80 {size: 0x0 channel: 0x0 cmd: 0x00000c80} <-- (height + x) * cons + * 448 0x00000000 {size: 0x0 channel: 0x0 cmd: 0x00000000} <-- y * cons + * 449 0x00000960 {size: 0x0 channel: 0x0 cmd: 0x00000960} <-- (width + y) * cons + * 44a 0x00082a00 {size: 0x2 channel: 0x1 cmd: 0x00000a00} <-- VIEWPORT_DIMS + * 44b 0x04000000 <-- (Width_from_glViewport << 16) | x + * 44c 0x03000000 <-- (Height_from_glViewport << 16) | (win_height - height - y) + * + */ + +} + +/* Initialize the context's hardware state. */ +void nouveauDDInitState(nouveauContextPtr nmesa) +{ + +} + +/* Initialize the driver's state functions */ +void nouveauDDInitStateFuncs(GLcontext *ctx) +{ + ctx->Driver.UpdateState = NULL; //nouveauDDInvalidateState; + + ctx->Driver.ClearIndex = NULL; + ctx->Driver.ClearColor = NULL; //nouveauDDClearColor; + ctx->Driver.ClearStencil = NULL; //nouveauDDClearStencil; + ctx->Driver.DrawBuffer = NULL; //nouveauDDDrawBuffer; + ctx->Driver.ReadBuffer = NULL; //nouveauDDReadBuffer; + + ctx->Driver.IndexMask = NULL; + ctx->Driver.ColorMask = NULL; //nouveauDDColorMask; + ctx->Driver.AlphaFunc = NULL; //nouveauDDAlphaFunc; + ctx->Driver.BlendEquationSeparate = NULL; //nouveauDDBlendEquationSeparate; + ctx->Driver.BlendFuncSeparate = NULL; //nouveauDDBlendFuncSeparate; + ctx->Driver.ClearDepth = NULL; //nouveauDDClearDepth; + ctx->Driver.CullFace = NULL; //nouveauDDCullFace; + ctx->Driver.FrontFace = NULL; //nouveauDDFrontFace; + ctx->Driver.DepthFunc = NULL; //nouveauDDDepthFunc; + ctx->Driver.DepthMask = NULL; //nouveauDDDepthMask; + ctx->Driver.Enable = NULL; //nouveauDDEnable; + ctx->Driver.Fogfv = NULL; //nouveauDDFogfv; + ctx->Driver.Hint = NULL; + ctx->Driver.Lightfv = NULL; + ctx->Driver.LightModelfv = NULL; //nouveauDDLightModelfv; + ctx->Driver.LogicOpcode = NULL; //nouveauDDLogicOpCode; + ctx->Driver.PolygonMode = NULL; + ctx->Driver.PolygonStipple = NULL; //nouveauDDPolygonStipple; + ctx->Driver.RenderMode = NULL; //nouveauDDRenderMode; + ctx->Driver.Scissor = NULL; //nouveauDDScissor; + ctx->Driver.ShadeModel = NULL; //nouveauDDShadeModel; + ctx->Driver.StencilFuncSeparate = NULL; //nouveauDDStencilFuncSeparate; + ctx->Driver.StencilMaskSeparate = NULL; //nouveauDDStencilMaskSeparate; + ctx->Driver.StencilOpSeparate = NULL; //nouveauDDStencilOpSeparate; + + ctx->Driver.DepthRange = NULL; //nouveauDepthRange; + ctx->Driver.Viewport = nouveauViewport; + + /* Pixel path fallbacks. + */ + ctx->Driver.Accum = _swrast_Accum; + ctx->Driver.Bitmap = _swrast_Bitmap; + ctx->Driver.CopyPixels = _swrast_CopyPixels; + ctx->Driver.DrawPixels = _swrast_DrawPixels; + ctx->Driver.ReadPixels = _swrast_ReadPixels; + + /* Swrast hooks for imaging extensions: + */ + ctx->Driver.CopyColorTable = _swrast_CopyColorTable; + ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable; + ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; + ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.h b/src/mesa/drivers/dri/nouveau/nouveau_state.h new file mode 100644 index 0000000000..70c50588a8 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.h @@ -0,0 +1,42 @@ +/************************************************************************** + +Copyright 2006 Jeremy Kolb +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_STATE_H__ +#define __NOUVEAU_STATE_H__ + +#include "nouveau_context.h" + +extern void nouveauDDInitState(nouveauContextPtr nmesa); +extern void nouveauDDInitStateFuncs(GLcontext *ctx); + +/* +extern void nouveauDDUpdateState(GLcontext *ctx); +extern void nouveauDDUpdateHWState(GLcontext *ctx); + +extern void nouveauEmitHwStateLocked(nouveauContextPtr nmesa); +*/ +#endif + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_tris.c b/src/mesa/drivers/dri/nouveau/nouveau_tris.c index 3a48393662..9749915b41 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_tris.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_tris.c @@ -26,7 +26,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_context.h" #include "nouveau_tris.h" -#include +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/tnl.h" +#include "tnl/t_pipeline.h" /* Common tri functions */ -- cgit v1.2.3 From 199512968be28aa5a4f41c4f30e0e311e31b252a Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Fri, 14 Apr 2006 22:41:16 +0000 Subject: Cleaned stuff in the tcl code --- src/mesa/drivers/dri/nouveau/nouveau_context.c | 1 + src/mesa/drivers/dri/nouveau/nouveau_context.h | 13 +++++++++++ src/mesa/drivers/dri/nouveau/nouveau_tris.c | 30 ++++++++++---------------- src/mesa/drivers/dri/nouveau/nouveau_tris.h | 3 +++ src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 7 +++--- src/mesa/drivers/dri/nouveau/nv10_swtcl.h | 3 ++- 6 files changed, 33 insertions(+), 24 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 9e025a5231..683e6d6ea6 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -134,6 +134,7 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, case NV_04: case NV_05: default: + //nv03TriInitFunctions( ctx ); break; case NV_10: case NV_20: diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index c2929a16a8..93c6f1dfff 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -88,6 +88,7 @@ typedef struct nouveau_context { GLuint specular_offset; /* The drawing fallbacks */ + GLuint Fallback; nouveau_tri_func* draw_tri; nouveau_line_func* draw_line; nouveau_point_func* draw_point; @@ -122,6 +123,18 @@ typedef struct nouveau_context { #define NOUVEAU_CONTEXT(ctx) ((nouveauContextPtr)(ctx->DriverCtx)) +#define NOUVEAU_FALLBACK_TEXTURE 0x0001 +#define NOUVEAU_FALLBACK_DRAW_BUFFER 0x0002 +#define NOUVEAU_FALLBACK_READ_BUFFER 0x0004 +#define NOUVEAU_FALLBACK_STENCIL 0x0008 +#define NOUVEAU_FALLBACK_RENDER_MODE 0x0010 +#define NOUVEAU_FALLBACK_LOGICOP 0x0020 +#define NOUVEAU_FALLBACK_SEP_SPECULAR 0x0040 +#define NOUVEAU_FALLBACK_BLEND_EQ 0x0080 +#define NOUVEAU_FALLBACK_BLEND_FUNC 0x0100 +#define NOUVEAU_FALLBACK_PROJTEX 0x0200 +#define NOUVEAU_FALLBACK_DISABLE 0x0400 + extern GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, __DRIcontextPrivate *driContextPriv, diff --git a/src/mesa/drivers/dri/nouveau/nouveau_tris.c b/src/mesa/drivers/dri/nouveau/nouveau_tris.c index 9749915b41..53a18d2f73 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_tris.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_tris.c @@ -26,6 +26,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_context.h" #include "nouveau_tris.h" +#include "nv10_swtcl.h" +#include "nouveau_span.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" @@ -44,9 +46,7 @@ void nouveau_fallback_tri(struct nouveau_context *nmesa, _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 ); } @@ -58,9 +58,7 @@ void nouveau_fallback_line(struct nouveau_context *nmesa, 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 ); } @@ -70,12 +68,9 @@ void nouveau_fallback_point(struct nouveau_context *nmesa, 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; @@ -85,7 +80,11 @@ void nouveauFallback(struct nouveau_context *nmesa, GLuint bit, GLboolean mode) if (mode) { nmesa->Fallback |= bit; if (oldfallback == 0) { - nv40FinishPrimitive(nmesa); + if (nmesa->screen->card_typerenderIndex = ~0; @@ -96,14 +95,7 @@ void nouveauFallback(struct nouveau_context *nmesa, GLuint bit, GLboolean mode) 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; + nouveauInitTriFunctions(ctx); _tnl_invalidate_vertex_state( ctx, ~0 ); _tnl_invalidate_vertices( ctx, ~0 ); @@ -118,10 +110,10 @@ void nouveauFallback(struct nouveau_context *nmesa, GLuint bit, GLboolean mode) void nouveauRunPipeline( GLcontext *ctx ) { - struct nouveau_context *vmesa = NOUVEAU_CONTEXT(ctx); + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - if (vmesa->newState) { - vmesa->newRenderState |= vmesa->newState; + if (nmesa->newState) { + nmesa->newRenderState |= nmesa->newState; } _tnl_run_pipeline( ctx ); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_tris.h b/src/mesa/drivers/dri/nouveau/nouveau_tris.h index 4d9de538d7..950f662570 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_tris.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_tris.h @@ -47,6 +47,9 @@ extern void nouveauFallback(struct nouveau_context *nmesa, GLuint bit, GLboolean extern void nouveauRunPipeline( GLcontext *ctx ); +extern void nouveauTriInitFunctions( GLcontext *ctx ); + + #endif /* __NOUVEAU_TRIS_H__ */ diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 3eafde39a7..e04a4ece5e 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -88,7 +88,7 @@ static inline void nv10StartPrimitive(struct nouveau_context* nmesa) BEGIN_RING_PRIM(channel,NV20_BEGIN_VERTICES,NOUVEAU_MIN_PRIM_SIZE); } -static inline void nv10FinishPrimitive(struct nouveau_context *nmesa) +inline void nv10FinishPrimitive(struct nouveau_context *nmesa) { FINISH_RING_PRIM(); if (nmesa->screen->card_type==NV_10) @@ -788,13 +788,11 @@ static void nv10RenderPrimitive( GLcontext *ctx, GLuint prim ) } - /**********************************************************************/ /* Initialization. */ /**********************************************************************/ - -void nouveauInitTriFuncs(GLcontext *ctx) +void nouveauTriInitFunctions(GLcontext *ctx) { struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); @@ -821,3 +819,4 @@ void nouveauInitTriFuncs(GLcontext *ctx) } + diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.h b/src/mesa/drivers/dri/nouveau/nv10_swtcl.h index 7b42967dd8..fd57eeaa95 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.h +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.h @@ -31,8 +31,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "mtypes.h" -extern void nv10TriInitFunctions( GLcontext *ctx ); extern void nv10Fallback( GLcontext *ctx, GLuint bit, GLboolean mode ); +extern void nv10FinishPrimitive(struct nouveau_context *nmesa); +extern void nv10RenderStart(GLcontext *ctx); #define FALLBACK( nmesa, bit, mode ) nouveauFallback( nmesa->glCtx, bit, mode ) #endif /* __NV10_SWTCL_H__ */ -- cgit v1.2.3 From b7d4314fe1619223caf2f59b1b28e05d7ff0e662 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Fri, 14 Apr 2006 22:43:44 +0000 Subject: Added vertex attributes to the context --- src/mesa/drivers/dri/nouveau/nouveau_context.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 93c6f1dfff..dcb1442033 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -83,10 +83,14 @@ typedef struct nouveau_context { volatile unsigned char* mmio; /* State for tris */ - GLuint vertex_size; GLuint color_offset; GLuint specular_offset; + /* Vertex state */ + GLuint vertex_size; + struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; + GLuint vertex_attr_count; + /* The drawing fallbacks */ GLuint Fallback; nouveau_tri_func* draw_tri; -- cgit v1.2.3 From 4b2d8b46c8c68b0d10d9d3fa4a3820fa44ef4738 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Fri, 14 Apr 2006 22:48:03 +0000 Subject: Silence the lock warning --- src/mesa/drivers/dri/nouveau/nouveau_span.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_span.c b/src/mesa/drivers/dri/nouveau/nouveau_span.c index f990a8907e..1763b37e53 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_span.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_span.c @@ -28,6 +28,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_context.h" #include "nouveau_span.h" #include "nouveau_fifo.h" +#include "nouveau_lock.h" #include "swrast/swrast.h" -- cgit v1.2.3 From 576b3433dacd1f36fe5bb33dcf6c1dbadfe152c9 Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Fri, 14 Apr 2006 22:50:14 +0000 Subject: Cleaning --- src/mesa/drivers/dri/nouveau/nouveau_context.h | 7 ++++++- src/mesa/drivers/dri/nouveau/nouveau_state.c | 13 +++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index dcb1442033..442681cb7e 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -54,6 +54,10 @@ nouveau_fifo; #include "tnl_dd/t_dd_vertex.h" #undef TAG +/* Subpixel offsets for window coordinates (triangles): */ +#define SUBPIXEL_X (0.0F) +#define SUBPIXEL_Y (0.125F) + struct nouveau_context; typedef void (*nouveau_tri_func)( struct nouveau_context*, @@ -121,7 +125,8 @@ typedef struct nouveau_context { uint32_t vblank_flags; - GLfloat viewport[16]; + GLmatrix viewport; + GLfloat depth_scale; }nouveauContextRec, *nouveauContextPtr; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c index c88b33b884..5d12d1ca9f 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -40,10 +40,9 @@ static void nouveauCalcViewport(GLcontext *ctx) { /* Calculate the Viewport Matrix */ -/* Taken from the intel driver nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); const GLfloat *v = ctx->Viewport._WindowMap.m; - GLfloat *m = nmesa->ViewportMatrix.m; + GLfloat *m = nmesa->viewport.m; GLint h = 0; if (nmesa->driDrawable) @@ -55,7 +54,7 @@ static void nouveauCalcViewport(GLcontext *ctx) m[MAT_TY] = - v[MAT_TY] + h; m[MAT_SZ] = v[MAT_SZ] * nmesa->depth_scale; m[MAT_TZ] = v[MAT_TZ] * nmesa->depth_scale; -*/ + } static nouveauViewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) @@ -75,7 +74,13 @@ static nouveauViewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) * 44c 0x03000000 <-- (Height_from_glViewport << 16) | (win_height - height - y) * */ + + nouveauCalcViewport(ctx); +} +void nouveauDepthRange(GLcontext *ctx) +{ + nouveauCalcViewport(ctx); } /* Initialize the context's hardware state. */ @@ -120,7 +125,7 @@ void nouveauDDInitStateFuncs(GLcontext *ctx) ctx->Driver.StencilMaskSeparate = NULL; //nouveauDDStencilMaskSeparate; ctx->Driver.StencilOpSeparate = NULL; //nouveauDDStencilOpSeparate; - ctx->Driver.DepthRange = NULL; //nouveauDepthRange; + ctx->Driver.DepthRange = nouveauDepthRange; ctx->Driver.Viewport = nouveauViewport; /* Pixel path fallbacks. -- cgit v1.2.3 From 4c850f346bde46fef009e43ec46aaac709e8da5a Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Fri, 14 Apr 2006 22:58:30 +0000 Subject: Added render index field to the context --- src/mesa/drivers/dri/nouveau/nouveau_context.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 442681cb7e..e1b56e36f5 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -127,7 +127,8 @@ typedef struct nouveau_context { GLmatrix viewport; GLfloat depth_scale; - + GLfloat depth_scale; + GLuint render_index; }nouveauContextRec, *nouveauContextPtr; #define NOUVEAU_CONTEXT(ctx) ((nouveauContextPtr)(ctx->DriverCtx)) -- cgit v1.2.3 From 911ec211a5bb801ef3d445f75c705259e53c7597 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Fri, 14 Apr 2006 22:59:33 +0000 Subject: ooops --- src/mesa/drivers/dri/nouveau/nouveau_context.h | 1 - 1 file changed, 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index e1b56e36f5..207e446739 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -127,7 +127,6 @@ typedef struct nouveau_context { GLmatrix viewport; GLfloat depth_scale; - GLfloat depth_scale; GLuint render_index; }nouveauContextRec, *nouveauContextPtr; -- cgit v1.2.3 From 97d11ecd6c5d23f682db5c6ef7dfec89185ae307 Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Fri, 14 Apr 2006 23:02:39 +0000 Subject: Add more feilds to context. --- src/mesa/drivers/dri/nouveau/nouveau_context.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 207e446739..e09d804ccf 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -125,9 +125,12 @@ typedef struct nouveau_context { uint32_t vblank_flags; + GLuint new_state; + GLuint new_render_state; + GLuint render_index; GLmatrix viewport; GLfloat depth_scale; - GLuint render_index; + }nouveauContextRec, *nouveauContextPtr; #define NOUVEAU_CONTEXT(ctx) ((nouveauContextPtr)(ctx->DriverCtx)) -- cgit v1.2.3 From b0c4cfed608f21f255b8637ec5ff499fc36ee302 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Fri, 14 Apr 2006 23:47:45 +0000 Subject: More work on the tcl code... still have to make my mind on a number of things --- src/mesa/drivers/dri/nouveau/nouveau_context.h | 1 + src/mesa/drivers/dri/nouveau/nouveau_tris.c | 14 +++++++++----- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 6 +++--- src/mesa/drivers/dri/nouveau/nv10_swtcl.h | 1 + 4 files changed, 14 insertions(+), 8 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index e09d804ccf..c23b633bb9 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -92,6 +92,7 @@ typedef struct nouveau_context { /* Vertex state */ GLuint vertex_size; + char *verts; struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; GLuint vertex_attr_count; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_tris.c b/src/mesa/drivers/dri/nouveau/nouveau_tris.c index 53a18d2f73..8622b9349c 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_tris.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_tris.c @@ -87,7 +87,7 @@ void nouveauFallback(struct nouveau_context *nmesa, GLuint bit, GLboolean mode) } _swsetup_Wakeup(ctx); - nmesa->renderIndex = ~0; + nmesa->render_index = ~0; } } else { @@ -95,14 +95,18 @@ void nouveauFallback(struct nouveau_context *nmesa, GLuint bit, GLboolean mode) if (oldfallback == bit) { _swrast_flush( ctx ); - nouveauInitTriFunctions(ctx); + if (nmesa->screen->card_typevertex_attrs, nmesa->vertex_attr_count, - nmesa->ViewportMatrix.m, 0 ); + nmesa->viewport.m, 0 ); } } } @@ -112,8 +116,8 @@ void nouveauRunPipeline( GLcontext *ctx ) { struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - if (nmesa->newState) { - nmesa->newRenderState |= nmesa->newState; + if (nmesa->new_state) { + nmesa->new_render_state |= nmesa->new_state; } _tnl_run_pipeline( ctx ); diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index e04a4ece5e..9a1748f48a 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -593,8 +593,8 @@ static void nv10ChooseRenderState(GLcontext *ctx) index = NOUVEAU_MAX_TRIFUNC; /* flat specular */ } - if (nmesa->renderIndex != index) { - nmesa->renderIndex = index; + if (nmesa->render_index != index) { + nmesa->render_index = index; tnl->Driver.Render.Points = rast_tab[index].points; tnl->Driver.Render.Line = rast_tab[index].line; @@ -792,7 +792,7 @@ static void nv10RenderPrimitive( GLcontext *ctx, GLuint prim ) /* Initialization. */ /**********************************************************************/ -void nouveauTriInitFunctions(GLcontext *ctx) +void nv10TriInitFunctions(GLcontext *ctx) { struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.h b/src/mesa/drivers/dri/nouveau/nv10_swtcl.h index fd57eeaa95..03338fbe13 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.h +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.h @@ -34,6 +34,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. extern void nv10Fallback( GLcontext *ctx, GLuint bit, GLboolean mode ); extern void nv10FinishPrimitive(struct nouveau_context *nmesa); extern void nv10RenderStart(GLcontext *ctx); +extern void nv10TriInitFunctions(GLcontext *ctx); #define FALLBACK( nmesa, bit, mode ) nouveauFallback( nmesa->glCtx, bit, mode ) #endif /* __NV10_SWTCL_H__ */ -- cgit v1.2.3 From a7d88857680d3d4d2a0788f18c49149dd2118b6f Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Sat, 15 Apr 2006 00:21:44 +0000 Subject: State changes. --- src/mesa/drivers/dri/nouveau/nouveau_context.h | 17 +++++ src/mesa/drivers/dri/nouveau/nouveau_screen.h | 2 + src/mesa/drivers/dri/nouveau/nouveau_state.c | 89 +++++++++++++++++++++++++- 3 files changed, 105 insertions(+), 3 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index c23b633bb9..7405bb4145 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -96,6 +96,9 @@ typedef struct nouveau_context { struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; GLuint vertex_attr_count; + /* Color state */ + GLuint clear_color; + /* The drawing fallbacks */ GLuint Fallback; nouveau_tri_func* draw_tri; @@ -134,8 +137,22 @@ typedef struct nouveau_context { }nouveauContextRec, *nouveauContextPtr; + #define NOUVEAU_CONTEXT(ctx) ((nouveauContextPtr)(ctx->DriverCtx)) +/* Flags for what context state needs to be updated: */ +#define NOUVEAU_NEW_ALPHA 0x0001 +#define NOUVEAU_NEW_DEPTH 0x0002 +#define NOUVEAU_NEW_FOG 0x0004 +#define NOUVEAU_NEW_CLIP 0x0008 +#define NOUVEAU_NEW_CULL 0x0010 +#define NOUVEAU_NEW_MASKS 0x0020 +#define NOUVEAU_NEW_RENDER_NOT 0x0040 +#define NOUVEAU_NEW_WINDOW 0x0080 +#define NOUVEAU_NEW_CONTEXT 0x0100 +#define NOUVEAU_NEW_ALL 0x01ff + +/* Flags for software fallback cases: */ #define NOUVEAU_FALLBACK_TEXTURE 0x0001 #define NOUVEAU_FALLBACK_DRAW_BUFFER 0x0002 #define NOUVEAU_FALLBACK_READ_BUFFER 0x0004 diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.h b/src/mesa/drivers/dri/nouveau/nouveau_screen.h index 997b05fecd..f6959419c5 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.h @@ -35,6 +35,8 @@ typedef struct { u_int32_t bus_type; u_int32_t agp_mode; + GLint fbFormat; + GLuint frontOffset; GLuint frontPitch; GLuint backOffset; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c index 5d12d1ca9f..b7f53ff957 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -28,6 +28,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_state.h" #include "nouveau_ioctl.h" #include "nouveau_tris.h" +#include "nouveau_fifo.h" #include "swrast/swrast.h" #include "array_cache/acache.h" @@ -36,6 +37,38 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tnl/t_pipeline.h" +#include "mtypes.h" +#include "colormac.h" + +static __inline__ GLuint nouveauPackColor(GLuint format, + GLubyte r, GLubyte g, + GLubyte b, GLubyte a) +{ + switch (format) { + case 2: + return PACK_COLOR_565( r, g, b ); + case 4: + return PACK_COLOR_8888( r, g, b, a); + default: + fprintf(stderr, "unknown format %d\n", (int)format); + return 0; + } +} + +static void nouveauDDClearColor(GLcontext *ctx, const GLfloat color[4]) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte c[4]; + + CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]); + + nmesa->clear_color = nouveauPackColor( nmesa->screen->fbFormat, + c[0], c[1], c[2], c[3] ); +} + static void nouveauCalcViewport(GLcontext *ctx) { /* Calculate the Viewport Matrix */ @@ -57,7 +90,7 @@ static void nouveauCalcViewport(GLcontext *ctx) } -static nouveauViewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +static void nouveauViewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) { /* * Need to send (at least on an nv35 the following: @@ -78,11 +111,61 @@ static nouveauViewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) nouveauCalcViewport(ctx); } -void nouveauDepthRange(GLcontext *ctx) +static void nouveauDepthRange(GLcontext *ctx) { nouveauCalcViewport(ctx); } +static void nouveauDDUpdateHWState(GLcontext *ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + int new_state = nmesa->new_state; + + if ( new_state || nmesa->new_render_state & _NEW_TEXTURE ) + { + FINISH_RING_PRIM(); + + nmesa->new_state = 0; + + /* Update the various parts of the context's state. + */ + /* + if ( new_state & NOUVEAU_NEW_ALPHA ) + nouveauUpdateAlphaMode( ctx ); + + if ( new_state & NOUVEAU_NEW_DEPTH ) + nouveauUpdateZMode( ctx ); + + if ( new_state & NOUVEAU_NEW_FOG ) + nouveauUpdateFogAttrib( ctx ); + + if ( new_state & NOUVEAU_NEW_CLIP ) + nouveauUpdateClipping( ctx ); + + if ( new_state & NOUVEAU_NEW_CULL ) + nouveauUpdateCull( ctx ); + + if ( new_state & NOUVEAU_NEW_MASKS ) + nouveauUpdateMasks( ctx ); + + if ( new_state & NOUVEAU_NEW_WINDOW ) + nouveauUpdateWindow( ctx ); + + if ( nmesa->new_render_state & _NEW_TEXTURE ) { + nouveauUpdateTextureState( ctx ); + }*/ + } +} + +static void nouveauDDInvalidateState(GLcontext *ctx, GLuint new_state) +{ + _swrast_InvalidateState( ctx, new_state ); + _swsetup_InvalidateState( ctx, new_state ); + _ac_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); + NOUVEAU_CONTEXT(ctx)->new_render_state |= new_state; +} + /* Initialize the context's hardware state. */ void nouveauDDInitState(nouveauContextPtr nmesa) { @@ -92,7 +175,7 @@ void nouveauDDInitState(nouveauContextPtr nmesa) /* Initialize the driver's state functions */ void nouveauDDInitStateFuncs(GLcontext *ctx) { - ctx->Driver.UpdateState = NULL; //nouveauDDInvalidateState; + ctx->Driver.UpdateState = nouveauDDInvalidateState; ctx->Driver.ClearIndex = NULL; ctx->Driver.ClearColor = NULL; //nouveauDDClearColor; -- cgit v1.2.3 From ddf936193a574ce7efd387b0e3bbec51998736f8 Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Mon, 17 Apr 2006 00:08:03 +0000 Subject: Changed invalid context fields to valid ones. --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 9a1748f48a..d825de6559 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -739,8 +739,8 @@ static void nv10RenderStart(GLcontext *ctx) { struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - if (nmesa->newState) { - nmesa->newRenderState |= nmesa->newState; + if (nmesa->new_state) { + nmesa->new_render_state |= nmesa->new_state; } if (nmesa->Fallback) { @@ -748,10 +748,10 @@ static void nv10RenderStart(GLcontext *ctx) return; } - if (nmesa->newRenderState) { + if (nmesa->new_render_state) { nv10ChooseVertexState(ctx); nv10ChooseRenderState(ctx); - nmesa->newRenderState = 0; + nmesa->new_render_state = 0; } } @@ -771,7 +771,7 @@ void nv10RasterPrimitive(GLcontext *ctx, { struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - assert (!nmesa->newState); + assert (!nmesa->new_state); if (hwprim != nmesa->current_primitive) { -- cgit v1.2.3 From 13a2d6698fce050732b421107a2a92b37a5e01f8 Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Mon, 17 Apr 2006 15:20:29 +0000 Subject: More context. --- src/mesa/drivers/dri/nouveau/nouveau_context.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 7405bb4145..e1c5d4d54e 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -96,8 +96,10 @@ typedef struct nouveau_context { struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; GLuint vertex_attr_count; - /* Color state */ + /* Clear state */ GLuint clear_color; + GLuint clear_depth; + GLuint clear_stencil; /* The drawing fallbacks */ GLuint Fallback; -- cgit v1.2.3 From 5411b96c5fc9b50ca4cd1ae61eb9d8b00fe5ff9a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 3 Jun 2006 16:36:23 +0000 Subject: Add start of vertex shader backend, will most likely not work correctly yet --- src/mesa/drivers/dri/nouveau/nouveau_shader.c | 91 ++++ src/mesa/drivers/dri/nouveau/nouveau_shader.h | 74 +++ src/mesa/drivers/dri/nouveau/nv40_reg.h | 472 +++++++++++++++++ src/mesa/drivers/dri/nouveau/nv40_vtxprog.c | 736 ++++++++++++++++++++++++++ 4 files changed, 1373 insertions(+) create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_shader.c create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_shader.h create mode 100644 src/mesa/drivers/dri/nouveau/nv40_reg.h create mode 100644 src/mesa/drivers/dri/nouveau/nv40_vtxprog.c (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.c b/src/mesa/drivers/dri/nouveau/nouveau_shader.c new file mode 100644 index 0000000000..ef8f02e910 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.c @@ -0,0 +1,91 @@ +#include "glheader.h" +#include "macros.h" +#include "enums.h" + +#include "program.h" +#include "nouveau_context.h" +#include "nouveau_shader.h" + +static struct program * +nv40NewProgram(GLcontext *ctx, GLenum target, GLuint id) +{ +} + +static void +nv40BindProgram(GLcontext *ctx, GLenum target, struct program *prog) +{ +} + +static void +nv40DeleteProgram(GLcontext *ctx, struct program *prog) +{ +} + +static void +nv40ProgramStringNotify(GLcontext *ctx, GLenum target, + struct program *prog) +{ +} + +static GLboolean +nv40IsProgramNative(GLcontext *ctx, GLenum target, struct program *prog) +{ +} + +void +nouveauInitShaderFuncs(GLcontext *ctx) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + + if (nmesa->screen->card_type == NV_40) { + ctx->Driver.NewProgram = nv40NewProgram; + ctx->Driver.BindProgram = nv40BindProgram; + ctx->Driver.DeleteProgram = nv40DeleteProgram; + ctx->Driver.ProgramStringNotify = nv40ProgramStringNotify; + ctx->Driver.IsProgramNative = nv40IsProgramNative; + } +} + +#define LONGBITS (sizeof(long) * 8) +void +nvsBitSet(long *rec, int bit) +{ + int ri = bit / LONGBITS; + int rb = bit % LONGBITS; + + rec[ri] |= (1 << rb); +} + +void +nvsBitClear(long *rec, int bit) +{ + int ri = bit / LONGBITS; + int rb = bit % LONGBITS; + + rec[ri] &= ~(1 << rb); +} + +void +nvsRecInit(long **rec, int max) +{ + int c = (max / LONGBITS) + ((max % LONGBITS) ? 1 : 0); + *rec = calloc(c, sizeof(long)); +} + +int +nvsAllocIndex(long *rec, int max) +{ + int c = (max / LONGBITS) + ((max % LONGBITS) ? 1 : 0); + int i, idx = 0; + + for (i=0;i (guess..) */ +#define NV40_VP_PROGRAM_START_ID 0x1EA0 /* Start executing program from instruction */ + +/* Vertex programs instruction set + * + * 128bit opcodes, split into 4 32-bit ones for ease of use. + * + * Non-native instructions + * ABS - MOV + NV40_VP_INST0_DEST_ABS + * POW - EX2 + MUL + LG2 + * SUB - ADD, second source negated + * SWZ - MOV + * XPD - + * + * Register access + * - Only one INPUT can be accessed per-instruction (move extras into TEMPs) + * - Only one CONST can be accessed per-instruction (move extras into TEMPs) + * + * Relative Addressing + * According to the value returned for MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB + * there are only two address registers available. The destination in the ARL + * instruction is set to TEMP (The temp isn't actually written). + * + * When using vanilla ARB_v_p, the proprietary driver will squish both the available + * ADDRESS regs into the first hardware reg in the X and Y components. + * + * To use an address reg as an index into consts, the CONST_SRC is set to + * (const_base + offset) and INDEX_CONST is set. + * + * It is similar for inputs, INPUT_SRC is set to the offset value and INDEX_INPUT + * is set. + * + * To access the second address reg use ADDR_REG_SELECT_1. A particular component + * of the address regs is selected with ADDR_SWZ. + * + * Only one address register can be accessed per instruction, but you may use + * the address reg as an index into both consts and inputs in the same instruction + * as long as the swizzles also match. + * + * Conditional execution (see NV_vertex_program{2,3} for details) + * All instructions appear to be able to modify one of two condition code registers. + * This is enabled by setting COND_UPDATE_ENABLE. The second condition registers is + * updated by setting COND_REG_SELECT_1. + * + * Conditional execution of an instruction is enabled by setting COND_TEST_ENABLE, and + * selecting the condition which will allow the test to pass with COND_{FL,LT,...}. + * It is possible to swizzle the values in the condition register, which allows for + * testing against an individual component. + * + * Branching + * The BRA/CAL instructions seem to follow a slightly different opcode layout. The + * destination instruction ID (IADDR) overlaps SRC2. Instruction ID's seem to be + * numbered based on the UPLOAD_FROM_ID FIFO command, and is incremented automatically + * on each UPLOAD_INST FIFO command. + * + * Conditional branching is achieved by using the condition tests described above. + * There doesn't appear to be dedicated looping instructions, but this can be done + * using a temp reg + conditional branching. + * + * Subroutines may be uploaded before the main program itself, but the first executed + * instruction is determined by the PROGRAM_START_ID FIFO command. + * + * Texture lookup + * TODO + */ + +/* ---- OPCODE BITS 127:96 / data DWORD 0 --- */ +#define NV40_VP_INST0_UNK0 (1 << 30) /* set when writing result regs */ +#define NV40_VP_INST_COND_UPDATE_ENABLE ((1 << 14)|1<<29) /* unsure about this */ +#define NV40_VP_INST_INDEX_INPUT (1 << 27) /* Use an address reg as in index into attribs */ +#define NV40_VP_INST_COND_REG_SELECT_1 (1 << 25) +#define NV40_VP_INST_ADDR_REG_SELECT_1 (1 << 24) +#define NV40_VP_INST_DEST_TEMP_ABS (1 << 21) +#define NV40_VP_INST_DEST_TEMP_SHIFT 15 +#define NV40_VP_INST_DEST_TEMP_MASK (0x3F << 15) +#define NV40_VP_INST_COND_TEST_ENABLE (1 << 13) /* write masking based on condition test */ +#define NV40_VP_INST_COND_SHIFT 10 +#define NV40_VP_INST_COND_MASK (0x7 << 10) +# define NV40_VP_INST_COND_FL 0 +# define NV40_VP_INST_COND_LT 1 +# define NV40_VP_INST_COND_EQ 2 +# define NV40_VP_INST_COND_LE 3 +# define NV40_VP_INST_COND_GT 4 +# define NV40_VP_INST_COND_NE 5 +# define NV40_VP_INST_COND_GE 6 +# define NV40_VP_INST_COND_TR 7 +#define NV40_VP_INST_COND_SWZ_X_SHIFT 8 +#define NV40_VP_INST_COND_SWZ_X_MASK (3 << 8) +#define NV40_VP_INST_COND_SWZ_Y_SHIFT 6 +#define NV40_VP_INST_COND_SWZ_Y_MASK (3 << 6) +#define NV40_VP_INST_COND_SWZ_Z_SHIFT 4 +#define NV40_VP_INST_COND_SWZ_Z_MASK (3 << 4) +#define NV40_VP_INST_COND_SWZ_W_SHIFT 2 +#define NV40_VP_INST_COND_SWZ_W_MASK (3 << 2) +#define NV40_VP_INST_COND_SWZ_ALL_SHIFT 2 +#define NV40_VP_INST_COND_SWZ_ALL_MASK (0xFF << 2) +#define NV40_VP_INST_ADDR_SWZ_SHIFT 0 +#define NV40_VP_INST_ADDR_SWZ_MASK (0x03 << 0) + +/* ---- OPCODE BITS 95:64 / data DWORD 1 --- */ +#define NV40_VP_INST_OPCODE_SHIFT 22 +#define NV40_VP_INST_OPCODE_MASK (0x3FF << 22) +/*TODO: confirm which source slots correspond to the GL sources, + * renouveau should be correct in most places though.. Also, + * document them here. + */ +# define NV40_VP_INST_OP_NOP 0x000 +# define NV40_VP_INST_OP_MOV 0x001 +# define NV40_VP_INST_OP_MUL 0x002 +# define NV40_VP_INST_OP_ADD 0x003 +# define NV40_VP_INST_OP_MAD 0x004 +# define NV40_VP_INST_OP_DP3 0x005 +# define NV40_VP_INST_OP_DP4 0x007 +# define NV40_VP_INST_OP_DPH 0x006 +# define NV40_VP_INST_OP_DST 0x008 +# define NV40_VP_INST_OP_MIN 0x009 +# define NV40_VP_INST_OP_MAX 0x00A +# define NV40_VP_INST_OP_SLT 0x00B +# define NV40_VP_INST_OP_SGE 0x00C +# define NV40_VP_INST_OP_ARL 0x00D +# define NV40_VP_INST_OP_FRC 0x00E +# define NV40_VP_INST_OP_FLR 0x00F +# define NV40_VP_INST_OP_SEQ 0x010 +# define NV40_VP_INST_OP_SFL 0x011 +# define NV40_VP_INST_OP_SGT 0x012 +# define NV40_VP_INST_OP_SLE 0x013 +# define NV40_VP_INST_OP_SNE 0x014 +# define NV40_VP_INST_OP_STR 0x015 +# define NV40_VP_INST_OP_SSG 0x016 +# define NV40_VP_INST_OP_ARR 0x017 +# define NV40_VP_INST_OP_ARA 0x018 +# define NV40_VP_INST_OP_RCP 0x040 +# define NV40_VP_INST_OP_RCC 0x060 +# define NV40_VP_INST_OP_RSQ 0x080 +# define NV40_VP_INST_OP_EXP 0x0A0 +# define NV40_VP_INST_OP_LOG 0x0C0 +# define NV40_VP_INST_OP_LIT 0x0E0 +# define NV40_VP_INST_OP_BRA 0x120 +# define NV40_VP_INST_OP_CAL 0x160 +# define NV40_VP_INST_OP_RET 0x180 +# define NV40_VP_INST_OP_LG2 0x1A0 +# define NV40_VP_INST_OP_EX2 0x1C0 +# define NV40_VP_INST_OP_COS 0x200 +# define NV40_VP_INST_OP_PUSHA 0x260 +# define NV40_VP_INST_OP_POPA 0x280 +#define NV40_VP_INST_CONST_SRC_SHIFT 12 +#define NV40_VP_INST_CONST_SRC_MASK (0xFF << 12) +#define NV40_VP_INST_INPUT_SRC_SHIFT 8 +#define NV40_VP_INST_INPUT_SRC_MASK (0x0F << 8) +# define NV40_VP_INST_IN_POS 0 /* These seem to match the bindings specified in */ +# define NV40_VP_INST_IN_WEIGHT 1 /* the ARB_v_p spec (2.14.3.1) */ +# define NV40_VP_INST_IN_NORMAL 2 +# define NV40_VP_INST_IN_COL0 3 /* Should probably confirm them all thougth */ +# define NV40_VP_INST_IN_COL1 4 +# define NV40_VP_INST_IN_FOGC 5 +# define NV40_VP_INST_IN_TC0 8 +# define NV40_VP_INST_IN_TC(n) (8+n) +#define NV40_VP_INST_SRC0H_SHIFT 0 +#define NV40_VP_INST_SRC0H_MASK (0xFF << 0) + +/* ---- OPCODE BITS 63:32 / data DWORD 2 --- */ +#define NV40_VP_INST_SRC0L_SHIFT 23 +#define NV40_VP_INST_SRC0L_MASK (0x1FF << 23) +#define NV40_VP_INST_SRC1_SHIFT 6 +#define NV40_VP_INST_SRC1_MASK (0x1FFFF << 6) +#define NV40_VP_INST_SRC2H_SHIFT 0 +#define NV40_VP_INST_SRC2H_MASK (0x3F << 0) +#define NV40_VP_INST_IADDRH_SHIFT 0 +#define NV40_VP_INST_IADDRH_MASK (0x1F << 0) /* guess, need to test this */ +# +/* ---- OPCODE BITS 31:0 / data DWORD 3 --- */ +#define NV40_VP_INST_IADDRL_SHIFT 29 +#define NV40_VP_INST_IADDRL_MASK (7 << 29) +#define NV40_VP_INST_SRC2L_SHIFT 21 +#define NV40_VP_INST_SRC2L_MASK (0x7FF << 21) +/* bits 7-12 seem to always be set to 1 */ +#define NV40_VP_INST_WRITEMASK_SHIFT 13 +#define NV40_VP_INST_WRITEMASK_MASK (0xF << 13) +# define NV40_VP_INST_WRITEMASK_X (1 << 16) +# define NV40_VP_INST_WRITEMASK_Y (1 << 15) +# define NV40_VP_INST_WRITEMASK_Z (1 << 14) +# define NV40_VP_INST_WRITEMASK_W (1 << 13) +#define NV40_VP_INST_DEST_SHIFT 2 +#define NV40_VP_INST_DEST_MASK (31 << 2) +# define NV40_VP_INST_DEST_POS 0 +# define NV40_VP_INST_DEST_COL0 1 +# define NV40_VP_INST_DEST_COL1 2 +# define NV40_VP_INST_DEST_BFC0 3 +# define NV40_VP_INST_DEST_BFC1 4 +# define NV40_VP_INST_DEST_FOGC 5 +# define NV40_VP_INST_DEST_PSZ 6 +# define NV40_VP_INST_DEST_TC0 7 +# define NV40_VP_INST_DEST_TC(n) (7+n) +# define NV40_VP_INST_DEST_TEMP 0x1F /* see NV40_VP_INST0_* for actual register */ +#define NV40_VP_INST_INDEX_CONST (1 << 1) +#define NV40_VP_INST_UNK_00 (1 << 0) /* appears to be set on the last inst only */ + +/* Useful to split the source selection regs into their pieces */ +#define NV40_VP_SRC0_HIGH_SHIFT 9 +#define NV40_VP_SRC0_HIGH_MASK 0x0001FE00 +#define NV40_VP_SRC0_LOW_MASK 0x000001FF +#define NV40_VP_SRC2_HIGH_SHIFT 11 +#define NV40_VP_SRC2_HIGH_MASK 0x0001F800 +#define NV40_VP_SRC2_LOW_MASK 0x000007FF + +/* Source selection - these are the bits you fill NV40_VP_INST_SRCn with */ +#define NV40_VP_SRC_NEGATE 16 +#define NV40_VP_SRC_SWZ_X_SHIFT 14 +#define NV40_VP_SRC_SWZ_X_MASK (3 << 14) +#define NV40_VP_SRC_SWZ_Y_SHIFT 12 +#define NV40_VP_SRC_SWZ_Y_MASK (3 << 12) +#define NV40_VP_SRC_SWZ_Z_SHIFT 10 +#define NV40_VP_SRC_SWZ_Z_MASK (3 << 10) +#define NV40_VP_SRC_SWZ_W_SHIFT 8 +#define NV40_VP_SRC_SWZ_W_MASK (3 << 8) +#define NV40_VP_SRC_SWZ_ALL_SHIFT 8 +#define NV40_VP_SRC_SWZ_ALL_MASK (0xFF << 8) +#define NV40_VP_SRC_TEMP_SRC_SHIFT 2 +#define NV40_VP_SRC_TEMP_SRC_MASK (0x3F << 2) +#define NV40_VP_SRC_REG_TYPE_SHIFT 0 +#define NV40_VP_SRC_REG_TYPE_MASK (3 << 0) +# define NV40_VP_SRC_REG_TYPE_UNK0 0 +# define NV40_VP_SRC_REG_TYPE_TEMP 1 +# define NV40_VP_SRC_REG_TYPE_INPUT 2 +# define NV40_VP_SRC_REG_TYPE_CONST 3 + +/* +-- GF6800GT - PCIID 10de:0045 (rev a1) -- + +== Fragment program instruction set + Not FIFO commands, uploaded into a memory buffer. The fragment program has + always appeared in the same map as the texture image data has. Usually it's + the first thing in the map, followed immediately by the textures. +*/ + + +/* + * Each fragment program opcode appears to be comprised of 4 32-bit values. + * + * 0 - Opcode, output reg/mask, ATTRIB source + * 1 - Source 0 + * 2 - Source 1 + * 3 - Source 2 + * + * Constants are inserted directly after the instruction that uses them. + * + * It appears that it's not possible to use two input registers in one + * instruction as the input sourcing is done in the instruction dword + * and not the source selection dwords. As such instructions such as: + * + * ADD result.color, fragment.color, fragment.texcoord[0]; + * + * must be split into two MOV's and then an ADD (nvidia does this) but + * I'm not sure why it's not just one MOV and then source the second input + * in the ADD instruction.. + * + * Negation of the full source is done with NV40_FP_REG_NEGATE, arbitrary + * negation requires multiplication with a const. + * + * Arbitrary swizzling is supported with the exception of SWIZZLE_ZERO/SWIZZLE_ONE + * The temp/result regs appear to be initialised to (0.0, 0.0, 0.0, 0.0) as SWIZZLE_ZERO + * is implemented simply by not writing to the relevant components of the destination. + * + * Non-native instructions: + * LIT + * LRP - MAD+MAD + * SUB - ADD, negate second source + * RSQ - LG2 + EX2 + * POW - LG2 + MUL + EX2 + * SCS - COS + SIN + * XPD + * DP2 - MUL + ADD + */ + +//== Opcode / Destination selection == +#define NV40_FP_OP_PROGRAM_END 0x00000001 +#define NV40_FP_OP_OUT_RESULT (1 << 0) /* uncertain? and what about depth? */ +#define NV40_FP_OP_OUT_REG_SHIFT 1 +#define NV40_FP_OP_OUT_REG_MASK (31 << 1) /* uncertain */ +#define NV40_FP_OP_OUTMASK_SHIFT 9 +#define NV40_FP_OP_OUTMASK_MASK (0xF << 9) +# define NV40_FP_OP_OUT_X (1 << 9) +# define NV40_FP_OP_OUT_Y (1 << 10) +# define NV40_FP_OP_OUT_Z (1 << 11) +# define NV40_FP_OP_OUT_W (1 << 12) +/* Uncertain about these, especially the input_src values.. it's possible that + * they can be dynamically changed. + */ +#define NV40_FP_OP_INPUT_SRC_SHIFT 13 +#define NV40_FP_OP_INPUT_SRC_MASK (15 << 13) +# define NV40_FP_OP_INPUT_SRC_POSITION 0x0 +# define NV40_FP_OP_INPUT_SRC_COL0 0x1 +# define NV40_FP_OP_INPUT_SRC_COL1 0x2 +# define NV40_FP_OP_INPUT_SRC_TC0 0x4 +# define NV40_FP_OP_INPUT_SRC_TC(n) (0x4 + n) +#define NV40_FP_OP_TEX_UNIT_SHIFT 17 +#define NV40_FP_OP_TEX_UNIT_MASK (0xF << 17) /* guess */ +#define NV40_FP_OP_PRECISION_SHIFT 22 +#define NV40_FP_OP_PRECISION_MASK (3 << 22) +# define NV40_FP_PRECISION_FP32 0 +# define NV40_FP_PRECISION_FP16 1 +# define NV40_FP_PRECISION_FX12 2 +#define NV40_FP_OP_OPCODE_SHIFT 24 +#define NV40_FP_OP_OPCODE_MASK (0x7F << 24) +# define NV40_FP_OP_OPCODE_MOV 0x01 +# define NV40_FP_OP_OPCODE_MUL 0x02 +# define NV40_FP_OP_OPCODE_ADD 0x03 +# define NV40_FP_OP_OPCODE_MAD 0x04 +# define NV40_FP_OP_OPCODE_DP3 0x05 +# define NV40_FP_OP_OPCODE_DP4 0x06 +# define NV40_FP_OP_OPCODE_DST 0x07 +# define NV40_FP_OP_OPCODE_MIN 0x08 +# define NV40_FP_OP_OPCODE_MAX 0x09 +# define NV40_FP_OP_OPCODE_SLT 0x0A +# define NV40_FP_OP_OPCODE_SGE 0x0B +# define NV40_FP_OP_OPCODE_SLE 0x0C +# define NV40_FP_OP_OPCODE_SGT 0x0D +# define NV40_FP_OP_OPCODE_SNE 0x0E +# define NV40_FP_OP_OPCODE_SEQ 0x0F +# define NV40_FP_OP_OPCODE_FRC 0x10 +# define NV40_FP_OP_OPCODE_FLR 0x11 +# define NV40_FP_OP_OPCODE_TEX 0x17 +# define NV40_FP_OP_OPCODE_TXP 0x18 +# define NV40_FP_OP_OPCODE_RCP 0x1A +# define NV40_FP_OP_OPCODE_EX2 0x1C +# define NV40_FP_OP_OPCODE_LG2 0x1D +# define NV40_FP_OP_OPCODE_COS 0x22 +# define NV40_FP_OP_OPCODE_SIN 0x23 +# define NV40_FP_OP_OPCODE_DP2A 0x2E +# define NV40_FP_OP_OPCODE_TXB 0x31 +# define NV40_FP_OP_OPCODE_DIV 0x3A +#define NV40_FP_OP_OUT_SAT (1 << 31) + +/* high order bits of SRC0 */ +#define NV40_FP_OP_OUT_ABS (1 << 29) +#define NV40_FP_OP_COND_SWZ_W_SHIFT 27 +#define NV40_FP_OP_COND_SWZ_W_MASK (3 << 27) +#define NV40_FP_OP_COND_SWZ_Z_SHIFT 25 +#define NV40_FP_OP_COND_SWZ_Z_MASK (3 << 25) +#define NV40_FP_OP_COND_SWZ_Y_SHIFT 23 +#define NV40_FP_OP_COND_SWZ_Y_MASK (3 << 23) +#define NV40_FP_OP_COND_SWZ_X_SHIFT 21 +#define NV40_FP_OP_COND_SWZ_X_MASK (3 << 21) +#define NV40_FP_OP_COND_SWZ_ALL_SHIFT 21 +#define NV40_FP_OP_COND_SWZ_ALL_MASK (0xFF << 21) +#define NV40_FP_OP_COND_SHIFT 18 +#define NV40_FP_OP_COND_MASK (0x07 << 18) +# define NV40_FP_OP_COND_FL 0 +# define NV40_FP_OP_COND_LT 1 +# define NV40_FP_OP_COND_EQ 2 +# define NV40_FP_OP_COND_LE 3 +# define NV40_FP_OP_COND_GT 4 +# define NV40_FP_OP_COND_NE 5 +# define NV40_FP_OP_COND_GE 6 +# define NV40_FP_OP_COND_TR 7 + +/* high order bits of SRC1 */ +#define NV40_FP_OP_SRC_SCALE_SHIFT 28 +#define NV40_FP_OP_SRC_SCALE_MASK (3 << 28) + +//== Register selection == +#define NV40_FP_REG_SRC_INPUT (1 << 0) /* uncertain */ +#define NV40_FP_REG_SRC_CONST (1 << 1) +#define NV40_FP_REG_SRC_SHIFT 2 /* uncertain */ +#define NV40_FP_REG_SRC_MASK (31 << 2) +#define NV40_FP_REG_UNK_0 (1 << 8) +#define NV40_FP_REG_SWZ_ALL_SHIFT 9 +#define NV40_FP_REG_SWZ_ALL_MASK (255 << 9) +#define NV40_FP_REG_SWZ_X_SHIFT 9 +#define NV40_FP_REG_SWZ_X_MASK (3 << 9) +#define NV40_FP_REG_SWZ_Y_SHIFT 11 +#define NV40_FP_REG_SWZ_Y_MASK (3 << 11) +#define NV40_FP_REG_SWZ_Z_SHIFT 13 +#define NV40_FP_REG_SWZ_Z_MASK (3 << 13) +#define NV40_FP_REG_SWZ_W_SHIFT 15 +#define NV40_FP_REG_SWZ_W_MASK (3 << 15) +# define NV40_FP_SWIZZLE_X 0 +# define NV40_FP_SWIZZLE_Y 1 +# define NV40_FP_SWIZZLE_Z 2 +# define NV40_FP_SWIZZLE_W 3 +#define NV40_FP_REG_NEGATE (1 << 17) + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nv40_vtxprog.c b/src/mesa/drivers/dri/nouveau/nv40_vtxprog.c new file mode 100644 index 0000000000..582bf65ea0 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv40_vtxprog.c @@ -0,0 +1,736 @@ +#include "glheader.h" +#include "macros.h" +#include "enums.h" +#include "program.h" +#include "program_instruction.h" + +#include "nouveau_reg.h" +#include "nouveau_shader.h" +#include "nouveau_msg.h" + +#include "nv40_reg.h" + +/* TODO: + * - Implement support for constants + * - Handle SWZ with 0/1 components and partial negate masks + * - Handle ARB_position_invarient + * - Relative register addressing + * - Implement any missing instructions + */ + +static int t_dst_mask(int mask); + +static int +alloc_hw_temp(nouveau_vertex_program *vp) +{ + return nvsAllocIndex(vp->hwtemps_in_use, 64); +} + +static void +free_hw_temp(nouveau_vertex_program *vp, int id) +{ + nvsBitClear(vp->hwtemps_in_use, id); +} + +static int +alloc_temp(nouveau_vertex_program *vp) +{ + int idx; + + idx = nvsAllocIndex(vp->temps_in_use, 64); + if (!idx) + return -1; + + vp->temps[idx].file = HW_TEMP; + vp->temps[idx].hw_id = -1; + vp->temps[idx].ref = -1; + + return idx; +} + +static void +free_temp(nouveau_vertex_program *vp, nouveau_srcreg *temp) +{ + if (!temp) return; + + if (vp->temps[temp->idx].hw_id != -1) + free_hw_temp(vp, vp->temps[temp->idx].hw_id); + nvsBitClear(vp->temps_in_use, temp->idx); +} + +static void +make_srcreg(nouveau_vertex_program *vp, + nouveau_srcreg *src, + nouveau_regtype type, + int id) +{ + switch (type) { + case HW_INPUT: + src->hw = &vp->inputs[id]; + src->idx = id; + break; + case HW_TEMP: + src->hw = &vp->temps[id]; + src->idx = id; + break; + case HW_CONST: + //FIXME: TODO + break; + default: + assert(0); + break; + } + + src->negate = 0; + src->swizzle = 0x1B /* 00011011 - XYZW */; +} + +static void +make_dstreg(nouveau_vertex_program *vp, + nouveau_dstreg *dest, + nouveau_regtype type, + int id) +{ + if (type == HW_TEMP && id == -1) + dest->idx = alloc_temp(vp); + else + dest->idx = id; + switch (type) { + case HW_TEMP: + dest->idx = id; + if (dest->idx == -1) + dest->idx = alloc_temp(vp); + dest->hw = &vp->temps[dest->idx]; + break; + case HW_OUTPUT: + dest->hw = NULL; + dest->idx = id; + break; + default: + assert(0); + break; + } + + dest->mask = t_dst_mask(WRITEMASK_XYZW); + dest->condup = 0; + dest->condreg = 0; + dest->condtest = NV40_VP_INST_COND_TR; + dest->condswz = 0x1B /* 00011011 - XYZW */; +} + +static unsigned int +src_to_hw(nouveau_vertex_program *vp, nouveau_srcreg *src, + unsigned int *is, unsigned int *cs) +{ + unsigned int hs = 0; + + if (!src) { + /* unused sources seem to be INPUT swz XYZW, dont't know if this + * actually matters or not... + */ + hs |= (NV40_VP_SRC_REG_TYPE_INPUT << NV40_VP_SRC_REG_TYPE_SHIFT); + hs |= (0x1B << NV40_VP_SRC_SWZ_ALL_SHIFT); + return hs; + } + + switch (src->hw->file) { + case HW_INPUT: + if (*is != -1) { + fprintf(stderr, "multiple inputs detected... not good\n"); + return; + } + *is = src->hw->hw_id; + hs |= (NV40_VP_SRC_REG_TYPE_INPUT << NV40_VP_SRC_REG_TYPE_SHIFT); + break; + case HW_CONST: + if (*cs != -1) { + fprintf(stderr, "multiple consts detected... not good\n"); + return; + } + *cs = src->hw->hw_id; + hs |= (NV40_VP_SRC_REG_TYPE_CONST << NV40_VP_SRC_REG_TYPE_SHIFT); + break; + case HW_TEMP: + if (src->hw->hw_id == -1) { + fprintf(stderr, "read from unwritten temp!\n"); + return; + } + hs |= (NV40_VP_SRC_REG_TYPE_TEMP << NV40_VP_SRC_REG_TYPE_SHIFT) | + (src->hw->hw_id << NV40_VP_SRC_TEMP_SRC_SHIFT); + + if (--src->hw->ref == 0) + free_hw_temp(vp, src->hw->hw_id); + } + + hs |= (src->swizzle << NV40_VP_SRC_SWZ_ALL_SHIFT); + if (src->negate) + hs |= NV40_VP_SRC_NEGATE; + + return hs; +} + +static void +instruction_store(nouveau_vertex_program *vp, unsigned int inst[]) +{ + if ((vp->inst_count+1) > vp->insns_alloced) { + vp->insns = realloc(vp->insns, sizeof(unsigned int) * (vp->inst_count+1) * 4); + vp->insns_alloced = vp->inst_count+1; + } + vp->insns[(vp->inst_count*4) + 0] = inst[0]; + vp->insns[(vp->inst_count*4) + 1] = inst[1]; + vp->insns[(vp->inst_count*4) + 2] = inst[2]; + vp->insns[(vp->inst_count*4) + 3] = inst[3]; + vp->inst_count++; +} + +static void +emit_arith(nouveau_vertex_program *vp, int op, + nouveau_dstreg *dest, + nouveau_srcreg *src0, + nouveau_srcreg *src1, + nouveau_srcreg *src2, + int flags) +{ + nouveau_regrec *hwdest = dest->hw; + unsigned int hs0, hs1, hs2; + unsigned int hop[4] = { 0, 0, 0, 0 }; + int insrc = -1, constsrc = -1; + + /* Calculate source reg state */ + hs0 = src_to_hw(vp, src0, &insrc, &constsrc); + hs1 = src_to_hw(vp, src1, &insrc, &constsrc); + hs2 = src_to_hw(vp, src2, &insrc, &constsrc); + + /* Append it to the instruction */ + hop[1] |= (((hs0 & NV40_VP_SRC0_HIGH_MASK) >> NV40_VP_SRC0_HIGH_SHIFT) + << NV40_VP_INST_SRC0H_SHIFT); + hop[2] |= ((hs0 & NV40_VP_SRC0_LOW_MASK) << NV40_VP_INST_SRC0L_SHIFT) | + (hs1 << NV40_VP_INST_SRC1_SHIFT) | + (((hs2 & NV40_VP_SRC2_HIGH_MASK) >> NV40_VP_SRC2_HIGH_SHIFT) + << NV40_VP_INST_SRC2H_SHIFT); + hop[3] |= (hs2 & NV40_VP_SRC2_LOW_MASK) << NV40_VP_INST_SRC2L_SHIFT; + + /* bits 127:96 */ + hop[0] |= (dest->condtest << NV40_VP_INST_COND_SHIFT) | + (dest->condswz << NV40_VP_INST_COND_SWZ_ALL_SHIFT); + if (dest->condtest != NV40_VP_INST_COND_TR) + hop[0] |= NV40_VP_INST_COND_TEST_ENABLE; + if (dest->condreg) hop[0] |= NV40_VP_INST_COND_REG_SELECT_1; + if (dest->condup ) hop[0] |= NV40_VP_INST_COND_UPDATE_ENABLE; + + if (hwdest->file == HW_OUTPUT) + hop[0] |= NV40_VP_INST0_UNK0; + else { + if (hwdest->hw_id == -1) + hwdest->hw_id = alloc_hw_temp(vp); + + hop[0] = (hwdest->hw_id << NV40_VP_INST_DEST_TEMP_SHIFT); + if (flags & NOUVEAU_OUT_ABS) + hop[0] |= NV40_VP_INST_DEST_TEMP_ABS; + + nvsBitSet(vp->hwtemps_written, hwdest->hw_id); + if (--hwdest->ref == 0) + free_hw_temp(vp, hwdest->hw_id); + } + + /* bits 95:64 */ + if (constsrc == -1) constsrc = 0; + if (insrc == -1) insrc = 0; + + constsrc &= 0xFF; + insrc &= 0x0F; + hop[1] |= (op << NV40_VP_INST_OPCODE_SHIFT) | + (constsrc << NV40_VP_INST_CONST_SRC_SHIFT) | + (insrc << NV40_VP_INST_INPUT_SRC_SHIFT); + + /* bits 31:0 */ + if (hwdest->file == HW_OUTPUT) { + hop[3] |= (dest->mask | (hwdest->hw_id << NV40_VP_INST_DEST_SHIFT)); + } else { + hop[3] |= (dest->mask | (NV40_VP_INST_DEST_TEMP << NV40_VP_INST_DEST_SHIFT)); + } + hop[3] |= (0x3F << 7); /*FIXME: what is this?*/ + + printf("0x%08x\n", hop[0]); + printf("0x%08x\n", hop[1]); + printf("0x%08x\n", hop[2]); + printf("0x%08x\n", hop[3]); + + instruction_store(vp, hop); +} + +static int +t_swizzle(GLuint swz) +{ + int x, y, z, w; + x = GET_SWZ(swz, 0); + y = GET_SWZ(swz, 1); + z = GET_SWZ(swz, 2); + w = GET_SWZ(swz, 3); + + if ((xFile) { + case PROGRAM_TEMPORARY: + ns->hw = &vp->temps[src->Index]; + break; + case PROGRAM_INPUT: + ns->hw = &vp->inputs[src->Index]; + break; + default: + fprintf(stderr, "Unhandled source register file!\n"); + break; + } + + ns->swizzle = t_swizzle(src->Swizzle); + if ((src->NegateBase != 0xF && src->NegateBase != 0x0) || + ns->swizzle == -1) { + WARN_ONCE("Unhandled source swizzle/negate, results will be incorrect\n"); + ns->swizzle = 0x1B; // 00 01 10 11 - XYZW + ns->negate = (src->NegateBase) ? 1 : 0; + } else + ns->negate = (src->NegateBase) ? 1 : 0; + +} + +static int +t_dst_mask(int mask) +{ + int hwmask = 0; + + if (mask & WRITEMASK_X) hwmask |= NV40_VP_INST_WRITEMASK_X; + if (mask & WRITEMASK_Y) hwmask |= NV40_VP_INST_WRITEMASK_Y; + if (mask & WRITEMASK_Z) hwmask |= NV40_VP_INST_WRITEMASK_Z; + if (mask & WRITEMASK_W) hwmask |= NV40_VP_INST_WRITEMASK_W; + + return hwmask; +} + +static int +t_dst_index(int idx) +{ + int hwidx; + + switch (idx) { + case VERT_RESULT_HPOS: + return NV40_VP_INST_DEST_POS; + case VERT_RESULT_COL0: + return NV40_VP_INST_DEST_COL0; + case VERT_RESULT_COL1: + return NV40_VP_INST_DEST_COL1; + case VERT_RESULT_FOGC: + return NV40_VP_INST_DEST_FOGC; + case VERT_RESULT_TEX0: + case VERT_RESULT_TEX1: + case VERT_RESULT_TEX2: + case VERT_RESULT_TEX3: + case VERT_RESULT_TEX4: + case VERT_RESULT_TEX5: + case VERT_RESULT_TEX6: + case VERT_RESULT_TEX7: + return NV40_VP_INST_DEST_TC(idx - VERT_RESULT_TEX0); + case VERT_RESULT_PSIZ: + return NV40_VP_INST_DEST_PSZ; + case VERT_RESULT_BFC0: + return NV40_VP_INST_DEST_BFC0; + case VERT_RESULT_BFC1: + return NV40_VP_INST_DEST_BFC1; + default: + fprintf(stderr, "Unknown result reg index!\n"); + return -1; + } +} + +static int +t_cond_test(GLuint test) +{ + switch(test) { + case COND_GT: return NV40_VP_INST_COND_GT; + case COND_EQ: return NV40_VP_INST_COND_EQ; + case COND_LT: return NV40_VP_INST_COND_LT; + case COND_GE: return NV40_VP_INST_COND_GE; + case COND_LE: return NV40_VP_INST_COND_LE; + case COND_NE: return NV40_VP_INST_COND_NE; + case COND_TR: return NV40_VP_INST_COND_TR; + case COND_FL: return NV40_VP_INST_COND_FL; + default: + WARN_ONCE("unknown CondMask!\n"); + return -1; + } +} + +#define ARITH_1OP(op) do { \ + t_src_reg(vp, &vpi->SrcReg[0], &src0); \ + emit_arith(vp, op, &dest, &src0, NULL, NULL, 0); \ +} while(0); +#define ARITH_1OP_SCALAR(op) do { \ + t_src_reg(vp, &vpi->SrcReg[0], &src0); \ + emit_arith(vp, op, &dest, NULL, NULL, &src0, 0); \ +} while(0); +#define ARITH_2OP(op) do { \ + t_src_reg(vp, &vpi->SrcReg[0], &src0); \ + t_src_reg(vp, &vpi->SrcReg[1], &src1); \ + emit_arith(vp, op, &dest, &src0, &src1, NULL, 0); \ +} while(0); +#define ARITH_3OP(op) do { \ + t_src_reg(vp, &vpi->SrcReg[0], &src0); \ + t_src_reg(vp, &vpi->SrcReg[1], &src1); \ + t_src_reg(vp, &vpi->SrcReg[2], &src2); \ + emit_arith(vp, op, &dest, &src0, &src1, &src2, 0); \ +} while(0); + +static int +translate(nouveau_vertex_program *vp) +{ + struct vertex_program *mvp = &vp->mesa_program; + struct prog_instruction *vpi; + + + for (vpi=mvp->Base.Instructions; vpi->Opcode!=OPCODE_END; vpi++) { + nouveau_srcreg src0, src1, src2, sT0; + nouveau_dstreg dest, dT0; + + switch (vpi->DstReg.File) { + case PROGRAM_OUTPUT: + make_dstreg(vp, &dest, HW_OUTPUT, t_dst_index(vpi->DstReg.Index)); + break; + case PROGRAM_TEMPORARY: + make_dstreg(vp, &dest, HW_TEMP, vpi->DstReg.Index); + break; + default: + assert(0); + } + dest.mask = t_dst_mask(vpi->DstReg.WriteMask); + dest.condtest = t_cond_test(vpi->DstReg.CondMask); + dest.condswz = t_swizzle(vpi->DstReg.CondSwizzle); + dest.condreg = vpi->DstReg.CondSrc; + + switch (vpi->Opcode) { + /* ARB_vertex_program requirements */ + case OPCODE_ABS: + t_src_reg(vp, &vpi->SrcReg[0], &src0); + emit_arith(vp, NV40_VP_INST_OP_MOV, &dest, + &src0, NULL, NULL, + NOUVEAU_OUT_ABS + ); + break; + case OPCODE_ADD: + t_src_reg(vp, &vpi->SrcReg[0], &src0); + t_src_reg(vp, &vpi->SrcReg[1], &src1); + emit_arith(vp, NV40_VP_INST_OP_ADD, &dest, + &src0, NULL, &src1, + 0 + ); + break; + case OPCODE_ARL: + break; + case OPCODE_DP3: + ARITH_2OP(NV40_VP_INST_OP_DP3); + break; + case OPCODE_DP4: + ARITH_2OP(NV40_VP_INST_OP_DP4); + break; + case OPCODE_DPH: + ARITH_2OP(NV40_VP_INST_OP_DPH); + break; + case OPCODE_DST: + ARITH_2OP(NV40_VP_INST_OP_DST); + break; + case OPCODE_EX2: + ARITH_1OP_SCALAR(NV40_VP_INST_OP_EX2); + break; + case OPCODE_EXP: + ARITH_1OP_SCALAR(NV40_VP_INST_OP_EXP); + break; + case OPCODE_FLR: + ARITH_1OP(NV40_VP_INST_OP_FLR); + break; + case OPCODE_FRC: + ARITH_1OP(NV40_VP_INST_OP_FRC); + break; + case OPCODE_LG2: + ARITH_1OP_SCALAR(NV40_VP_INST_OP_LG2); + break; + case OPCODE_LIT: + t_src_reg(vp, &vpi->SrcReg[0], &src0); + t_src_reg(vp, &vpi->SrcReg[1], &src1); + t_src_reg(vp, &vpi->SrcReg[2], &src2); + emit_arith(vp, NV40_VP_INST_OP_LIT, &dest, + &src0, &src1, &src2, + 0 + ); + break; + case OPCODE_LOG: + ARITH_1OP_SCALAR(NV40_VP_INST_OP_LOG); + break; + case OPCODE_MAD: + ARITH_3OP(NV40_VP_INST_OP_MAD); + break; + case OPCODE_MAX: + ARITH_2OP(NV40_VP_INST_OP_MAX); + break; + case OPCODE_MIN: + ARITH_2OP(NV40_VP_INST_OP_MIN); + break; + case OPCODE_MOV: + ARITH_1OP(NV40_VP_INST_OP_MOV); + break; + case OPCODE_MUL: + ARITH_2OP(NV40_VP_INST_OP_MOV); + break; + case OPCODE_POW: + t_src_reg(vp, &vpi->SrcReg[0], &src0); + t_src_reg(vp, &vpi->SrcReg[1], &src1); + make_dstreg(vp, &dT0, HW_TEMP, -1); + make_srcreg(vp, &sT0, HW_TEMP, dT0.idx); + + dT0.mask = t_dst_mask(WRITEMASK_X); + emit_arith(vp, NV40_VP_INST_OP_LG2, &dT0, + NULL, NULL, &src0, + 0); + sT0.swizzle = 0x0; /* 00000000 - XXXX */ + emit_arith(vp, NV40_VP_INST_OP_MUL, &dT0, + &sT0, &src1, NULL, + 0); + emit_arith(vp, NV40_VP_INST_OP_EX2, &dest, + NULL, NULL, &sT0, + 0); + break; + case OPCODE_RCP: + ARITH_1OP_SCALAR(NV40_VP_INST_OP_RCP); + break; + case OPCODE_RSQ: + ARITH_1OP_SCALAR(NV40_VP_INST_OP_RSQ); + break; + case OPCODE_SGE: + ARITH_2OP(NV40_VP_INST_OP_SGE); + break; + case OPCODE_SLT: + ARITH_2OP(NV40_VP_INST_OP_SLT); + break; + case OPCODE_SUB: + t_src_reg(vp, &vpi->SrcReg[0], &src0); + t_src_reg(vp, &vpi->SrcReg[1], &src1); + src1.negate = !src1.negate; + + emit_arith(vp, NV40_VP_INST_OP_ADD, &dest, + &src0, NULL, &src1, + 0 + ); + break; + case OPCODE_SWZ: + ARITH_1OP(NV40_VP_INST_OP_MOV); + break; + + case OPCODE_XPD: + break; + /* NV_vertex_program3 requirements */ + case OPCODE_SEQ: + ARITH_2OP(NV40_VP_INST_OP_SEQ); + break; + case OPCODE_SFL: + ARITH_2OP(NV40_VP_INST_OP_SFL); + break; + case OPCODE_SGT: + ARITH_2OP(NV40_VP_INST_OP_SGT); + break; + case OPCODE_SLE: + ARITH_2OP(NV40_VP_INST_OP_SLE); + break; + case OPCODE_SNE: + ARITH_2OP(NV40_VP_INST_OP_SNE); + break; + case OPCODE_STR: + ARITH_2OP(NV40_VP_INST_OP_STR); + break; + case OPCODE_SSG: + ARITH_1OP(NV40_VP_INST_OP_SSG); + break; + case OPCODE_ARL_NV: + break; + case OPCODE_ARR: + break; + case OPCODE_ARA: + break; + case OPCODE_RCC: + ARITH_1OP_SCALAR(NV40_VP_INST_OP_SSG); + break; + case OPCODE_BRA: + break; + case OPCODE_CAL: + break; + case OPCODE_RET: + break; + case OPCODE_PUSHA: + break; + case OPCODE_POPA: + break; + default: + break; + } + } + + return 0; +} + +/* Pre-init vertex program + * - Grab reference counts on temps + * - Where multiple inputs are used in a single instruction, + * emit instructions to move the extras into temps + */ +static int +init(nouveau_vertex_program *vp) +{ + struct vertex_program *mvp = &vp->mesa_program; + struct prog_instruction *vpi; + int i; + + nvsRecInit(&vp->temps_in_use, 64); + nvsRecInit(&vp->hwtemps_written, 64); + nvsRecInit(&vp->hwtemps_in_use , 64); + + for (vpi=mvp->Base.Instructions; vpi->Opcode!=OPCODE_END; vpi++) { + int in_done = 0; + int in_idx; + + for (i=0;i<3;i++) { + struct prog_src_register *src = &vpi->SrcReg[i]; + /*FIXME: does not handle relative addressing!*/ + int idx = src->Index; + + switch (src->File) { + case PROGRAM_TEMPORARY: + vp->temps[idx].file = HW_TEMP; + vp->temps[idx].hw_id = -1; + vp->temps[idx].ref++; + nvsBitSet(vp->temps_in_use, idx); + break; + case PROGRAM_INPUT: + if (vp->inputs[idx].file == HW_TEMP) { + vp->inputs[idx].ref++; + break; + } + + if (!in_done || (in_idx == idx)) { + vp->inputs[idx].file = HW_INPUT; + vp->inputs[idx].hw_id = idx; + vp->inputs[idx].ref++; + in_done = 1; + in_idx = idx; + } else { + vp->inputs[idx].file = HW_TEMP; + vp->inputs[idx].ref++; + } + break; + default: + break; + } + } + + switch (vpi->DstReg.File) { + case PROGRAM_TEMPORARY: + vp->temps[vpi->DstReg.Index].file = HW_TEMP; + vp->temps[vpi->DstReg.Index].hw_id = -1; + vp->temps[vpi->DstReg.Index].ref++; + nvsBitSet(vp->temps_in_use, vpi->DstReg.Index); + break; + default: + break; + } + } + + /* Now we can move any inputs that need it into temps */ + for (i=0; i<14; i++) { + if (vp->inputs[i].file == HW_TEMP) { + nouveau_srcreg src; + nouveau_dstreg dest; + + make_dstreg(vp, &dest, HW_TEMP , -1); + make_srcreg(vp, &src , HW_INPUT, i); + + emit_arith(vp, NV40_VP_INST_OP_MOV, &dest, + &src, NULL, NULL, + 0 + ); + + vp->inputs[i].file = HW_TEMP; + vp->inputs[i].hw_id = dest.hw->hw_id; + } + } + + return 0; +} + +int +nv40TranslateVertexProgram(nouveau_vertex_program *vp) +{ + int ret; + + ret = init(vp); + if (ret) + return ret; + + ret = translate(vp); + if (ret) + return ret; + + return 0; +} + +int +main(int argc, char **argv) +{ + nouveau_vertex_program *vp = calloc(1, sizeof(nouveau_vertex_program)); + struct vertex_program *mvp = &vp->mesa_program; + struct prog_instruction inst[3]; + + /* + "ADD t0, vertex.color, vertex.position;\n" + "ADD result.position, t0, vertex.position;\n" + */ + + inst[0].Opcode = OPCODE_ADD; + inst[0].SrcReg[0].File = PROGRAM_INPUT; + inst[0].SrcReg[0].Index = VERT_ATTRIB_COLOR0; + inst[0].SrcReg[0].NegateBase = 0; + inst[0].SrcReg[0].Swizzle = MAKE_SWIZZLE4(0, 1, 2, 3); + inst[0].SrcReg[1].File = PROGRAM_INPUT; + inst[0].SrcReg[1].Index = VERT_ATTRIB_POS; + inst[0].SrcReg[1].NegateBase = 0; + inst[0].SrcReg[1].Swizzle = MAKE_SWIZZLE4(0, 1, 2, 3); + inst[0].SrcReg[2].File = PROGRAM_UNDEFINED; + inst[0].DstReg.File = PROGRAM_TEMPORARY; + inst[0].DstReg.Index = 0; + inst[0].DstReg.WriteMask = WRITEMASK_XYZW; + + inst[1].Opcode = OPCODE_ADD; + inst[1].SrcReg[0].File = PROGRAM_TEMPORARY; + inst[1].SrcReg[0].Index = 0; + inst[1].SrcReg[0].NegateBase = 0; + inst[1].SrcReg[0].Swizzle = MAKE_SWIZZLE4(0, 1, 2, 3); + inst[1].SrcReg[1].File = PROGRAM_INPUT; + inst[1].SrcReg[1].Index = VERT_ATTRIB_POS; + inst[1].SrcReg[1].NegateBase = 0; + inst[1].SrcReg[1].Swizzle = MAKE_SWIZZLE4(0, 1, 2, 3); + inst[0].SrcReg[2].File = PROGRAM_UNDEFINED; + inst[1].DstReg.File = PROGRAM_OUTPUT; + inst[1].DstReg.Index = VERT_RESULT_HPOS; + inst[1].DstReg.WriteMask = WRITEMASK_XYZW; + + inst[2].Opcode = OPCODE_END; + + mvp->Base.Instructions = inst; + + nv40TranslateVertexProgram(vp); +} + -- cgit v1.2.3 From ac9d1ecec2ad5f55742fa1ccc4853f560ca7fcd9 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 3 Jun 2006 16:37:46 +0000 Subject: Another TODO, so I don't forget.. --- src/mesa/drivers/dri/nouveau/nv40_vtxprog.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv40_vtxprog.c b/src/mesa/drivers/dri/nouveau/nv40_vtxprog.c index 582bf65ea0..43909725df 100644 --- a/src/mesa/drivers/dri/nouveau/nv40_vtxprog.c +++ b/src/mesa/drivers/dri/nouveau/nv40_vtxprog.c @@ -16,6 +16,7 @@ * - Handle ARB_position_invarient * - Relative register addressing * - Implement any missing instructions + * - Fix scalar instructions (the other "writemask") */ static int t_dst_mask(int mask); -- cgit v1.2.3 From 6d1f98da2ba921fa18cd19ef43f2760549a2aea4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 3 Jun 2006 17:15:50 +0000 Subject: A couple of quick fixes, the original had some half-finished modifications.. --- src/mesa/drivers/dri/nouveau/nv40_vtxprog.c | 75 +++++++++++++++++------------ 1 file changed, 45 insertions(+), 30 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv40_vtxprog.c b/src/mesa/drivers/dri/nouveau/nv40_vtxprog.c index 43909725df..8bdacb89e7 100644 --- a/src/mesa/drivers/dri/nouveau/nv40_vtxprog.c +++ b/src/mesa/drivers/dri/nouveau/nv40_vtxprog.c @@ -67,7 +67,7 @@ make_srcreg(nouveau_vertex_program *vp, { switch (type) { case HW_INPUT: - src->hw = &vp->inputs[id]; + src->hw = NULL; src->idx = id; break; case HW_TEMP: @@ -134,33 +134,38 @@ src_to_hw(nouveau_vertex_program *vp, nouveau_srcreg *src, return hs; } - switch (src->hw->file) { - case HW_INPUT: - if (*is != -1) { - fprintf(stderr, "multiple inputs detected... not good\n"); - return; - } - *is = src->hw->hw_id; + if (!src->hw) { /* this is a forced read from a "real" hardware source */ + *is = src->idx; hs |= (NV40_VP_SRC_REG_TYPE_INPUT << NV40_VP_SRC_REG_TYPE_SHIFT); - break; - case HW_CONST: - if (*cs != -1) { - fprintf(stderr, "multiple consts detected... not good\n"); - return; - } - *cs = src->hw->hw_id; - hs |= (NV40_VP_SRC_REG_TYPE_CONST << NV40_VP_SRC_REG_TYPE_SHIFT); - break; - case HW_TEMP: - if (src->hw->hw_id == -1) { - fprintf(stderr, "read from unwritten temp!\n"); - return; - } - hs |= (NV40_VP_SRC_REG_TYPE_TEMP << NV40_VP_SRC_REG_TYPE_SHIFT) | - (src->hw->hw_id << NV40_VP_SRC_TEMP_SRC_SHIFT); + } else { + switch (src->hw->file) { + case HW_INPUT: + if (*is != -1) { + fprintf(stderr, "multiple inputs detected... not good\n"); + return; + } + *is = src->hw->hw_id; + hs |= (NV40_VP_SRC_REG_TYPE_INPUT << NV40_VP_SRC_REG_TYPE_SHIFT); + break; + case HW_CONST: + if (*cs != -1) { + fprintf(stderr, "multiple consts detected... not good\n"); + return; + } + *cs = src->hw->hw_id; + hs |= (NV40_VP_SRC_REG_TYPE_CONST << NV40_VP_SRC_REG_TYPE_SHIFT); + break; + case HW_TEMP: + if (src->hw->hw_id == -1) { + fprintf(stderr, "read from unwritten temp!\n"); + return; + } + hs |= (NV40_VP_SRC_REG_TYPE_TEMP << NV40_VP_SRC_REG_TYPE_SHIFT) | + (src->hw->hw_id << NV40_VP_SRC_TEMP_SRC_SHIFT); - if (--src->hw->ref == 0) - free_hw_temp(vp, src->hw->hw_id); + if (--src->hw->ref == 0) + free_hw_temp(vp, src->hw->hw_id); + } } hs |= (src->swizzle << NV40_VP_SRC_SWZ_ALL_SHIFT); @@ -219,13 +224,13 @@ emit_arith(nouveau_vertex_program *vp, int op, if (dest->condreg) hop[0] |= NV40_VP_INST_COND_REG_SELECT_1; if (dest->condup ) hop[0] |= NV40_VP_INST_COND_UPDATE_ENABLE; - if (hwdest->file == HW_OUTPUT) + if (hwdest == NULL /* write output */) hop[0] |= NV40_VP_INST0_UNK0; else { if (hwdest->hw_id == -1) hwdest->hw_id = alloc_hw_temp(vp); - hop[0] = (hwdest->hw_id << NV40_VP_INST_DEST_TEMP_SHIFT); + hop[0] |= (hwdest->hw_id << NV40_VP_INST_DEST_TEMP_SHIFT); if (flags & NOUVEAU_OUT_ABS) hop[0] |= NV40_VP_INST_DEST_TEMP_ABS; @@ -245,8 +250,8 @@ emit_arith(nouveau_vertex_program *vp, int op, (insrc << NV40_VP_INST_INPUT_SRC_SHIFT); /* bits 31:0 */ - if (hwdest->file == HW_OUTPUT) { - hop[3] |= (dest->mask | (hwdest->hw_id << NV40_VP_INST_DEST_SHIFT)); + if (hwdest == NULL) { + hop[3] |= (dest->mask | (dest->idx << NV40_VP_INST_DEST_SHIFT)); } else { hop[3] |= (dest->mask | (NV40_VP_INST_DEST_TEMP << NV40_VP_INST_DEST_SHIFT)); } @@ -713,6 +718,11 @@ main(int argc, char **argv) inst[0].DstReg.File = PROGRAM_TEMPORARY; inst[0].DstReg.Index = 0; inst[0].DstReg.WriteMask = WRITEMASK_XYZW; + inst[0].DstReg.CondMask = COND_TR; + inst[0].DstReg.CondSwizzle = MAKE_SWIZZLE4(0, 1, 2, 3); + inst[0].DstReg.CondSrc = 0; + inst[0].CondUpdate = 0; + inst[0].CondDst = 0; inst[1].Opcode = OPCODE_ADD; inst[1].SrcReg[0].File = PROGRAM_TEMPORARY; @@ -727,6 +737,11 @@ main(int argc, char **argv) inst[1].DstReg.File = PROGRAM_OUTPUT; inst[1].DstReg.Index = VERT_RESULT_HPOS; inst[1].DstReg.WriteMask = WRITEMASK_XYZW; + inst[1].DstReg.CondMask = COND_TR; + inst[1].DstReg.CondSwizzle = MAKE_SWIZZLE4(0, 1, 2, 3); + inst[1].DstReg.CondSrc = 0; + inst[1].CondUpdate = 0; + inst[1].CondDst = 0; inst[2].Opcode = OPCODE_END; -- cgit v1.2.3 From 179c1013d2a8aa83e6bd716a791930863604c46b Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 8 Sep 2006 20:17:59 +0000 Subject: Remove useless reference to fifo_num field --- src/mesa/drivers/dri/nouveau/nouveau_ioctl.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_ioctl.c b/src/mesa/drivers/dri/nouveau/nouveau_ioctl.c index 32bdcef06b..4530cf9133 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_ioctl.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_ioctl.c @@ -39,15 +39,13 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. 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); + MESSAGE("Fifo init ok. Channel %d\n", fifo_init.channel); // XXX needs more stuff } -- cgit v1.2.3 From 6f0388ec71aaab8673fe2facf6811259a9787797 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 8 Sep 2006 21:23:04 +0000 Subject: basic primitives --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 71 ++++++++++++++++++------------- 1 file changed, 41 insertions(+), 30 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index d825de6559..bbd674855c 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -170,40 +170,51 @@ static inline void nv10_draw_point(nouveauContextPtr nmesa, * 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 \ - nv10_draw_triangle(nmesa, a, b, c); \ - } while (0) +#define CTX_ARG nouveauContextPtr nmesa +#define VERTEX nouveauVertex -#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 \ - nv10_draw_quad(nmesa, a, b, c, d); \ - } while (0) +#undef TAG +#define TAG(x) nouveau_##x -#define LINE(v0, v1) \ - do { \ - if (DO_FALLBACK) \ - nmesa->draw_line(nmesa, v0, v1); \ - else \ - nv10_draw_line(nmesa, v0, v1); \ - } while (0) +static __inline void TAG(quad)( CTX_ARG, + VERTEX *v0, + VERTEX *v1, + VERTEX *v2, + VERTEX *v3 ) +{ + (*nmesa->draw_tri)(nmesa, v0, v1, v3); + (*nmesa->draw_tri)(nmesa, v1, v2, v3); + /* FIXME: Need to add nmesa->draw_quad in nouveau_context ? */ + /* nv10_draw_quad(nmesa, v0, v1, v2, v3); */ +} -#define POINT(v0) \ - do { \ - if (DO_FALLBACK) \ - nmesa->draw_point(nmesa, v0); \ - else \ - nv10_draw_point(nmesa, v0); \ - } while (0) +static __inline void TAG(triangle)( CTX_ARG, + VERTEX *v0, + VERTEX *v1, + VERTEX *v2 ) +{ + (*nmesa->draw_tri)(nmesa, v0, v1, v2); +} +static __inline void TAG(line)( CTX_ARG, + VERTEX *v0, + VERTEX *v1 ) +{ + (*nmesa->draw_line)(nmesa, v0, v1); +} + +static __inline void TAG(point)( CTX_ARG, + VERTEX *v0 ) +{ + (*nmesa->draw_point)(nmesa, v0); +} + +#define QUAD( a, b, c, d ) nouveau_quad( nmesa, a, b, c, d ) +#define TRI( a, b, c ) nouveau_triangle( nmesa, a, b, c ) +#define LINE( a, b ) nouveau_line( nmesa, a, b ) +#define POINT( a ) nouveau_point( nmesa, a ) + +#undef TAG /*********************************************************************** * Build render functions from dd templates * -- cgit v1.2.3 From ad0f65537695492a6651857d59d7bad27bae6c8b Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 8 Sep 2006 21:27:17 +0000 Subject: vert_copy_rgba macro --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index bbd674855c..7f3d275c40 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -272,15 +272,7 @@ static struct { color->alpha=(c)[3]; \ } while (0) -#define VERT_COPY_RGBA( v0, v1 ) \ - do { \ - if (coloroffset) { \ - v0->f[coloroffset][0] = v1->f[coloroffset][0]; \ - v0->f[coloroffset][1] = v1->f[coloroffset][1]; \ - v0->f[coloroffset][2] = v1->f[coloroffset][2]; \ - v0->f[coloroffset][3] = v1->f[coloroffset][3]; \ - } \ - } while (0) +#define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset] #define VERT_SET_SPEC( v, c ) \ do { \ -- cgit v1.2.3 From 07d4c63ddc39a41c1048bd92c41b22b8c11712f3 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 8 Sep 2006 21:30:32 +0000 Subject: vert_copy_spec macro --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 7f3d275c40..75b35271f6 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -286,9 +286,11 @@ static struct { #define VERT_COPY_SPEC( v0, v1 ) \ do { \ if (specoffset) { \ - v0->f[specoffset][0] = v1->f[specoffset][0]; \ - v0->f[specoffset][1] = v1->f[specoffset][1]; \ - v0->f[specoffset][2] = v1->f[specoffset][2]; \ + nouveau_color_t *spec0 = (nouveau_color_t *)&((v0)->ui[specoffset]); \ + nouveau_color_t *spec1 = (nouveau_color_t *)&((v1)->ui[specoffset]); \ + spec0->red = spec1->red; \ + spec0->green = spec1->green; \ + spec0->blue = spec1->blue; \ } \ } while (0) -- cgit v1.2.3 From 7a968481a00216e07d9a7d6400de147ddab66efd Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 8 Sep 2006 21:34:47 +0000 Subject: render_primitive macro --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 75b35271f6..217193ba99 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -327,7 +327,7 @@ static const GLuint hw_prim[GL_POLYGON+1] = { }; #define RASTERIZE(x) nv10RasterPrimitive( ctx, x, hw_prim[x] ) -#define RENDER_PRIMITIVE nmesa->renderPrimitive +#define RENDER_PRIMITIVE nmesa->current_primitive #define TAG(x) x #define IND NOUVEAU_FALLBACK_BIT #include "tnl_dd/t_dd_unfilled.h" -- cgit v1.2.3 From 1961611247313603f72315285be91c6b97df7e03 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 8 Sep 2006 21:41:58 +0000 Subject: reimport sw stuff --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 40 ++++--------------------------- 1 file changed, 4 insertions(+), 36 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 217193ba99..2ed151f0fc 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -166,48 +166,16 @@ static inline void nv10_draw_point(nouveauContextPtr nmesa, -/*********************************************************************** - * Macros for nouveau_dd_tritmp.h to draw basic primitives * - ***********************************************************************/ - #define CTX_ARG nouveauContextPtr nmesa #define VERTEX nouveauVertex #undef TAG #define TAG(x) nouveau_##x +#include "tnl_dd/t_dd_triemit.h" -static __inline void TAG(quad)( CTX_ARG, - VERTEX *v0, - VERTEX *v1, - VERTEX *v2, - VERTEX *v3 ) -{ - (*nmesa->draw_tri)(nmesa, v0, v1, v3); - (*nmesa->draw_tri)(nmesa, v1, v2, v3); - /* FIXME: Need to add nmesa->draw_quad in nouveau_context ? */ - /* nv10_draw_quad(nmesa, v0, v1, v2, v3); */ -} - -static __inline void TAG(triangle)( CTX_ARG, - VERTEX *v0, - VERTEX *v1, - VERTEX *v2 ) -{ - (*nmesa->draw_tri)(nmesa, v0, v1, v2); -} - -static __inline void TAG(line)( CTX_ARG, - VERTEX *v0, - VERTEX *v1 ) -{ - (*nmesa->draw_line)(nmesa, v0, v1); -} - -static __inline void TAG(point)( CTX_ARG, - VERTEX *v0 ) -{ - (*nmesa->draw_point)(nmesa, v0); -} +/*********************************************************************** + * Macros for nouveau_dd_tritmp.h to draw basic primitives * + ***********************************************************************/ #define QUAD( a, b, c, d ) nouveau_quad( nmesa, a, b, c, d ) #define TRI( a, b, c ) nouveau_triangle( nmesa, a, b, c ) -- cgit v1.2.3 From cdd433b29be9ad39b0c2e69d76d2de51f29eba2b Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 8 Sep 2006 21:52:25 +0000 Subject: more macros, still missing the alloc_verts one --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 2ed151f0fc..35135fc706 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -167,6 +167,11 @@ static inline void nv10_draw_point(nouveauContextPtr nmesa, #define CTX_ARG nouveauContextPtr nmesa +#define GET_VERTEX_DWORDS() nmesa->vertex_size +#define LOCAL_VARS \ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); \ + const char *nouveauverts = (char *)nmesa->verts; +#define VERT(x) (r200Vertex *)(r200verts + ((x) * vertsize * sizeof(int))) #define VERTEX nouveauVertex #undef TAG @@ -269,6 +274,7 @@ static struct { #define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->f[specoffset] = spec[idx] +#undef LOCAL_VARS #define LOCAL_VARS(n) \ struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); \ GLuint color[n], spec[n]; \ -- cgit v1.2.3 From ddaf3060fa5105dd9c769086a4bbfdb2488ae86b Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 8 Sep 2006 23:18:27 +0000 Subject: nv10: vertex attribute output format --- src/mesa/drivers/dri/nouveau/nouveau_reg.h | 2 ++ src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 23 ++++++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_reg.h b/src/mesa/drivers/dri/nouveau/nouveau_reg.h index 5f4b0624ad..583a2b82cb 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_reg.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_reg.h @@ -65,6 +65,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV20_VERTEX_ATTRIBUTE_TYPE_MASK 0x0000000f #define NV20_VERTEX_ATTRIBUTE_TYPE_FLOAT 0x00000002 #define NV20_VERTEX_ATTRIBUTE_SIZE_MASK 0x000000f0 +#define NV10_VERTEX_ATTRIBUTE(i) (0x00000d04+i*8) +#define NV10_VERTEX_SET_FORMAT 0x00000cf0 /* Rendering commands */ #define NV10_PRIMITIVE 0x00000dfc diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 35135fc706..55507b277b 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -670,7 +670,28 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa, GLuint * Tell the hardware about the vertex format */ if (nmesa->screen->card_type==NV_10) { - // XXX needs some love + int size; + +#define NV10_SET_VERTEX_ATTRIB(i,j,k) \ + do { \ + size = attr_size[j] << 4; \ + size |= (attr_size[j]*4) << 8; \ + size |= NV20_VERTEX_ATTRIBUTE_TYPE_FLOAT; \ + BEGIN_RING_SIZE(channel, NV10_VERTEX_ATTRIBUTE(i),1); \ + OUT_RING(size); \ + } while (0) + + NV10_SET_VERTEX_ATTRIB(0, _TNL_ATTRIB_POS); + NV10_SET_VERTEX_ATTRIB(1, _TNL_ATTRIB_COLOR0); + NV10_SET_VERTEX_ATTRIB(2, _TNL_ATTRIB_COLOR1); + NV10_SET_VERTEX_ATTRIB(3, _TNL_ATTRIB_TX0); + NV10_SET_VERTEX_ATTRIB(4, _TNL_ATTRIB_TX1); + NV10_SET_VERTEX_ATTRIB(5, _TNL_ATTRIB_NORMAL); + NV10_SET_VERTEX_ATTRIB(6, _TNL_ATTRIB_WEIGHT); + NV10_SET_VERTEX_ATTRIB(7, _TNL_ATTRIB_FOG); + + BEGIN_RING_SIZE(channel, NV10_VERTEX_SET_FORMAT); + OUT_RING(0); } else if (nmesa->screen->card_type==NV_20) { for(i=0;i<16;i++) { -- cgit v1.2.3 From ae481e1560d0c99b6fb2c4b240f9b99dafd9c4b1 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 8 Sep 2006 23:19:45 +0000 Subject: oops, time to go to bed --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 55507b277b..31a54b3e5c 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -672,7 +672,7 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa, GLuint if (nmesa->screen->card_type==NV_10) { int size; -#define NV10_SET_VERTEX_ATTRIB(i,j,k) \ +#define NV10_SET_VERTEX_ATTRIB(i,j) \ do { \ size = attr_size[j] << 4; \ size |= (attr_size[j]*4) << 8; \ -- cgit v1.2.3 From 908388b11841c50c94c1c746819276809a545a32 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sun, 17 Sep 2006 11:58:52 +0000 Subject: Some work towards making the nv10 swtcl compile --- src/mesa/drivers/dri/nouveau/nouveau_context.h | 6 ++-- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 41 ++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 9 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index e1c5d4d54e..ad3d00f588 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -103,9 +103,9 @@ typedef struct nouveau_context { /* The drawing fallbacks */ GLuint Fallback; - nouveau_tri_func* draw_tri; - nouveau_line_func* draw_line; - nouveau_point_func* draw_point; + nouveau_tri_func draw_tri; + nouveau_line_func draw_line; + nouveau_point_func draw_point; /* Cliprects information */ GLuint numClipRects; diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 31a54b3e5c..0ddc466d5b 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -171,7 +171,7 @@ static inline void nv10_draw_point(nouveauContextPtr nmesa, #define LOCAL_VARS \ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); \ const char *nouveauverts = (char *)nmesa->verts; -#define VERT(x) (r200Vertex *)(r200verts + ((x) * vertsize * sizeof(int))) +#define VERT(x) (nouveauVertex *)(nouveauverts + ((x) * vertsize * sizeof(int))) #define VERTEX nouveauVertex #undef TAG @@ -182,10 +182,39 @@ static inline void nv10_draw_point(nouveauContextPtr nmesa, * Macros for nouveau_dd_tritmp.h to draw basic primitives * ***********************************************************************/ -#define QUAD( a, b, c, d ) nouveau_quad( nmesa, a, b, c, d ) -#define TRI( a, b, c ) nouveau_triangle( nmesa, a, b, c ) -#define LINE( a, b ) nouveau_line( nmesa, a, b ) -#define POINT( a ) nouveau_point( nmesa, a ) +#define TRI(a, b, c) \ + do { \ + if (DO_FALLBACK) \ + nmesa->draw_tri(nmesa, a, b, c); \ + else \ + nv10_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 \ + nv10_draw_quad(nmesa, a, b, c, d); \ + } while (0) + +#define LINE(v0, v1) \ + do { \ + if (DO_FALLBACK) \ + nmesa->draw_line(nmesa, v0, v1); \ + else \ + nv10_draw_line(nmesa, v0, v1); \ + } while (0) + +#define POINT(v0) \ + do { \ + if (DO_FALLBACK) \ + nmesa->draw_point(nmesa, v0); \ + else \ + nv10_draw_point(nmesa, v0); \ + } while (0) #undef TAG @@ -467,7 +496,7 @@ static void nouveauRenderClippedPoly(GLcontext *ctx, const GLuint *elts, { TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - GLuint prim = NOUVEAU_CONTEXT(ctx)->renderPrimitive; + GLuint prim = NOUVEAU_CONTEXT(ctx)->current_primitive; /* Render the new vertices as an unclipped polygon. */ -- cgit v1.2.3 From e324c52237fd1184a1f8436c8735cdd9ade5e067 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sun, 17 Sep 2006 12:09:11 +0000 Subject: Make nouveau actually compile --- src/mesa/drivers/dri/nouveau/nouveau_context.h | 2 +- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 26 +++++++++++++++++--------- src/mesa/drivers/dri/nouveau/nv10_swtcl.h | 1 - 3 files changed, 18 insertions(+), 11 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index ad3d00f588..28fe944280 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -113,7 +113,7 @@ typedef struct nouveau_context { /* The rendering context information */ GLenum current_primitive; /* the current primitive enum */ - GLuint render_inputs; /* the current render inputs */ + GLuint render_inputs_bitset; /* the current render inputs */ nouveauScreenRec *screen; drm_nouveau_sarea_t *sarea; diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 0ddc466d5b..65c24f3779 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -52,8 +52,9 @@ /* XXX hack for now */ #define channel 1 -static void nv10RenderPrimitive( GLcontext *ctx, GLenum prim ); static void nv10RasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim ); +static void nv10RenderPrimitive( GLcontext *ctx, GLenum prim ); +static void nv10ResetLineStipple( GLcontext *ctx ); @@ -466,7 +467,7 @@ const GLuint vertsize = nmesa->vertex_size; \ 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_STIPPLE if ( stipple ) nv10ResetLineStipple( ctx ); #define RESET_OCCLUSION #define PRESERVE_VB_DEFS #define ELT(x) x @@ -650,6 +651,7 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa, GLuint for(i=8;i<16;i++) { if (index&(1<TexCoordPtr[i]; else attr_size[i]=0; @@ -713,13 +715,13 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa, GLuint NV10_SET_VERTEX_ATTRIB(0, _TNL_ATTRIB_POS); NV10_SET_VERTEX_ATTRIB(1, _TNL_ATTRIB_COLOR0); NV10_SET_VERTEX_ATTRIB(2, _TNL_ATTRIB_COLOR1); - NV10_SET_VERTEX_ATTRIB(3, _TNL_ATTRIB_TX0); - NV10_SET_VERTEX_ATTRIB(4, _TNL_ATTRIB_TX1); + NV10_SET_VERTEX_ATTRIB(3, _TNL_ATTRIB_TEX0); + NV10_SET_VERTEX_ATTRIB(4, _TNL_ATTRIB_TEX1); NV10_SET_VERTEX_ATTRIB(5, _TNL_ATTRIB_NORMAL); NV10_SET_VERTEX_ATTRIB(6, _TNL_ATTRIB_WEIGHT); NV10_SET_VERTEX_ATTRIB(7, _TNL_ATTRIB_FOG); - BEGIN_RING_SIZE(channel, NV10_VERTEX_SET_FORMAT); + BEGIN_RING_SIZE(channel, NV10_VERTEX_SET_FORMAT,1); OUT_RING(0); } else if (nmesa->screen->card_type==NV_20) { for(i=0;i<16;i++) @@ -749,11 +751,11 @@ static void nv10ChooseVertexState( GLcontext *ctx ) { struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); - GLuint index = tnl->render_inputs; + GLuint index = tnl->render_inputs_bitset; - if (index!=nmesa->render_inputs) + if (index!=nmesa->render_inputs_bitset) { - nmesa->render_inputs=index; + nmesa->render_inputs_bitset=index; nv10OutputVertexFormat(nmesa,index); } } @@ -766,6 +768,7 @@ static void nv10ChooseVertexState( GLcontext *ctx ) static void nv10RenderStart(GLcontext *ctx) { + TNLcontext *tnl = TNL_CONTEXT(ctx); struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); if (nmesa->new_state) { @@ -816,6 +819,11 @@ static void nv10RenderPrimitive( GLcontext *ctx, GLuint prim ) nv10RasterPrimitive( ctx, prim, hw_prim[prim] ); } +static void nv10ResetLineStipple( GLcontext *ctx ) +{ + /* FIXME do something here */ +} + /**********************************************************************/ /* Initialization. */ @@ -836,7 +844,7 @@ void nv10TriInitFunctions(GLcontext *ctx) tnl->Driver.Render.Start = nv10RenderStart; tnl->Driver.Render.Finish = nv10RenderFinish; tnl->Driver.Render.PrimitiveNotify = nv10RenderPrimitive; - tnl->Driver.Render.ResetLineStipple = nouveauResetLineStipple; + tnl->Driver.Render.ResetLineStipple = nv10ResetLineStipple; tnl->Driver.Render.BuildVertices = _tnl_build_vertices; tnl->Driver.Render.CopyPV = _tnl_copy_pv; tnl->Driver.Render.Interp = _tnl_interp; diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.h b/src/mesa/drivers/dri/nouveau/nv10_swtcl.h index 03338fbe13..7c854addd2 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.h +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.h @@ -33,7 +33,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. extern void nv10Fallback( GLcontext *ctx, GLuint bit, GLboolean mode ); extern void nv10FinishPrimitive(struct nouveau_context *nmesa); -extern void nv10RenderStart(GLcontext *ctx); extern void nv10TriInitFunctions(GLcontext *ctx); #define FALLBACK( nmesa, bit, mode ) nouveauFallback( nmesa->glCtx, bit, mode ) -- cgit v1.2.3 From c67f54552077b780df574cbcdea70b2cc37076ef Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sun, 17 Sep 2006 14:36:07 +0000 Subject: Small changes --- src/mesa/drivers/dri/nouveau/nouveau_context.c | 2 -- src/mesa/drivers/dri/nouveau/nouveau_context.h | 2 +- src/mesa/drivers/dri/nouveau/nouveau_tris.c | 1 - src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 5 +++-- 4 files changed, 4 insertions(+), 6 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 683e6d6ea6..d84e73c015 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -55,8 +55,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. int NOUVEAU_DEBUG = 0; #endif -#define NOUVEAU_FALLBACK_DISABLE 1 - static const struct dri_debug_control debug_control[] = { { NULL, 0 } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 28fe944280..c5783993c7 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -92,7 +92,7 @@ typedef struct nouveau_context { /* Vertex state */ GLuint vertex_size; - char *verts; + GLubyte *verts; struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; GLuint vertex_attr_count; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_tris.c b/src/mesa/drivers/dri/nouveau/nouveau_tris.c index 8622b9349c..bb8ead3b23 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_tris.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_tris.c @@ -74,7 +74,6 @@ void nouveau_fallback_point(struct nouveau_context *nmesa, 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) { diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 65c24f3779..af9f4fabf4 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -48,6 +48,7 @@ #include "nouveau_reg.h" #include "nouveau_tex.h" #include "nouveau_fifo.h" +#include "nouveau_msg.h" /* XXX hack for now */ #define channel 1 @@ -651,8 +652,7 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa, GLuint for(i=8;i<16;i++) { if (index&(1<TexCoordPtr[i]; + attr_size[i]=VB->TexCoordPtr[i]->size; else attr_size[i]=0; } @@ -822,6 +822,7 @@ static void nv10RenderPrimitive( GLcontext *ctx, GLuint prim ) static void nv10ResetLineStipple( GLcontext *ctx ) { /* FIXME do something here */ + WARN_ONCE("Unimplemented nv10ResetLineStipple\n"); } -- cgit v1.2.3 From 473a38622e46d46b74d7426d0a2f4b60f4a1d5d4 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sun, 17 Sep 2006 15:30:40 +0000 Subject: Rename nouveau_tris.* to nouveau_swtcl.* --- src/mesa/drivers/dri/nouveau/Makefile | 2 +- src/mesa/drivers/dri/nouveau/nouveau_ioctl.c | 5 +- src/mesa/drivers/dri/nouveau/nouveau_ioctl.h | 4 +- src/mesa/drivers/dri/nouveau/nouveau_state.c | 2 +- src/mesa/drivers/dri/nouveau/nouveau_swtcl.c | 127 +++++++++++++++++++++++++++ src/mesa/drivers/dri/nouveau/nouveau_swtcl.h | 55 ++++++++++++ src/mesa/drivers/dri/nouveau/nouveau_tris.c | 125 -------------------------- src/mesa/drivers/dri/nouveau/nouveau_tris.h | 55 ------------ src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 2 +- 9 files changed, 190 insertions(+), 187 deletions(-) create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_swtcl.c create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_swtcl.h delete mode 100644 src/mesa/drivers/dri/nouveau/nouveau_tris.c delete mode 100644 src/mesa/drivers/dri/nouveau/nouveau_tris.h (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile index fc51205019..ee7bc5d317 100644 --- a/src/mesa/drivers/dri/nouveau/Makefile +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -16,7 +16,7 @@ DRIVER_SOURCES = \ nouveau_span.c \ nouveau_state.c \ nouveau_tex.c \ - nouveau_tris.c \ + nouveau_swtcl.c \ nv10_swtcl.c C_SOURCES = \ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_ioctl.c b/src/mesa/drivers/dri/nouveau/nouveau_ioctl.c index 4530cf9133..46ac527f83 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_ioctl.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_ioctl.c @@ -36,13 +36,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_msg.h" // here we call the fifo initialization ioctl and fill in stuff accordingly -void nouveauIoctlInitFifo() +void nouveauIoctlInitFifo(nouveauContextPtr nmesa) { int ret; - __DRIscreenPrivate *sPriv; drm_nouveau_fifo_init_t fifo_init; - ret = drmCommandWriteRead(sPriv->fd, DRM_NOUVEAU_FIFO_INIT, &fifo_init, sizeof(fifo_init)); + ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_FIFO_INIT, &fifo_init, sizeof(fifo_init)); if (ret) FATAL("Fifo initialization ioctl failed (returned %d)\n",ret); MESSAGE("Fifo init ok. Channel %d\n", fifo_init.channel); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_ioctl.h b/src/mesa/drivers/dri/nouveau/nouveau_ioctl.h index 3147265e90..ce77d3d11e 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_ioctl.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_ioctl.h @@ -28,7 +28,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef __NOUVEAU_IOCTL_H__ #define __NOUVEAU_IOCTL_H__ -extern void nouveauIoctlInitFifo(); +#include "nouveau_context.h" + +extern void nouveauIoctlInitFifo(nouveauContextPtr nmesa); extern void nouveauIoctlInitFunctions(struct dd_function_table *functions); #endif /* __NOUVEAU_IOCTL_H__ */ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c index b7f53ff957..417fd9fbcc 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -27,7 +27,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_context.h" #include "nouveau_state.h" #include "nouveau_ioctl.h" -#include "nouveau_tris.h" +#include "nouveau_swtcl.h" #include "nouveau_fifo.h" #include "swrast/swrast.h" diff --git a/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c b/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c new file mode 100644 index 0000000000..7c7ba7374b --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c @@ -0,0 +1,127 @@ +/************************************************************************** + +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. + +**************************************************************************/ + +/* Common software TCL code */ + +#include "nouveau_context.h" +#include "nouveau_swtcl.h" +#include "nv10_swtcl.h" +#include "nouveau_span.h" +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/tnl.h" +#include "tnl/t_pipeline.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]); + _swrast_Triangle(ctx, &v[0], &v[1], &v[2]); +} + + +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]); + _swrast_Line(ctx, &v[0], &v[1]); +} + + +void nouveau_fallback_point(struct nouveau_context *nmesa, + nouveauVertex *v0) +{ + GLcontext *ctx = nmesa->glCtx; + SWvertex v[1]; + _swsetup_Translate(ctx, v0, &v[0]); + _swrast_Point(ctx, &v[0]); +} + +void nouveauFallback(struct nouveau_context *nmesa, GLuint bit, GLboolean mode) +{ + GLcontext *ctx = nmesa->glCtx; + GLuint oldfallback = nmesa->Fallback; + + if (mode) { + nmesa->Fallback |= bit; + if (oldfallback == 0) { + if (nmesa->screen->card_typerender_index = ~0; + } + } + else { + nmesa->Fallback &= ~bit; + if (oldfallback == bit) { + _swrast_flush( ctx ); + + if (nmesa->screen->card_typevertex_attrs, + nmesa->vertex_attr_count, + nmesa->viewport.m, 0 ); + } + } +} + + +void nouveauRunPipeline( GLcontext *ctx ) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + + if (nmesa->new_state) { + nmesa->new_render_state |= nmesa->new_state; + } + + _tnl_run_pipeline( ctx ); +} + + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_swtcl.h b/src/mesa/drivers/dri/nouveau/nouveau_swtcl.h new file mode 100644 index 0000000000..ba4d8725a6 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_swtcl.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_SWTCL_H__ +#define __NOUVEAU_SWTCL_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 ); + +extern void nouveauTriInitFunctions( GLcontext *ctx ); + + +#endif /* __NOUVEAU_SWTCL_H__ */ + + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_tris.c b/src/mesa/drivers/dri/nouveau/nouveau_tris.c deleted file mode 100644 index bb8ead3b23..0000000000 --- a/src/mesa/drivers/dri/nouveau/nouveau_tris.c +++ /dev/null @@ -1,125 +0,0 @@ -/************************************************************************** - -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_tris.h" -#include "nv10_swtcl.h" -#include "nouveau_span.h" -#include "swrast/swrast.h" -#include "swrast_setup/swrast_setup.h" -#include "tnl/tnl.h" -#include "tnl/t_pipeline.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]); - _swrast_Triangle(ctx, &v[0], &v[1], &v[2]); -} - - -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]); - _swrast_Line(ctx, &v[0], &v[1]); -} - - -void nouveau_fallback_point(struct nouveau_context *nmesa, - nouveauVertex *v0) -{ - GLcontext *ctx = nmesa->glCtx; - SWvertex v[1]; - _swsetup_Translate(ctx, v0, &v[0]); - _swrast_Point(ctx, &v[0]); -} - -void nouveauFallback(struct nouveau_context *nmesa, GLuint bit, GLboolean mode) -{ - GLcontext *ctx = nmesa->glCtx; - GLuint oldfallback = nmesa->Fallback; - - if (mode) { - nmesa->Fallback |= bit; - if (oldfallback == 0) { - if (nmesa->screen->card_typerender_index = ~0; - } - } - else { - nmesa->Fallback &= ~bit; - if (oldfallback == bit) { - _swrast_flush( ctx ); - - if (nmesa->screen->card_typevertex_attrs, - nmesa->vertex_attr_count, - nmesa->viewport.m, 0 ); - } - } -} - - -void nouveauRunPipeline( GLcontext *ctx ) -{ - struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - - if (nmesa->new_state) { - nmesa->new_render_state |= nmesa->new_state; - } - - _tnl_run_pipeline( ctx ); -} - - diff --git a/src/mesa/drivers/dri/nouveau/nouveau_tris.h b/src/mesa/drivers/dri/nouveau/nouveau_tris.h deleted file mode 100644 index 950f662570..0000000000 --- a/src/mesa/drivers/dri/nouveau/nouveau_tris.h +++ /dev/null @@ -1,55 +0,0 @@ -/************************************************************************** - -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 ); - -extern void nouveauTriInitFunctions( GLcontext *ctx ); - - -#endif /* __NOUVEAU_TRIS_H__ */ - - diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index af9f4fabf4..34546cc234 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -40,7 +40,7 @@ #include "tnl/t_context.h" #include "tnl/t_pipeline.h" -#include "nouveau_tris.h" +#include "nouveau_swtcl.h" #include "nv10_swtcl.h" #include "nouveau_context.h" #include "nouveau_span.h" -- cgit v1.2.3 From 7d907ef69c3cbd6cd0c49f454bc933bc9c343d31 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sun, 17 Sep 2006 17:46:36 +0000 Subject: Some small changes --- src/mesa/drivers/dri/nouveau/nouveau_context.c | 7 ++++--- src/mesa/drivers/dri/nouveau/nouveau_ioctl.c | 9 +++++++-- src/mesa/drivers/dri/nouveau/nouveau_lock.c | 1 - 3 files changed, 11 insertions(+), 6 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index d84e73c015..3ca5edf782 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -71,7 +71,6 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, struct dd_function_table functions; nouveauContextPtr nmesa; nouveauScreenPtr screen; - int i; /* Allocate the context */ nmesa = (nouveauContextPtr) CALLOC( sizeof(*nmesa) ); @@ -129,16 +128,18 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, switch(nmesa->screen->card_type) { case NV_03: + //nv03TriInitFunctions( ctx ); + break; case NV_04: case NV_05: - default: - //nv03TriInitFunctions( ctx ); + //nv04TriInitFunctions( ctx ); break; case NV_10: case NV_20: case NV_30: case NV_40: case G_70: + default: nv10TriInitFunctions( ctx ); break; } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_ioctl.c b/src/mesa/drivers/dri/nouveau/nouveau_ioctl.c index 46ac527f83..ce55373934 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_ioctl.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_ioctl.c @@ -44,8 +44,13 @@ void nouveauIoctlInitFifo(nouveauContextPtr nmesa) ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_FIFO_INIT, &fifo_init, sizeof(fifo_init)); if (ret) FATAL("Fifo initialization ioctl failed (returned %d)\n",ret); - MESSAGE("Fifo init ok. Channel %d\n", fifo_init.channel); - // XXX needs more stuff + MESSAGE("Fifo init ok. Using context %d\n", fifo_init.channel); + + // XXX needs more stuff : + // - map the command buffer + // - map the fifo control regs + // - create the 3D object + } void nouveauIoctlInitFunctions(struct dd_function_table *functions) diff --git a/src/mesa/drivers/dri/nouveau/nouveau_lock.c b/src/mesa/drivers/dri/nouveau/nouveau_lock.c index 1bd2ee4ca9..7dd67a143a 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_lock.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_lock.c @@ -44,7 +44,6 @@ 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 ); -- cgit v1.2.3 From a05db7f505caef75296170bcb6884ba287b1ab25 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 24 Sep 2006 13:16:23 +0000 Subject: Kill all the current shader code. --- src/mesa/drivers/dri/nouveau/nouveau_shader.c | 91 ---- src/mesa/drivers/dri/nouveau/nouveau_shader.h | 74 --- src/mesa/drivers/dri/nouveau/nv40_reg.h | 472 ---------------- src/mesa/drivers/dri/nouveau/nv40_vtxprog.c | 752 -------------------------- 4 files changed, 1389 deletions(-) delete mode 100644 src/mesa/drivers/dri/nouveau/nouveau_shader.c delete mode 100644 src/mesa/drivers/dri/nouveau/nouveau_shader.h delete mode 100644 src/mesa/drivers/dri/nouveau/nv40_reg.h delete mode 100644 src/mesa/drivers/dri/nouveau/nv40_vtxprog.c (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.c b/src/mesa/drivers/dri/nouveau/nouveau_shader.c deleted file mode 100644 index ef8f02e910..0000000000 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.c +++ /dev/null @@ -1,91 +0,0 @@ -#include "glheader.h" -#include "macros.h" -#include "enums.h" - -#include "program.h" -#include "nouveau_context.h" -#include "nouveau_shader.h" - -static struct program * -nv40NewProgram(GLcontext *ctx, GLenum target, GLuint id) -{ -} - -static void -nv40BindProgram(GLcontext *ctx, GLenum target, struct program *prog) -{ -} - -static void -nv40DeleteProgram(GLcontext *ctx, struct program *prog) -{ -} - -static void -nv40ProgramStringNotify(GLcontext *ctx, GLenum target, - struct program *prog) -{ -} - -static GLboolean -nv40IsProgramNative(GLcontext *ctx, GLenum target, struct program *prog) -{ -} - -void -nouveauInitShaderFuncs(GLcontext *ctx) -{ - struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - - if (nmesa->screen->card_type == NV_40) { - ctx->Driver.NewProgram = nv40NewProgram; - ctx->Driver.BindProgram = nv40BindProgram; - ctx->Driver.DeleteProgram = nv40DeleteProgram; - ctx->Driver.ProgramStringNotify = nv40ProgramStringNotify; - ctx->Driver.IsProgramNative = nv40IsProgramNative; - } -} - -#define LONGBITS (sizeof(long) * 8) -void -nvsBitSet(long *rec, int bit) -{ - int ri = bit / LONGBITS; - int rb = bit % LONGBITS; - - rec[ri] |= (1 << rb); -} - -void -nvsBitClear(long *rec, int bit) -{ - int ri = bit / LONGBITS; - int rb = bit % LONGBITS; - - rec[ri] &= ~(1 << rb); -} - -void -nvsRecInit(long **rec, int max) -{ - int c = (max / LONGBITS) + ((max % LONGBITS) ? 1 : 0); - *rec = calloc(c, sizeof(long)); -} - -int -nvsAllocIndex(long *rec, int max) -{ - int c = (max / LONGBITS) + ((max % LONGBITS) ? 1 : 0); - int i, idx = 0; - - for (i=0;i (guess..) */ -#define NV40_VP_PROGRAM_START_ID 0x1EA0 /* Start executing program from instruction */ - -/* Vertex programs instruction set - * - * 128bit opcodes, split into 4 32-bit ones for ease of use. - * - * Non-native instructions - * ABS - MOV + NV40_VP_INST0_DEST_ABS - * POW - EX2 + MUL + LG2 - * SUB - ADD, second source negated - * SWZ - MOV - * XPD - - * - * Register access - * - Only one INPUT can be accessed per-instruction (move extras into TEMPs) - * - Only one CONST can be accessed per-instruction (move extras into TEMPs) - * - * Relative Addressing - * According to the value returned for MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB - * there are only two address registers available. The destination in the ARL - * instruction is set to TEMP (The temp isn't actually written). - * - * When using vanilla ARB_v_p, the proprietary driver will squish both the available - * ADDRESS regs into the first hardware reg in the X and Y components. - * - * To use an address reg as an index into consts, the CONST_SRC is set to - * (const_base + offset) and INDEX_CONST is set. - * - * It is similar for inputs, INPUT_SRC is set to the offset value and INDEX_INPUT - * is set. - * - * To access the second address reg use ADDR_REG_SELECT_1. A particular component - * of the address regs is selected with ADDR_SWZ. - * - * Only one address register can be accessed per instruction, but you may use - * the address reg as an index into both consts and inputs in the same instruction - * as long as the swizzles also match. - * - * Conditional execution (see NV_vertex_program{2,3} for details) - * All instructions appear to be able to modify one of two condition code registers. - * This is enabled by setting COND_UPDATE_ENABLE. The second condition registers is - * updated by setting COND_REG_SELECT_1. - * - * Conditional execution of an instruction is enabled by setting COND_TEST_ENABLE, and - * selecting the condition which will allow the test to pass with COND_{FL,LT,...}. - * It is possible to swizzle the values in the condition register, which allows for - * testing against an individual component. - * - * Branching - * The BRA/CAL instructions seem to follow a slightly different opcode layout. The - * destination instruction ID (IADDR) overlaps SRC2. Instruction ID's seem to be - * numbered based on the UPLOAD_FROM_ID FIFO command, and is incremented automatically - * on each UPLOAD_INST FIFO command. - * - * Conditional branching is achieved by using the condition tests described above. - * There doesn't appear to be dedicated looping instructions, but this can be done - * using a temp reg + conditional branching. - * - * Subroutines may be uploaded before the main program itself, but the first executed - * instruction is determined by the PROGRAM_START_ID FIFO command. - * - * Texture lookup - * TODO - */ - -/* ---- OPCODE BITS 127:96 / data DWORD 0 --- */ -#define NV40_VP_INST0_UNK0 (1 << 30) /* set when writing result regs */ -#define NV40_VP_INST_COND_UPDATE_ENABLE ((1 << 14)|1<<29) /* unsure about this */ -#define NV40_VP_INST_INDEX_INPUT (1 << 27) /* Use an address reg as in index into attribs */ -#define NV40_VP_INST_COND_REG_SELECT_1 (1 << 25) -#define NV40_VP_INST_ADDR_REG_SELECT_1 (1 << 24) -#define NV40_VP_INST_DEST_TEMP_ABS (1 << 21) -#define NV40_VP_INST_DEST_TEMP_SHIFT 15 -#define NV40_VP_INST_DEST_TEMP_MASK (0x3F << 15) -#define NV40_VP_INST_COND_TEST_ENABLE (1 << 13) /* write masking based on condition test */ -#define NV40_VP_INST_COND_SHIFT 10 -#define NV40_VP_INST_COND_MASK (0x7 << 10) -# define NV40_VP_INST_COND_FL 0 -# define NV40_VP_INST_COND_LT 1 -# define NV40_VP_INST_COND_EQ 2 -# define NV40_VP_INST_COND_LE 3 -# define NV40_VP_INST_COND_GT 4 -# define NV40_VP_INST_COND_NE 5 -# define NV40_VP_INST_COND_GE 6 -# define NV40_VP_INST_COND_TR 7 -#define NV40_VP_INST_COND_SWZ_X_SHIFT 8 -#define NV40_VP_INST_COND_SWZ_X_MASK (3 << 8) -#define NV40_VP_INST_COND_SWZ_Y_SHIFT 6 -#define NV40_VP_INST_COND_SWZ_Y_MASK (3 << 6) -#define NV40_VP_INST_COND_SWZ_Z_SHIFT 4 -#define NV40_VP_INST_COND_SWZ_Z_MASK (3 << 4) -#define NV40_VP_INST_COND_SWZ_W_SHIFT 2 -#define NV40_VP_INST_COND_SWZ_W_MASK (3 << 2) -#define NV40_VP_INST_COND_SWZ_ALL_SHIFT 2 -#define NV40_VP_INST_COND_SWZ_ALL_MASK (0xFF << 2) -#define NV40_VP_INST_ADDR_SWZ_SHIFT 0 -#define NV40_VP_INST_ADDR_SWZ_MASK (0x03 << 0) - -/* ---- OPCODE BITS 95:64 / data DWORD 1 --- */ -#define NV40_VP_INST_OPCODE_SHIFT 22 -#define NV40_VP_INST_OPCODE_MASK (0x3FF << 22) -/*TODO: confirm which source slots correspond to the GL sources, - * renouveau should be correct in most places though.. Also, - * document them here. - */ -# define NV40_VP_INST_OP_NOP 0x000 -# define NV40_VP_INST_OP_MOV 0x001 -# define NV40_VP_INST_OP_MUL 0x002 -# define NV40_VP_INST_OP_ADD 0x003 -# define NV40_VP_INST_OP_MAD 0x004 -# define NV40_VP_INST_OP_DP3 0x005 -# define NV40_VP_INST_OP_DP4 0x007 -# define NV40_VP_INST_OP_DPH 0x006 -# define NV40_VP_INST_OP_DST 0x008 -# define NV40_VP_INST_OP_MIN 0x009 -# define NV40_VP_INST_OP_MAX 0x00A -# define NV40_VP_INST_OP_SLT 0x00B -# define NV40_VP_INST_OP_SGE 0x00C -# define NV40_VP_INST_OP_ARL 0x00D -# define NV40_VP_INST_OP_FRC 0x00E -# define NV40_VP_INST_OP_FLR 0x00F -# define NV40_VP_INST_OP_SEQ 0x010 -# define NV40_VP_INST_OP_SFL 0x011 -# define NV40_VP_INST_OP_SGT 0x012 -# define NV40_VP_INST_OP_SLE 0x013 -# define NV40_VP_INST_OP_SNE 0x014 -# define NV40_VP_INST_OP_STR 0x015 -# define NV40_VP_INST_OP_SSG 0x016 -# define NV40_VP_INST_OP_ARR 0x017 -# define NV40_VP_INST_OP_ARA 0x018 -# define NV40_VP_INST_OP_RCP 0x040 -# define NV40_VP_INST_OP_RCC 0x060 -# define NV40_VP_INST_OP_RSQ 0x080 -# define NV40_VP_INST_OP_EXP 0x0A0 -# define NV40_VP_INST_OP_LOG 0x0C0 -# define NV40_VP_INST_OP_LIT 0x0E0 -# define NV40_VP_INST_OP_BRA 0x120 -# define NV40_VP_INST_OP_CAL 0x160 -# define NV40_VP_INST_OP_RET 0x180 -# define NV40_VP_INST_OP_LG2 0x1A0 -# define NV40_VP_INST_OP_EX2 0x1C0 -# define NV40_VP_INST_OP_COS 0x200 -# define NV40_VP_INST_OP_PUSHA 0x260 -# define NV40_VP_INST_OP_POPA 0x280 -#define NV40_VP_INST_CONST_SRC_SHIFT 12 -#define NV40_VP_INST_CONST_SRC_MASK (0xFF << 12) -#define NV40_VP_INST_INPUT_SRC_SHIFT 8 -#define NV40_VP_INST_INPUT_SRC_MASK (0x0F << 8) -# define NV40_VP_INST_IN_POS 0 /* These seem to match the bindings specified in */ -# define NV40_VP_INST_IN_WEIGHT 1 /* the ARB_v_p spec (2.14.3.1) */ -# define NV40_VP_INST_IN_NORMAL 2 -# define NV40_VP_INST_IN_COL0 3 /* Should probably confirm them all thougth */ -# define NV40_VP_INST_IN_COL1 4 -# define NV40_VP_INST_IN_FOGC 5 -# define NV40_VP_INST_IN_TC0 8 -# define NV40_VP_INST_IN_TC(n) (8+n) -#define NV40_VP_INST_SRC0H_SHIFT 0 -#define NV40_VP_INST_SRC0H_MASK (0xFF << 0) - -/* ---- OPCODE BITS 63:32 / data DWORD 2 --- */ -#define NV40_VP_INST_SRC0L_SHIFT 23 -#define NV40_VP_INST_SRC0L_MASK (0x1FF << 23) -#define NV40_VP_INST_SRC1_SHIFT 6 -#define NV40_VP_INST_SRC1_MASK (0x1FFFF << 6) -#define NV40_VP_INST_SRC2H_SHIFT 0 -#define NV40_VP_INST_SRC2H_MASK (0x3F << 0) -#define NV40_VP_INST_IADDRH_SHIFT 0 -#define NV40_VP_INST_IADDRH_MASK (0x1F << 0) /* guess, need to test this */ -# -/* ---- OPCODE BITS 31:0 / data DWORD 3 --- */ -#define NV40_VP_INST_IADDRL_SHIFT 29 -#define NV40_VP_INST_IADDRL_MASK (7 << 29) -#define NV40_VP_INST_SRC2L_SHIFT 21 -#define NV40_VP_INST_SRC2L_MASK (0x7FF << 21) -/* bits 7-12 seem to always be set to 1 */ -#define NV40_VP_INST_WRITEMASK_SHIFT 13 -#define NV40_VP_INST_WRITEMASK_MASK (0xF << 13) -# define NV40_VP_INST_WRITEMASK_X (1 << 16) -# define NV40_VP_INST_WRITEMASK_Y (1 << 15) -# define NV40_VP_INST_WRITEMASK_Z (1 << 14) -# define NV40_VP_INST_WRITEMASK_W (1 << 13) -#define NV40_VP_INST_DEST_SHIFT 2 -#define NV40_VP_INST_DEST_MASK (31 << 2) -# define NV40_VP_INST_DEST_POS 0 -# define NV40_VP_INST_DEST_COL0 1 -# define NV40_VP_INST_DEST_COL1 2 -# define NV40_VP_INST_DEST_BFC0 3 -# define NV40_VP_INST_DEST_BFC1 4 -# define NV40_VP_INST_DEST_FOGC 5 -# define NV40_VP_INST_DEST_PSZ 6 -# define NV40_VP_INST_DEST_TC0 7 -# define NV40_VP_INST_DEST_TC(n) (7+n) -# define NV40_VP_INST_DEST_TEMP 0x1F /* see NV40_VP_INST0_* for actual register */ -#define NV40_VP_INST_INDEX_CONST (1 << 1) -#define NV40_VP_INST_UNK_00 (1 << 0) /* appears to be set on the last inst only */ - -/* Useful to split the source selection regs into their pieces */ -#define NV40_VP_SRC0_HIGH_SHIFT 9 -#define NV40_VP_SRC0_HIGH_MASK 0x0001FE00 -#define NV40_VP_SRC0_LOW_MASK 0x000001FF -#define NV40_VP_SRC2_HIGH_SHIFT 11 -#define NV40_VP_SRC2_HIGH_MASK 0x0001F800 -#define NV40_VP_SRC2_LOW_MASK 0x000007FF - -/* Source selection - these are the bits you fill NV40_VP_INST_SRCn with */ -#define NV40_VP_SRC_NEGATE 16 -#define NV40_VP_SRC_SWZ_X_SHIFT 14 -#define NV40_VP_SRC_SWZ_X_MASK (3 << 14) -#define NV40_VP_SRC_SWZ_Y_SHIFT 12 -#define NV40_VP_SRC_SWZ_Y_MASK (3 << 12) -#define NV40_VP_SRC_SWZ_Z_SHIFT 10 -#define NV40_VP_SRC_SWZ_Z_MASK (3 << 10) -#define NV40_VP_SRC_SWZ_W_SHIFT 8 -#define NV40_VP_SRC_SWZ_W_MASK (3 << 8) -#define NV40_VP_SRC_SWZ_ALL_SHIFT 8 -#define NV40_VP_SRC_SWZ_ALL_MASK (0xFF << 8) -#define NV40_VP_SRC_TEMP_SRC_SHIFT 2 -#define NV40_VP_SRC_TEMP_SRC_MASK (0x3F << 2) -#define NV40_VP_SRC_REG_TYPE_SHIFT 0 -#define NV40_VP_SRC_REG_TYPE_MASK (3 << 0) -# define NV40_VP_SRC_REG_TYPE_UNK0 0 -# define NV40_VP_SRC_REG_TYPE_TEMP 1 -# define NV40_VP_SRC_REG_TYPE_INPUT 2 -# define NV40_VP_SRC_REG_TYPE_CONST 3 - -/* --- GF6800GT - PCIID 10de:0045 (rev a1) -- - -== Fragment program instruction set - Not FIFO commands, uploaded into a memory buffer. The fragment program has - always appeared in the same map as the texture image data has. Usually it's - the first thing in the map, followed immediately by the textures. -*/ - - -/* - * Each fragment program opcode appears to be comprised of 4 32-bit values. - * - * 0 - Opcode, output reg/mask, ATTRIB source - * 1 - Source 0 - * 2 - Source 1 - * 3 - Source 2 - * - * Constants are inserted directly after the instruction that uses them. - * - * It appears that it's not possible to use two input registers in one - * instruction as the input sourcing is done in the instruction dword - * and not the source selection dwords. As such instructions such as: - * - * ADD result.color, fragment.color, fragment.texcoord[0]; - * - * must be split into two MOV's and then an ADD (nvidia does this) but - * I'm not sure why it's not just one MOV and then source the second input - * in the ADD instruction.. - * - * Negation of the full source is done with NV40_FP_REG_NEGATE, arbitrary - * negation requires multiplication with a const. - * - * Arbitrary swizzling is supported with the exception of SWIZZLE_ZERO/SWIZZLE_ONE - * The temp/result regs appear to be initialised to (0.0, 0.0, 0.0, 0.0) as SWIZZLE_ZERO - * is implemented simply by not writing to the relevant components of the destination. - * - * Non-native instructions: - * LIT - * LRP - MAD+MAD - * SUB - ADD, negate second source - * RSQ - LG2 + EX2 - * POW - LG2 + MUL + EX2 - * SCS - COS + SIN - * XPD - * DP2 - MUL + ADD - */ - -//== Opcode / Destination selection == -#define NV40_FP_OP_PROGRAM_END 0x00000001 -#define NV40_FP_OP_OUT_RESULT (1 << 0) /* uncertain? and what about depth? */ -#define NV40_FP_OP_OUT_REG_SHIFT 1 -#define NV40_FP_OP_OUT_REG_MASK (31 << 1) /* uncertain */ -#define NV40_FP_OP_OUTMASK_SHIFT 9 -#define NV40_FP_OP_OUTMASK_MASK (0xF << 9) -# define NV40_FP_OP_OUT_X (1 << 9) -# define NV40_FP_OP_OUT_Y (1 << 10) -# define NV40_FP_OP_OUT_Z (1 << 11) -# define NV40_FP_OP_OUT_W (1 << 12) -/* Uncertain about these, especially the input_src values.. it's possible that - * they can be dynamically changed. - */ -#define NV40_FP_OP_INPUT_SRC_SHIFT 13 -#define NV40_FP_OP_INPUT_SRC_MASK (15 << 13) -# define NV40_FP_OP_INPUT_SRC_POSITION 0x0 -# define NV40_FP_OP_INPUT_SRC_COL0 0x1 -# define NV40_FP_OP_INPUT_SRC_COL1 0x2 -# define NV40_FP_OP_INPUT_SRC_TC0 0x4 -# define NV40_FP_OP_INPUT_SRC_TC(n) (0x4 + n) -#define NV40_FP_OP_TEX_UNIT_SHIFT 17 -#define NV40_FP_OP_TEX_UNIT_MASK (0xF << 17) /* guess */ -#define NV40_FP_OP_PRECISION_SHIFT 22 -#define NV40_FP_OP_PRECISION_MASK (3 << 22) -# define NV40_FP_PRECISION_FP32 0 -# define NV40_FP_PRECISION_FP16 1 -# define NV40_FP_PRECISION_FX12 2 -#define NV40_FP_OP_OPCODE_SHIFT 24 -#define NV40_FP_OP_OPCODE_MASK (0x7F << 24) -# define NV40_FP_OP_OPCODE_MOV 0x01 -# define NV40_FP_OP_OPCODE_MUL 0x02 -# define NV40_FP_OP_OPCODE_ADD 0x03 -# define NV40_FP_OP_OPCODE_MAD 0x04 -# define NV40_FP_OP_OPCODE_DP3 0x05 -# define NV40_FP_OP_OPCODE_DP4 0x06 -# define NV40_FP_OP_OPCODE_DST 0x07 -# define NV40_FP_OP_OPCODE_MIN 0x08 -# define NV40_FP_OP_OPCODE_MAX 0x09 -# define NV40_FP_OP_OPCODE_SLT 0x0A -# define NV40_FP_OP_OPCODE_SGE 0x0B -# define NV40_FP_OP_OPCODE_SLE 0x0C -# define NV40_FP_OP_OPCODE_SGT 0x0D -# define NV40_FP_OP_OPCODE_SNE 0x0E -# define NV40_FP_OP_OPCODE_SEQ 0x0F -# define NV40_FP_OP_OPCODE_FRC 0x10 -# define NV40_FP_OP_OPCODE_FLR 0x11 -# define NV40_FP_OP_OPCODE_TEX 0x17 -# define NV40_FP_OP_OPCODE_TXP 0x18 -# define NV40_FP_OP_OPCODE_RCP 0x1A -# define NV40_FP_OP_OPCODE_EX2 0x1C -# define NV40_FP_OP_OPCODE_LG2 0x1D -# define NV40_FP_OP_OPCODE_COS 0x22 -# define NV40_FP_OP_OPCODE_SIN 0x23 -# define NV40_FP_OP_OPCODE_DP2A 0x2E -# define NV40_FP_OP_OPCODE_TXB 0x31 -# define NV40_FP_OP_OPCODE_DIV 0x3A -#define NV40_FP_OP_OUT_SAT (1 << 31) - -/* high order bits of SRC0 */ -#define NV40_FP_OP_OUT_ABS (1 << 29) -#define NV40_FP_OP_COND_SWZ_W_SHIFT 27 -#define NV40_FP_OP_COND_SWZ_W_MASK (3 << 27) -#define NV40_FP_OP_COND_SWZ_Z_SHIFT 25 -#define NV40_FP_OP_COND_SWZ_Z_MASK (3 << 25) -#define NV40_FP_OP_COND_SWZ_Y_SHIFT 23 -#define NV40_FP_OP_COND_SWZ_Y_MASK (3 << 23) -#define NV40_FP_OP_COND_SWZ_X_SHIFT 21 -#define NV40_FP_OP_COND_SWZ_X_MASK (3 << 21) -#define NV40_FP_OP_COND_SWZ_ALL_SHIFT 21 -#define NV40_FP_OP_COND_SWZ_ALL_MASK (0xFF << 21) -#define NV40_FP_OP_COND_SHIFT 18 -#define NV40_FP_OP_COND_MASK (0x07 << 18) -# define NV40_FP_OP_COND_FL 0 -# define NV40_FP_OP_COND_LT 1 -# define NV40_FP_OP_COND_EQ 2 -# define NV40_FP_OP_COND_LE 3 -# define NV40_FP_OP_COND_GT 4 -# define NV40_FP_OP_COND_NE 5 -# define NV40_FP_OP_COND_GE 6 -# define NV40_FP_OP_COND_TR 7 - -/* high order bits of SRC1 */ -#define NV40_FP_OP_SRC_SCALE_SHIFT 28 -#define NV40_FP_OP_SRC_SCALE_MASK (3 << 28) - -//== Register selection == -#define NV40_FP_REG_SRC_INPUT (1 << 0) /* uncertain */ -#define NV40_FP_REG_SRC_CONST (1 << 1) -#define NV40_FP_REG_SRC_SHIFT 2 /* uncertain */ -#define NV40_FP_REG_SRC_MASK (31 << 2) -#define NV40_FP_REG_UNK_0 (1 << 8) -#define NV40_FP_REG_SWZ_ALL_SHIFT 9 -#define NV40_FP_REG_SWZ_ALL_MASK (255 << 9) -#define NV40_FP_REG_SWZ_X_SHIFT 9 -#define NV40_FP_REG_SWZ_X_MASK (3 << 9) -#define NV40_FP_REG_SWZ_Y_SHIFT 11 -#define NV40_FP_REG_SWZ_Y_MASK (3 << 11) -#define NV40_FP_REG_SWZ_Z_SHIFT 13 -#define NV40_FP_REG_SWZ_Z_MASK (3 << 13) -#define NV40_FP_REG_SWZ_W_SHIFT 15 -#define NV40_FP_REG_SWZ_W_MASK (3 << 15) -# define NV40_FP_SWIZZLE_X 0 -# define NV40_FP_SWIZZLE_Y 1 -# define NV40_FP_SWIZZLE_Z 2 -# define NV40_FP_SWIZZLE_W 3 -#define NV40_FP_REG_NEGATE (1 << 17) - -#endif diff --git a/src/mesa/drivers/dri/nouveau/nv40_vtxprog.c b/src/mesa/drivers/dri/nouveau/nv40_vtxprog.c deleted file mode 100644 index 8bdacb89e7..0000000000 --- a/src/mesa/drivers/dri/nouveau/nv40_vtxprog.c +++ /dev/null @@ -1,752 +0,0 @@ -#include "glheader.h" -#include "macros.h" -#include "enums.h" -#include "program.h" -#include "program_instruction.h" - -#include "nouveau_reg.h" -#include "nouveau_shader.h" -#include "nouveau_msg.h" - -#include "nv40_reg.h" - -/* TODO: - * - Implement support for constants - * - Handle SWZ with 0/1 components and partial negate masks - * - Handle ARB_position_invarient - * - Relative register addressing - * - Implement any missing instructions - * - Fix scalar instructions (the other "writemask") - */ - -static int t_dst_mask(int mask); - -static int -alloc_hw_temp(nouveau_vertex_program *vp) -{ - return nvsAllocIndex(vp->hwtemps_in_use, 64); -} - -static void -free_hw_temp(nouveau_vertex_program *vp, int id) -{ - nvsBitClear(vp->hwtemps_in_use, id); -} - -static int -alloc_temp(nouveau_vertex_program *vp) -{ - int idx; - - idx = nvsAllocIndex(vp->temps_in_use, 64); - if (!idx) - return -1; - - vp->temps[idx].file = HW_TEMP; - vp->temps[idx].hw_id = -1; - vp->temps[idx].ref = -1; - - return idx; -} - -static void -free_temp(nouveau_vertex_program *vp, nouveau_srcreg *temp) -{ - if (!temp) return; - - if (vp->temps[temp->idx].hw_id != -1) - free_hw_temp(vp, vp->temps[temp->idx].hw_id); - nvsBitClear(vp->temps_in_use, temp->idx); -} - -static void -make_srcreg(nouveau_vertex_program *vp, - nouveau_srcreg *src, - nouveau_regtype type, - int id) -{ - switch (type) { - case HW_INPUT: - src->hw = NULL; - src->idx = id; - break; - case HW_TEMP: - src->hw = &vp->temps[id]; - src->idx = id; - break; - case HW_CONST: - //FIXME: TODO - break; - default: - assert(0); - break; - } - - src->negate = 0; - src->swizzle = 0x1B /* 00011011 - XYZW */; -} - -static void -make_dstreg(nouveau_vertex_program *vp, - nouveau_dstreg *dest, - nouveau_regtype type, - int id) -{ - if (type == HW_TEMP && id == -1) - dest->idx = alloc_temp(vp); - else - dest->idx = id; - switch (type) { - case HW_TEMP: - dest->idx = id; - if (dest->idx == -1) - dest->idx = alloc_temp(vp); - dest->hw = &vp->temps[dest->idx]; - break; - case HW_OUTPUT: - dest->hw = NULL; - dest->idx = id; - break; - default: - assert(0); - break; - } - - dest->mask = t_dst_mask(WRITEMASK_XYZW); - dest->condup = 0; - dest->condreg = 0; - dest->condtest = NV40_VP_INST_COND_TR; - dest->condswz = 0x1B /* 00011011 - XYZW */; -} - -static unsigned int -src_to_hw(nouveau_vertex_program *vp, nouveau_srcreg *src, - unsigned int *is, unsigned int *cs) -{ - unsigned int hs = 0; - - if (!src) { - /* unused sources seem to be INPUT swz XYZW, dont't know if this - * actually matters or not... - */ - hs |= (NV40_VP_SRC_REG_TYPE_INPUT << NV40_VP_SRC_REG_TYPE_SHIFT); - hs |= (0x1B << NV40_VP_SRC_SWZ_ALL_SHIFT); - return hs; - } - - if (!src->hw) { /* this is a forced read from a "real" hardware source */ - *is = src->idx; - hs |= (NV40_VP_SRC_REG_TYPE_INPUT << NV40_VP_SRC_REG_TYPE_SHIFT); - } else { - switch (src->hw->file) { - case HW_INPUT: - if (*is != -1) { - fprintf(stderr, "multiple inputs detected... not good\n"); - return; - } - *is = src->hw->hw_id; - hs |= (NV40_VP_SRC_REG_TYPE_INPUT << NV40_VP_SRC_REG_TYPE_SHIFT); - break; - case HW_CONST: - if (*cs != -1) { - fprintf(stderr, "multiple consts detected... not good\n"); - return; - } - *cs = src->hw->hw_id; - hs |= (NV40_VP_SRC_REG_TYPE_CONST << NV40_VP_SRC_REG_TYPE_SHIFT); - break; - case HW_TEMP: - if (src->hw->hw_id == -1) { - fprintf(stderr, "read from unwritten temp!\n"); - return; - } - hs |= (NV40_VP_SRC_REG_TYPE_TEMP << NV40_VP_SRC_REG_TYPE_SHIFT) | - (src->hw->hw_id << NV40_VP_SRC_TEMP_SRC_SHIFT); - - if (--src->hw->ref == 0) - free_hw_temp(vp, src->hw->hw_id); - } - } - - hs |= (src->swizzle << NV40_VP_SRC_SWZ_ALL_SHIFT); - if (src->negate) - hs |= NV40_VP_SRC_NEGATE; - - return hs; -} - -static void -instruction_store(nouveau_vertex_program *vp, unsigned int inst[]) -{ - if ((vp->inst_count+1) > vp->insns_alloced) { - vp->insns = realloc(vp->insns, sizeof(unsigned int) * (vp->inst_count+1) * 4); - vp->insns_alloced = vp->inst_count+1; - } - vp->insns[(vp->inst_count*4) + 0] = inst[0]; - vp->insns[(vp->inst_count*4) + 1] = inst[1]; - vp->insns[(vp->inst_count*4) + 2] = inst[2]; - vp->insns[(vp->inst_count*4) + 3] = inst[3]; - vp->inst_count++; -} - -static void -emit_arith(nouveau_vertex_program *vp, int op, - nouveau_dstreg *dest, - nouveau_srcreg *src0, - nouveau_srcreg *src1, - nouveau_srcreg *src2, - int flags) -{ - nouveau_regrec *hwdest = dest->hw; - unsigned int hs0, hs1, hs2; - unsigned int hop[4] = { 0, 0, 0, 0 }; - int insrc = -1, constsrc = -1; - - /* Calculate source reg state */ - hs0 = src_to_hw(vp, src0, &insrc, &constsrc); - hs1 = src_to_hw(vp, src1, &insrc, &constsrc); - hs2 = src_to_hw(vp, src2, &insrc, &constsrc); - - /* Append it to the instruction */ - hop[1] |= (((hs0 & NV40_VP_SRC0_HIGH_MASK) >> NV40_VP_SRC0_HIGH_SHIFT) - << NV40_VP_INST_SRC0H_SHIFT); - hop[2] |= ((hs0 & NV40_VP_SRC0_LOW_MASK) << NV40_VP_INST_SRC0L_SHIFT) | - (hs1 << NV40_VP_INST_SRC1_SHIFT) | - (((hs2 & NV40_VP_SRC2_HIGH_MASK) >> NV40_VP_SRC2_HIGH_SHIFT) - << NV40_VP_INST_SRC2H_SHIFT); - hop[3] |= (hs2 & NV40_VP_SRC2_LOW_MASK) << NV40_VP_INST_SRC2L_SHIFT; - - /* bits 127:96 */ - hop[0] |= (dest->condtest << NV40_VP_INST_COND_SHIFT) | - (dest->condswz << NV40_VP_INST_COND_SWZ_ALL_SHIFT); - if (dest->condtest != NV40_VP_INST_COND_TR) - hop[0] |= NV40_VP_INST_COND_TEST_ENABLE; - if (dest->condreg) hop[0] |= NV40_VP_INST_COND_REG_SELECT_1; - if (dest->condup ) hop[0] |= NV40_VP_INST_COND_UPDATE_ENABLE; - - if (hwdest == NULL /* write output */) - hop[0] |= NV40_VP_INST0_UNK0; - else { - if (hwdest->hw_id == -1) - hwdest->hw_id = alloc_hw_temp(vp); - - hop[0] |= (hwdest->hw_id << NV40_VP_INST_DEST_TEMP_SHIFT); - if (flags & NOUVEAU_OUT_ABS) - hop[0] |= NV40_VP_INST_DEST_TEMP_ABS; - - nvsBitSet(vp->hwtemps_written, hwdest->hw_id); - if (--hwdest->ref == 0) - free_hw_temp(vp, hwdest->hw_id); - } - - /* bits 95:64 */ - if (constsrc == -1) constsrc = 0; - if (insrc == -1) insrc = 0; - - constsrc &= 0xFF; - insrc &= 0x0F; - hop[1] |= (op << NV40_VP_INST_OPCODE_SHIFT) | - (constsrc << NV40_VP_INST_CONST_SRC_SHIFT) | - (insrc << NV40_VP_INST_INPUT_SRC_SHIFT); - - /* bits 31:0 */ - if (hwdest == NULL) { - hop[3] |= (dest->mask | (dest->idx << NV40_VP_INST_DEST_SHIFT)); - } else { - hop[3] |= (dest->mask | (NV40_VP_INST_DEST_TEMP << NV40_VP_INST_DEST_SHIFT)); - } - hop[3] |= (0x3F << 7); /*FIXME: what is this?*/ - - printf("0x%08x\n", hop[0]); - printf("0x%08x\n", hop[1]); - printf("0x%08x\n", hop[2]); - printf("0x%08x\n", hop[3]); - - instruction_store(vp, hop); -} - -static int -t_swizzle(GLuint swz) -{ - int x, y, z, w; - x = GET_SWZ(swz, 0); - y = GET_SWZ(swz, 1); - z = GET_SWZ(swz, 2); - w = GET_SWZ(swz, 3); - - if ((xFile) { - case PROGRAM_TEMPORARY: - ns->hw = &vp->temps[src->Index]; - break; - case PROGRAM_INPUT: - ns->hw = &vp->inputs[src->Index]; - break; - default: - fprintf(stderr, "Unhandled source register file!\n"); - break; - } - - ns->swizzle = t_swizzle(src->Swizzle); - if ((src->NegateBase != 0xF && src->NegateBase != 0x0) || - ns->swizzle == -1) { - WARN_ONCE("Unhandled source swizzle/negate, results will be incorrect\n"); - ns->swizzle = 0x1B; // 00 01 10 11 - XYZW - ns->negate = (src->NegateBase) ? 1 : 0; - } else - ns->negate = (src->NegateBase) ? 1 : 0; - -} - -static int -t_dst_mask(int mask) -{ - int hwmask = 0; - - if (mask & WRITEMASK_X) hwmask |= NV40_VP_INST_WRITEMASK_X; - if (mask & WRITEMASK_Y) hwmask |= NV40_VP_INST_WRITEMASK_Y; - if (mask & WRITEMASK_Z) hwmask |= NV40_VP_INST_WRITEMASK_Z; - if (mask & WRITEMASK_W) hwmask |= NV40_VP_INST_WRITEMASK_W; - - return hwmask; -} - -static int -t_dst_index(int idx) -{ - int hwidx; - - switch (idx) { - case VERT_RESULT_HPOS: - return NV40_VP_INST_DEST_POS; - case VERT_RESULT_COL0: - return NV40_VP_INST_DEST_COL0; - case VERT_RESULT_COL1: - return NV40_VP_INST_DEST_COL1; - case VERT_RESULT_FOGC: - return NV40_VP_INST_DEST_FOGC; - case VERT_RESULT_TEX0: - case VERT_RESULT_TEX1: - case VERT_RESULT_TEX2: - case VERT_RESULT_TEX3: - case VERT_RESULT_TEX4: - case VERT_RESULT_TEX5: - case VERT_RESULT_TEX6: - case VERT_RESULT_TEX7: - return NV40_VP_INST_DEST_TC(idx - VERT_RESULT_TEX0); - case VERT_RESULT_PSIZ: - return NV40_VP_INST_DEST_PSZ; - case VERT_RESULT_BFC0: - return NV40_VP_INST_DEST_BFC0; - case VERT_RESULT_BFC1: - return NV40_VP_INST_DEST_BFC1; - default: - fprintf(stderr, "Unknown result reg index!\n"); - return -1; - } -} - -static int -t_cond_test(GLuint test) -{ - switch(test) { - case COND_GT: return NV40_VP_INST_COND_GT; - case COND_EQ: return NV40_VP_INST_COND_EQ; - case COND_LT: return NV40_VP_INST_COND_LT; - case COND_GE: return NV40_VP_INST_COND_GE; - case COND_LE: return NV40_VP_INST_COND_LE; - case COND_NE: return NV40_VP_INST_COND_NE; - case COND_TR: return NV40_VP_INST_COND_TR; - case COND_FL: return NV40_VP_INST_COND_FL; - default: - WARN_ONCE("unknown CondMask!\n"); - return -1; - } -} - -#define ARITH_1OP(op) do { \ - t_src_reg(vp, &vpi->SrcReg[0], &src0); \ - emit_arith(vp, op, &dest, &src0, NULL, NULL, 0); \ -} while(0); -#define ARITH_1OP_SCALAR(op) do { \ - t_src_reg(vp, &vpi->SrcReg[0], &src0); \ - emit_arith(vp, op, &dest, NULL, NULL, &src0, 0); \ -} while(0); -#define ARITH_2OP(op) do { \ - t_src_reg(vp, &vpi->SrcReg[0], &src0); \ - t_src_reg(vp, &vpi->SrcReg[1], &src1); \ - emit_arith(vp, op, &dest, &src0, &src1, NULL, 0); \ -} while(0); -#define ARITH_3OP(op) do { \ - t_src_reg(vp, &vpi->SrcReg[0], &src0); \ - t_src_reg(vp, &vpi->SrcReg[1], &src1); \ - t_src_reg(vp, &vpi->SrcReg[2], &src2); \ - emit_arith(vp, op, &dest, &src0, &src1, &src2, 0); \ -} while(0); - -static int -translate(nouveau_vertex_program *vp) -{ - struct vertex_program *mvp = &vp->mesa_program; - struct prog_instruction *vpi; - - - for (vpi=mvp->Base.Instructions; vpi->Opcode!=OPCODE_END; vpi++) { - nouveau_srcreg src0, src1, src2, sT0; - nouveau_dstreg dest, dT0; - - switch (vpi->DstReg.File) { - case PROGRAM_OUTPUT: - make_dstreg(vp, &dest, HW_OUTPUT, t_dst_index(vpi->DstReg.Index)); - break; - case PROGRAM_TEMPORARY: - make_dstreg(vp, &dest, HW_TEMP, vpi->DstReg.Index); - break; - default: - assert(0); - } - dest.mask = t_dst_mask(vpi->DstReg.WriteMask); - dest.condtest = t_cond_test(vpi->DstReg.CondMask); - dest.condswz = t_swizzle(vpi->DstReg.CondSwizzle); - dest.condreg = vpi->DstReg.CondSrc; - - switch (vpi->Opcode) { - /* ARB_vertex_program requirements */ - case OPCODE_ABS: - t_src_reg(vp, &vpi->SrcReg[0], &src0); - emit_arith(vp, NV40_VP_INST_OP_MOV, &dest, - &src0, NULL, NULL, - NOUVEAU_OUT_ABS - ); - break; - case OPCODE_ADD: - t_src_reg(vp, &vpi->SrcReg[0], &src0); - t_src_reg(vp, &vpi->SrcReg[1], &src1); - emit_arith(vp, NV40_VP_INST_OP_ADD, &dest, - &src0, NULL, &src1, - 0 - ); - break; - case OPCODE_ARL: - break; - case OPCODE_DP3: - ARITH_2OP(NV40_VP_INST_OP_DP3); - break; - case OPCODE_DP4: - ARITH_2OP(NV40_VP_INST_OP_DP4); - break; - case OPCODE_DPH: - ARITH_2OP(NV40_VP_INST_OP_DPH); - break; - case OPCODE_DST: - ARITH_2OP(NV40_VP_INST_OP_DST); - break; - case OPCODE_EX2: - ARITH_1OP_SCALAR(NV40_VP_INST_OP_EX2); - break; - case OPCODE_EXP: - ARITH_1OP_SCALAR(NV40_VP_INST_OP_EXP); - break; - case OPCODE_FLR: - ARITH_1OP(NV40_VP_INST_OP_FLR); - break; - case OPCODE_FRC: - ARITH_1OP(NV40_VP_INST_OP_FRC); - break; - case OPCODE_LG2: - ARITH_1OP_SCALAR(NV40_VP_INST_OP_LG2); - break; - case OPCODE_LIT: - t_src_reg(vp, &vpi->SrcReg[0], &src0); - t_src_reg(vp, &vpi->SrcReg[1], &src1); - t_src_reg(vp, &vpi->SrcReg[2], &src2); - emit_arith(vp, NV40_VP_INST_OP_LIT, &dest, - &src0, &src1, &src2, - 0 - ); - break; - case OPCODE_LOG: - ARITH_1OP_SCALAR(NV40_VP_INST_OP_LOG); - break; - case OPCODE_MAD: - ARITH_3OP(NV40_VP_INST_OP_MAD); - break; - case OPCODE_MAX: - ARITH_2OP(NV40_VP_INST_OP_MAX); - break; - case OPCODE_MIN: - ARITH_2OP(NV40_VP_INST_OP_MIN); - break; - case OPCODE_MOV: - ARITH_1OP(NV40_VP_INST_OP_MOV); - break; - case OPCODE_MUL: - ARITH_2OP(NV40_VP_INST_OP_MOV); - break; - case OPCODE_POW: - t_src_reg(vp, &vpi->SrcReg[0], &src0); - t_src_reg(vp, &vpi->SrcReg[1], &src1); - make_dstreg(vp, &dT0, HW_TEMP, -1); - make_srcreg(vp, &sT0, HW_TEMP, dT0.idx); - - dT0.mask = t_dst_mask(WRITEMASK_X); - emit_arith(vp, NV40_VP_INST_OP_LG2, &dT0, - NULL, NULL, &src0, - 0); - sT0.swizzle = 0x0; /* 00000000 - XXXX */ - emit_arith(vp, NV40_VP_INST_OP_MUL, &dT0, - &sT0, &src1, NULL, - 0); - emit_arith(vp, NV40_VP_INST_OP_EX2, &dest, - NULL, NULL, &sT0, - 0); - break; - case OPCODE_RCP: - ARITH_1OP_SCALAR(NV40_VP_INST_OP_RCP); - break; - case OPCODE_RSQ: - ARITH_1OP_SCALAR(NV40_VP_INST_OP_RSQ); - break; - case OPCODE_SGE: - ARITH_2OP(NV40_VP_INST_OP_SGE); - break; - case OPCODE_SLT: - ARITH_2OP(NV40_VP_INST_OP_SLT); - break; - case OPCODE_SUB: - t_src_reg(vp, &vpi->SrcReg[0], &src0); - t_src_reg(vp, &vpi->SrcReg[1], &src1); - src1.negate = !src1.negate; - - emit_arith(vp, NV40_VP_INST_OP_ADD, &dest, - &src0, NULL, &src1, - 0 - ); - break; - case OPCODE_SWZ: - ARITH_1OP(NV40_VP_INST_OP_MOV); - break; - - case OPCODE_XPD: - break; - /* NV_vertex_program3 requirements */ - case OPCODE_SEQ: - ARITH_2OP(NV40_VP_INST_OP_SEQ); - break; - case OPCODE_SFL: - ARITH_2OP(NV40_VP_INST_OP_SFL); - break; - case OPCODE_SGT: - ARITH_2OP(NV40_VP_INST_OP_SGT); - break; - case OPCODE_SLE: - ARITH_2OP(NV40_VP_INST_OP_SLE); - break; - case OPCODE_SNE: - ARITH_2OP(NV40_VP_INST_OP_SNE); - break; - case OPCODE_STR: - ARITH_2OP(NV40_VP_INST_OP_STR); - break; - case OPCODE_SSG: - ARITH_1OP(NV40_VP_INST_OP_SSG); - break; - case OPCODE_ARL_NV: - break; - case OPCODE_ARR: - break; - case OPCODE_ARA: - break; - case OPCODE_RCC: - ARITH_1OP_SCALAR(NV40_VP_INST_OP_SSG); - break; - case OPCODE_BRA: - break; - case OPCODE_CAL: - break; - case OPCODE_RET: - break; - case OPCODE_PUSHA: - break; - case OPCODE_POPA: - break; - default: - break; - } - } - - return 0; -} - -/* Pre-init vertex program - * - Grab reference counts on temps - * - Where multiple inputs are used in a single instruction, - * emit instructions to move the extras into temps - */ -static int -init(nouveau_vertex_program *vp) -{ - struct vertex_program *mvp = &vp->mesa_program; - struct prog_instruction *vpi; - int i; - - nvsRecInit(&vp->temps_in_use, 64); - nvsRecInit(&vp->hwtemps_written, 64); - nvsRecInit(&vp->hwtemps_in_use , 64); - - for (vpi=mvp->Base.Instructions; vpi->Opcode!=OPCODE_END; vpi++) { - int in_done = 0; - int in_idx; - - for (i=0;i<3;i++) { - struct prog_src_register *src = &vpi->SrcReg[i]; - /*FIXME: does not handle relative addressing!*/ - int idx = src->Index; - - switch (src->File) { - case PROGRAM_TEMPORARY: - vp->temps[idx].file = HW_TEMP; - vp->temps[idx].hw_id = -1; - vp->temps[idx].ref++; - nvsBitSet(vp->temps_in_use, idx); - break; - case PROGRAM_INPUT: - if (vp->inputs[idx].file == HW_TEMP) { - vp->inputs[idx].ref++; - break; - } - - if (!in_done || (in_idx == idx)) { - vp->inputs[idx].file = HW_INPUT; - vp->inputs[idx].hw_id = idx; - vp->inputs[idx].ref++; - in_done = 1; - in_idx = idx; - } else { - vp->inputs[idx].file = HW_TEMP; - vp->inputs[idx].ref++; - } - break; - default: - break; - } - } - - switch (vpi->DstReg.File) { - case PROGRAM_TEMPORARY: - vp->temps[vpi->DstReg.Index].file = HW_TEMP; - vp->temps[vpi->DstReg.Index].hw_id = -1; - vp->temps[vpi->DstReg.Index].ref++; - nvsBitSet(vp->temps_in_use, vpi->DstReg.Index); - break; - default: - break; - } - } - - /* Now we can move any inputs that need it into temps */ - for (i=0; i<14; i++) { - if (vp->inputs[i].file == HW_TEMP) { - nouveau_srcreg src; - nouveau_dstreg dest; - - make_dstreg(vp, &dest, HW_TEMP , -1); - make_srcreg(vp, &src , HW_INPUT, i); - - emit_arith(vp, NV40_VP_INST_OP_MOV, &dest, - &src, NULL, NULL, - 0 - ); - - vp->inputs[i].file = HW_TEMP; - vp->inputs[i].hw_id = dest.hw->hw_id; - } - } - - return 0; -} - -int -nv40TranslateVertexProgram(nouveau_vertex_program *vp) -{ - int ret; - - ret = init(vp); - if (ret) - return ret; - - ret = translate(vp); - if (ret) - return ret; - - return 0; -} - -int -main(int argc, char **argv) -{ - nouveau_vertex_program *vp = calloc(1, sizeof(nouveau_vertex_program)); - struct vertex_program *mvp = &vp->mesa_program; - struct prog_instruction inst[3]; - - /* - "ADD t0, vertex.color, vertex.position;\n" - "ADD result.position, t0, vertex.position;\n" - */ - - inst[0].Opcode = OPCODE_ADD; - inst[0].SrcReg[0].File = PROGRAM_INPUT; - inst[0].SrcReg[0].Index = VERT_ATTRIB_COLOR0; - inst[0].SrcReg[0].NegateBase = 0; - inst[0].SrcReg[0].Swizzle = MAKE_SWIZZLE4(0, 1, 2, 3); - inst[0].SrcReg[1].File = PROGRAM_INPUT; - inst[0].SrcReg[1].Index = VERT_ATTRIB_POS; - inst[0].SrcReg[1].NegateBase = 0; - inst[0].SrcReg[1].Swizzle = MAKE_SWIZZLE4(0, 1, 2, 3); - inst[0].SrcReg[2].File = PROGRAM_UNDEFINED; - inst[0].DstReg.File = PROGRAM_TEMPORARY; - inst[0].DstReg.Index = 0; - inst[0].DstReg.WriteMask = WRITEMASK_XYZW; - inst[0].DstReg.CondMask = COND_TR; - inst[0].DstReg.CondSwizzle = MAKE_SWIZZLE4(0, 1, 2, 3); - inst[0].DstReg.CondSrc = 0; - inst[0].CondUpdate = 0; - inst[0].CondDst = 0; - - inst[1].Opcode = OPCODE_ADD; - inst[1].SrcReg[0].File = PROGRAM_TEMPORARY; - inst[1].SrcReg[0].Index = 0; - inst[1].SrcReg[0].NegateBase = 0; - inst[1].SrcReg[0].Swizzle = MAKE_SWIZZLE4(0, 1, 2, 3); - inst[1].SrcReg[1].File = PROGRAM_INPUT; - inst[1].SrcReg[1].Index = VERT_ATTRIB_POS; - inst[1].SrcReg[1].NegateBase = 0; - inst[1].SrcReg[1].Swizzle = MAKE_SWIZZLE4(0, 1, 2, 3); - inst[0].SrcReg[2].File = PROGRAM_UNDEFINED; - inst[1].DstReg.File = PROGRAM_OUTPUT; - inst[1].DstReg.Index = VERT_RESULT_HPOS; - inst[1].DstReg.WriteMask = WRITEMASK_XYZW; - inst[1].DstReg.CondMask = COND_TR; - inst[1].DstReg.CondSwizzle = MAKE_SWIZZLE4(0, 1, 2, 3); - inst[1].DstReg.CondSrc = 0; - inst[1].CondUpdate = 0; - inst[1].CondDst = 0; - - inst[2].Opcode = OPCODE_END; - - mvp->Base.Instructions = inst; - - nv40TranslateVertexProgram(vp); -} - -- cgit v1.2.3 From efef291dc71eb57f90785a26957f4b3e01733156 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 30 Oct 2006 16:43:39 +0000 Subject: checkpoint - remove dead files, otherwise untested --- src/mesa/drivers/dri/i965/Makefile | 8 - src/mesa/drivers/dri/i965/brw_attrib.h | 113 --- src/mesa/drivers/dri/i965/brw_attrib_tmp.h | 485 ----------- src/mesa/drivers/dri/i965/brw_context.c | 5 - src/mesa/drivers/dri/i965/brw_draw.c | 55 +- src/mesa/drivers/dri/i965/brw_draw.h | 47 +- src/mesa/drivers/dri/i965/brw_draw_upload.c | 4 +- src/mesa/drivers/dri/i965/brw_exec.c | 125 --- src/mesa/drivers/dri/i965/brw_exec.h | 150 ---- src/mesa/drivers/dri/i965/brw_exec_api.c | 716 ----------------- src/mesa/drivers/dri/i965/brw_exec_array.c | 283 ------- src/mesa/drivers/dri/i965/brw_exec_draw.c | 227 ------ src/mesa/drivers/dri/i965/brw_exec_eval.c | 255 ------ src/mesa/drivers/dri/i965/brw_fallback.c | 6 +- src/mesa/drivers/dri/i965/brw_fallback.h | 4 +- src/mesa/drivers/dri/i965/brw_metaops.c | 5 +- src/mesa/drivers/dri/i965/brw_save.c | 126 --- src/mesa/drivers/dri/i965/brw_save.h | 171 ---- src/mesa/drivers/dri/i965/brw_save_api.c | 1162 --------------------------- src/mesa/drivers/dri/i965/brw_save_draw.c | 209 ----- 20 files changed, 42 insertions(+), 4114 deletions(-) delete mode 100644 src/mesa/drivers/dri/i965/brw_attrib.h delete mode 100644 src/mesa/drivers/dri/i965/brw_attrib_tmp.h delete mode 100644 src/mesa/drivers/dri/i965/brw_exec.c delete mode 100644 src/mesa/drivers/dri/i965/brw_exec.h delete mode 100644 src/mesa/drivers/dri/i965/brw_exec_api.c delete mode 100644 src/mesa/drivers/dri/i965/brw_exec_array.c delete mode 100644 src/mesa/drivers/dri/i965/brw_exec_draw.c delete mode 100644 src/mesa/drivers/dri/i965/brw_exec_eval.c delete mode 100644 src/mesa/drivers/dri/i965/brw_save.c delete mode 100644 src/mesa/drivers/dri/i965/brw_save.h delete mode 100644 src/mesa/drivers/dri/i965/brw_save_api.c delete mode 100644 src/mesa/drivers/dri/i965/brw_save_draw.c (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile index 213eac895c..8ec422509f 100644 --- a/src/mesa/drivers/dri/i965/Makefile +++ b/src/mesa/drivers/dri/i965/Makefile @@ -40,11 +40,6 @@ DRIVER_SOURCES = \ brw_eu_debug.c \ brw_eu_emit.c \ brw_eu_util.c \ - brw_exec.c \ - brw_exec_api.c \ - brw_exec_array.c \ - brw_exec_draw.c \ - brw_exec_eval.c \ brw_fallback.c \ brw_gs.c \ brw_gs_emit.c \ @@ -53,9 +48,6 @@ DRIVER_SOURCES = \ brw_metaops.c \ brw_misc_state.c \ brw_program.c \ - brw_save.c \ - brw_save_api.c \ - brw_save_draw.c \ brw_sf.c \ brw_sf_emit.c \ brw_sf_state.c \ diff --git a/src/mesa/drivers/dri/i965/brw_attrib.h b/src/mesa/drivers/dri/i965/brw_attrib.h deleted file mode 100644 index a8efc3a528..0000000000 --- a/src/mesa/drivers/dri/i965/brw_attrib.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - Copyright (C) Intel Corp. 2006. All Rights Reserved. - Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to - develop this 3D driver. - - 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 - */ - -#ifndef BRW_ATTRIB_H -#define BRW_ATTRIB_H - - -/* - * Note: The first attributes match the VERT_ATTRIB_* definitions - * in mtypes.h. However, the tnl module has additional attributes - * for materials, color indexes, edge flags, etc. - */ -/* Although it's nice to use these as bit indexes in a DWORD flag, we - * could manage without if necessary. Another limit currently is the - * number of bits allocated for these numbers in places like vertex - * program instruction formats and register layouts. - */ -enum { - BRW_ATTRIB_POS = 0, - BRW_ATTRIB_WEIGHT = 1, - BRW_ATTRIB_NORMAL = 2, - BRW_ATTRIB_COLOR0 = 3, - BRW_ATTRIB_COLOR1 = 4, - BRW_ATTRIB_FOG = 5, - BRW_ATTRIB_INDEX = 6, - BRW_ATTRIB_EDGEFLAG = 7, - BRW_ATTRIB_TEX0 = 8, - BRW_ATTRIB_TEX1 = 9, - BRW_ATTRIB_TEX2 = 10, - BRW_ATTRIB_TEX3 = 11, - BRW_ATTRIB_TEX4 = 12, - BRW_ATTRIB_TEX5 = 13, - BRW_ATTRIB_TEX6 = 14, - BRW_ATTRIB_TEX7 = 15, - - BRW_ATTRIB_GENERIC0 = 16, /* Not used? */ - BRW_ATTRIB_GENERIC1 = 17, - BRW_ATTRIB_GENERIC2 = 18, - BRW_ATTRIB_GENERIC3 = 19, - BRW_ATTRIB_GENERIC4 = 20, - BRW_ATTRIB_GENERIC5 = 21, - BRW_ATTRIB_GENERIC6 = 22, - BRW_ATTRIB_GENERIC7 = 23, - BRW_ATTRIB_GENERIC8 = 24, - BRW_ATTRIB_GENERIC9 = 25, - BRW_ATTRIB_GENERIC10 = 26, - BRW_ATTRIB_GENERIC11 = 27, - BRW_ATTRIB_GENERIC12 = 28, - BRW_ATTRIB_GENERIC13 = 29, - BRW_ATTRIB_GENERIC14 = 30, - BRW_ATTRIB_GENERIC15 = 31, - - BRW_ATTRIB_MAT_FRONT_AMBIENT = 32, - BRW_ATTRIB_MAT_BACK_AMBIENT = 33, - BRW_ATTRIB_MAT_FRONT_DIFFUSE = 34, - BRW_ATTRIB_MAT_BACK_DIFFUSE = 35, - BRW_ATTRIB_MAT_FRONT_SPECULAR = 36, - BRW_ATTRIB_MAT_BACK_SPECULAR = 37, - BRW_ATTRIB_MAT_FRONT_EMISSION = 38, - BRW_ATTRIB_MAT_BACK_EMISSION = 39, - BRW_ATTRIB_MAT_FRONT_SHININESS = 40, - BRW_ATTRIB_MAT_BACK_SHININESS = 41, - BRW_ATTRIB_MAT_FRONT_INDEXES = 42, - BRW_ATTRIB_MAT_BACK_INDEXES = 43, - - BRW_ATTRIB_MAX = 44 -} ; - -#define BRW_ATTRIB_FIRST_MATERIAL BRW_ATTRIB_MAT_FRONT_AMBIENT - -#define BRW_MAX_COPIED_VERTS 3 - - -static inline GLuint64EXT brw_translate_inputs( GLboolean vp_enabled, - GLuint mesa_inputs ) -{ - GLuint64EXT inputs = mesa_inputs; - if (vp_enabled) - return inputs; - else - return (inputs & 0xffff) | ((inputs & 0xffff0000) << 16); -} - - -#endif diff --git a/src/mesa/drivers/dri/i965/brw_attrib_tmp.h b/src/mesa/drivers/dri/i965/brw_attrib_tmp.h deleted file mode 100644 index 3089bd6cac..0000000000 --- a/src/mesa/drivers/dri/i965/brw_attrib_tmp.h +++ /dev/null @@ -1,485 +0,0 @@ -/************************************************************************** - -Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. - -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 -TUNGSTEN GRAPHICS AND/OR THEIR 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. - -**************************************************************************/ - -#define ATTR1FV( A, V ) ATTR( A, 1, (V)[0], 0, 0, 1 ) -#define ATTR2FV( A, V ) ATTR( A, 2, (V)[0], (V)[1], 0, 1 ) -#define ATTR3FV( A, V ) ATTR( A, 3, (V)[0], (V)[1], (V)[2], 1 ) -#define ATTR4FV( A, V ) ATTR( A, 4, (V)[0], (V)[1], (V)[2], (V)[3] ) - -#define ATTR1F( A, X ) ATTR( A, 1, X, 0, 0, 1 ) -#define ATTR2F( A, X, Y ) ATTR( A, 2, X, Y, 0, 1 ) -#define ATTR3F( A, X, Y, Z ) ATTR( A, 3, X, Y, Z, 1 ) -#define ATTR4F( A, X, Y, Z, W ) ATTR( A, 4, X, Y, Z, W ) - -#define MAT_ATTR( A, N, V ) ATTR( A, N, (V)[0], (V)[1], (V)[2], (V)[3] ) - -static void GLAPIENTRY TAG(Vertex2f)( GLfloat x, GLfloat y ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR2F( BRW_ATTRIB_POS, x, y ); -} - -static void GLAPIENTRY TAG(Vertex2fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR2FV( BRW_ATTRIB_POS, v ); -} - -static void GLAPIENTRY TAG(Vertex3f)( GLfloat x, GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3F( BRW_ATTRIB_POS, x, y, z ); -} - -static void GLAPIENTRY TAG(Vertex3fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3FV( BRW_ATTRIB_POS, v ); -} - -static void GLAPIENTRY TAG(Vertex4f)( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR4F( BRW_ATTRIB_POS, x, y, z, w ); -} - -static void GLAPIENTRY TAG(Vertex4fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR4FV( BRW_ATTRIB_POS, v ); -} - -static void GLAPIENTRY TAG(TexCoord1f)( GLfloat x ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR1F( BRW_ATTRIB_TEX0, x ); -} - -static void GLAPIENTRY TAG(TexCoord1fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR1FV( BRW_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY TAG(TexCoord2f)( GLfloat x, GLfloat y ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR2F( BRW_ATTRIB_TEX0, x, y ); -} - -static void GLAPIENTRY TAG(TexCoord2fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR2FV( BRW_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY TAG(TexCoord3f)( GLfloat x, GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3F( BRW_ATTRIB_TEX0, x, y, z ); -} - -static void GLAPIENTRY TAG(TexCoord3fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3FV( BRW_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY TAG(TexCoord4f)( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR4F( BRW_ATTRIB_TEX0, x, y, z, w ); -} - -static void GLAPIENTRY TAG(TexCoord4fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR4FV( BRW_ATTRIB_TEX0, v ); -} - -static void GLAPIENTRY TAG(Normal3f)( GLfloat x, GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3F( BRW_ATTRIB_NORMAL, x, y, z ); -} - -static void GLAPIENTRY TAG(Normal3fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3FV( BRW_ATTRIB_NORMAL, v ); -} - -static void GLAPIENTRY TAG(FogCoordfEXT)( GLfloat x ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR1F( BRW_ATTRIB_FOG, x ); -} - -static void GLAPIENTRY TAG(FogCoordfvEXT)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR1FV( BRW_ATTRIB_FOG, v ); -} - -static void GLAPIENTRY TAG(Color3f)( GLfloat x, GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3F( BRW_ATTRIB_COLOR0, x, y, z ); -} - -static void GLAPIENTRY TAG(Color3fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3FV( BRW_ATTRIB_COLOR0, v ); -} - -static void GLAPIENTRY TAG(Color4f)( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR4F( BRW_ATTRIB_COLOR0, x, y, z, w ); -} - -static void GLAPIENTRY TAG(Color4fv)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR4FV( BRW_ATTRIB_COLOR0, v ); -} - -static void GLAPIENTRY TAG(SecondaryColor3fEXT)( GLfloat x, GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3F( BRW_ATTRIB_COLOR1, x, y, z ); -} - -static void GLAPIENTRY TAG(SecondaryColor3fvEXT)( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR3FV( BRW_ATTRIB_COLOR1, v ); -} - - -static void GLAPIENTRY TAG(EdgeFlag)( GLboolean b ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR1F( BRW_ATTRIB_EDGEFLAG, (GLfloat)b ); -} - -static void GLAPIENTRY TAG(Indexf)( GLfloat f ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR1F( BRW_ATTRIB_INDEX, f ); -} - -static void GLAPIENTRY TAG(Indexfv)( const GLfloat *f ) -{ - GET_CURRENT_CONTEXT( ctx ); - ATTR1FV( BRW_ATTRIB_INDEX, f ); -} - - -static void GLAPIENTRY TAG(MultiTexCoord1f)( GLenum target, GLfloat x ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0; - ATTR1F( attr, x ); -} - -static void GLAPIENTRY TAG(MultiTexCoord1fv)( GLenum target, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0; - ATTR1FV( attr, v ); -} - -static void GLAPIENTRY TAG(MultiTexCoord2f)( GLenum target, GLfloat x, GLfloat y ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0; - ATTR2F( attr, x, y ); -} - -static void GLAPIENTRY TAG(MultiTexCoord2fv)( GLenum target, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0; - ATTR2FV( attr, v ); -} - -static void GLAPIENTRY TAG(MultiTexCoord3f)( GLenum target, GLfloat x, GLfloat y, - GLfloat z) -{ - GET_CURRENT_CONTEXT( ctx ); - GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0; - ATTR3F( attr, x, y, z ); -} - -static void GLAPIENTRY TAG(MultiTexCoord3fv)( GLenum target, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0; - ATTR3FV( attr, v ); -} - -static void GLAPIENTRY TAG(MultiTexCoord4f)( GLenum target, GLfloat x, GLfloat y, - GLfloat z, GLfloat w ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0; - ATTR4F( attr, x, y, z, w ); -} - -static void GLAPIENTRY TAG(MultiTexCoord4fv)( GLenum target, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLuint attr = (target & 0x7) + BRW_ATTRIB_TEX0; - ATTR4FV( attr, v ); -} - - -static void GLAPIENTRY TAG(VertexAttrib1fARB)( GLuint index, GLfloat x ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index == 0) - ATTR1F(0, x); - else if (index < MAX_VERTEX_ATTRIBS) - ATTR1F(BRW_ATTRIB_GENERIC0 + index, x); - else - ERROR(); -} - -static void GLAPIENTRY TAG(VertexAttrib1fvARB)( GLuint index, - const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index == 0) - ATTR1FV(0, v); - else if (index < MAX_VERTEX_ATTRIBS) - ATTR1FV(BRW_ATTRIB_GENERIC0 + index, v); - else - ERROR(); -} - -static void GLAPIENTRY TAG(VertexAttrib2fARB)( GLuint index, GLfloat x, - GLfloat y ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index == 0) - ATTR2F(0, x, y); - else if (index < MAX_VERTEX_ATTRIBS) - ATTR2F(BRW_ATTRIB_GENERIC0 + index, x, y); - else - ERROR(); -} - -static void GLAPIENTRY TAG(VertexAttrib2fvARB)( GLuint index, - const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index == 0) - ATTR2FV(0, v); - else if (index < MAX_VERTEX_ATTRIBS) - ATTR2FV(BRW_ATTRIB_GENERIC0 + index, v); - else - ERROR(); -} - -static void GLAPIENTRY TAG(VertexAttrib3fARB)( GLuint index, GLfloat x, - GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index == 0) - ATTR3F(0, x, y, z); - else if (index < MAX_VERTEX_ATTRIBS) - ATTR3F(BRW_ATTRIB_GENERIC0 + index, x, y, z); - else - ERROR(); -} - -static void GLAPIENTRY TAG(VertexAttrib3fvARB)( GLuint index, - const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index == 0) - ATTR3FV(0, v); - else if (index < MAX_VERTEX_ATTRIBS) - ATTR3FV(BRW_ATTRIB_GENERIC0 + index, v); - else - ERROR(); -} - -static void GLAPIENTRY TAG(VertexAttrib4fARB)( GLuint index, GLfloat x, - GLfloat y, GLfloat z, - GLfloat w ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index == 0) - ATTR4F(0, x, y, z, w); - else if (index < MAX_VERTEX_ATTRIBS) - ATTR4F(BRW_ATTRIB_GENERIC0 + index, x, y, z, w); - else - ERROR(); -} - -static void GLAPIENTRY TAG(VertexAttrib4fvARB)( GLuint index, - const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index == 0) - ATTR4FV(0, v); - else if (index < MAX_VERTEX_ATTRIBS) - ATTR4FV(BRW_ATTRIB_GENERIC0 + index, v); - else - ERROR(); -} - - -/* Although we don't export NV_vertex_program, these entrypoints are - * used by the display list and other code specifically because of - * their property of aliasing with other attributes. - */ -static void GLAPIENTRY TAG(VertexAttrib1fNV)( GLuint index, GLfloat x ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index < BRW_ATTRIB_MAX) - ATTR1F(index, x); -} - -static void GLAPIENTRY TAG(VertexAttrib1fvNV)( GLuint index, - const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index < BRW_ATTRIB_MAX) - ATTR1FV(index, v); -} - -static void GLAPIENTRY TAG(VertexAttrib2fNV)( GLuint index, GLfloat x, - GLfloat y ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index < BRW_ATTRIB_MAX) - ATTR2F(index, x, y); -} - -static void GLAPIENTRY TAG(VertexAttrib2fvNV)( GLuint index, - const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index < BRW_ATTRIB_MAX) - ATTR2FV(index, v); -} - -static void GLAPIENTRY TAG(VertexAttrib3fNV)( GLuint index, GLfloat x, - GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index < BRW_ATTRIB_MAX) - ATTR3F(index, x, y, z); -} - -static void GLAPIENTRY TAG(VertexAttrib3fvNV)( GLuint index, - const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index < BRW_ATTRIB_MAX) - ATTR3FV(index, v); -} - -static void GLAPIENTRY TAG(VertexAttrib4fNV)( GLuint index, GLfloat x, - GLfloat y, GLfloat z, - GLfloat w ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index < BRW_ATTRIB_MAX) - ATTR4F(index, x, y, z, w); -} - -static void GLAPIENTRY TAG(VertexAttrib4fvNV)( GLuint index, - const GLfloat *v ) -{ - GET_CURRENT_CONTEXT( ctx ); - if (index < BRW_ATTRIB_MAX) - ATTR4FV(index, v); -} - - -#define MAT( ATTR, N, face, params ) \ -do { \ - if (face != GL_BACK) \ - MAT_ATTR( ATTR, N, params ); /* front */ \ - if (face != GL_FRONT) \ - MAT_ATTR( ATTR + 1, N, params ); /* back */ \ -} while (0) - - -/* Colormaterial conflicts are dealt with later. - */ -static void GLAPIENTRY TAG(Materialfv)( GLenum face, GLenum pname, - const GLfloat *params ) -{ - GET_CURRENT_CONTEXT( ctx ); - switch (pname) { - case GL_EMISSION: - MAT( BRW_ATTRIB_MAT_FRONT_EMISSION, 4, face, params ); - break; - case GL_AMBIENT: - MAT( BRW_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params ); - break; - case GL_DIFFUSE: - MAT( BRW_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params ); - break; - case GL_SPECULAR: - MAT( BRW_ATTRIB_MAT_FRONT_SPECULAR, 4, face, params ); - break; - case GL_SHININESS: - MAT( BRW_ATTRIB_MAT_FRONT_SHININESS, 1, face, params ); - break; - case GL_COLOR_INDEXES: - MAT( BRW_ATTRIB_MAT_FRONT_INDEXES, 3, face, params ); - break; - case GL_AMBIENT_AND_DIFFUSE: - MAT( BRW_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params ); - MAT( BRW_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params ); - break; - default: - ERROR(); - return; - } -} - - -#undef ATTR1FV -#undef ATTR2FV -#undef ATTR3FV -#undef ATTR4FV - -#undef ATTR1F -#undef ATTR2F -#undef ATTR3F -#undef ATTR4F - -#undef MAT -#undef MAT_ATTR diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c index c1f6617f3f..b9256d5185 100644 --- a/src/mesa/drivers/dri/i965/brw_context.c +++ b/src/mesa/drivers/dri/i965/brw_context.c @@ -156,11 +156,6 @@ GLboolean brwCreateContext( const __GLcontextModes *mesaVis, brw_ProgramCacheInit( ctx ); - /* Hook our functions into exec and compile dispatch tables. Only - * fallback on out-of-memory situations. - */ - brw_exec_init( ctx ); - brw_save_init( ctx ); { const char *filename = getenv("INTEL_REPLAY"); diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index 5c0c5da7ea..1bc39762bc 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -143,7 +143,7 @@ static void brw_emit_cliprect( struct brw_context *brw, static void brw_emit_prim( struct brw_context *brw, - const struct brw_draw_prim *prim ) + const struct vbo_prim *prim ) { struct brw_3d_primitive prim_packet; @@ -230,7 +230,7 @@ static void brw_merge_inputs( struct brw_context *brw, } static GLboolean check_fallbacks( struct brw_context *brw, - const struct brw_draw_prim *prim, + const struct vbo_prim *prim, GLuint nr_prims ) { GLuint i; @@ -284,12 +284,11 @@ static GLboolean check_fallbacks( struct brw_context *brw, static GLboolean brw_try_draw_prims( GLcontext *ctx, const struct gl_client_array *arrays[], - const struct brw_draw_prim *prim, + const struct vbo_prim *prim, GLuint nr_prims, - const struct brw_draw_index_buffer *ib, + const struct _mesa_index_buffer *ib, GLuint min_index, - GLuint max_index, - GLuint flags ) + GLuint max_index ) { struct intel_context *intel = intel_context(ctx); struct brw_context *brw = brw_context(ctx); @@ -412,43 +411,47 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, } -GLboolean brw_draw_prims( GLcontext *ctx, - const struct gl_client_array *arrays[], - const struct brw_draw_prim *prim, - GLuint nr_prims, - const struct brw_draw_index_buffer *ib, - GLuint min_index, - GLuint max_index, - GLuint flags ) +void brw_draw_prims( GLcontext *ctx, + const struct gl_client_array *arrays[], + const struct vbo_prim *prim, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLuint min_index, + GLuint max_index ) { struct intel_context *intel = intel_context(ctx); GLboolean retval; - retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index, flags); + retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); + /* This looks like out-of-memory but potentially we have + * situation where there is enough memory but it has become + * fragmented. Clear out all heaps and start from scratch by + * faking a contended lock event: (done elsewhere) + */ if (!retval && bmError(intel)) { - DBG("retrying\n"); - /* This looks like out-of-memory but potentially we have - * situation where there is enough memory but it has become - * fragmented. Clear out all heaps and start from scratch by - * faking a contended lock event: (done elsewhere) - */ - /* Then try a second time only to upload textures and draw the * primitives: */ - retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index, flags); + retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); + } + + /* Otherwise, we really are out of memory. Pass the drawing + * command to the software tnl module and which will in turn call + * swrast to do the drawing. + */ + if (!retval) { + brw_fallback(); + _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); + brw_unfallback(); } if (intel->aub_file && (INTEL_DEBUG & DEBUG_SYNC)) { intelFinish( &intel->ctx ); intel->aub_wrap = 1; } - - - return retval; } diff --git a/src/mesa/drivers/dri/i965/brw_draw.h b/src/mesa/drivers/dri/i965/brw_draw.h index 92640bf725..b68cd86115 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.h +++ b/src/mesa/drivers/dri/i965/brw_draw.h @@ -33,40 +33,14 @@ struct brw_context; -struct brw_draw_prim { - GLuint mode:8; - GLuint indexed:1; - GLuint begin:1; - GLuint end:1; - GLuint weak:1; - GLuint pad:20; - - GLuint start; - GLuint count; -}; - -struct brw_draw_index_buffer { - GLuint count; - GLenum type; - struct gl_buffer_object *obj; - const void *ptr; - GLuint rebase; -}; - - -#define BRW_DRAW_SORTED 0x1 -#define BRW_DRAW_ALL_INTERLEAVED 0x2 -#define BRW_DRAW_NON_INTERLEAVED 0x4 -#define BRW_DRAW_LOCKED 0x8 GLboolean brw_draw_prims( GLcontext *ctx, const struct gl_client_array *arrays[], - const struct brw_draw_prim *prims, + const struct vbo_prim *prims, GLuint nr_prims, - const struct brw_draw_index_buffer *ib, + const struct _mesa_index_buffer *ib, GLuint min_index, - GLuint max_index, - GLuint flags ); + GLuint max_index ); void brw_draw_init( struct brw_context *brw ); void brw_draw_destroy( struct brw_context *brw ); @@ -80,25 +54,12 @@ void brw_init_current_values(GLcontext *ctx, /* brw_draw_upload.c */ void brw_upload_indices( struct brw_context *brw, - const struct brw_draw_index_buffer *index_buffer); + const struct _mesa_index_buffer *index_buffer); GLboolean brw_upload_vertices( struct brw_context *brw, GLuint min_index, GLuint max_index ); -/* Helpers for save, exec. Should probably have their own file: - */ -struct brw_exec_context; -struct brw_save_context; - -struct brw_exec_save { - struct brw_exec_context *exec; - struct brw_save_context *save; -}; - -/* Doesn't really belong here: - */ -#define IMM_CONTEXT(ctx) ((struct brw_exec_save *)((ctx)->swtnl_im)) #endif diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index cde0aa6481..4d930c6c9e 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -568,7 +568,7 @@ static GLuint element_size( GLenum type ) static void rebase_indices_to_vbo_indices( struct brw_context *brw, - const struct brw_draw_index_buffer *index_buffer, + const struct vbo_index_buffer *index_buffer, struct gl_buffer_object **vbo_return, GLuint *offset_return ) { @@ -642,7 +642,7 @@ static void rebase_indices_to_vbo_indices( struct brw_context *brw, void brw_upload_indices( struct brw_context *brw, - const struct brw_draw_index_buffer *index_buffer) + const struct vbo_index_buffer *index_buffer) { struct intel_context *intel = &brw->intel; GLuint ib_size = get_size(index_buffer->type) * index_buffer->count; diff --git a/src/mesa/drivers/dri/i965/brw_exec.c b/src/mesa/drivers/dri/i965/brw_exec.c deleted file mode 100644 index fc06c3c361..0000000000 --- a/src/mesa/drivers/dri/i965/brw_exec.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.3 - * - * Copyright (C) 1999-2005 Brian Paul 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, 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 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 - * BRIAN PAUL 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 - */ - - -#include "api_arrayelt.h" -#include "glheader.h" -#include "imports.h" -#include "context.h" -#include "macros.h" -#include "mtypes.h" -#include "dlist.h" -#include "vtxfmt.h" - -#include "brw_exec.h" - - -void brw_exec_init( GLcontext *ctx ) -{ - struct brw_exec_context *exec = CALLOC_STRUCT(brw_exec_context); - - if (ctx->swtnl_im == NULL) { - ctx->swtnl_im = CALLOC_STRUCT(brw_exec_save); - } - - exec->ctx = ctx; - IMM_CONTEXT(ctx)->exec = exec; - - /* Initialize the arrayelt helper - */ - if (!ctx->aelt_context && - !_ae_create_context( ctx )) - return; - - brw_exec_vtx_init( exec ); - brw_exec_array_init( exec ); - - ctx->Driver.NeedFlush = 0; - ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; - ctx->Driver.FlushVertices = brw_exec_FlushVertices; - - exec->eval.recalculate_maps = 1; -} - - -void brw_exec_destroy( GLcontext *ctx ) -{ - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - - if (ctx->aelt_context) { - _ae_destroy_context( ctx ); - ctx->aelt_context = NULL; - } - - brw_exec_vtx_destroy( exec ); - brw_exec_array_destroy( exec ); - - if (exec) { - FREE(exec); - IMM_CONTEXT(ctx)->exec = NULL; - } - - if (IMM_CONTEXT(ctx)->exec == NULL && - IMM_CONTEXT(ctx)->save == NULL) { - FREE(IMM_CONTEXT(ctx)); - ctx->swtnl_im = NULL; - } -} - -/* Really want to install these callbacks to a central facility to be - * invoked according to the state flags. That will have to wait for a - * mesa rework: - */ -void brw_exec_invalidate_state( GLcontext *ctx, GLuint new_state ) -{ - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - - if (new_state & (_NEW_PROGRAM|_NEW_EVAL)) - exec->eval.recalculate_maps = 1; - - _ae_invalidate_state(ctx, new_state); -} - - -void brw_exec_wakeup( GLcontext *ctx ) -{ - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - - ctx->Driver.FlushVertices = brw_exec_FlushVertices; - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; - - /* Hook our functions into exec and compile dispatch tables. - */ - _mesa_install_exec_vtxfmt( ctx, &exec->vtxfmt ); - - /* Assume we haven't been getting state updates either: - */ - brw_exec_invalidate_state( ctx, ~0 ); -} - - - diff --git a/src/mesa/drivers/dri/i965/brw_exec.h b/src/mesa/drivers/dri/i965/brw_exec.h deleted file mode 100644 index f07b448587..0000000000 --- a/src/mesa/drivers/dri/i965/brw_exec.h +++ /dev/null @@ -1,150 +0,0 @@ -/************************************************************************** - -Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. - -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 -TUNGSTEN GRAPHICS AND/OR THEIR 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 - * - */ - -#ifndef __BRW_EXEC_H__ -#define __BRW_EXEC_H__ - -#include "mtypes.h" -#include "brw_attrib.h" -#include "brw_draw.h" - - -#define BRW_MAX_PRIM 64 - -/* Wierd implementation stuff: - */ -#define BRW_VERT_BUFFER_SIZE (1024*16) /* dwords == 64k */ -#define BRW_MAX_ATTR_CODEGEN 16 -#define ERROR_ATTRIB 16 - - - - -struct brw_exec_eval1_map { - struct gl_1d_map *map; - GLuint sz; -}; - -struct brw_exec_eval2_map { - struct gl_2d_map *map; - GLuint sz; -}; - - - -struct brw_exec_copied_vtx { - GLfloat buffer[BRW_ATTRIB_MAX * 4 * BRW_MAX_COPIED_VERTS]; - GLuint nr; -}; - - -typedef void (*brw_attrfv_func)( const GLfloat * ); - - -struct brw_exec_context -{ - GLcontext *ctx; - GLvertexformat vtxfmt; - - struct { - struct gl_buffer_object *bufferobj; - GLubyte *buffer_map; - - GLuint vertex_size; - - struct brw_draw_prim prim[BRW_MAX_PRIM]; - GLuint prim_count; - - GLfloat *vbptr; /* cursor, points into buffer */ - GLfloat vertex[BRW_ATTRIB_MAX*4]; /* current vertex */ - - GLfloat *current[BRW_ATTRIB_MAX]; /* points into ctx->Current, ctx->Light.Material */ - GLfloat CurrentFloatEdgeFlag; - - GLuint vert_count; - GLuint max_vert; - struct brw_exec_copied_vtx copied; - - GLubyte attrsz[BRW_ATTRIB_MAX]; - GLubyte active_sz[BRW_ATTRIB_MAX]; - - GLfloat *attrptr[BRW_ATTRIB_MAX]; - struct gl_client_array arrays[BRW_ATTRIB_MAX]; - const struct gl_client_array *inputs[BRW_ATTRIB_MAX]; - } vtx; - - - struct { - GLboolean recalculate_maps; - struct brw_exec_eval1_map map1[BRW_ATTRIB_MAX]; - struct brw_exec_eval2_map map2[BRW_ATTRIB_MAX]; - } eval; - - struct { - const struct gl_client_array *inputs[BRW_ATTRIB_MAX]; - - struct gl_buffer_object *index_obj; - } array; -}; - - - -/* External API: - */ -void brw_exec_init( GLcontext *ctx ); -void brw_exec_destroy( GLcontext *ctx ); -void brw_exec_invalidate_state( GLcontext *ctx, GLuint new_state ); -void brw_exec_FlushVertices( GLcontext *ctx, GLuint flags ); -void brw_exec_wakeup( GLcontext *ctx ); - - -/* Internal functions: - */ -void brw_exec_array_init( struct brw_exec_context *exec ); -void brw_exec_array_destroy( struct brw_exec_context *exec ); - - -void brw_exec_vtx_init( struct brw_exec_context *exec ); -void brw_exec_vtx_destroy( struct brw_exec_context *exec ); -void brw_exec_vtx_flush( struct brw_exec_context *exec ); -void brw_exec_vtx_wrap( struct brw_exec_context *exec ); - -void brw_exec_eval_update( struct brw_exec_context *exec ); - -void brw_exec_do_EvalCoord2f( struct brw_exec_context *exec, - GLfloat u, GLfloat v ); - -void brw_exec_do_EvalCoord1f( struct brw_exec_context *exec, - GLfloat u); - -#endif diff --git a/src/mesa/drivers/dri/i965/brw_exec_api.c b/src/mesa/drivers/dri/i965/brw_exec_api.c deleted file mode 100644 index 470fa6f417..0000000000 --- a/src/mesa/drivers/dri/i965/brw_exec_api.c +++ /dev/null @@ -1,716 +0,0 @@ -/************************************************************************** - -Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. - -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 -TUNGSTEN GRAPHICS AND/OR THEIR 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 - */ - -#include "glheader.h" -#include "context.h" -#include "macros.h" -#include "vtxfmt.h" -#include "dlist.h" -#include "state.h" -#include "light.h" -#include "api_arrayelt.h" -#include "api_noop.h" -#include "dispatch.h" - -#include "brw_exec.h" - -static void reset_attrfv( struct brw_exec_context *exec ); - - -/* Close off the last primitive, execute the buffer, restart the - * primitive. - */ -static void brw_exec_wrap_buffers( struct brw_exec_context *exec ) -{ - if (exec->vtx.prim_count == 0) { - exec->vtx.copied.nr = 0; - exec->vtx.vert_count = 0; - exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map; - } - else { - GLuint last_begin = exec->vtx.prim[exec->vtx.prim_count-1].begin; - GLuint last_count; - - if (exec->ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) { - GLint i = exec->vtx.prim_count - 1; - assert(i >= 0); - exec->vtx.prim[i].count = (exec->vtx.vert_count - - exec->vtx.prim[i].start); - } - - last_count = exec->vtx.prim[exec->vtx.prim_count-1].count; - - /* Execute the buffer and save copied vertices. - */ - if (exec->vtx.vert_count) - brw_exec_vtx_flush( exec ); - else { - exec->vtx.prim_count = 0; - exec->vtx.copied.nr = 0; - } - - /* Emit a glBegin to start the new list. - */ - assert(exec->vtx.prim_count == 0); - - if (exec->ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) { - exec->vtx.prim[0].mode = exec->ctx->Driver.CurrentExecPrimitive; - exec->vtx.prim[0].start = 0; - exec->vtx.prim[0].count = 0; - exec->vtx.prim_count++; - - if (exec->vtx.copied.nr == last_count) - exec->vtx.prim[0].begin = last_begin; - } - } -} - - -/* Deal with buffer wrapping where provoked by the vertex buffer - * filling up, as opposed to upgrade_vertex(). - */ -void brw_exec_vtx_wrap( struct brw_exec_context *exec ) -{ - GLfloat *data = exec->vtx.copied.buffer; - GLuint i; - - /* Run pipeline on current vertices, copy wrapped vertices - * to exec->vtx.copied. - */ - brw_exec_wrap_buffers( exec ); - - /* Copy stored stored vertices to start of new list. - */ - assert(exec->vtx.max_vert - exec->vtx.vert_count > exec->vtx.copied.nr); - - for (i = 0 ; i < exec->vtx.copied.nr ; i++) { - _mesa_memcpy( exec->vtx.vbptr, data, - exec->vtx.vertex_size * sizeof(GLfloat)); - exec->vtx.vbptr += exec->vtx.vertex_size; - data += exec->vtx.vertex_size; - exec->vtx.vert_count++; - } - - exec->vtx.copied.nr = 0; -} - - -/* - * Copy the active vertex's values to the ctx->Current fields. - */ -static void brw_exec_copy_to_current( struct brw_exec_context *exec ) -{ - GLcontext *ctx = exec->ctx; - GLuint i; - - for (i = BRW_ATTRIB_POS+1 ; i < BRW_ATTRIB_MAX ; i++) { - if (exec->vtx.attrsz[i]) { - /* Note: the exec->vtx.current[i] pointers point into the - * ctx->Current.Attrib and ctx->Light.Material.Attrib arrays. - */ - COPY_CLEAN_4V(exec->vtx.current[i], - exec->vtx.attrsz[i], - exec->vtx.attrptr[i]); - - /* This triggers rather too much recalculation of Mesa state - * that doesn't get used (eg light positions). - */ - if (i >= BRW_ATTRIB_MAT_FRONT_AMBIENT && - i <= BRW_ATTRIB_MAT_BACK_INDEXES) - ctx->NewState |= _NEW_LIGHT; - } - } - - /* color index is special (it's not a float[4] so COPY_CLEAN_4V above - * will trash adjacent memory!) - */ - if (exec->vtx.attrsz[BRW_ATTRIB_INDEX]) { - ctx->Current.Index = exec->vtx.attrptr[BRW_ATTRIB_INDEX][0]; - } - - /* Edgeflag requires additional treatment: - */ - if (exec->vtx.attrsz[BRW_ATTRIB_EDGEFLAG]) { - ctx->Current.EdgeFlag = (exec->vtx.CurrentFloatEdgeFlag == 1.0); - } - - /* Colormaterial -- this kindof sucks. - */ - if (ctx->Light.ColorMaterialEnabled && - exec->vtx.attrsz[BRW_ATTRIB_COLOR0]) { - _mesa_update_color_material(ctx, - ctx->Current.Attrib[BRW_ATTRIB_COLOR0]); - } - - ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; -} - - -static void brw_exec_copy_from_current( struct brw_exec_context *exec ) -{ - GLcontext *ctx = exec->ctx; - GLint i; - - /* Edgeflag requires additional treatment: - */ - exec->vtx.CurrentFloatEdgeFlag = - (GLfloat)ctx->Current.EdgeFlag; - - for (i = BRW_ATTRIB_POS+1 ; i < BRW_ATTRIB_MAX ; i++) - switch (exec->vtx.attrsz[i]) { - case 4: exec->vtx.attrptr[i][3] = exec->vtx.current[i][3]; - case 3: exec->vtx.attrptr[i][2] = exec->vtx.current[i][2]; - case 2: exec->vtx.attrptr[i][1] = exec->vtx.current[i][1]; - case 1: exec->vtx.attrptr[i][0] = exec->vtx.current[i][0]; - break; - } - - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; -} - - -/* Flush existing data, set new attrib size, replay copied vertices. - */ -static void brw_exec_wrap_upgrade_vertex( struct brw_exec_context *exec, - GLuint attr, - GLuint newsz ) -{ - GLcontext *ctx = exec->ctx; - GLint lastcount = exec->vtx.vert_count; - GLfloat *tmp; - GLuint oldsz; - GLuint i; - - /* Run pipeline on current vertices, copy wrapped vertices - * to exec->vtx.copied. - */ - brw_exec_wrap_buffers( exec ); - - - /* Do a COPY_TO_CURRENT to ensure back-copying works for the case - * when the attribute already exists in the vertex and is having - * its size increased. - */ - brw_exec_copy_to_current( exec ); - - - /* Heuristic: Attempt to isolate attributes received outside - * begin/end so that they don't bloat the vertices. - */ - if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END && - exec->vtx.attrsz[attr] == 0 && - lastcount > 8 && - exec->vtx.vertex_size) { - reset_attrfv( exec ); - } - - /* Fix up sizes: - */ - oldsz = exec->vtx.attrsz[attr]; - exec->vtx.attrsz[attr] = newsz; - - exec->vtx.vertex_size += newsz - oldsz; - exec->vtx.max_vert = BRW_VERT_BUFFER_SIZE / exec->vtx.vertex_size; - exec->vtx.vert_count = 0; - exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map; - - - /* Recalculate all the attrptr[] values - */ - for (i = 0, tmp = exec->vtx.vertex ; i < BRW_ATTRIB_MAX ; i++) { - if (exec->vtx.attrsz[i]) { - exec->vtx.attrptr[i] = tmp; - tmp += exec->vtx.attrsz[i]; - } - else - exec->vtx.attrptr[i] = NULL; /* will not be dereferenced */ - } - - /* Copy from current to repopulate the vertex with correct values. - */ - brw_exec_copy_from_current( exec ); - - /* Replay stored vertices to translate them - * to new format here. - * - * -- No need to replay - just copy piecewise - */ - if (exec->vtx.copied.nr) - { - GLfloat *data = exec->vtx.copied.buffer; - GLfloat *dest = exec->vtx.vbptr; - GLuint j; - - assert(exec->vtx.vbptr == (GLfloat *)exec->vtx.buffer_map); - - for (i = 0 ; i < exec->vtx.copied.nr ; i++) { - for (j = 0 ; j < BRW_ATTRIB_MAX ; j++) { - if (exec->vtx.attrsz[j]) { - if (j == attr) { - if (oldsz) { - COPY_CLEAN_4V( dest, oldsz, data ); - data += oldsz; - dest += newsz; - } else { - COPY_SZ_4V( dest, newsz, exec->vtx.current[j] ); - dest += newsz; - } - } - else { - GLuint sz = exec->vtx.attrsz[j]; - COPY_SZ_4V( dest, sz, data ); - dest += sz; - data += sz; - } - } - } - } - - exec->vtx.vbptr = dest; - exec->vtx.vert_count += exec->vtx.copied.nr; - exec->vtx.copied.nr = 0; - } -} - - -static void brw_exec_fixup_vertex( GLcontext *ctx, - GLuint attr, GLuint sz ) -{ - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - int i; - - if (sz > exec->vtx.attrsz[attr]) { - /* New size is larger. Need to flush existing vertices and get - * an enlarged vertex format. - */ - brw_exec_wrap_upgrade_vertex( exec, attr, sz ); - } - else if (sz < exec->vtx.active_sz[attr]) { - static const GLfloat id[4] = { 0, 0, 0, 1 }; - - /* New size is smaller - just need to fill in some - * zeros. Don't need to flush or wrap. - */ - for (i = sz ; i <= exec->vtx.attrsz[attr] ; i++) - exec->vtx.attrptr[attr][i-1] = id[i-1]; - } - - exec->vtx.active_sz[attr] = sz; - - /* Does setting NeedFlush belong here? Necessitates resetting - * vtxfmt on each flush (otherwise flags won't get reset - * afterwards). - */ - if (attr == 0) - exec->ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; - else - exec->ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; -} - - - - -/* - */ -#define ATTR( A, N, V0, V1, V2, V3 ) \ -do { \ - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; \ - \ - if (exec->vtx.active_sz[A] != N) \ - brw_exec_fixup_vertex(ctx, A, N); \ - \ - { \ - GLfloat *dest = exec->vtx.attrptr[A]; \ - if (N>0) dest[0] = V0; \ - if (N>1) dest[1] = V1; \ - if (N>2) dest[2] = V2; \ - if (N>3) dest[3] = V3; \ - } \ - \ - if ((A) == 0) { \ - GLuint i; \ - \ - for (i = 0; i < exec->vtx.vertex_size; i++) \ - exec->vtx.vbptr[i] = exec->vtx.vertex[i]; \ - \ - exec->vtx.vbptr += exec->vtx.vertex_size; \ - exec->ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; \ - \ - if (++exec->vtx.vert_count >= exec->vtx.max_vert) \ - brw_exec_vtx_wrap( exec ); \ - } \ -} while (0) - - -#define ERROR() _mesa_error( ctx, GL_INVALID_ENUM, __FUNCTION__ ) -#define TAG(x) brw_##x - -#include "brw_attrib_tmp.h" - - - - - -/* Eval - */ -static void GLAPIENTRY brw_exec_EvalCoord1f( GLfloat u ) -{ - GET_CURRENT_CONTEXT( ctx ); - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - - { - GLint i; - if (exec->eval.recalculate_maps) - brw_exec_eval_update( exec ); - - for (i = 0 ; i <= BRW_ATTRIB_INDEX ; i++) { - if (exec->eval.map1[i].map) - if (exec->vtx.active_sz[i] != exec->eval.map1[i].sz) - brw_exec_fixup_vertex( ctx, i, exec->eval.map1[i].sz ); - } - } - - - _mesa_memcpy( exec->vtx.copied.buffer, exec->vtx.vertex, - exec->vtx.vertex_size * sizeof(GLfloat)); - - brw_exec_do_EvalCoord1f( exec, u ); - - _mesa_memcpy( exec->vtx.vertex, exec->vtx.copied.buffer, - exec->vtx.vertex_size * sizeof(GLfloat)); -} - -static void GLAPIENTRY brw_exec_EvalCoord2f( GLfloat u, GLfloat v ) -{ - GET_CURRENT_CONTEXT( ctx ); - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - - { - GLint i; - if (exec->eval.recalculate_maps) - brw_exec_eval_update( exec ); - - for (i = 0 ; i <= BRW_ATTRIB_INDEX ; i++) { - if (exec->eval.map2[i].map) - if (exec->vtx.active_sz[i] != exec->eval.map2[i].sz) - brw_exec_fixup_vertex( ctx, i, exec->eval.map2[i].sz ); - } - - if (ctx->Eval.AutoNormal) - if (exec->vtx.active_sz[BRW_ATTRIB_NORMAL] != 3) - brw_exec_fixup_vertex( ctx, BRW_ATTRIB_NORMAL, 3 ); - } - - _mesa_memcpy( exec->vtx.copied.buffer, exec->vtx.vertex, - exec->vtx.vertex_size * sizeof(GLfloat)); - - brw_exec_do_EvalCoord2f( exec, u, v ); - - _mesa_memcpy( exec->vtx.vertex, exec->vtx.copied.buffer, - exec->vtx.vertex_size * sizeof(GLfloat)); -} - -static void GLAPIENTRY brw_exec_EvalCoord1fv( const GLfloat *u ) -{ - brw_exec_EvalCoord1f( u[0] ); -} - -static void GLAPIENTRY brw_exec_EvalCoord2fv( const GLfloat *u ) -{ - brw_exec_EvalCoord2f( u[0], u[1] ); -} - -static void GLAPIENTRY brw_exec_EvalPoint1( GLint i ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLfloat du = ((ctx->Eval.MapGrid1u2 - ctx->Eval.MapGrid1u1) / - (GLfloat) ctx->Eval.MapGrid1un); - GLfloat u = i * du + ctx->Eval.MapGrid1u1; - - brw_exec_EvalCoord1f( u ); -} - - -static void GLAPIENTRY brw_exec_EvalPoint2( GLint i, GLint j ) -{ - GET_CURRENT_CONTEXT( ctx ); - GLfloat du = ((ctx->Eval.MapGrid2u2 - ctx->Eval.MapGrid2u1) / - (GLfloat) ctx->Eval.MapGrid2un); - GLfloat dv = ((ctx->Eval.MapGrid2v2 - ctx->Eval.MapGrid2v1) / - (GLfloat) ctx->Eval.MapGrid2vn); - GLfloat u = i * du + ctx->Eval.MapGrid2u1; - GLfloat v = j * dv + ctx->Eval.MapGrid2v1; - - brw_exec_EvalCoord2f( u, v ); -} - - -/* Build a list of primitives on the fly. Keep - * ctx->Driver.CurrentExecPrimitive uptodate as well. - */ -static void GLAPIENTRY brw_exec_Begin( GLenum mode ) -{ - GET_CURRENT_CONTEXT( ctx ); - - if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) { - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - int i; - - if (ctx->NewState) { - _mesa_update_state( ctx ); - - if ((ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) || - (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glBegin (invalid vertex/fragment program)"); - return; - } - - CALL_Begin(ctx->Exec, (mode)); - return; - } - - /* Heuristic: attempt to isolate attributes occuring outside - * begin/end pairs. - */ - if (exec->vtx.vertex_size && !exec->vtx.attrsz[0]) - brw_exec_FlushVertices( ctx, ~0 ); - - i = exec->vtx.prim_count++; - exec->vtx.prim[i].mode = mode; - exec->vtx.prim[i].begin = 1; - exec->vtx.prim[i].end = 0; - exec->vtx.prim[i].indexed = 0; - exec->vtx.prim[i].weak = 0; - exec->vtx.prim[i].pad = 0; - exec->vtx.prim[i].start = exec->vtx.vert_count; - exec->vtx.prim[i].count = 0; - - ctx->Driver.CurrentExecPrimitive = mode; - } - else - _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" ); - -} - -static void GLAPIENTRY brw_exec_End( void ) -{ - GET_CURRENT_CONTEXT( ctx ); - - if (ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) { - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - int idx = exec->vtx.vert_count; - int i = exec->vtx.prim_count - 1; - - exec->vtx.prim[i].end = 1; - exec->vtx.prim[i].count = idx - exec->vtx.prim[i].start; - - ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1; - - if (exec->vtx.prim_count == BRW_MAX_PRIM) - brw_exec_vtx_flush( exec ); - } - else - _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" ); -} - - -static void brw_exec_vtxfmt_init( struct brw_exec_context *exec ) -{ - GLvertexformat *vfmt = &exec->vtxfmt; - - vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ - vfmt->Begin = brw_exec_Begin; - vfmt->CallList = _mesa_CallList; - vfmt->CallLists = _mesa_CallLists; - vfmt->End = brw_exec_End; - vfmt->EvalCoord1f = brw_exec_EvalCoord1f; - vfmt->EvalCoord1fv = brw_exec_EvalCoord1fv; - vfmt->EvalCoord2f = brw_exec_EvalCoord2f; - vfmt->EvalCoord2fv = brw_exec_EvalCoord2fv; - vfmt->EvalPoint1 = brw_exec_EvalPoint1; - vfmt->EvalPoint2 = brw_exec_EvalPoint2; - - vfmt->Rectf = _mesa_noop_Rectf; - vfmt->EvalMesh1 = _mesa_noop_EvalMesh1; - vfmt->EvalMesh2 = _mesa_noop_EvalMesh2; - - - /* from attrib_tmp.h: - */ - vfmt->Color3f = brw_Color3f; - vfmt->Color3fv = brw_Color3fv; - vfmt->Color4f = brw_Color4f; - vfmt->Color4fv = brw_Color4fv; - vfmt->FogCoordfEXT = brw_FogCoordfEXT; - vfmt->FogCoordfvEXT = brw_FogCoordfvEXT; - vfmt->MultiTexCoord1fARB = brw_MultiTexCoord1f; - vfmt->MultiTexCoord1fvARB = brw_MultiTexCoord1fv; - vfmt->MultiTexCoord2fARB = brw_MultiTexCoord2f; - vfmt->MultiTexCoord2fvARB = brw_MultiTexCoord2fv; - vfmt->MultiTexCoord3fARB = brw_MultiTexCoord3f; - vfmt->MultiTexCoord3fvARB = brw_MultiTexCoord3fv; - vfmt->MultiTexCoord4fARB = brw_MultiTexCoord4f; - vfmt->MultiTexCoord4fvARB = brw_MultiTexCoord4fv; - vfmt->Normal3f = brw_Normal3f; - vfmt->Normal3fv = brw_Normal3fv; - vfmt->SecondaryColor3fEXT = brw_SecondaryColor3fEXT; - vfmt->SecondaryColor3fvEXT = brw_SecondaryColor3fvEXT; - vfmt->TexCoord1f = brw_TexCoord1f; - vfmt->TexCoord1fv = brw_TexCoord1fv; - vfmt->TexCoord2f = brw_TexCoord2f; - vfmt->TexCoord2fv = brw_TexCoord2fv; - vfmt->TexCoord3f = brw_TexCoord3f; - vfmt->TexCoord3fv = brw_TexCoord3fv; - vfmt->TexCoord4f = brw_TexCoord4f; - vfmt->TexCoord4fv = brw_TexCoord4fv; - vfmt->Vertex2f = brw_Vertex2f; - vfmt->Vertex2fv = brw_Vertex2fv; - vfmt->Vertex3f = brw_Vertex3f; - vfmt->Vertex3fv = brw_Vertex3fv; - vfmt->Vertex4f = brw_Vertex4f; - vfmt->Vertex4fv = brw_Vertex4fv; - - vfmt->VertexAttrib1fARB = brw_VertexAttrib1fARB; - vfmt->VertexAttrib1fvARB = brw_VertexAttrib1fvARB; - vfmt->VertexAttrib2fARB = brw_VertexAttrib2fARB; - vfmt->VertexAttrib2fvARB = brw_VertexAttrib2fvARB; - vfmt->VertexAttrib3fARB = brw_VertexAttrib3fARB; - vfmt->VertexAttrib3fvARB = brw_VertexAttrib3fvARB; - vfmt->VertexAttrib4fARB = brw_VertexAttrib4fARB; - vfmt->VertexAttrib4fvARB = brw_VertexAttrib4fvARB; - - vfmt->VertexAttrib1fNV = brw_VertexAttrib1fNV; - vfmt->VertexAttrib1fvNV = brw_VertexAttrib1fvNV; - vfmt->VertexAttrib2fNV = brw_VertexAttrib2fNV; - vfmt->VertexAttrib2fvNV = brw_VertexAttrib2fvNV; - vfmt->VertexAttrib3fNV = brw_VertexAttrib3fNV; - vfmt->VertexAttrib3fvNV = brw_VertexAttrib3fvNV; - vfmt->VertexAttrib4fNV = brw_VertexAttrib4fNV; - vfmt->VertexAttrib4fvNV = brw_VertexAttrib4fvNV; - - vfmt->Materialfv = brw_Materialfv; - - vfmt->EdgeFlag = brw_EdgeFlag; - vfmt->Indexf = brw_Indexf; - vfmt->Indexfv = brw_Indexfv; - -} - - -static void brw_exec_current_init( struct brw_exec_context *exec ) -{ - GLcontext *ctx = exec->ctx; - GLint i; - - /* setup the pointers for the typical 16 vertex attributes */ - for (i = 0; i < BRW_ATTRIB_FIRST_MATERIAL; i++) - exec->vtx.current[i] = ctx->Current.Attrib[i]; - - /* setup pointers for the 12 material attributes */ - for (i = 0; i < MAT_ATTRIB_MAX; i++) - exec->vtx.current[BRW_ATTRIB_FIRST_MATERIAL + i] = - ctx->Light.Material.Attrib[i]; - - exec->vtx.current[BRW_ATTRIB_INDEX] = &ctx->Current.Index; - exec->vtx.current[BRW_ATTRIB_EDGEFLAG] = &exec->vtx.CurrentFloatEdgeFlag; -} - -void brw_exec_vtx_init( struct brw_exec_context *exec ) -{ - GLcontext *ctx = exec->ctx; - GLuint i; - - /* Allocate a buffer object. Will just reuse this object - * continuously. - */ - exec->vtx.bufferobj = ctx->Array.NullBufferObj; - exec->vtx.buffer_map = ALIGN_MALLOC(BRW_VERT_BUFFER_SIZE * sizeof(GLfloat), 64); - - brw_exec_current_init( exec ); - brw_exec_vtxfmt_init( exec ); - - /* Hook our functions into the dispatch table. - */ - _mesa_install_exec_vtxfmt( exec->ctx, &exec->vtxfmt ); - - for (i = 0 ; i < BRW_ATTRIB_MAX ; i++) { - exec->vtx.attrsz[i] = 0; - exec->vtx.active_sz[i] = 0; - exec->vtx.inputs[i] = &exec->vtx.arrays[i]; - } - - exec->vtx.vertex_size = 0; -} - - -void brw_exec_vtx_destroy( struct brw_exec_context *exec ) -{ - if (exec->vtx.buffer_map) { - ALIGN_FREE(exec->vtx.buffer_map); - exec->vtx.buffer_map = NULL; - } -} - - -void brw_exec_FlushVertices( GLcontext *ctx, GLuint flags ) -{ - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - - if (exec->ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) - return; - - if (exec->vtx.vert_count) { - brw_exec_vtx_flush( exec ); - } - - if (exec->vtx.vertex_size) { - brw_exec_copy_to_current( exec ); - reset_attrfv( exec ); - } - - exec->ctx->Driver.NeedFlush = 0; -} - - -static void reset_attrfv( struct brw_exec_context *exec ) -{ - GLuint i; - - for (i = 0 ; i < BRW_ATTRIB_MAX ; i++) { - exec->vtx.attrsz[i] = 0; - exec->vtx.active_sz[i] = 0; - } - - exec->vtx.vertex_size = 0; -} - diff --git a/src/mesa/drivers/dri/i965/brw_exec_array.c b/src/mesa/drivers/dri/i965/brw_exec_array.c deleted file mode 100644 index ca19a19837..0000000000 --- a/src/mesa/drivers/dri/i965/brw_exec_array.c +++ /dev/null @@ -1,283 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * 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 TUNGSTEN 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 "glheader.h" -#include "context.h" -#include "state.h" -#include "api_validate.h" -#include "api_noop.h" -#include "dispatch.h" - -#include "brw_attrib.h" -#include "brw_draw.h" -#include "brw_exec.h" -#include "brw_fallback.h" - -static GLuint get_max_index( GLuint count, GLuint type, - const GLvoid *indices ) -{ - GLint i; - - /* Compute max element. This is only needed for upload of non-VBO, - * non-constant data elements. - * - * XXX: Postpone this calculation until it is known that it is - * needed. Otherwise could scan this pointlessly in the all-vbo - * case. - */ - switch(type) { - case GL_UNSIGNED_INT: { - const GLuint *ui_indices = (const GLuint *)indices; - GLuint max_ui = 0; - for (i = 0; i < count; i++) - if (ui_indices[i] > max_ui) - max_ui = ui_indices[i]; - return max_ui; - } - case GL_UNSIGNED_SHORT: { - const GLushort *us_indices = (const GLushort *)indices; - GLuint max_us = 0; - for (i = 0; i < count; i++) - if (us_indices[i] > max_us) - max_us = us_indices[i]; - return max_us; - } - case GL_UNSIGNED_BYTE: { - const GLubyte *ub_indices = (const GLubyte *)indices; - GLuint max_ub = 0; - for (i = 0; i < count; i++) - if (ub_indices[i] > max_ub) - max_ub = ub_indices[i]; - return max_ub; - } - default: - return 0; - } -} - - - - -/*********************************************************************** - * API functions. - */ - -static void GLAPIENTRY -brw_exec_DrawArrays(GLenum mode, GLint start, GLsizei count) -{ - GET_CURRENT_CONTEXT(ctx); - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - struct brw_draw_prim prim[1]; - GLboolean ok; - - if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) - return; - - FLUSH_CURRENT( ctx, 0 ); - - if (ctx->NewState) - _mesa_update_state( ctx ); - - prim[0].begin = 1; - prim[0].end = 1; - prim[0].weak = 0; - prim[0].pad = 0; - - if (exec->array.inputs[0]->BufferObj->Name) { - /* Use vertex attribute as a hint to tell us if we expect all - * arrays to be in VBO's and if so, don't worry about avoiding - * the upload of elements < start. - */ - prim[0].mode = mode; - prim[0].start = start; - prim[0].count = count; - prim[0].indexed = 0; - - ok = brw_draw_prims( ctx, exec->array.inputs, prim, 1, NULL, 0, start + count, 0 ); - } - else { - /* If not using VBO's, we don't want to upload any more elements - * than necessary from the arrays as they will not be valid next - * time the application tries to draw with them. - */ - prim[0].mode = mode; - prim[0].start = 0; - prim[0].count = count; - prim[0].indexed = 0; - - ok = brw_draw_prims( ctx, exec->array.inputs, prim, 1, NULL, start, start + count, 0 ); - } - - if (!ok) { - brw_fallback(ctx); - CALL_DrawArrays(ctx->Exec, ( mode, start, count )); - brw_unfallback(ctx); - } -} - - - -static void GLAPIENTRY -brw_exec_DrawRangeElements(GLenum mode, - GLuint start, GLuint end, - GLsizei count, GLenum type, const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - struct brw_exec_context *exec = IMM_CONTEXT(ctx)->exec; - struct brw_draw_index_buffer ib; - struct brw_draw_prim prim[1]; - - if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count, type, indices )) - return; - - FLUSH_CURRENT( ctx, 0 ); - - if (ctx->NewState) - _mesa_update_state( ctx ); - - ib.count = count; - ib.type = type; - ib.obj = ctx->Array.ElementArrayBufferObj; - ib.ptr = indices; - - if (ctx->Array.ElementArrayBufferObj->Name) { - /* Use the fact that indices are in a VBO as a hint that the - * program has put all the arrays in VBO's and we don't have to - * worry about performance implications of start > 0. - * - * XXX: consider passing start as min_index to draw_prims instead. - */ - ib.rebase = 0; - } - else { - ib.rebase = start; - } - - prim[0].begin = 1; - prim[0].end = 1; - prim[0].weak = 0; - prim[0].pad = 0; - prim[0].mode = mode; - prim[0].start = 0; - prim[0].count = count; - prim[0].indexed = 1; - - if (!brw_draw_prims( ctx, exec->array.inputs, prim, 1, &ib, ib.rebase, end+1, 0 )) { - brw_fallback(ctx); - CALL_DrawRangeElements(ctx->Exec, (mode, start, end, count, type, indices)); - brw_unfallback(ctx); - } -} - - -static void GLAPIENTRY -brw_exec_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - GLuint max_index; - - if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) - return; - - if (ctx->Array.ElementArrayBufferObj->Name) { - const GLvoid *map = ctx->Driver.MapBuffer(ctx, - GL_ELEMENT_ARRAY_BUFFER_ARB, - GL_DYNAMIC_READ_ARB, - ctx->Array.ElementArrayBufferObj); - - max_index = get_max_index(count, type, ADD_POINTERS(map, indices)); - - ctx->Driver.UnmapBuffer(ctx, - GL_ELEMENT_ARRAY_BUFFER_ARB, - ctx->Array.ElementArrayBufferObj); - } - else { - max_index = get_max_index(count, type, indices); - } - - brw_exec_DrawRangeElements(mode, 0, max_index, count, type, indices); -} - - -/*********************************************************************** - * Initialization - */ - - -static void init_arrays( GLcontext *ctx, - const struct gl_client_array *arrays[] ) -{ - struct gl_array_object *obj = ctx->Array.ArrayObj; - GLuint i; - - memset(arrays, 0, sizeof(*arrays) * BRW_ATTRIB_MAX); - - arrays[BRW_ATTRIB_POS] = &obj->Vertex; - arrays[BRW_ATTRIB_NORMAL] = &obj->Normal; - arrays[BRW_ATTRIB_COLOR0] = &obj->Color; - arrays[BRW_ATTRIB_COLOR1] = &obj->SecondaryColor; - arrays[BRW_ATTRIB_FOG] = &obj->FogCoord; - - for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) - arrays[BRW_ATTRIB_TEX0 + i] = &obj->TexCoord[i]; - - arrays[BRW_ATTRIB_INDEX] = &obj->Index; - arrays[BRW_ATTRIB_EDGEFLAG] = &obj->EdgeFlag; - - for (i = BRW_ATTRIB_GENERIC0; i <= BRW_ATTRIB_GENERIC15; i++) - arrays[i] = &obj->VertexAttrib[i - BRW_ATTRIB_GENERIC0]; -} - - - - -void brw_exec_array_init( struct brw_exec_context *exec ) -{ - GLcontext *ctx = exec->ctx; - - init_arrays(ctx, exec->array.inputs); - -#if 1 - exec->vtxfmt.DrawArrays = brw_exec_DrawArrays; - exec->vtxfmt.DrawElements = brw_exec_DrawElements; - exec->vtxfmt.DrawRangeElements = brw_exec_DrawRangeElements; -#else - exec->vtxfmt.DrawArrays = _mesa_noop_DrawArrays; - exec->vtxfmt.DrawElements = _mesa_noop_DrawElements; - exec->vtxfmt.DrawRangeElements = _mesa_noop_DrawRangeElements; -#endif - - exec->array.index_obj = ctx->Driver.NewBufferObject(ctx, 1, GL_ARRAY_BUFFER_ARB); -} - - -void brw_exec_array_destroy( struct brw_exec_context *exec ) -{ - GLcontext *ctx = exec->ctx; - - ctx->Driver.DeleteBuffer(ctx, exec->array.index_obj); -} diff --git a/src/mesa/drivers/dri/i965/brw_exec_draw.c b/src/mesa/drivers/dri/i965/brw_exec_draw.c deleted file mode 100644 index 62bda9845b..0000000000 --- a/src/mesa/drivers/dri/i965/brw_exec_draw.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 5.1 - * - * Copyright (C) 1999-2003 Brian Paul 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, 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 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 - * BRIAN PAUL 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 - */ - -#include "glheader.h" -#include "context.h" -#include "enums.h" -#include "state.h" -#include "macros.h" - -#include "brw_exec.h" -#include "brw_draw.h" -#include "brw_fallback.h" - - -static void brw_exec_debug_verts( struct brw_exec_context *exec ) -{ - GLuint count = exec->vtx.vert_count; - GLuint i; - - _mesa_printf("%s: %u vertices %d primitives, %d vertsize\n", - __FUNCTION__, - count, - exec->vtx.prim_count, - exec->vtx.vertex_size); - - for (i = 0 ; i < exec->vtx.prim_count ; i++) { - struct brw_draw_prim *prim = &exec->vtx.prim[i]; - _mesa_printf(" prim %d: %s%s %d..%d %s %s\n", - i, - _mesa_lookup_enum_by_nr(prim->mode), - prim->weak ? " (weak)" : "", - prim->start, - prim->start + prim->count, - prim->begin ? "BEGIN" : "(wrap)", - prim->end ? "END" : "(wrap)"); - } -} - - -/* - * NOTE: Need to have calculated primitives by this point -- do it on the fly. - * NOTE: Old 'parity' issue is gone. - */ -static GLuint brw_copy_vertices( struct brw_exec_context *exec ) -{ - GLuint nr = exec->vtx.prim[exec->vtx.prim_count-1].count; - GLuint ovf, i; - GLuint sz = exec->vtx.vertex_size; - GLfloat *dst = exec->vtx.copied.buffer; - GLfloat *src = ((GLfloat *)exec->vtx.buffer_map + - exec->vtx.prim[exec->vtx.prim_count-1].start * - exec->vtx.vertex_size); - - - switch( exec->ctx->Driver.CurrentExecPrimitive ) - { - case GL_POINTS: - return 0; - case GL_LINES: - ovf = nr&1; - for (i = 0 ; i < ovf ; i++) - _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) ); - return i; - case GL_TRIANGLES: - ovf = nr%3; - for (i = 0 ; i < ovf ; i++) - _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) ); - return i; - case GL_QUADS: - ovf = nr&3; - for (i = 0 ; i < ovf ; i++) - _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) ); - return i; - case GL_LINE_STRIP: - if (nr == 0) - return 0; - else { - _mesa_memcpy( dst, src+(nr-1)*sz, sz * sizeof(GLfloat) ); - return 1; - } - case GL_LINE_LOOP: - case GL_TRIANGLE_FAN: - case GL_POLYGON: - if (nr == 0) - return 0; - else if (nr == 1) { - _mesa_memcpy( dst, src+0, sz * sizeof(GLfloat) ); - return 1; - } else { - _mesa_memcpy( dst, src+0, sz * sizeof(GLfloat) ); - _mesa_memcpy( dst+sz, src+(nr-1)*sz, sz * sizeof(GLfloat) ); - return 2; - } - case GL_TRIANGLE_STRIP: - case GL_QUAD_STRIP: - switch (nr) { - case 0: ovf = 0; break; - case 1: ovf = 1; break; - default: ovf = 2 + (nr&1); break; - } - for (i = 0 ; i < ovf ; i++) - _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat) ); - return i; - case GL_POLYGON+1: - return 0; - default: - assert(0); - return 0; - } -} - - -/* TODO: populate these as the vertex is defined: - */ -static void brw_exec_bind_arrays( struct brw_exec_context *exec ) -{ - struct gl_client_array *arrays = exec->vtx.arrays; - GLuint count = exec->vtx.vert_count; - GLubyte *data = exec->vtx.buffer_map; - GLuint attr; - - memset(arrays, 0, BRW_ATTRIB_MAX * sizeof(arrays[0])); - - /* Make all active attributes (including edgeflag) available as - * arrays of floats. - */ - for (attr = 0; attr < BRW_ATTRIB_MAX ; attr++) { - if (exec->vtx.attrsz[attr]) { - arrays[attr].Ptr = (void *)data; - arrays[attr].Size = exec->vtx.attrsz[attr]; - arrays[attr].StrideB = exec->vtx.vertex_size * sizeof(GLfloat); - arrays[attr].Stride = exec->vtx.vertex_size * sizeof(GLfloat); - arrays[attr].Type = GL_FLOAT; - arrays[attr].Enabled = 1; - arrays[attr].BufferObj = exec->vtx.bufferobj; /* NullBufferObj */ - arrays[attr]._MaxElement = count; /* ??? */ - - data += exec->vtx.attrsz[attr] * sizeof(GLfloat); - } - } -} - - -static -void brw_exec_loopback_vertex_list( GLcontext *ctx, - struct brw_exec_context *exec ) -{ - const GLfloat *buffer = (const GLfloat *)exec->vtx.buffer_map; - - brw_fallback(ctx); - - brw_loopback_vertex_list( ctx, - buffer, - exec->vtx.attrsz, - exec->vtx.prim, - exec->vtx.prim_count, - 0, /* XXX - copied.nr */ - exec->vtx.vertex_size); - - - brw_unfallback(ctx); -} - - -/** - * Execute the buffer and save copied verts. - */ -void brw_exec_vtx_flush( struct brw_exec_context *exec ) -{ - if (0) - brw_exec_debug_verts( exec ); - - - if (exec->vtx.prim_count && - exec->vtx.vert_count) { - - exec->vtx.copied.nr = brw_copy_vertices( exec ); - - if (exec->vtx.copied.nr != exec->vtx.vert_count) { - GLcontext *ctx = exec->ctx; - - brw_exec_bind_arrays( exec ); - - - if (!brw_draw_prims( ctx, - exec->vtx.inputs, - exec->vtx.prim, - exec->vtx.prim_count, - NULL, - 0, - exec->vtx.vert_count, - 0 )) { - /* Fallback path: - */ - brw_exec_loopback_vertex_list(ctx, exec); - } - } - } - - exec->vtx.prim_count = 0; - exec->vtx.vert_count = 0; - exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map; -} diff --git a/src/mesa/drivers/dri/i965/brw_exec_eval.c b/src/mesa/drivers/dri/i965/brw_exec_eval.c deleted file mode 100644 index 9dbeb1b58e..0000000000 --- a/src/mesa/drivers/dri/i965/brw_exec_eval.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.1 - * - * Copyright (C) 1999-2004 Brian Paul 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, 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 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 - * BRIAN PAUL 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 - */ - -#include "glheader.h" -#include "api_eval.h" -#include "context.h" -#include "macros.h" -#include "math/m_eval.h" -#include "brw_exec.h" -#include "dispatch.h" - - -static void clear_active_eval1( struct brw_exec_context *exec, GLuint attr ) -{ - exec->eval.map1[attr].map = NULL; -} - -static void clear_active_eval2( struct brw_exec_context *exec, GLuint attr ) -{ - exec->eval.map2[attr].map = NULL; -} - -static void set_active_eval1( struct brw_exec_context *exec, GLuint attr, GLuint dim, - struct gl_1d_map *map ) -{ - if (!exec->eval.map1[attr].map) { - exec->eval.map1[attr].map = map; - exec->eval.map1[attr].sz = dim; - } -} - -static void set_active_eval2( struct brw_exec_context *exec, GLuint attr, GLuint dim, - struct gl_2d_map *map ) -{ - if (!exec->eval.map2[attr].map) { - exec->eval.map2[attr].map = map; - exec->eval.map2[attr].sz = dim; - } -} - -void brw_exec_eval_update( struct brw_exec_context *exec ) -{ - GLcontext *ctx = exec->ctx; - GLuint attr; - - /* Vertex program maps have priority over conventional attribs */ - - for (attr = 0; attr < BRW_ATTRIB_FIRST_MATERIAL; attr++) { - clear_active_eval1( exec, attr ); - clear_active_eval2( exec, attr ); - } - - /* _NEW_PROGRAM */ - if (ctx->VertexProgram._Enabled) { - for (attr = 0; attr < BRW_ATTRIB_FIRST_MATERIAL; attr++) { - /* _NEW_EVAL */ - if (ctx->Eval.Map1Attrib[attr]) - set_active_eval1( exec, attr, 4, &ctx->EvalMap.Map1Attrib[attr] ); - - if (ctx->Eval.Map2Attrib[attr]) - set_active_eval2( exec, attr, 4, &ctx->EvalMap.Map2Attrib[attr] ); - } - } - - if (ctx->Eval.Map1Color4) - set_active_eval1( exec, BRW_ATTRIB_COLOR0, 4, &ctx->EvalMap.Map1Color4 ); - - if (ctx->Eval.Map2Color4) - set_active_eval2( exec, BRW_ATTRIB_COLOR0, 4, &ctx->EvalMap.Map2Color4 ); - - if (ctx->Eval.Map1TextureCoord4) - set_active_eval1( exec, BRW_ATTRIB_TEX0, 4, &ctx->EvalMap.Map1Texture4 ); - else if (ctx->Eval.Map1TextureCoord3) - set_active_eval1( exec, BRW_ATTRIB_TEX0, 3, &ctx->EvalMap.Map1Texture3 ); - else if (ctx->Eval.Map1TextureCoord2) - set_active_eval1( exec, BRW_ATTRIB_TEX0, 2, &ctx->EvalMap.Map1Texture2 ); - else if (ctx->Eval.Map1TextureCoord1) - set_active_eval1( exec, BRW_ATTRIB_TEX0, 1, &ctx->EvalMap.Map1Texture1 ); - - if (ctx->Eval.Map2TextureCoord4) - set_active_eval2( exec, BRW_ATTRIB_TEX0, 4, &ctx->EvalMap.Map2Texture4 ); - else if (ctx->Eval.Map2TextureCoord3) - set_active_eval2( exec, BRW_ATTRIB_TEX0, 3, &ctx->EvalMap.Map2Texture3 ); - else if (ctx->Eval.Map2TextureCoord2) - set_active_eval2( exec, BRW_ATTRIB_TEX0, 2, &ctx->EvalMap.Map2Texture2 ); - else if (ctx->Eval.Map2TextureCoord1) - set_active_eval2( exec, BRW_ATTRIB_TEX0, 1, &ctx->EvalMap.Map2Texture1 ); - - if (ctx->Eval.Map1Normal) - set_active_eval1( exec, BRW_ATTRIB_NORMAL, 3, &ctx->EvalMap.Map1Normal ); - - if (ctx->Eval.Map2Normal) - set_active_eval2( exec, BRW_ATTRIB_NORMAL, 3, &ctx->EvalMap.Map2Normal ); - - if (ctx->Eval.Map1Vertex4) - set_active_eval1( exec, BRW_ATTRIB_POS, 4, &ctx->EvalMap.Map1Vertex4 ); - else if (ctx->Eval.Map1Vertex3) - set_active_eval1( exec, BRW_ATTRIB_POS, 3, &ctx->EvalMap.Map1Vertex3 ); - - if (ctx->Eval.Map2Vertex4) - set_active_eval2( exec, BRW_ATTRIB_POS, 4, &ctx->EvalMap.Map2Vertex4 ); - else if (ctx->Eval.Map2Vertex3) - set_active_eval2( exec, BRW_ATTRIB_POS, 3, &ctx->EvalMap.Map2Vertex3 ); - - exec->eval.recalculate_maps = 0; -} - - - -void brw_exec_do_EvalCoord1f(struct brw_exec_context *exec, GLfloat u) -{ - GLuint attr; - - for (attr = 1; attr <= BRW_ATTRIB_INDEX; attr++) { - struct gl_1d_map *map = exec->eval.map1[attr].map; - if (map) { - GLfloat uu = (u - map->u1) * map->du; - GLfloat data[4]; - - ASSIGN_4V(data, 0, 0, 0, 1); - - _math_horner_bezier_curve(map->Points, data, uu, - exec->eval.map1[attr].sz, - map->Order); - - COPY_SZ_4V( exec->vtx.attrptr[attr], - exec->vtx.attrsz[attr], - data ); - } - } - - /** Vertex -- EvalCoord1f is a noop if this map not enabled: - **/ - if (exec->eval.map1[0].map) { - struct gl_1d_map *map = exec->eval.map1[0].map; - GLfloat uu = (u - map->u1) * map->du; - GLfloat vertex[4]; - - ASSIGN_4V(vertex, 0, 0, 0, 1); - - _math_horner_bezier_curve(map->Points, vertex, uu, - exec->eval.map1[0].sz, - map->Order); - - if (exec->eval.map1[0].sz == 4) - CALL_Vertex4fv(GET_DISPATCH(), ( vertex )); - else - CALL_Vertex3fv(GET_DISPATCH(), ( vertex )); - } -} - - - -void brw_exec_do_EvalCoord2f( struct brw_exec_context *exec, - GLfloat u, GLfloat v ) -{ - GLuint attr; - - for (attr = 1; attr <= BRW_ATTRIB_INDEX; attr++) { - struct gl_2d_map *map = exec->eval.map2[attr].map; - if (map) { - GLfloat uu = (u - map->u1) * map->du; - GLfloat vv = (v - map->v1) * map->dv; - GLfloat data[4]; - - ASSIGN_4V(data, 0, 0, 0, 1); - - _math_horner_bezier_surf(map->Points, - data, - uu, vv, - exec->eval.map2[attr].sz, - map->Uorder, map->Vorder); - - COPY_SZ_4V( exec->vtx.attrptr[attr], - exec->vtx.attrsz[attr], - data ); - } - } - - /** Vertex -- EvalCoord2f is a noop if this map not enabled: - **/ - if (exec->eval.map2[0].map) { - struct gl_2d_map *map = exec->eval.map2[0].map; - GLfloat uu = (u - map->u1) * map->du; - GLfloat vv = (v - map->v1) * map->dv; - GLfloat vertex[4]; - - ASSIGN_4V(vertex, 0, 0, 0, 1); - - if (exec->ctx->Eval.AutoNormal) { - GLfloat normal[4]; - GLfloat du[4], dv[4]; - - _math_de_casteljau_surf(map->Points, vertex, du, dv, uu, vv, - exec->eval.map2[0].sz, - map->Uorder, map->Vorder); - - if (exec->eval.map2[0].sz == 4) { - du[0] = du[0]*vertex[3] - du[3]*vertex[0]; - du[1] = du[1]*vertex[3] - du[3]*vertex[1]; - du[2] = du[2]*vertex[3] - du[3]*vertex[2]; - - dv[0] = dv[0]*vertex[3] - dv[3]*vertex[0]; - dv[1] = dv[1]*vertex[3] - dv[3]*vertex[1]; - dv[2] = dv[2]*vertex[3] - dv[3]*vertex[2]; - } - - - CROSS3(normal, du, dv); - NORMALIZE_3FV(normal); - normal[3] = 1.0; - - COPY_SZ_4V( exec->vtx.attrptr[BRW_ATTRIB_NORMAL], - exec->vtx.attrsz[BRW_ATTRIB_NORMAL], - normal ); - - } - else { - _math_horner_bezier_surf(map->Points, vertex, uu, vv, - exec->eval.map2[0].sz, - map->Uorder, map->Vorder); - } - - if (exec->vtx.attrsz[0] == 4) - CALL_Vertex4fv(GET_DISPATCH(), ( vertex )); - else - CALL_Vertex3fv(GET_DISPATCH(), ( vertex )); - } -} - - diff --git a/src/mesa/drivers/dri/i965/brw_fallback.c b/src/mesa/drivers/dri/i965/brw_fallback.c index 4d84ba8813..aab30b6863 100644 --- a/src/mesa/drivers/dri/i965/brw_fallback.c +++ b/src/mesa/drivers/dri/i965/brw_fallback.c @@ -198,7 +198,7 @@ struct loopback_attr { */ static void loopback_prim( GLcontext *ctx, const GLfloat *buffer, - const struct brw_draw_prim *prim, + const struct vbo_prim *prim, GLuint wrap_count, GLuint vertex_size, const struct loopback_attr *la, GLuint nr ) @@ -252,7 +252,7 @@ static void loopback_prim( GLcontext *ctx, * primitives. */ static void loopback_weak_prim( GLcontext *ctx, - const struct brw_draw_prim *prim ) + const struct vbo_prim *prim ) { /* Use the prim_weak flag to ensure that if this primitive * wraps, we don't mistake future vertex_lists for part of the @@ -271,7 +271,7 @@ static void loopback_weak_prim( GLcontext *ctx, void brw_loopback_vertex_list( GLcontext *ctx, const GLfloat *buffer, const GLubyte *attrsz, - const struct brw_draw_prim *prim, + const struct vbo_prim *prim, GLuint prim_count, GLuint wrap_count, GLuint vertex_size) diff --git a/src/mesa/drivers/dri/i965/brw_fallback.h b/src/mesa/drivers/dri/i965/brw_fallback.h index 81a2d344b8..684a46cd17 100644 --- a/src/mesa/drivers/dri/i965/brw_fallback.h +++ b/src/mesa/drivers/dri/i965/brw_fallback.h @@ -31,7 +31,7 @@ #include "mtypes.h" /* for GLcontext... */ struct brw_context; -struct brw_draw_prim; +struct vbo_prim; void brw_fallback( GLcontext *ctx ); void brw_unfallback( GLcontext *ctx ); @@ -39,7 +39,7 @@ void brw_unfallback( GLcontext *ctx ); void brw_loopback_vertex_list( GLcontext *ctx, const GLfloat *buffer, const GLubyte *attrsz, - const struct brw_draw_prim *prim, + const struct vbo_prim *prim, GLuint prim_count, GLuint wrap_count, GLuint vertex_size); diff --git a/src/mesa/drivers/dri/i965/brw_metaops.c b/src/mesa/drivers/dri/i965/brw_metaops.c index 18ca7b1341..d8b6069cfc 100644 --- a/src/mesa/drivers/dri/i965/brw_metaops.c +++ b/src/mesa/drivers/dri/i965/brw_metaops.c @@ -303,7 +303,7 @@ static void meta_draw_quad(struct intel_context *intel, struct gl_client_array pos_array; struct gl_client_array color_array; struct gl_client_array *attribs[BRW_ATTRIB_MAX]; - struct brw_draw_prim prim[1]; + struct vbo_prim prim[1]; GLfloat pos[4][3]; GLubyte color[4]; @@ -395,8 +395,7 @@ static void meta_draw_quad(struct intel_context *intel, prim, 1, NULL, 0, - 4, - BRW_DRAW_LOCKED )) + 4 )) { /* This should not be possible: */ diff --git a/src/mesa/drivers/dri/i965/brw_save.c b/src/mesa/drivers/dri/i965/brw_save.c deleted file mode 100644 index 1af7791c4d..0000000000 --- a/src/mesa/drivers/dri/i965/brw_save.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.3 - * - * Copyright (C) 1999-2005 Brian Paul 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, 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 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 - * BRIAN PAUL 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 - */ - - -#include "mtypes.h" -#include "api_arrayelt.h" -#include "dlist.h" -#include "vtxfmt.h" -#include "imports.h" - -#include "brw_save.h" - - - -void brw_save_init( GLcontext *ctx ) -{ - struct brw_save_context *save = CALLOC_STRUCT(brw_save_context); - - if (ctx->swtnl_im == NULL) { - ctx->swtnl_im = CALLOC_STRUCT(brw_exec_save); - } - - save->ctx = ctx; - IMM_CONTEXT(ctx)->save = save; - - /* Initialize the arrayelt helper - */ - if (!ctx->aelt_context && - !_ae_create_context( ctx )) - return; - - brw_save_api_init( save ); - brw_save_wakeup(ctx); - - ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN; -} - - -void brw_save_destroy( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - if (save) { - FREE(save); - IMM_CONTEXT(ctx)->save = NULL; - } - - if (ctx->aelt_context) { - _ae_destroy_context( ctx ); - ctx->aelt_context = NULL; - } - - if (IMM_CONTEXT(ctx)->exec == NULL && - IMM_CONTEXT(ctx)->save == NULL) { - FREE(IMM_CONTEXT(ctx)); - ctx->swtnl_im = NULL; - } -} - - -void brw_save_invalidate_state( GLcontext *ctx, GLuint new_state ) -{ - _ae_invalidate_state(ctx, new_state); -} - - -/* Note that this can occur during the playback of a display list: - */ -void brw_save_fallback( GLcontext *ctx, GLboolean fallback ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - - if (fallback) - save->replay_flags |= BRW_SAVE_FALLBACK; - else - save->replay_flags &= ~BRW_SAVE_FALLBACK; -} - - -/* I don't see any reason to swap this code out on fallbacks. It - * wouldn't really mean anything to do so anyway as the old lists are - * still around from pre-fallback. Instead, the above code ensures - * that vertices are routed back through immediate mode dispatch on - * fallback. - * - * The below can be moved into init or removed: - */ -void brw_save_wakeup( GLcontext *ctx ) -{ - ctx->Driver.NewList = brw_save_NewList; - ctx->Driver.EndList = brw_save_EndList; - ctx->Driver.SaveFlushVertices = brw_save_SaveFlushVertices; - ctx->Driver.BeginCallList = brw_save_BeginCallList; - ctx->Driver.EndCallList = brw_save_EndCallList; - ctx->Driver.NotifySaveBegin = brw_save_NotifyBegin; - - /* Assume we haven't been getting state updates either: - */ - brw_save_invalidate_state( ctx, ~0 ); -} - - - diff --git a/src/mesa/drivers/dri/i965/brw_save.h b/src/mesa/drivers/dri/i965/brw_save.h deleted file mode 100644 index 41cabe6508..0000000000 --- a/src/mesa/drivers/dri/i965/brw_save.h +++ /dev/null @@ -1,171 +0,0 @@ -/************************************************************************** - -Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. - -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 -TUNGSTEN GRAPHICS AND/OR THEIR 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 - * - */ - -#ifndef BRW_SAVE_H -#define BRW_SAVE_H - -#include "mtypes.h" -#include "brw_attrib.h" -#include "brw_draw.h" - - -struct brw_save_copied_vtx { - GLfloat buffer[BRW_ATTRIB_MAX * 4 * BRW_MAX_COPIED_VERTS]; - GLuint nr; -}; - - -/* For display lists, this structure holds a run of vertices of the - * same format, and a strictly well-formed set of begin/end pairs, - * starting on the first vertex and ending at the last. Vertex - * copying on buffer breaks is precomputed according to these - * primitives, though there are situations where the copying will need - * correction at execute-time, perhaps by replaying the list as - * immediate mode commands. - * - * On executing this list, the 'current' values may be updated with - * the values of the final vertex, and often no fixup of the start of - * the vertex list is required. - * - * Eval and other commands that don't fit into these vertex lists are - * compiled using the fallback opcode mechanism provided by dlist.c. - */ -struct brw_save_vertex_list { - GLubyte attrsz[BRW_ATTRIB_MAX]; - GLuint vertex_size; - - GLuint buffer_offset; - GLuint count; - GLuint wrap_count; /* number of copied vertices at start */ - GLboolean dangling_attr_ref; /* current attr implicitly referenced - outside the list */ - - struct brw_draw_prim *prim; - GLuint prim_count; - - struct brw_save_vertex_store *vertex_store; - struct brw_save_primitive_store *prim_store; -}; - -/* These buffers should be a reasonable size to support upload to - * hardware. Current brw implementation will re-upload on any - * changes, so don't make too big or apps which dynamically create - * dlists and use only a few times will suffer. - * - * Consider stategy of uploading regions from the VBO on demand in the - * case of dynamic vbos. Then make the dlist code signal that - * likelyhood as it occurs. No reason we couldn't change usage - * internally even though this probably isn't allowed for client VBOs? - */ -#define BRW_SAVE_BUFFER_SIZE (8*1024) /* dwords */ -#define BRW_SAVE_PRIM_SIZE 128 -#define BRW_SAVE_PRIM_WEAK 0x40 - -#define BRW_SAVE_FALLBACK 0x10000000 - -/* Storage to be shared among several vertex_lists. - */ -struct brw_save_vertex_store { - struct gl_buffer_object *bufferobj; - GLfloat *buffer; - GLuint used; - GLuint refcount; -}; - -struct brw_save_primitive_store { - struct brw_draw_prim buffer[BRW_SAVE_PRIM_SIZE]; - GLuint used; - GLuint refcount; -}; - - -struct brw_save_context { - GLcontext *ctx; - GLvertexformat vtxfmt; - struct gl_client_array arrays[BRW_ATTRIB_MAX]; - const struct gl_client_array *inputs[BRW_ATTRIB_MAX]; - - GLubyte attrsz[BRW_ATTRIB_MAX]; - GLubyte active_sz[BRW_ATTRIB_MAX]; - GLuint vertex_size; - - GLfloat *buffer; - GLuint count; - GLuint wrap_count; - GLuint replay_flags; - - struct brw_draw_prim *prim; - GLuint prim_count, prim_max; - - struct brw_save_vertex_store *vertex_store; - struct brw_save_primitive_store *prim_store; - - GLfloat *vbptr; /* cursor, points into buffer */ - GLfloat vertex[BRW_ATTRIB_MAX*4]; /* current values */ - GLfloat *attrptr[BRW_ATTRIB_MAX]; - GLuint vert_count; - GLuint max_vert; - GLboolean dangling_attr_ref; - GLboolean have_materials; - - GLuint opcode_vertex_list; - - struct brw_save_copied_vtx copied; - - GLfloat CurrentFloatEdgeFlag; - - GLfloat *current[BRW_ATTRIB_MAX]; /* points into ctx->ListState */ - GLubyte *currentsz[BRW_ATTRIB_MAX]; -}; - - -void brw_save_init( GLcontext *ctx ); -void brw_save_destroy( GLcontext *ctx ); -void brw_save_wakeup( GLcontext *ctx ); -void brw_save_invalidate_state( GLcontext *ctx, GLuint new_state ); -void brw_save_fallback( GLcontext *ctx, GLboolean fallback ); - -/* Callbacks: - */ -void brw_save_EndList( GLcontext *ctx ); -void brw_save_NewList( GLcontext *ctx, GLuint list, GLenum mode ); -void brw_save_EndCallList( GLcontext *ctx ); -void brw_save_BeginCallList( GLcontext *ctx, struct mesa_display_list *list ); -void brw_save_SaveFlushVertices( GLcontext *ctx ); -GLboolean brw_save_NotifyBegin( GLcontext *ctx, GLenum mode ); - -void brw_save_playback_vertex_list( GLcontext *ctx, void *data ); - -void brw_save_api_init( struct brw_save_context *save ); - -#endif diff --git a/src/mesa/drivers/dri/i965/brw_save_api.c b/src/mesa/drivers/dri/i965/brw_save_api.c deleted file mode 100644 index 9c0e4af48a..0000000000 --- a/src/mesa/drivers/dri/i965/brw_save_api.c +++ /dev/null @@ -1,1162 +0,0 @@ -/************************************************************************** - -Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. - -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 -TUNGSTEN GRAPHICS AND/OR THEIR 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 - */ - - - -/* Display list compiler attempts to store lists of vertices with the - * same vertex layout. Additionally it attempts to minimize the need - * for execute-time fixup of these vertex lists, allowing them to be - * cached on hardware. - * - * There are still some circumstances where this can be thwarted, for - * example by building a list that consists of one very long primitive - * (eg Begin(Triangles), 1000 vertices, End), and calling that list - * from inside a different begin/end object (Begin(Lines), CallList, - * End). - * - * In that case the code will have to replay the list as individual - * commands through the Exec dispatch table, or fix up the copied - * vertices at execute-time. - * - * The other case where fixup is required is when a vertex attribute - * is introduced in the middle of a primitive. Eg: - * Begin(Lines) - * TexCoord1f() Vertex2f() - * TexCoord1f() Color3f() Vertex2f() - * End() - * - * If the current value of Color isn't known at compile-time, this - * primitive will require fixup. - * - * - * The list compiler currently doesn't attempt to compile lists - * containing EvalCoord or EvalPoint commands. On encountering one of - * these, compilation falls back to opcodes. - * - * This could be improved to fallback only when a mix of EvalCoord and - * Vertex commands are issued within a single primitive. - */ - - -#include "glheader.h" -#include "context.h" -#include "dlist.h" -#include "enums.h" -#include "macros.h" -#include "api_validate.h" -#include "api_arrayelt.h" -#include "vtxfmt.h" -#include "dispatch.h" - -#include "brw_save.h" -#include "brw_fallback.h" - - - - -/* - * NOTE: Old 'parity' issue is gone, but copying can still be - * wrong-footed on replay. - */ -static GLuint _save_copy_vertices( GLcontext *ctx, - const struct brw_save_vertex_list *node, - const GLfloat *src_buffer) -{ - struct brw_save_context *save = IMM_CONTEXT( ctx )->save; - const struct brw_draw_prim *prim = &node->prim[node->prim_count-1]; - GLuint nr = prim->count; - GLuint sz = save->vertex_size; - const GLfloat *src = src_buffer + prim->start * sz; - GLfloat *dst = save->copied.buffer; - GLuint ovf, i; - - if (prim->end) - return 0; - - switch( prim->mode ) - { - case GL_POINTS: - return 0; - case GL_LINES: - ovf = nr&1; - for (i = 0 ; i < ovf ; i++) - _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) ); - return i; - case GL_TRIANGLES: - ovf = nr%3; - for (i = 0 ; i < ovf ; i++) - _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) ); - return i; - case GL_QUADS: - ovf = nr&3; - for (i = 0 ; i < ovf ; i++) - _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) ); - return i; - case GL_LINE_STRIP: - if (nr == 0) - return 0; - else { - _mesa_memcpy( dst, src+(nr-1)*sz, sz*sizeof(GLfloat) ); - return 1; - } - case GL_LINE_LOOP: - case GL_TRIANGLE_FAN: - case GL_POLYGON: - if (nr == 0) - return 0; - else if (nr == 1) { - _mesa_memcpy( dst, src+0, sz*sizeof(GLfloat) ); - return 1; - } else { - _mesa_memcpy( dst, src+0, sz*sizeof(GLfloat) ); - _mesa_memcpy( dst+sz, src+(nr-1)*sz, sz*sizeof(GLfloat) ); - return 2; - } - case GL_TRIANGLE_STRIP: - case GL_QUAD_STRIP: - switch (nr) { - case 0: ovf = 0; break; - case 1: ovf = 1; break; - default: ovf = 2 + (nr&1); break; - } - for (i = 0 ; i < ovf ; i++) - _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) ); - return i; - default: - assert(0); - return 0; - } -} - - -static struct brw_save_vertex_store *alloc_vertex_store( GLcontext *ctx ) -{ - struct brw_save_vertex_store *vertex_store = CALLOC_STRUCT(brw_save_vertex_store); - - /* obj->Name needs to be non-zero, but won't ever be examined more - * closely than that. In particular these buffers won't be entered - * into the hash and can never be confused with ones visible to the - * user. Perhaps there could be a special number for internal - * buffers: - */ - vertex_store->bufferobj = ctx->Driver.NewBufferObject(ctx, 1, GL_ARRAY_BUFFER_ARB); - - ctx->Driver.BufferData( ctx, - GL_ARRAY_BUFFER_ARB, - BRW_SAVE_BUFFER_SIZE * sizeof(GLfloat), - NULL, - GL_STATIC_DRAW_ARB, - vertex_store->bufferobj); - - vertex_store->buffer = NULL; - vertex_store->used = 0; - vertex_store->refcount = 1; - - return vertex_store; -} - -static void free_vertex_store( GLcontext *ctx, struct brw_save_vertex_store *vertex_store ) -{ - assert(!vertex_store->buffer); - - if (vertex_store->bufferobj) - ctx->Driver.DeleteBuffer( ctx, vertex_store->bufferobj ); - - FREE( vertex_store ); -} - -static GLfloat *map_vertex_store( GLcontext *ctx, struct brw_save_vertex_store *vertex_store ) -{ - assert(vertex_store->bufferobj); - assert(!vertex_store->buffer); - vertex_store->buffer = (GLfloat *)ctx->Driver.MapBuffer(ctx, - GL_ARRAY_BUFFER_ARB, /* not used */ - GL_STATIC_DRAW_ARB, /* not used */ - vertex_store->bufferobj); - - assert(vertex_store->buffer); - return vertex_store->buffer + vertex_store->used; -} - -static void unmap_vertex_store( GLcontext *ctx, struct brw_save_vertex_store *vertex_store ) -{ - ctx->Driver.UnmapBuffer( ctx, GL_ARRAY_BUFFER_ARB, vertex_store->bufferobj ); - vertex_store->buffer = NULL; -} - - -static struct brw_save_primitive_store *alloc_prim_store( GLcontext *ctx ) -{ - struct brw_save_primitive_store *store = CALLOC_STRUCT(brw_save_primitive_store); - (void) ctx; - store->used = 0; - store->refcount = 1; - return store; -} - -static void _save_reset_counters( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - - save->prim = save->prim_store->buffer + save->prim_store->used; - save->buffer = (save->vertex_store->buffer + - save->vertex_store->used); - - assert(save->buffer == save->vbptr); - - if (save->vertex_size) - save->max_vert = ((BRW_SAVE_BUFFER_SIZE - save->vertex_store->used) / - save->vertex_size); - else - save->max_vert = 0; - - save->vert_count = 0; - save->prim_count = 0; - save->prim_max = BRW_SAVE_PRIM_SIZE - save->prim_store->used; - save->dangling_attr_ref = 0; -} - - -/* Insert the active immediate struct onto the display list currently - * being built. - */ -static void _save_compile_vertex_list( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - struct brw_save_vertex_list *node; - - /* Allocate space for this structure in the display list currently - * being compiled. - */ - node = (struct brw_save_vertex_list *) - _mesa_alloc_instruction(ctx, save->opcode_vertex_list, sizeof(*node)); - - if (!node) - return; - - /* Duplicate our template, increment refcounts to the storage structs: - */ - _mesa_memcpy(node->attrsz, save->attrsz, sizeof(node->attrsz)); - node->vertex_size = save->vertex_size; - node->buffer_offset = (save->buffer - save->vertex_store->buffer) * sizeof(GLfloat); - node->count = save->vert_count; - node->wrap_count = save->copied.nr; - node->dangling_attr_ref = save->dangling_attr_ref; - node->prim = save->prim; - node->prim_count = save->prim_count; - node->vertex_store = save->vertex_store; - node->prim_store = save->prim_store; - - node->vertex_store->refcount++; - node->prim_store->refcount++; - - assert(node->attrsz[BRW_ATTRIB_POS] != 0 || - node->count == 0); - - if (save->dangling_attr_ref) - ctx->ListState.CurrentList->flags |= MESA_DLIST_DANGLING_REFS; - - save->vertex_store->used += save->vertex_size * node->count; - save->prim_store->used += node->prim_count; - - - /* Copy duplicated vertices - */ - save->copied.nr = _save_copy_vertices( ctx, node, save->buffer ); - - - /* Deal with GL_COMPILE_AND_EXECUTE: - */ - if (ctx->ExecuteFlag) { - struct _glapi_table *dispatch = GET_DISPATCH(); - - _glapi_set_dispatch(ctx->Exec); - - brw_loopback_vertex_list( ctx, - (const GLfloat *)((const char *)save->vertex_store->buffer + - node->buffer_offset), - node->attrsz, - node->prim, - node->prim_count, - node->wrap_count, - node->vertex_size); - - _glapi_set_dispatch(dispatch); - } - - - /* Decide whether the storage structs are full, or can be used for - * the next vertex lists as well. - */ - if (save->vertex_store->used > - BRW_SAVE_BUFFER_SIZE - 16 * (save->vertex_size + 4)) { - - /* Unmap old store: - */ - unmap_vertex_store( ctx, save->vertex_store ); - - /* Release old reference: - */ - save->vertex_store->refcount--; - assert(save->vertex_store->refcount != 0); - save->vertex_store = NULL; - - /* Allocate and map new store: - */ - save->vertex_store = alloc_vertex_store( ctx ); - save->vbptr = map_vertex_store( ctx, save->vertex_store ); - } - - if (save->prim_store->used > BRW_SAVE_PRIM_SIZE - 6) { - save->prim_store->refcount--; - assert(save->prim_store->refcount != 0); - save->prim_store = alloc_prim_store( ctx ); - } - - /* Reset our structures for the next run of vertices: - */ - _save_reset_counters( ctx ); -} - - -/* TODO -- If no new vertices have been stored, don't bother saving - * it. - */ -static void _save_wrap_buffers( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLint i = save->prim_count - 1; - GLenum mode; - GLboolean weak; - - assert(i < (GLint) save->prim_max); - assert(i >= 0); - - /* Close off in-progress primitive. - */ - save->prim[i].count = (save->vert_count - - save->prim[i].start); - mode = save->prim[i].mode; - weak = save->prim[i].weak; - - /* store the copied vertices, and allocate a new list. - */ - _save_compile_vertex_list( ctx ); - - /* Restart interrupted primitive - */ - save->prim[0].mode = mode; - save->prim[0].weak = weak; - save->prim[0].begin = 0; - save->prim[0].end = 0; - save->prim[0].pad = 0; - save->prim[0].start = 0; - save->prim[0].count = 0; - save->prim_count = 1; -} - - - -/* Called only when buffers are wrapped as the result of filling the - * vertex_store struct. - */ -static void _save_wrap_filled_vertex( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLfloat *data = save->copied.buffer; - GLuint i; - - /* Emit a glEnd to close off the last vertex list. - */ - _save_wrap_buffers( ctx ); - - /* Copy stored stored vertices to start of new list. - */ - assert(save->max_vert - save->vert_count > save->copied.nr); - - for (i = 0 ; i < save->copied.nr ; i++) { - _mesa_memcpy( save->vbptr, data, save->vertex_size * sizeof(GLfloat)); - data += save->vertex_size; - save->vbptr += save->vertex_size; - save->vert_count++; - } -} - - -static void _save_copy_to_current( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLuint i; - - for (i = BRW_ATTRIB_POS+1 ; i <= BRW_ATTRIB_INDEX ; i++) { - if (save->attrsz[i]) { - save->currentsz[i][0] = save->attrsz[i]; - COPY_CLEAN_4V(save->current[i], - save->attrsz[i], - save->attrptr[i]); - } - } - - /* Edgeflag requires special treatment: - * - * TODO: change edgeflag to GLfloat in Mesa. - */ - if (save->attrsz[BRW_ATTRIB_EDGEFLAG]) { - ctx->ListState.ActiveEdgeFlag = 1; - save->CurrentFloatEdgeFlag = - save->attrptr[BRW_ATTRIB_EDGEFLAG][0]; - ctx->ListState.CurrentEdgeFlag = - (save->CurrentFloatEdgeFlag == 1.0); - } -} - - -static void _save_copy_from_current( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLint i; - - for (i = BRW_ATTRIB_POS+1 ; i <= BRW_ATTRIB_INDEX ; i++) - switch (save->attrsz[i]) { - case 4: save->attrptr[i][3] = save->current[i][3]; - case 3: save->attrptr[i][2] = save->current[i][2]; - case 2: save->attrptr[i][1] = save->current[i][1]; - case 1: save->attrptr[i][0] = save->current[i][0]; - case 0: break; - } - - /* Edgeflag requires special treatment: - */ - if (save->attrsz[BRW_ATTRIB_EDGEFLAG]) { - save->CurrentFloatEdgeFlag = (GLfloat)ctx->ListState.CurrentEdgeFlag; - save->attrptr[BRW_ATTRIB_EDGEFLAG][0] = save->CurrentFloatEdgeFlag; - } -} - - - - -/* Flush existing data, set new attrib size, replay copied vertices. - */ -static void _save_upgrade_vertex( GLcontext *ctx, - GLuint attr, - GLuint newsz ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLuint oldsz; - GLuint i; - GLfloat *tmp; - - /* Store the current run of vertices, and emit a GL_END. Emit a - * BEGIN in the new buffer. - */ - if (save->vert_count) - _save_wrap_buffers( ctx ); - else - assert( save->copied.nr == 0 ); - - /* Do a COPY_TO_CURRENT to ensure back-copying works for the case - * when the attribute already exists in the vertex and is having - * its size increased. - */ - _save_copy_to_current( ctx ); - - /* Fix up sizes: - */ - oldsz = save->attrsz[attr]; - save->attrsz[attr] = newsz; - - save->vertex_size += newsz - oldsz; - save->max_vert = ((BRW_SAVE_BUFFER_SIZE - save->vertex_store->used) / - save->vertex_size); - save->vert_count = 0; - - /* Recalculate all the attrptr[] values: - */ - for (i = 0, tmp = save->vertex ; i < BRW_ATTRIB_MAX ; i++) { - if (save->attrsz[i]) { - save->attrptr[i] = tmp; - tmp += save->attrsz[i]; - } - else - save->attrptr[i] = NULL; /* will not be dereferenced. */ - } - - /* Copy from current to repopulate the vertex with correct values. - */ - _save_copy_from_current( ctx ); - - /* Replay stored vertices to translate them to new format here. - * - * If there are copied vertices and the new (upgraded) attribute - * has not been defined before, this list is somewhat degenerate, - * and will need fixup at runtime. - */ - if (save->copied.nr) - { - GLfloat *data = save->copied.buffer; - GLfloat *dest = save->buffer; - GLuint j; - - /* Need to note this and fix up at runtime (or loopback): - */ - if (save->currentsz[attr][0] == 0) { - assert(oldsz == 0); - save->dangling_attr_ref = GL_TRUE; - } - - for (i = 0 ; i < save->copied.nr ; i++) { - for (j = 0 ; j < BRW_ATTRIB_MAX ; j++) { - if (save->attrsz[j]) { - if (j == attr) { - if (oldsz) { - COPY_CLEAN_4V( dest, oldsz, data ); - data += oldsz; - dest += newsz; - } - else { - COPY_SZ_4V( dest, newsz, save->current[attr] ); - dest += newsz; - } - } - else { - GLint sz = save->attrsz[j]; - COPY_SZ_4V( dest, sz, data ); - data += sz; - dest += sz; - } - } - } - } - - save->vbptr = dest; - save->vert_count += save->copied.nr; - } -} - -static void save_fixup_vertex( GLcontext *ctx, GLuint attr, GLuint sz ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - - if (sz > save->attrsz[attr]) { - /* New size is larger. Need to flush existing vertices and get - * an enlarged vertex format. - */ - _save_upgrade_vertex( ctx, attr, sz ); - } - else if (sz < save->active_sz[attr]) { - static GLfloat id[4] = { 0, 0, 0, 1 }; - GLuint i; - - /* New size is equal or smaller - just need to fill in some - * zeros. - */ - for (i = sz ; i <= save->attrsz[attr] ; i++) - save->attrptr[attr][i-1] = id[i-1]; - } - - save->active_sz[attr] = sz; -} - -static void _save_reset_vertex( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLuint i; - - for (i = 0 ; i < BRW_ATTRIB_MAX ; i++) { - save->attrsz[i] = 0; - save->active_sz[i] = 0; - } - - save->vertex_size = 0; -} - - - -#define ERROR() _mesa_compile_error( ctx, GL_INVALID_ENUM, __FUNCTION__ ); - - -/* Only one size for each attribute may be active at once. Eg. if - * Color3f is installed/active, then Color4f may not be, even if the - * vertex actually contains 4 color coordinates. This is because the - * 3f version won't otherwise set color[3] to 1.0 -- this is the job - * of the chooser function when switching between Color4f and Color3f. - */ -#define ATTR( A, N, V0, V1, V2, V3 ) \ -do { \ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; \ - \ - if (save->active_sz[A] != N) \ - save_fixup_vertex(ctx, A, N); \ - \ - { \ - GLfloat *dest = save->attrptr[A]; \ - if (N>0) dest[0] = V0; \ - if (N>1) dest[1] = V1; \ - if (N>2) dest[2] = V2; \ - if (N>3) dest[3] = V3; \ - } \ - \ - if ((A) == 0) { \ - GLuint i; \ - \ - for (i = 0; i < save->vertex_size; i++) \ - save->vbptr[i] = save->vertex[i]; \ - \ - save->vbptr += save->vertex_size; \ - \ - if (++save->vert_count >= save->max_vert) \ - _save_wrap_filled_vertex( ctx ); \ - } \ -} while (0) - -#define TAG(x) _save_##x - -#include "brw_attrib_tmp.h" - - - - -/* Cope with EvalCoord/CallList called within a begin/end object: - * -- Flush current buffer - * -- Fallback to opcodes for the rest of the begin/end object. - */ -#define DO_FALLBACK(ctx) \ -do { \ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; \ - \ - if (save->vert_count || save->prim_count) \ - _save_compile_vertex_list( ctx ); \ - \ - _save_copy_to_current( ctx ); \ - _save_reset_vertex( ctx ); \ - _save_reset_counters( ctx ); \ - _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); \ - ctx->Driver.SaveNeedFlush = 0; \ -} while (0) - -static void GLAPIENTRY _save_EvalCoord1f( GLfloat u ) -{ - GET_CURRENT_CONTEXT(ctx); - DO_FALLBACK(ctx); - ctx->Save->EvalCoord1f( u ); -} - -static void GLAPIENTRY _save_EvalCoord1fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - DO_FALLBACK(ctx); - ctx->Save->EvalCoord1fv( v ); -} - -static void GLAPIENTRY _save_EvalCoord2f( GLfloat u, GLfloat v ) -{ - GET_CURRENT_CONTEXT(ctx); - DO_FALLBACK(ctx); - ctx->Save->EvalCoord2f( u, v ); -} - -static void GLAPIENTRY _save_EvalCoord2fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - DO_FALLBACK(ctx); - ctx->Save->EvalCoord2fv( v ); -} - -static void GLAPIENTRY _save_EvalPoint1( GLint i ) -{ - GET_CURRENT_CONTEXT(ctx); - DO_FALLBACK(ctx); - ctx->Save->EvalPoint1( i ); -} - -static void GLAPIENTRY _save_EvalPoint2( GLint i, GLint j ) -{ - GET_CURRENT_CONTEXT(ctx); - DO_FALLBACK(ctx); - ctx->Save->EvalPoint2( i, j ); -} - -static void GLAPIENTRY _save_CallList( GLuint l ) -{ - GET_CURRENT_CONTEXT(ctx); - DO_FALLBACK(ctx); - ctx->Save->CallList( l ); -} - -static void GLAPIENTRY _save_CallLists( GLsizei n, GLenum type, const GLvoid *v ) -{ - GET_CURRENT_CONTEXT(ctx); - DO_FALLBACK(ctx); - ctx->Save->CallLists( n, type, v ); -} - - - - -/* This begin is hooked into ... Updating of - * ctx->Driver.CurrentSavePrimitive is already taken care of. - */ -GLboolean brw_save_NotifyBegin( GLcontext *ctx, GLenum mode ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - - GLuint i = save->prim_count++; - - assert(i < save->prim_max); - save->prim[i].mode = mode & ~BRW_SAVE_PRIM_WEAK; - save->prim[i].begin = 1; - save->prim[i].end = 0; - save->prim[i].weak = (mode & BRW_SAVE_PRIM_WEAK) ? 1 : 0; - save->prim[i].pad = 0; - save->prim[i].start = save->vert_count; - save->prim[i].count = 0; - - _mesa_install_save_vtxfmt( ctx, &save->vtxfmt ); - ctx->Driver.SaveNeedFlush = 1; - return GL_TRUE; -} - - - -static void GLAPIENTRY _save_End( void ) -{ - GET_CURRENT_CONTEXT( ctx ); - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLint i = save->prim_count - 1; - - ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END; - save->prim[i].end = 1; - save->prim[i].count = (save->vert_count - - save->prim[i].start); - - if (i == (GLint) save->prim_max - 1) { - _save_compile_vertex_list( ctx ); - assert(save->copied.nr == 0); - } - - /* Swap out this vertex format while outside begin/end. Any color, - * etc. received between here and the next begin will be compiled - * as opcodes. - */ - _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); -} - - -/* These are all errors as this vtxfmt is only installed inside - * begin/end pairs. - */ -static void GLAPIENTRY _save_DrawElements(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) count; (void) type; (void) indices; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawElements" ); -} - - -static void GLAPIENTRY _save_DrawRangeElements(GLenum mode, - GLuint start, GLuint end, - GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) start; (void) end; (void) count; (void) type; (void) indices; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawRangeElements" ); -} - -static void GLAPIENTRY _save_DrawArrays(GLenum mode, GLint start, GLsizei count) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) start; (void) count; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawArrays" ); -} - -static void GLAPIENTRY _save_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) -{ - GET_CURRENT_CONTEXT(ctx); - (void) x1; (void) y1; (void) x2; (void) y2; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glRectf" ); -} - -static void GLAPIENTRY _save_EvalMesh1( GLenum mode, GLint i1, GLint i2 ) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) i1; (void) i2; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh1" ); -} - -static void GLAPIENTRY _save_EvalMesh2( GLenum mode, GLint i1, GLint i2, - GLint j1, GLint j2 ) -{ - GET_CURRENT_CONTEXT(ctx); - (void) mode; (void) i1; (void) i2; (void) j1; (void) j2; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh2" ); -} - -static void GLAPIENTRY _save_Begin( GLenum mode ) -{ - GET_CURRENT_CONTEXT( ctx ); - (void) mode; - _mesa_compile_error( ctx, GL_INVALID_OPERATION, "Recursive glBegin" ); -} - - -/* Unlike the functions above, these are to be hooked into the vtxfmt - * maintained in ctx->ListState, active when the list is known or - * suspected to be outside any begin/end primitive. - */ -static void GLAPIENTRY _save_OBE_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) -{ - GET_CURRENT_CONTEXT(ctx); - brw_save_NotifyBegin( ctx, GL_QUADS | BRW_SAVE_PRIM_WEAK ); - CALL_Vertex2f(GET_DISPATCH(), ( x1, y1 )); - CALL_Vertex2f(GET_DISPATCH(), ( x2, y1 )); - CALL_Vertex2f(GET_DISPATCH(), ( x2, y2 )); - CALL_Vertex2f(GET_DISPATCH(), ( x1, y2 )); - CALL_End(GET_DISPATCH(), ()); -} - - -static void GLAPIENTRY _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei count) -{ - GET_CURRENT_CONTEXT(ctx); - GLint i; - - if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) - return; - - brw_save_NotifyBegin( ctx, mode | BRW_SAVE_PRIM_WEAK ); - for (i = 0; i < count; i++) - CALL_ArrayElement(GET_DISPATCH(), (start + i)); - CALL_End(GET_DISPATCH(), ()); -} - -/* Could do better by copying the arrays and element list intact and - * then emitting an indexed prim at runtime. - */ -static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - GLint i; - - if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) - return; - - brw_save_NotifyBegin( ctx, mode | BRW_SAVE_PRIM_WEAK ); - - switch (type) { - case GL_UNSIGNED_BYTE: - for (i = 0 ; i < count ; i++) - CALL_ArrayElement(GET_DISPATCH(), ( ((GLubyte *)indices)[i] )); - break; - case GL_UNSIGNED_SHORT: - for (i = 0 ; i < count ; i++) - CALL_ArrayElement(GET_DISPATCH(), ( ((GLushort *)indices)[i] )); - break; - case GL_UNSIGNED_INT: - for (i = 0 ; i < count ; i++) - CALL_ArrayElement(GET_DISPATCH(), ( ((GLuint *)indices)[i] )); - break; - default: - _mesa_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" ); - break; - } - - CALL_End(GET_DISPATCH(), ()); -} - -static void GLAPIENTRY _save_OBE_DrawRangeElements(GLenum mode, - GLuint start, GLuint end, - GLsizei count, GLenum type, - const GLvoid *indices) -{ - GET_CURRENT_CONTEXT(ctx); - if (_mesa_validate_DrawRangeElements( ctx, mode, - start, end, - count, type, indices )) - _save_OBE_DrawElements( mode, count, type, indices ); -} - - - - - -static void _save_vtxfmt_init( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLvertexformat *vfmt = &save->vtxfmt; - - vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ - vfmt->Begin = _save_Begin; - vfmt->Color3f = _save_Color3f; - vfmt->Color3fv = _save_Color3fv; - vfmt->Color4f = _save_Color4f; - vfmt->Color4fv = _save_Color4fv; - vfmt->EdgeFlag = _save_EdgeFlag; - vfmt->End = _save_End; - vfmt->FogCoordfEXT = _save_FogCoordfEXT; - vfmt->FogCoordfvEXT = _save_FogCoordfvEXT; - vfmt->Indexf = _save_Indexf; - vfmt->Indexfv = _save_Indexfv; - vfmt->Materialfv = _save_Materialfv; - vfmt->MultiTexCoord1fARB = _save_MultiTexCoord1f; - vfmt->MultiTexCoord1fvARB = _save_MultiTexCoord1fv; - vfmt->MultiTexCoord2fARB = _save_MultiTexCoord2f; - vfmt->MultiTexCoord2fvARB = _save_MultiTexCoord2fv; - vfmt->MultiTexCoord3fARB = _save_MultiTexCoord3f; - vfmt->MultiTexCoord3fvARB = _save_MultiTexCoord3fv; - vfmt->MultiTexCoord4fARB = _save_MultiTexCoord4f; - vfmt->MultiTexCoord4fvARB = _save_MultiTexCoord4fv; - vfmt->Normal3f = _save_Normal3f; - vfmt->Normal3fv = _save_Normal3fv; - vfmt->SecondaryColor3fEXT = _save_SecondaryColor3fEXT; - vfmt->SecondaryColor3fvEXT = _save_SecondaryColor3fvEXT; - vfmt->TexCoord1f = _save_TexCoord1f; - vfmt->TexCoord1fv = _save_TexCoord1fv; - vfmt->TexCoord2f = _save_TexCoord2f; - vfmt->TexCoord2fv = _save_TexCoord2fv; - vfmt->TexCoord3f = _save_TexCoord3f; - vfmt->TexCoord3fv = _save_TexCoord3fv; - vfmt->TexCoord4f = _save_TexCoord4f; - vfmt->TexCoord4fv = _save_TexCoord4fv; - vfmt->Vertex2f = _save_Vertex2f; - vfmt->Vertex2fv = _save_Vertex2fv; - vfmt->Vertex3f = _save_Vertex3f; - vfmt->Vertex3fv = _save_Vertex3fv; - vfmt->Vertex4f = _save_Vertex4f; - vfmt->Vertex4fv = _save_Vertex4fv; - vfmt->VertexAttrib1fARB = _save_VertexAttrib1fARB; - vfmt->VertexAttrib1fvARB = _save_VertexAttrib1fvARB; - vfmt->VertexAttrib2fARB = _save_VertexAttrib2fARB; - vfmt->VertexAttrib2fvARB = _save_VertexAttrib2fvARB; - vfmt->VertexAttrib3fARB = _save_VertexAttrib3fARB; - vfmt->VertexAttrib3fvARB = _save_VertexAttrib3fvARB; - vfmt->VertexAttrib4fARB = _save_VertexAttrib4fARB; - vfmt->VertexAttrib4fvARB = _save_VertexAttrib4fvARB; - - vfmt->VertexAttrib1fNV = _save_VertexAttrib1fNV; - vfmt->VertexAttrib1fvNV = _save_VertexAttrib1fvNV; - vfmt->VertexAttrib2fNV = _save_VertexAttrib2fNV; - vfmt->VertexAttrib2fvNV = _save_VertexAttrib2fvNV; - vfmt->VertexAttrib3fNV = _save_VertexAttrib3fNV; - vfmt->VertexAttrib3fvNV = _save_VertexAttrib3fvNV; - vfmt->VertexAttrib4fNV = _save_VertexAttrib4fNV; - vfmt->VertexAttrib4fvNV = _save_VertexAttrib4fvNV; - - /* This will all require us to fallback to saving the list as opcodes: - */ - vfmt->CallList = _save_CallList; /* inside begin/end */ - vfmt->CallLists = _save_CallLists; /* inside begin/end */ - vfmt->EvalCoord1f = _save_EvalCoord1f; - vfmt->EvalCoord1fv = _save_EvalCoord1fv; - vfmt->EvalCoord2f = _save_EvalCoord2f; - vfmt->EvalCoord2fv = _save_EvalCoord2fv; - vfmt->EvalPoint1 = _save_EvalPoint1; - vfmt->EvalPoint2 = _save_EvalPoint2; - - /* These are all errors as we at least know we are in some sort of - * begin/end pair: - */ - vfmt->EvalMesh1 = _save_EvalMesh1; - vfmt->EvalMesh2 = _save_EvalMesh2; - vfmt->Begin = _save_Begin; - vfmt->Rectf = _save_Rectf; - vfmt->DrawArrays = _save_DrawArrays; - vfmt->DrawElements = _save_DrawElements; - vfmt->DrawRangeElements = _save_DrawRangeElements; - -} - - -void brw_save_SaveFlushVertices( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - - /* Noop when we are actually active: - */ - if (ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM || - ctx->Driver.CurrentSavePrimitive <= GL_POLYGON) - return; - - if (save->vert_count || - save->prim_count) - _save_compile_vertex_list( ctx ); - - _save_copy_to_current( ctx ); - _save_reset_vertex( ctx ); - _save_reset_counters( ctx ); - ctx->Driver.SaveNeedFlush = 0; -} - -void brw_save_NewList( GLcontext *ctx, GLuint list, GLenum mode ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - - (void) list; (void) mode; - - if (!save->prim_store) - save->prim_store = alloc_prim_store( ctx ); - - if (!save->vertex_store) - save->vertex_store = alloc_vertex_store( ctx ); - - save->vbptr = map_vertex_store( ctx, save->vertex_store ); - - _save_reset_vertex( ctx ); - _save_reset_counters( ctx ); - ctx->Driver.SaveNeedFlush = 0; -} - -void brw_save_EndList( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - unmap_vertex_store( ctx, save->vertex_store ); - - assert(save->vertex_size == 0); -} - -void brw_save_BeginCallList( GLcontext *ctx, struct mesa_display_list *dlist ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - save->replay_flags |= dlist->flags; -} - -void brw_save_EndCallList( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - - if (ctx->ListState.CallDepth == 1) { - /* This is correct: want to keep only the BRW_SAVE_FALLBACK - * flag, if it is set: - */ - save->replay_flags &= BRW_SAVE_FALLBACK; - } -} - - -static void brw_destroy_vertex_list( GLcontext *ctx, void *data ) -{ - struct brw_save_vertex_list *node = (struct brw_save_vertex_list *)data; - (void) ctx; - - if ( --node->vertex_store->refcount == 0 ) - free_vertex_store( ctx, node->vertex_store ); - - if ( --node->prim_store->refcount == 0 ) - FREE( node->prim_store ); -} - - -static void brw_print_vertex_list( GLcontext *ctx, void *data ) -{ - struct brw_save_vertex_list *node = (struct brw_save_vertex_list *)data; - GLuint i; - (void) ctx; - - _mesa_debug(NULL, "BRW-VERTEX-LIST, %u vertices %d primitives, %d vertsize\n", - node->count, - node->prim_count, - node->vertex_size); - - for (i = 0 ; i < node->prim_count ; i++) { - struct brw_draw_prim *prim = &node->prim[i]; - _mesa_debug(NULL, " prim %d: %s%s %d..%d %s %s\n", - i, - _mesa_lookup_enum_by_nr(prim->mode), - prim->weak ? " (weak)" : "", - prim->start, - prim->start + prim->count, - (prim->begin) ? "BEGIN" : "(wrap)", - (prim->end) ? "END" : "(wrap)"); - } -} - - -static void _save_current_init( GLcontext *ctx ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLint i; - - for (i = 0; i < BRW_ATTRIB_FIRST_MATERIAL; i++) { - save->currentsz[i] = &ctx->ListState.ActiveAttribSize[i]; - save->current[i] = ctx->ListState.CurrentAttrib[i]; - } - - for (i = BRW_ATTRIB_FIRST_MATERIAL; i < BRW_ATTRIB_INDEX; i++) { - const GLuint j = i - BRW_ATTRIB_FIRST_MATERIAL; - ASSERT(j < MAT_ATTRIB_MAX); - save->currentsz[i] = &ctx->ListState.ActiveMaterialSize[j]; - save->current[i] = ctx->ListState.CurrentMaterial[j]; - } - - save->currentsz[BRW_ATTRIB_INDEX] = &ctx->ListState.ActiveIndex; - save->current[BRW_ATTRIB_INDEX] = &ctx->ListState.CurrentIndex; - - save->currentsz[BRW_ATTRIB_EDGEFLAG] = &ctx->ListState.ActiveEdgeFlag; - save->current[BRW_ATTRIB_EDGEFLAG] = &save->CurrentFloatEdgeFlag; -} - -/** - * Initialize the display list compiler - */ -void brw_save_api_init( struct brw_save_context *save ) -{ - GLcontext *ctx = save->ctx; - GLuint i; - - save->opcode_vertex_list = - _mesa_alloc_opcode( ctx, - sizeof(struct brw_save_vertex_list), - brw_save_playback_vertex_list, - brw_destroy_vertex_list, - brw_print_vertex_list ); - - ctx->Driver.NotifySaveBegin = brw_save_NotifyBegin; - - _save_vtxfmt_init( ctx ); - _save_current_init( ctx ); - - for (i = 0; i < BRW_ATTRIB_MAX; i++) - save->inputs[i] = &save->arrays[i]; - - /* Hook our array functions into the outside-begin-end vtxfmt in - * ctx->ListState. - */ - ctx->ListState.ListVtxfmt.Rectf = _save_OBE_Rectf; - ctx->ListState.ListVtxfmt.DrawArrays = _save_OBE_DrawArrays; - ctx->ListState.ListVtxfmt.DrawElements = _save_OBE_DrawElements; - ctx->ListState.ListVtxfmt.DrawRangeElements = _save_OBE_DrawRangeElements; - _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); -} - diff --git a/src/mesa/drivers/dri/i965/brw_save_draw.c b/src/mesa/drivers/dri/i965/brw_save_draw.c deleted file mode 100644 index 84f74d3f6c..0000000000 --- a/src/mesa/drivers/dri/i965/brw_save_draw.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.1 - * - * Copyright (C) 1999-2004 Brian Paul 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, 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 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 - * BRIAN PAUL 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. - */ - -/* Author: - * Keith Whitwell - */ - -#include "glheader.h" -#include "context.h" -#include "imports.h" -#include "mtypes.h" -#include "macros.h" -#include "light.h" -#include "state.h" - -#include "brw_save.h" -#include "brw_draw.h" -#include "brw_fallback.h" - - -static void _playback_copy_to_current( GLcontext *ctx, - const struct brw_save_vertex_list *node ) -{ - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - GLfloat vertex[BRW_ATTRIB_MAX * 4], *data = vertex; - GLuint i, offset; - - if (node->count) - offset = node->buffer_offset + (node->count-1) * node->vertex_size; - else - offset = node->buffer_offset; - - ctx->Driver.GetBufferSubData( ctx, 0, offset, node->vertex_size, - data, node->vertex_store->bufferobj ); - - for (i = BRW_ATTRIB_POS+1 ; i <= BRW_ATTRIB_INDEX ; i++) { - if (node->attrsz[i]) { - COPY_CLEAN_4V(save->current[i], node->attrsz[i], data); - data += node->attrsz[i]; - - if (i >= BRW_ATTRIB_MAT_FRONT_AMBIENT && - i <= BRW_ATTRIB_MAT_BACK_INDEXES) - ctx->NewState |= _NEW_LIGHT; - } - } - - /* Edgeflag requires special treatment: - */ - if (node->attrsz[BRW_ATTRIB_EDGEFLAG]) { - ctx->Current.EdgeFlag = (data[0] == 1.0); - } - - -#if 1 - /* Colormaterial -- this kindof sucks. - */ - if (ctx->Light.ColorMaterialEnabled) { - _mesa_update_color_material(ctx, ctx->Current.Attrib[BRW_ATTRIB_COLOR0]); - } -#endif - - /* CurrentExecPrimitive - */ - if (node->prim_count) { - const struct brw_draw_prim *prim = &node->prim[node->prim_count - 1]; - if (prim->end) - ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; - else - ctx->Driver.CurrentExecPrimitive = prim->mode; - } -} - - - -/* Treat the vertex storage as a VBO, define vertex arrays pointing - * into it: - */ -static void brw_bind_vertex_list( struct brw_save_context *save, - const struct brw_save_vertex_list *node ) -{ - struct gl_client_array *arrays = save->arrays; - GLuint data = node->buffer_offset; - GLuint attr; - - memset(arrays, 0, BRW_ATTRIB_MAX * sizeof(arrays[0])); - - for (attr = 0; attr <= BRW_ATTRIB_INDEX; attr++) { - if (node->attrsz[attr]) { - arrays[attr].Ptr = (const GLubyte *)data; - arrays[attr].Size = node->attrsz[attr]; - arrays[attr].StrideB = node->vertex_size * sizeof(GLfloat); - arrays[attr].Stride = node->vertex_size * sizeof(GLfloat); - arrays[attr].Type = GL_FLOAT; - arrays[attr].Enabled = 1; - arrays[attr].BufferObj = node->vertex_store->bufferobj; - arrays[attr]._MaxElement = node->count; /* ??? */ - - assert(arrays[attr].BufferObj->Name); - - data += node->attrsz[attr] * sizeof(GLfloat); - } - } -} - -static void brw_save_loopback_vertex_list( GLcontext *ctx, - const struct brw_save_vertex_list *list ) -{ - const char *buffer = ctx->Driver.MapBuffer(ctx, - GL_ARRAY_BUFFER_ARB, - GL_DYNAMIC_READ_ARB, /* ? */ - list->vertex_store->bufferobj); - - brw_loopback_vertex_list( ctx, - (const GLfloat *)(buffer + list->buffer_offset), - list->attrsz, - list->prim, - list->prim_count, - list->wrap_count, - list->vertex_size); - - ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER_ARB, - list->vertex_store->bufferobj); -} - - -/** - * Execute the buffer and save copied verts. - */ -void brw_save_playback_vertex_list( GLcontext *ctx, void *data ) -{ - const struct brw_save_vertex_list *node = (const struct brw_save_vertex_list *) data; - struct brw_save_context *save = IMM_CONTEXT(ctx)->save; - - FLUSH_CURRENT(ctx, 0); - - if (node->prim_count > 0 && node->count > 0) { - - if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END && - node->prim[0].begin) { - - /* Degenerate case: list is called inside begin/end pair and - * includes operations such as glBegin or glDrawArrays. - */ - if (0) - _mesa_printf("displaylist recursive begin"); - - brw_save_loopback_vertex_list( ctx, node ); - return; - } - else if (save->replay_flags) { - /* Various degnerate cases: translate into immediate mode - * calls rather than trying to execute in place. - */ - brw_save_loopback_vertex_list( ctx, node ); - return; - } - - if (ctx->NewState) - _mesa_update_state( ctx ); - - if ((ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) || - (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glBegin (invalid vertex/fragment program)"); - return; - } - - brw_bind_vertex_list( save, node ); - - if (!brw_draw_prims( save->ctx, - save->inputs, - node->prim, - node->prim_count, - NULL, - 0, /* Node is a VBO, so this is ok */ - node->count, - 0 )) { - brw_fallback(ctx); - brw_save_loopback_vertex_list( ctx, node ); - brw_unfallback(ctx); - return; - } - } - - /* Copy to current? - */ - _playback_copy_to_current( ctx, node ); -} -- cgit v1.2.3 From 48f5deab94be832a782a440f55a7bc742d50a62f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 30 Oct 2006 16:56:56 +0000 Subject: switch several dri drivers over --- src/mesa/drivers/dri/i810/i810context.c | 6 ++--- src/mesa/drivers/dri/i810/i810state.c | 4 ++-- src/mesa/drivers/dri/i915/i915_context.c | 5 ++-- src/mesa/drivers/dri/i915/intel_context.c | 8 +++---- src/mesa/drivers/dri/i965/brw_context.h | 1 - src/mesa/drivers/dri/i965/intel_context.c | 8 +++---- src/mesa/drivers/osmesa/osmesa.c | 3 ++- src/mesa/drivers/x11/xm_api.c | 2 +- src/mesa/drivers/x11/xm_dd.c | 1 + src/mesa/vbo/vbo.h | 40 +++++++++++++++++++++++++++++++ src/mesa/vbo/vbo_context.c | 3 ++- src/mesa/vbo/vbo_context.h | 3 --- 12 files changed, 62 insertions(+), 22 deletions(-) create mode 100644 src/mesa/vbo/vbo.h (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i810/i810context.c b/src/mesa/drivers/dri/i810/i810context.c index c0f4efd7a3..db8f7a19a2 100644 --- a/src/mesa/drivers/dri/i810/i810context.c +++ b/src/mesa/drivers/dri/i810/i810context.c @@ -44,7 +44,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/t_pipeline.h" @@ -287,7 +287,7 @@ i810CreateContext( const __GLcontextModes *mesaVis, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -350,7 +350,7 @@ i810DestroyContext(__DRIcontextPrivate *driContextPriv) release_texture_heaps = (imesa->glCtx->Shared->RefCount == 1); _swsetup_DestroyContext( imesa->glCtx ); _tnl_DestroyContext( imesa->glCtx ); - _ac_DestroyContext( imesa->glCtx ); + _vbo_DestroyContext( imesa->glCtx ); _swrast_DestroyContext( imesa->glCtx ); i810FreeVB( imesa->glCtx ); diff --git a/src/mesa/drivers/dri/i810/i810state.c b/src/mesa/drivers/dri/i810/i810state.c index 6f9d4b5bd4..3ad25282d9 100644 --- a/src/mesa/drivers/dri/i810/i810state.c +++ b/src/mesa/drivers/dri/i810/i810state.c @@ -21,8 +21,8 @@ #include "i810ioctl.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" #include "tnl/tnl.h" +#include "vbo/vbo.h" #include "swrast_setup/swrast_setup.h" #include "tnl/t_pipeline.h" @@ -953,7 +953,7 @@ static void i810InvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); I810_CONTEXT(ctx)->new_state |= new_state; } diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c index 2f78fd60b2..6ec34e5bde 100644 --- a/src/mesa/drivers/dri/i915/i915_context.c +++ b/src/mesa/drivers/dri/i915/i915_context.c @@ -36,7 +36,8 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" + #include "utils.h" #include "i915_reg.h" @@ -63,7 +64,7 @@ static void i915InvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); _tnl_invalidate_vertex_state( ctx, new_state ); INTEL_CONTEXT(ctx)->NewGLState |= new_state; diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c index 4be95301c3..3d543b2485 100644 --- a/src/mesa/drivers/dri/i915/intel_context.c +++ b/src/mesa/drivers/dri/i915/intel_context.c @@ -37,7 +37,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/t_pipeline.h" #include "tnl/t_vertex.h" @@ -228,7 +228,7 @@ static void intelInvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); _tnl_invalidate_vertex_state( ctx, new_state ); INTEL_CONTEXT(ctx)->NewGLState |= new_state; @@ -305,7 +305,7 @@ GLboolean intelInitContext( intelContextPtr intel, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -424,7 +424,7 @@ void intelDestroyContext(__DRIcontextPrivate *driContextPriv) release_texture_heaps = (intel->ctx.Shared->RefCount == 1); _swsetup_DestroyContext (&intel->ctx); _tnl_DestroyContext (&intel->ctx); - _ac_DestroyContext (&intel->ctx); + _vbo_DestroyContext (&intel->ctx); _swrast_DestroyContext (&intel->ctx); intel->Fallback = 0; /* don't call _swrast_Flush later */ diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index 1137bfd2c7..e2279ca276 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -36,7 +36,6 @@ #include "intel_context.h" #include "brw_structs.h" #include "imports.h" -#include "brw_attrib.h" /* Glossary: diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 36edd7db7f..c4c5488cbb 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -37,7 +37,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/t_pipeline.h" #include "tnl/t_vertex.h" @@ -216,7 +216,7 @@ static void intelInvalidateState( GLcontext *ctx, GLuint new_state ) _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); _tnl_invalidate_vertex_state( ctx, new_state ); @@ -322,7 +322,7 @@ GLboolean intelInitContext( struct intel_context *intel, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -467,7 +467,7 @@ void intelDestroyContext(__DRIcontextPrivate *driContextPriv) release_texture_heaps = (intel->ctx.Shared->RefCount == 1); _swsetup_DestroyContext (&intel->ctx); _tnl_DestroyContext (&intel->ctx); - _ac_DestroyContext (&intel->ctx); + _vbo_DestroyContext (&intel->ctx); _swrast_DestroyContext (&intel->ctx); intel->Fallback = 0; /* don't call _swrast_Flush later */ diff --git a/src/mesa/drivers/osmesa/osmesa.c b/src/mesa/drivers/osmesa/osmesa.c index 42a1bb5123..c4fc8821e5 100644 --- a/src/mesa/drivers/osmesa/osmesa.c +++ b/src/mesa/drivers/osmesa/osmesa.c @@ -50,7 +50,7 @@ #include "tnl/t_context.h" #include "tnl/t_pipeline.h" #include "drivers/common/driverfuncs.h" -#include "vbo/vbo_context.h" +#include "vbo/vbo.h" @@ -111,6 +111,7 @@ osmesa_update_state( GLcontext *ctx, GLuint new_state ) _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); } diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c index 6fb0d9bbbd..98a68dd4f4 100644 --- a/src/mesa/drivers/x11/xm_api.c +++ b/src/mesa/drivers/x11/xm_api.c @@ -74,7 +74,7 @@ #include "renderbuffer.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "vbo/vbo_context.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" diff --git a/src/mesa/drivers/x11/xm_dd.c b/src/mesa/drivers/x11/xm_dd.c index 39cec1dc9f..87bd5e4a30 100644 --- a/src/mesa/drivers/x11/xm_dd.c +++ b/src/mesa/drivers/x11/xm_dd.c @@ -831,6 +831,7 @@ xmesa_update_state( GLcontext *ctx, GLbitfield new_state ) */ _swrast_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); if (ctx->DrawBuffer->Name != 0) diff --git a/src/mesa/vbo/vbo.h b/src/mesa/vbo/vbo.h new file mode 100644 index 0000000000..96b25f18ee --- /dev/null +++ b/src/mesa/vbo/vbo.h @@ -0,0 +1,40 @@ +/* + * mesa 3-D graphics library + * Version: 6.5 + * + * Copyright (C) 1999-2006 Brian Paul 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, 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 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 + * BRIAN PAUL 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. + */ + +/** + * \file vbo_context.h + * \brief VBO builder module datatypes and definitions. + * \author Keith Whitwell + */ + + +#ifndef _VBO_H +#define _VBO_H + +GLboolean _vbo_CreateContext( GLcontext *ctx ); +void _vbo_DestroyContext( GLcontext *ctx ); +void _vbo_InvalidateState( GLcontext *ctx, GLuint new_state ); + + +#endif diff --git a/src/mesa/vbo/vbo_context.c b/src/mesa/vbo/vbo_context.c index 29dfe09d99..5279b2e13c 100644 --- a/src/mesa/vbo/vbo_context.c +++ b/src/mesa/vbo/vbo_context.c @@ -26,6 +26,7 @@ */ #include "mtypes.h" +#include "vbo.h" #include "vbo_context.h" #include "imports.h" #include "api_arrayelt.h" @@ -210,7 +211,7 @@ GLboolean _vbo_CreateContext( GLcontext *ctx ) return GL_TRUE; } -void vbo_save_invalidate_state( GLcontext *ctx, GLuint new_state ) +void _vbo_InvalidateState( GLcontext *ctx, GLuint new_state ) { _ae_invalidate_state(ctx, new_state); } diff --git a/src/mesa/vbo/vbo_context.h b/src/mesa/vbo/vbo_context.h index a20bfbd518..982da00437 100644 --- a/src/mesa/vbo/vbo_context.h +++ b/src/mesa/vbo/vbo_context.h @@ -55,9 +55,6 @@ #include "vbo_save.h" #include "vbo_exec.h" -GLboolean _vbo_CreateContext( GLcontext *ctx ); -void _vbo_DestroyContext( GLcontext *ctx ); - struct vbo_context { struct gl_client_array legacy_currval[16]; -- cgit v1.2.3 From f2eb6434ab1cf72e938956c82d2f530368a6be4a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 31 Oct 2006 11:28:45 +0000 Subject: cleanup code, compiles with vbo changes --- src/mesa/drivers/dri/i965/Makefile | 1 - src/mesa/drivers/dri/i965/brw_clip.h | 2 +- src/mesa/drivers/dri/i965/brw_context.c | 2 - src/mesa/drivers/dri/i965/brw_context.h | 22 +- src/mesa/drivers/dri/i965/brw_draw.c | 72 ++---- src/mesa/drivers/dri/i965/brw_draw.h | 16 +- src/mesa/drivers/dri/i965/brw_draw_current.c | 103 -------- src/mesa/drivers/dri/i965/brw_draw_upload.c | 11 +- src/mesa/drivers/dri/i965/brw_fallback.c | 346 --------------------------- src/mesa/drivers/dri/i965/brw_metaops.c | 69 +++--- src/mesa/drivers/dri/i965/brw_vs.c | 5 +- src/mesa/drivers/dri/i965/brw_vs_constval.c | 7 +- src/mesa/drivers/dri/i965/brw_vs_emit.c | 4 +- src/mesa/drivers/dri/i965/brw_vs_tnl.c | 40 ++-- src/mesa/drivers/dri/i965/brw_vtbl.c | 10 +- 15 files changed, 98 insertions(+), 612 deletions(-) delete mode 100644 src/mesa/drivers/dri/i965/brw_draw_current.c (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile index 8ec422509f..02fb93486e 100644 --- a/src/mesa/drivers/dri/i965/Makefile +++ b/src/mesa/drivers/dri/i965/Makefile @@ -34,7 +34,6 @@ DRIVER_SOURCES = \ brw_context.c \ brw_curbe.c \ brw_draw.c \ - brw_draw_current.c \ brw_draw_upload.c \ brw_eu.c \ brw_eu_debug.c \ diff --git a/src/mesa/drivers/dri/i965/brw_clip.h b/src/mesa/drivers/dri/i965/brw_clip.h index c3967c8c61..49b2770a51 100644 --- a/src/mesa/drivers/dri/i965/brw_clip.h +++ b/src/mesa/drivers/dri/i965/brw_clip.h @@ -116,7 +116,7 @@ struct brw_clip_compile { GLuint last_mrf; GLuint header_position_offset; - GLuint offset[BRW_ATTRIB_MAX]; + GLuint offset[VERT_ATTRIB_MAX]; }; #define ATTR_SIZE (4*4) diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c index b9256d5185..263110bf5e 100644 --- a/src/mesa/drivers/dri/i965/brw_context.c +++ b/src/mesa/drivers/dri/i965/brw_context.c @@ -34,8 +34,6 @@ #include "brw_aub.h" #include "brw_defines.h" #include "brw_draw.h" -#include "brw_exec.h" -#include "brw_save.h" #include "brw_vs.h" #include "imports.h" #include "intel_tex.h" diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index e2279ca276..0a61926ee8 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -214,7 +214,7 @@ struct brw_vs_prog_data { GLuint total_grf; GLuint outputs_written; - GLuint64EXT inputs_read; + GLuint inputs_read; /* Used for calculating urb partitions: */ @@ -381,10 +381,10 @@ struct brw_cached_batch_item { -/* Protect against a future where BRW_ATTRIB_MAX > 32. Wouldn't life +/* Protect against a future where VERT_ATTRIB_MAX > 32. Wouldn't life * be easier if C allowed arrays of packed elements? */ -#define ATTRIB_BIT_DWORDS ((BRW_ATTRIB_MAX+31)/32) +#define ATTRIB_BIT_DWORDS ((VERT_ATTRIB_MAX+31)/32) struct brw_vertex_element { const struct gl_client_array *glarray; @@ -400,8 +400,8 @@ struct brw_vertex_element { struct brw_vertex_info { - GLuint64EXT varying; /* varying:1[BRW_ATTRIB_MAX] */ - GLuint sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[BRW_ATTRIB_MAX] */ + GLuint varying; /* varying:1[VERT_ATTRIB_MAX] */ + GLuint sizes[ATTRIB_BIT_DWORDS * 2]; /* sizes:2[VERT_ATTRIB_MAX] */ }; @@ -448,14 +448,13 @@ struct brw_context struct brw_cached_batch_item *cached_batch_items; struct { - /* Fallback values for inputs not supplied: - */ - struct gl_client_array current_values[BRW_ATTRIB_MAX]; /* Arrays with buffer objects to copy non-bufferobj arrays into * for upload: */ - struct gl_client_array vbo_array[BRW_ATTRIB_MAX]; + struct gl_client_array vbo_array[VERT_ATTRIB_MAX]; + + struct brw_vertex_element inputs[VERT_ATTRIB_MAX]; #define BRW_NR_UPLOAD_BUFS 17 #define BRW_UPLOAD_INIT_SIZE (128*1024) @@ -468,11 +467,6 @@ struct brw_context GLuint wrap; } upload; - /* Currenly bound arrays, including fallbacks to current_values - * above: - */ - struct brw_vertex_element inputs[BRW_ATTRIB_MAX]; - /* Summary of size and varying of active arrays, so we can check * for changes to this state: */ diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index 1bc39762bc..63cb079ec9 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -35,7 +35,6 @@ #include "brw_draw.h" #include "brw_defines.h" -#include "brw_attrib.h" #include "brw_context.h" #include "brw_aub.h" #include "brw_state.h" @@ -45,7 +44,8 @@ #include "intel_batchbuffer.h" #include "intel_buffer_objects.h" - +#include "tnl/tnl.h" +#include "vbo/vbo_context.h" @@ -143,7 +143,7 @@ static void brw_emit_cliprect( struct brw_context *brw, static void brw_emit_prim( struct brw_context *brw, - const struct vbo_prim *prim ) + const struct _mesa_prim *prim ) { struct brw_3d_primitive prim_packet; @@ -170,34 +170,9 @@ static void brw_emit_prim( struct brw_context *brw, } } - - -static void update_current_size( struct gl_client_array *array) -{ - const GLfloat *ptr = (const GLfloat *)array->Ptr; - - assert(array->StrideB == 0); - assert(array->Type == GL_FLOAT || array->Type == GL_UNSIGNED_BYTE); - - if (ptr[3] != 1.0) - array->Size = 4; - else if (ptr[2] != 0.0) - array->Size = 3; - else if (ptr[1] != 0.0) - array->Size = 2; - else - array->Size = 1; -} - - - -/* Fill in any gaps in passed arrays with pointers to current - * attributes: - */ static void brw_merge_inputs( struct brw_context *brw, const struct gl_client_array *arrays[]) { - struct gl_client_array *current_values = brw->vb.current_values; struct brw_vertex_element *inputs = brw->vb.inputs; struct brw_vertex_info old = brw->vb.info; GLuint i; @@ -205,17 +180,11 @@ static void brw_merge_inputs( struct brw_context *brw, memset(inputs, 0, sizeof(*inputs)); memset(&brw->vb.info, 0, sizeof(brw->vb.info)); - for (i = 0; i < BRW_ATTRIB_MAX; i++) { - if (arrays[i] && arrays[i]->Enabled) - { - brw->vb.inputs[i].glarray = arrays[i]; + for (i = 0; i < VERT_ATTRIB_MAX; i++) { + brw->vb.inputs[i].glarray = arrays[i]; + + if (arrays[i]->StrideB != 0) brw->vb.info.varying |= 1 << i; - } - else - { - brw->vb.inputs[i].glarray = ¤t_values[i]; - update_current_size(¤t_values[i]); - } brw->vb.info.sizes[i/16] |= (inputs[i].glarray->Size - 1) << ((i%16) * 2); } @@ -229,8 +198,9 @@ static void brw_merge_inputs( struct brw_context *brw, brw->state.dirty.brw |= BRW_NEW_INPUT_VARYING; } + static GLboolean check_fallbacks( struct brw_context *brw, - const struct vbo_prim *prim, + const struct _mesa_prim *prim, GLuint nr_prims ) { GLuint i; @@ -284,7 +254,7 @@ static GLboolean check_fallbacks( struct brw_context *brw, static GLboolean brw_try_draw_prims( GLcontext *ctx, const struct gl_client_array *arrays[], - const struct vbo_prim *prim, + const struct _mesa_prim *prim, GLuint nr_prims, const struct _mesa_index_buffer *ib, GLuint min_index, @@ -297,11 +267,11 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, if (ctx->NewState) _mesa_update_state( ctx ); - + /* Bind all inputs, derive varying and size information: */ brw_merge_inputs( brw, arrays ); - + /* Have to validate state quite late. Will rebuild tnl_program, * which depends on varying information. * @@ -318,10 +288,6 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, } { - assert(intel->locked); - - - /* Set the first primitive early, ahead of validate_state: */ brw_set_prim(brw, prim[0].mode); @@ -413,7 +379,7 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, void brw_draw_prims( GLcontext *ctx, const struct gl_client_array *arrays[], - const struct vbo_prim *prim, + const struct _mesa_prim *prim, GLuint nr_prims, const struct _mesa_index_buffer *ib, GLuint min_index, @@ -430,7 +396,7 @@ void brw_draw_prims( GLcontext *ctx, * fragmented. Clear out all heaps and start from scratch by * faking a contended lock event: (done elsewhere) */ - if (!retval && bmError(intel)) { + if (!retval && !intel->Fallback && bmError(intel)) { DBG("retrying\n"); /* Then try a second time only to upload textures and draw the * primitives: @@ -443,9 +409,7 @@ void brw_draw_prims( GLcontext *ctx, * swrast to do the drawing. */ if (!retval) { - brw_fallback(); _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); - brw_unfallback(); } if (intel->aub_file && (INTEL_DEBUG & DEBUG_SYNC)) { @@ -464,8 +428,13 @@ static void brw_invalidate_vbo_cb( struct intel_context *intel, void *ptr ) void brw_draw_init( struct brw_context *brw ) { GLcontext *ctx = &brw->intel.ctx; + struct vbo_context *vbo = vbo_context(ctx); GLuint i; + /* Register our drawing function: + */ + vbo->draw_prims = brw_draw_prims; + brw->vb.upload.size = BRW_UPLOAD_INIT_SIZE; for (i = 0; i < BRW_NR_UPLOAD_BUFS; i++) { @@ -487,9 +456,6 @@ void brw_draw_init( struct brw_context *brw ) NULL, GL_DYNAMIC_DRAW_ARB, brw->vb.upload.vbo[0] ); - - - brw_init_current_values(ctx, brw->vb.current_values); } void brw_draw_destroy( struct brw_context *brw ) diff --git a/src/mesa/drivers/dri/i965/brw_draw.h b/src/mesa/drivers/dri/i965/brw_draw.h index b68cd86115..0f7b738310 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.h +++ b/src/mesa/drivers/dri/i965/brw_draw.h @@ -29,18 +29,18 @@ #define BRW_DRAW_H #include "mtypes.h" /* for GLcontext... */ -#include "brw_attrib.h" +#include "vbo/vbo.h" struct brw_context; -GLboolean brw_draw_prims( GLcontext *ctx, - const struct gl_client_array *arrays[], - const struct vbo_prim *prims, - GLuint nr_prims, - const struct _mesa_index_buffer *ib, - GLuint min_index, - GLuint max_index ); +void brw_draw_prims( GLcontext *ctx, + const struct gl_client_array *arrays[], + const struct _mesa_prim *prims, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLuint min_index, + GLuint max_index ); void brw_draw_init( struct brw_context *brw ); void brw_draw_destroy( struct brw_context *brw ); diff --git a/src/mesa/drivers/dri/i965/brw_draw_current.c b/src/mesa/drivers/dri/i965/brw_draw_current.c deleted file mode 100644 index 98d930738e..0000000000 --- a/src/mesa/drivers/dri/i965/brw_draw_current.c +++ /dev/null @@ -1,103 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * 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 TUNGSTEN 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 - -#include "glheader.h" -#include "context.h" -#include "state.h" -#include "api_validate.h" -#include "enums.h" - -#include "brw_context.h" -#include "brw_draw.h" - -#include "bufmgr.h" -#include "intel_buffer_objects.h" - - -void brw_init_current_values(GLcontext *ctx, - struct gl_client_array *arrays) -{ - GLuint i; - - memset(arrays, 0, sizeof(*arrays) * BRW_ATTRIB_MAX); - - /* Set up a constant (StrideB == 0) array for each current - * attribute: - */ - for (i = 0; i < BRW_ATTRIB_MAX; i++) { - struct gl_client_array *cl = &arrays[i]; - - switch (i) { - case BRW_ATTRIB_MAT_FRONT_SHININESS: - case BRW_ATTRIB_MAT_BACK_SHININESS: - case BRW_ATTRIB_INDEX: - case BRW_ATTRIB_EDGEFLAG: - cl->Size = 1; - break; - case BRW_ATTRIB_MAT_FRONT_INDEXES: - case BRW_ATTRIB_MAT_BACK_INDEXES: - cl->Size = 3; - break; - default: - /* This is fixed for the material attributes, for others will - * be determined at runtime: - */ - if (i >= BRW_ATTRIB_MAT_FRONT_AMBIENT) - cl->Size = 4; - else - cl->Size = 1; - break; - } - - switch (i) { - case BRW_ATTRIB_EDGEFLAG: - cl->Type = GL_UNSIGNED_BYTE; - cl->Ptr = (const void *)&ctx->Current.EdgeFlag; - break; - case BRW_ATTRIB_INDEX: - cl->Type = GL_FLOAT; - cl->Ptr = (const void *)&ctx->Current.Index; - break; - default: - cl->Type = GL_FLOAT; - if (i < BRW_ATTRIB_FIRST_MATERIAL) - cl->Ptr = (const void *)ctx->Current.Attrib[i]; - else - cl->Ptr = (const void *)ctx->Light.Material.Attrib[i - BRW_ATTRIB_FIRST_MATERIAL]; - break; - } - - cl->Stride = 0; - cl->StrideB = 0; - cl->Enabled = 1; - cl->Flags = 0; - cl->BufferObj = ctx->Array.NullBufferObj; - } -} - diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 4d930c6c9e..dfb598acdf 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -35,7 +35,6 @@ #include "brw_draw.h" #include "brw_defines.h" -#include "brw_attrib.h" #include "brw_context.h" #include "brw_aub.h" #include "brw_state.h" @@ -337,7 +336,6 @@ copy_array_to_vbo_array( struct brw_context *brw, vbo_array->Enabled = 1; vbo_array->Normalized = array->Normalized; vbo_array->_MaxElement = array->_MaxElement; /* ? */ - vbo_array->Flags = array->Flags; /* ? */ vbo_array->BufferObj = vbo; { @@ -380,7 +378,6 @@ interleaved_vbo_array( struct brw_context *brw, vbo_array->Enabled = 1; vbo_array->Normalized = array->Normalized; vbo_array->_MaxElement = array->_MaxElement; - vbo_array->Flags = array->Flags; /* ? */ vbo_array->BufferObj = uploaded_array->BufferObj; return vbo_array; @@ -400,10 +397,10 @@ GLboolean brw_upload_vertices( struct brw_context *brw, const void *ptr = NULL; GLuint interleave = 0; - struct brw_vertex_element *enabled[BRW_ATTRIB_MAX]; + struct brw_vertex_element *enabled[VERT_ATTRIB_MAX]; GLuint nr_enabled = 0; - struct brw_vertex_element *upload[BRW_ATTRIB_MAX]; + struct brw_vertex_element *upload[VERT_ATTRIB_MAX]; GLuint nr_uploads = 0; @@ -568,7 +565,7 @@ static GLuint element_size( GLenum type ) static void rebase_indices_to_vbo_indices( struct brw_context *brw, - const struct vbo_index_buffer *index_buffer, + const struct _mesa_index_buffer *index_buffer, struct gl_buffer_object **vbo_return, GLuint *offset_return ) { @@ -642,7 +639,7 @@ static void rebase_indices_to_vbo_indices( struct brw_context *brw, void brw_upload_indices( struct brw_context *brw, - const struct vbo_index_buffer *index_buffer) + const struct _mesa_index_buffer *index_buffer) { struct intel_context *intel = &brw->intel; GLuint ib_size = get_size(index_buffer->type) * index_buffer->count; diff --git a/src/mesa/drivers/dri/i965/brw_fallback.c b/src/mesa/drivers/dri/i965/brw_fallback.c index aab30b6863..86464b2ec5 100644 --- a/src/mesa/drivers/dri/i965/brw_fallback.c +++ b/src/mesa/drivers/dri/i965/brw_fallback.c @@ -30,8 +30,6 @@ #include "tnl/tnl.h" #include "context.h" #include "brw_context.h" -#include "brw_exec.h" -#include "brw_save.h" #include "brw_fallback.h" #include "glheader.h" @@ -40,294 +38,6 @@ #include "imports.h" #include "macros.h" #include "mtypes.h" -#include "dispatch.h" - - -typedef void (*attr_func)( GLcontext *ctx, GLint target, const GLfloat * ); - - -/* Wrapper functions in case glVertexAttrib*fvNV doesn't exist */ -static void VertexAttrib1fvNV(GLcontext *ctx, GLint target, const GLfloat *v) -{ - CALL_VertexAttrib1fvNV(ctx->Exec, (target, v)); -} - -static void VertexAttrib2fvNV(GLcontext *ctx, GLint target, const GLfloat *v) -{ - CALL_VertexAttrib2fvNV(ctx->Exec, (target, v)); -} - -static void VertexAttrib3fvNV(GLcontext *ctx, GLint target, const GLfloat *v) -{ - CALL_VertexAttrib3fvNV(ctx->Exec, (target, v)); -} - -static void VertexAttrib4fvNV(GLcontext *ctx, GLint target, const GLfloat *v) -{ - CALL_VertexAttrib4fvNV(ctx->Exec, (target, v)); -} - -static attr_func vert_attrfunc[4] = { - VertexAttrib1fvNV, - VertexAttrib2fvNV, - VertexAttrib3fvNV, - VertexAttrib4fvNV -}; - -#if 0 -static void VertexAttrib1fvARB(GLcontext *ctx, GLint target, const GLfloat *v) -{ - CALL_VertexAttrib1fvARB(ctx->Exec, (target, v)); -} - -static void VertexAttrib2fvARB(GLcontext *ctx, GLint target, const GLfloat *v) -{ - CALL_VertexAttrib2fvARB(ctx->Exec, (target, v)); -} - -static void VertexAttrib3fvARB(GLcontext *ctx, GLint target, const GLfloat *v) -{ - CALL_VertexAttrib3fvARB(ctx->Exec, (target, v)); -} - -static void VertexAttrib4fvARB(GLcontext *ctx, GLint target, const GLfloat *v) -{ - CALL_VertexAttrib4fvARB(ctx->Exec, (target, v)); -} - - -static attr_func vert_attrfunc_arb[4] = { - VertexAttrib1fvARB, - VertexAttrib2fvARB, - VertexAttrib3fvARB, - VertexAttrib4fvARB -}; -#endif - - - - - - -static void mat_attr1fv( GLcontext *ctx, GLint target, const GLfloat *v ) -{ - switch (target) { - case BRW_ATTRIB_MAT_FRONT_SHININESS: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_SHININESS, v )); - break; - case BRW_ATTRIB_MAT_BACK_SHININESS: - CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_SHININESS, v )); - break; - } -} - - -static void mat_attr3fv( GLcontext *ctx, GLint target, const GLfloat *v ) -{ - switch (target) { - case BRW_ATTRIB_MAT_FRONT_INDEXES: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_COLOR_INDEXES, v )); - break; - case BRW_ATTRIB_MAT_BACK_INDEXES: - CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_COLOR_INDEXES, v )); - break; - } -} - - -static void mat_attr4fv( GLcontext *ctx, GLint target, const GLfloat *v ) -{ - switch (target) { - case BRW_ATTRIB_MAT_FRONT_EMISSION: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_EMISSION, v )); - break; - case BRW_ATTRIB_MAT_BACK_EMISSION: - CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_EMISSION, v )); - break; - case BRW_ATTRIB_MAT_FRONT_AMBIENT: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_AMBIENT, v )); - break; - case BRW_ATTRIB_MAT_BACK_AMBIENT: - CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_AMBIENT, v )); - break; - case BRW_ATTRIB_MAT_FRONT_DIFFUSE: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_DIFFUSE, v )); - break; - case BRW_ATTRIB_MAT_BACK_DIFFUSE: - CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_DIFFUSE, v )); - break; - case BRW_ATTRIB_MAT_FRONT_SPECULAR: - CALL_Materialfv(ctx->Exec, ( GL_FRONT, GL_SPECULAR, v )); - break; - case BRW_ATTRIB_MAT_BACK_SPECULAR: - CALL_Materialfv(ctx->Exec, ( GL_BACK, GL_SPECULAR, v )); - break; - } -} - - -static attr_func mat_attrfunc[4] = { - mat_attr1fv, - NULL, - mat_attr3fv, - mat_attr4fv -}; - - -static void index_attr1fv(GLcontext *ctx, GLint target, const GLfloat *v) -{ - (void) target; - CALL_Indexf(ctx->Exec, (v[0])); -} - -static void edgeflag_attr1fv(GLcontext *ctx, GLint target, const GLfloat *v) -{ - (void) target; - CALL_EdgeFlag(ctx->Exec, ((GLboolean)(v[0] == 1.0))); -} - -struct loopback_attr { - GLint target; - GLint sz; - attr_func func; -}; - -/* Don't emit ends and begins on wrapped primitives. Don't replay - * wrapped vertices. If we get here, it's probably because the the - * precalculated wrapping is wrong. - */ -static void loopback_prim( GLcontext *ctx, - const GLfloat *buffer, - const struct vbo_prim *prim, - GLuint wrap_count, - GLuint vertex_size, - const struct loopback_attr *la, GLuint nr ) -{ - GLint start = prim->start; - GLint end = start + prim->count; - const GLfloat *data; - GLint j; - GLuint k; - - if (0) - _mesa_printf("loopback prim %s(%s,%s) verts %d..%d\n", - _mesa_lookup_enum_by_nr(prim->mode), - prim->begin ? "begin" : "..", - prim->end ? "end" : "..", - start, - end); - - if (prim->begin) { - CALL_Begin(GET_DISPATCH(), ( prim->mode )); - } - else { - assert(start == 0); - start += wrap_count; - } - - data = buffer + start * vertex_size; - - for (j = start ; j < end ; j++) { - const GLfloat *tmp = data + la[0].sz; - - for (k = 1 ; k < nr ; k++) { - la[k].func( ctx, la[k].target, tmp ); - tmp += la[k].sz; - } - - /* Fire the vertex - */ - la[0].func( ctx, BRW_ATTRIB_POS, data ); - data = tmp; - } - - if (prim->end) { - CALL_End(GET_DISPATCH(), ()); - } -} - -/* Primitives generated by DrawArrays/DrawElements/Rectf may be - * caught here. If there is no primitive in progress, execute them - * normally, otherwise need to track and discard the generated - * primitives. - */ -static void loopback_weak_prim( GLcontext *ctx, - const struct vbo_prim *prim ) -{ - /* Use the prim_weak flag to ensure that if this primitive - * wraps, we don't mistake future vertex_lists for part of the - * surrounding primitive. - * - * While this flag is set, we are simply disposing of data - * generated by an operation now known to be a noop. - */ - if (prim->begin) - ctx->Driver.CurrentExecPrimitive |= BRW_SAVE_PRIM_WEAK; - if (prim->end) - ctx->Driver.CurrentExecPrimitive &= ~BRW_SAVE_PRIM_WEAK; -} - - -void brw_loopback_vertex_list( GLcontext *ctx, - const GLfloat *buffer, - const GLubyte *attrsz, - const struct vbo_prim *prim, - GLuint prim_count, - GLuint wrap_count, - GLuint vertex_size) -{ - struct loopback_attr la[BRW_ATTRIB_MAX]; - GLuint i, nr = 0; - - for (i = 0 ; i <= BRW_ATTRIB_TEX7 ; i++) { - if (attrsz[i]) { - la[nr].target = i; - la[nr].sz = attrsz[i]; - la[nr].func = vert_attrfunc[attrsz[i]-1]; - nr++; - } - } - - for (i = BRW_ATTRIB_MAT_FRONT_AMBIENT ; - i <= BRW_ATTRIB_MAT_BACK_INDEXES ; - i++) { - if (attrsz[i]) { - la[nr].target = i; - la[nr].sz = attrsz[i]; - la[nr].func = mat_attrfunc[attrsz[i]-1]; - nr++; - } - } - - if (attrsz[BRW_ATTRIB_EDGEFLAG]) { - la[nr].target = BRW_ATTRIB_EDGEFLAG; - la[nr].sz = attrsz[BRW_ATTRIB_EDGEFLAG]; - la[nr].func = edgeflag_attr1fv; - nr++; - } - - if (attrsz[BRW_ATTRIB_INDEX]) { - la[nr].target = BRW_ATTRIB_INDEX; - la[nr].sz = attrsz[BRW_ATTRIB_INDEX]; - la[nr].func = index_attr1fv; - nr++; - } - - /* XXX ARB vertex attribs */ - - for (i = 0 ; i < prim_count ; i++) { - if ((prim[i].mode & BRW_SAVE_PRIM_WEAK) && - (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END)) - { - loopback_weak_prim( ctx, &prim[i] ); - } - else - { - loopback_prim( ctx, buffer, &prim[i], wrap_count, vertex_size, la, nr ); - } - } -} - @@ -402,62 +112,6 @@ const struct brw_tracked_state brw_check_fallback = { -/* If there is a fallback, fallback to software rasterization and - * transformation together. There is never a requirement to have - * software t&l but hardware rasterization. - * - * Further, all fallbacks are based on GL state, not on eg. primitive - * or vertex data. - */ - -static void do_fallback( struct brw_context *brw, - GLboolean fallback ) -{ - GLcontext *ctx = &brw->intel.ctx; - - /* flush: - */ - ctx->Driver.Flush( ctx ); - - if (fallback) { - _swsetup_Wakeup( ctx ); - _tnl_wakeup_exec( ctx ); - - /* Need this because tnl_wakeup_exec does too much: - */ - brw_save_wakeup(ctx); - brw_save_fallback(ctx, GL_TRUE); - } - else { - /* Flush vertices and copy-to-current: - */ - FLUSH_CURRENT(ctx, 0); - - _swrast_flush( ctx ); - - brw_exec_wakeup(ctx); - - /* Need this because tnl_wakeup_exec does too much: - */ - brw_save_wakeup(ctx); - brw_save_fallback(ctx, GL_FALSE); - } -} - - -void brw_fallback( GLcontext *ctx ) -{ - struct brw_context *brw = brw_context(ctx); - do_fallback(brw, 1); -} - - -void brw_unfallback( GLcontext *ctx ) -{ - struct brw_context *brw = brw_context(ctx); - do_fallback(brw, 0); -} - /* Not used: */ void intelFallback( struct intel_context *intel, GLuint bit, GLboolean mode ) diff --git a/src/mesa/drivers/dri/i965/brw_metaops.c b/src/mesa/drivers/dri/i965/brw_metaops.c index d8b6069cfc..2d4c84f612 100644 --- a/src/mesa/drivers/dri/i965/brw_metaops.c +++ b/src/mesa/drivers/dri/i965/brw_metaops.c @@ -46,7 +46,6 @@ #include "brw_context.h" #include "brw_defines.h" #include "brw_draw.h" -#include "brw_attrib.h" #include "brw_fallback.h" #define INIT(brw, STRUCT, ATTRIB) \ @@ -302,8 +301,8 @@ static void meta_draw_quad(struct intel_context *intel, struct brw_context *brw = brw_context(&intel->ctx); struct gl_client_array pos_array; struct gl_client_array color_array; - struct gl_client_array *attribs[BRW_ATTRIB_MAX]; - struct vbo_prim prim[1]; + struct gl_client_array *attribs[VERT_ATTRIB_MAX]; + struct _mesa_prim prim[1]; GLfloat pos[4][3]; GLubyte color[4]; @@ -353,29 +352,29 @@ static void meta_draw_quad(struct intel_context *intel, /* Ignoring texture coords. */ - memset(attribs, 0, BRW_ATTRIB_MAX * sizeof(*attribs)); - - attribs[BRW_ATTRIB_POS] = &pos_array; - attribs[BRW_ATTRIB_POS]->Ptr = 0; - attribs[BRW_ATTRIB_POS]->Type = GL_FLOAT; - attribs[BRW_ATTRIB_POS]->Enabled = 1; - attribs[BRW_ATTRIB_POS]->Size = 3; - attribs[BRW_ATTRIB_POS]->StrideB = 3 * sizeof(GLfloat); - attribs[BRW_ATTRIB_POS]->Stride = 3 * sizeof(GLfloat); - attribs[BRW_ATTRIB_POS]->_MaxElement = 4; - attribs[BRW_ATTRIB_POS]->Normalized = 0; - attribs[BRW_ATTRIB_POS]->BufferObj = brw->metaops.vbo; - - attribs[BRW_ATTRIB_COLOR0] = &color_array; - attribs[BRW_ATTRIB_COLOR0]->Ptr = (const GLubyte *)sizeof(pos); - attribs[BRW_ATTRIB_COLOR0]->Type = GL_UNSIGNED_BYTE; - attribs[BRW_ATTRIB_COLOR0]->Enabled = 1; - attribs[BRW_ATTRIB_COLOR0]->Size = 4; - attribs[BRW_ATTRIB_COLOR0]->StrideB = 0; - attribs[BRW_ATTRIB_COLOR0]->Stride = 0; - attribs[BRW_ATTRIB_COLOR0]->_MaxElement = 1; - attribs[BRW_ATTRIB_COLOR0]->Normalized = 1; - attribs[BRW_ATTRIB_COLOR0]->BufferObj = brw->metaops.vbo; + memset(attribs, 0, VERT_ATTRIB_MAX * sizeof(*attribs)); + + attribs[VERT_ATTRIB_POS] = &pos_array; + attribs[VERT_ATTRIB_POS]->Ptr = 0; + attribs[VERT_ATTRIB_POS]->Type = GL_FLOAT; + attribs[VERT_ATTRIB_POS]->Enabled = 1; + attribs[VERT_ATTRIB_POS]->Size = 3; + attribs[VERT_ATTRIB_POS]->StrideB = 3 * sizeof(GLfloat); + attribs[VERT_ATTRIB_POS]->Stride = 3 * sizeof(GLfloat); + attribs[VERT_ATTRIB_POS]->_MaxElement = 4; + attribs[VERT_ATTRIB_POS]->Normalized = 0; + attribs[VERT_ATTRIB_POS]->BufferObj = brw->metaops.vbo; + + attribs[VERT_ATTRIB_COLOR0] = &color_array; + attribs[VERT_ATTRIB_COLOR0]->Ptr = (const GLubyte *)sizeof(pos); + attribs[VERT_ATTRIB_COLOR0]->Type = GL_UNSIGNED_BYTE; + attribs[VERT_ATTRIB_COLOR0]->Enabled = 1; + attribs[VERT_ATTRIB_COLOR0]->Size = 4; + attribs[VERT_ATTRIB_COLOR0]->StrideB = 0; + attribs[VERT_ATTRIB_COLOR0]->Stride = 0; + attribs[VERT_ATTRIB_COLOR0]->_MaxElement = 1; + attribs[VERT_ATTRIB_COLOR0]->Normalized = 1; + attribs[VERT_ATTRIB_COLOR0]->BufferObj = brw->metaops.vbo; /* Just ignoring texture coordinates for now. */ @@ -390,18 +389,12 @@ static void meta_draw_quad(struct intel_context *intel, prim[0].start = 0; prim[0].count = 4; - if (!brw_draw_prims(&brw->intel.ctx, - (const struct gl_client_array **)attribs, - prim, 1, - NULL, - 0, - 4 )) - { - /* This should not be possible: - */ - _mesa_printf("brw_draw_prims failed in metaops!\n"); - assert(0); - } + brw_draw_prims(&brw->intel.ctx, + (const struct gl_client_array **)attribs, + prim, 1, + NULL, + 0, + 4 ); } diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c index e5a28b96e3..74c9d88e46 100644 --- a/src/mesa/drivers/dri/i965/brw_vs.c +++ b/src/mesa/drivers/dri/i965/brw_vs.c @@ -54,12 +54,11 @@ static void do_vs_prog( struct brw_context *brw, c.vp = vp; c.prog_data.outputs_written = vp->program.Base.OutputsWritten; - c.prog_data.inputs_read = brw_translate_inputs(brw->intel.ctx.VertexProgram._Enabled, - vp->program.Base.InputsRead); + c.prog_data.inputs_read = vp->program.Base.InputsRead; if (c.key.copy_edgeflag) { c.prog_data.outputs_written |= 1<vb.info.sizes[attr/16]; GLuint sizes_bits = (sizes_dword>>((attr%16)*2)) & 0x3; return sizes_bits + 1; +/* return brw->vb.inputs[attr].glarray->Size; */ } /* Calculate sizes of vertex program outputs. Size is the largest @@ -176,8 +177,6 @@ static void calc_wm_input_sizes( struct brw_context *brw ) struct tracker t; GLuint insn; GLuint i; - GLuint64EXT inputs = brw_translate_inputs(brw->intel.ctx.VertexProgram._Enabled, - vp->program.Base.InputsRead); memset(&t, 0, sizeof(t)); @@ -185,8 +184,8 @@ static void calc_wm_input_sizes( struct brw_context *brw ) if (brw->attribs.Light->Model.TwoSide) t.twoside = 1; - for (i = 0; i < BRW_ATTRIB_MAX; i++) - if (inputs & (1<program.Base.InputsRead & (1<nr_inputs = 0; - for (i = 0; i < BRW_ATTRIB_MAX; i++) { + for (i = 0; i < VERT_ATTRIB_MAX; i++) { if (c->prog_data.inputs_read & (1<nr_inputs++; c->regs[PROGRAM_INPUT][i] = brw_vec8_grf(reg, 0); @@ -791,7 +791,7 @@ static void emit_vertex_write( struct brw_vs_compile *c) if (c->key.copy_edgeflag) { brw_MOV(p, get_reg(c, PROGRAM_OUTPUT, VERT_RESULT_EDGE), - get_reg(c, PROGRAM_INPUT, BRW_ATTRIB_EDGEFLAG)); + get_reg(c, PROGRAM_INPUT, VERT_ATTRIB_EDGEFLAG)); } diff --git a/src/mesa/drivers/dri/i965/brw_vs_tnl.c b/src/mesa/drivers/dri/i965/brw_vs_tnl.c index 1df111f645..dc580998e3 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_tnl.c +++ b/src/mesa/drivers/dri/i965/brw_vs_tnl.c @@ -146,9 +146,13 @@ static void make_state_key( GLcontext *ctx, struct state_key *key ) } /* BRW_NEW_INPUT_VARYING */ - for (i = BRW_ATTRIB_MAT_FRONT_AMBIENT ; i < BRW_ATTRIB_INDEX ; i++) - if (brw->vb.info.varying & (1<light_material_mask |= 1<<(i-BRW_ATTRIB_MAT_FRONT_AMBIENT); + + /* For these programs, material values are stuffed into the + * generic slots: + */ + for (i = 0 ; i < MAT_ATTRIB_MAX ; i++) + if (brw->vb.info.varying & (1<<(VERT_ATTRIB_GENERIC0 + i))) + key->light_material_mask |= 1<attribs.Light->Light[i]; @@ -374,12 +378,6 @@ static void release_temps( struct tnl_program *p ) static struct ureg register_input( struct tnl_program *p, GLuint input ) { - /* Cram the material flags into the generic range. We'll translate - * them back later. - */ - if (input >= BRW_ATTRIB_MAT_FRONT_AMBIENT) - input -= BRW_ATTRIB_MAT_FRONT_AMBIENT; - assert(input < 32); p->program->Base.InputsRead |= (1<eye_position)) { - struct ureg pos = register_input( p, BRW_ATTRIB_POS ); + struct ureg pos = register_input( p, VERT_ATTRIB_POS ); struct ureg modelview[4]; p->eye_position = reserve_temp(p); @@ -709,7 +707,7 @@ static struct ureg get_eye_position_normalized( struct tnl_program *p ) static struct ureg get_eye_normal( struct tnl_program *p ) { if (is_undef(p->eye_normal)) { - struct ureg normal = register_input(p, BRW_ATTRIB_NORMAL ); + struct ureg normal = register_input(p, VERT_ATTRIB_NORMAL ); struct ureg mvinv[3]; register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 2, @@ -742,7 +740,7 @@ static struct ureg get_eye_normal( struct tnl_program *p ) static void build_hpos( struct tnl_program *p ) { - struct ureg pos = register_input( p, BRW_ATTRIB_POS ); + struct ureg pos = register_input( p, VERT_ATTRIB_POS ); struct ureg hpos = register_output( p, VERT_RESULT_HPOS ); struct ureg mvp[4]; @@ -786,9 +784,9 @@ static struct ureg get_material( struct tnl_program *p, GLuint side, GLuint attrib = material_attrib(side, property); if (p->color_materials & (1<materials & (1<state->fog_option && @@ -1298,7 +1296,7 @@ static void build_texture_transform( struct tnl_program *p ) for (j = 0; j < 4; j++) { switch (modes[j]) { case TXG_OBJ_LINEAR: { - struct ureg obj = register_input(p, BRW_ATTRIB_POS); + struct ureg obj = register_input(p, VERT_ATTRIB_POS); struct ureg plane = register_param3(p, STATE_TEXGEN, i, STATE_TEXGEN_OBJECT_S + j); @@ -1347,7 +1345,7 @@ static void build_texture_transform( struct tnl_program *p ) } if (copy_mask) { - struct ureg in = register_input(p, BRW_ATTRIB_TEX0+i); + struct ureg in = register_input(p, VERT_ATTRIB_TEX0+i); emit_op1(p, OPCODE_MOV, out_texgen, copy_mask, in ); } } @@ -1356,7 +1354,7 @@ static void build_texture_transform( struct tnl_program *p ) struct ureg texmat[4]; struct ureg in = (!is_undef(out_texgen) ? out_texgen : - register_input(p, BRW_ATTRIB_TEX0+i)); + register_input(p, VERT_ATTRIB_TEX0+i)); if (PREFER_DP4) { register_matrix_param6( p, STATE_MATRIX, STATE_TEXTURE, i, 0, 3, STATE_MATRIX, texmat ); @@ -1372,7 +1370,7 @@ static void build_texture_transform( struct tnl_program *p ) release_temps(p); } else { - emit_passthrough(p, BRW_ATTRIB_TEX0+i, VERT_RESULT_TEX0+i); + emit_passthrough(p, VERT_ATTRIB_TEX0+i, VERT_RESULT_TEX0+i); } } } @@ -1424,10 +1422,10 @@ static void build_tnl_program( struct tnl_program *p ) build_lighting(p); else { if (p->state->fragprog_inputs_read & FRAG_BIT_COL0) - emit_passthrough(p, BRW_ATTRIB_COLOR0, VERT_RESULT_COL0); + emit_passthrough(p, VERT_ATTRIB_COLOR0, VERT_RESULT_COL0); if (p->state->fragprog_inputs_read & FRAG_BIT_COL1) - emit_passthrough(p, BRW_ATTRIB_COLOR1, VERT_RESULT_COL1); + emit_passthrough(p, VERT_ATTRIB_COLOR1, VERT_RESULT_COL1); } } diff --git a/src/mesa/drivers/dri/i965/brw_vtbl.c b/src/mesa/drivers/dri/i965/brw_vtbl.c index 4896882034..a5738e5774 100644 --- a/src/mesa/drivers/dri/i965/brw_vtbl.c +++ b/src/mesa/drivers/dri/i965/brw_vtbl.c @@ -46,8 +46,6 @@ #include "brw_state.h" #include "brw_draw.h" -#include "brw_exec.h" -#include "brw_save.h" #include "brw_state.h" #include "brw_aub.h" #include "brw_fallback.h" @@ -68,9 +66,6 @@ static void brw_destroy_context( struct intel_context *intel ) brw_destroy_state(brw); brw_draw_destroy( brw ); - brw_exec_destroy( ctx ); - brw_save_destroy( ctx ); - brw_ProgramCacheDestroy( ctx ); } @@ -165,10 +160,7 @@ static GLuint brw_flush_cmd( void ) static void brw_invalidate_state( struct intel_context *intel, GLuint new_state ) { - GLcontext *ctx = &intel->ctx; - - brw_exec_invalidate_state(ctx, new_state); - brw_save_invalidate_state(ctx, new_state); + /* nothing */ } -- cgit v1.2.3 From 80c88304fc9d09531b2530b74973821e47b46753 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 31 Oct 2006 12:11:10 +0000 Subject: remove vtxfmt code, switch over to vbo --- src/mesa/drivers/dri/r200/Makefile | 6 +- src/mesa/drivers/dri/r200/r200_context.c | 25 +- src/mesa/drivers/dri/r200/r200_state.c | 6 +- src/mesa/drivers/dri/r200/r200_state_init.c | 3 +- src/mesa/drivers/dri/r200/r200_swtcl.c | 8 - src/mesa/drivers/dri/r200/r200_tcl.c | 2 +- src/mesa/drivers/dri/r200/r200_vtxfmt.c | 1234 ----------------------- src/mesa/drivers/dri/r200/r200_vtxfmt.h | 123 --- src/mesa/drivers/dri/r200/r200_vtxfmt_c.c | 1002 ------------------ src/mesa/drivers/dri/r200/r200_vtxfmt_sse.c | 234 ----- src/mesa/drivers/dri/r200/r200_vtxfmt_x86.c | 440 -------- src/mesa/drivers/dri/r200/r200_vtxtmp_x86.S | 499 --------- src/mesa/drivers/dri/radeon/Makefile | 9 +- src/mesa/drivers/dri/radeon/radeon_context.c | 26 +- src/mesa/drivers/dri/radeon/radeon_maos_verts.c | 2 +- src/mesa/drivers/dri/radeon/radeon_state.c | 6 +- src/mesa/drivers/dri/radeon/radeon_state_init.c | 3 +- src/mesa/drivers/dri/radeon/radeon_swtcl.c | 9 - src/mesa/drivers/dri/radeon/radeon_swtcl.h | 1 - src/mesa/drivers/dri/radeon/radeon_tcl.c | 2 +- src/mesa/drivers/dri/radeon/radeon_vtxfmt.c | 1086 -------------------- src/mesa/drivers/dri/radeon/radeon_vtxfmt.h | 120 --- src/mesa/drivers/dri/radeon/radeon_vtxfmt_c.c | 924 ----------------- src/mesa/drivers/dri/radeon/radeon_vtxfmt_sse.c | 236 ----- src/mesa/drivers/dri/radeon/radeon_vtxfmt_x86.c | 440 -------- src/mesa/drivers/dri/radeon/radeon_vtxtmp_x86.S | 498 --------- 26 files changed, 21 insertions(+), 6923 deletions(-) delete mode 100644 src/mesa/drivers/dri/r200/r200_vtxfmt.c delete mode 100644 src/mesa/drivers/dri/r200/r200_vtxfmt.h delete mode 100644 src/mesa/drivers/dri/r200/r200_vtxfmt_c.c delete mode 100644 src/mesa/drivers/dri/r200/r200_vtxfmt_sse.c delete mode 100644 src/mesa/drivers/dri/r200/r200_vtxfmt_x86.c delete mode 100644 src/mesa/drivers/dri/r200/r200_vtxtmp_x86.S delete mode 100644 src/mesa/drivers/dri/radeon/radeon_vtxfmt.c delete mode 100644 src/mesa/drivers/dri/radeon/radeon_vtxfmt.h delete mode 100644 src/mesa/drivers/dri/radeon/radeon_vtxfmt_c.c delete mode 100644 src/mesa/drivers/dri/radeon/radeon_vtxfmt_sse.c delete mode 100644 src/mesa/drivers/dri/radeon/radeon_vtxfmt_x86.c delete mode 100644 src/mesa/drivers/dri/radeon/radeon_vtxtmp_x86.S (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/r200/Makefile b/src/mesa/drivers/dri/r200/Makefile index 75c09ff867..e9144ac75c 100644 --- a/src/mesa/drivers/dri/r200/Makefile +++ b/src/mesa/drivers/dri/r200/Makefile @@ -26,10 +26,6 @@ DRIVER_SOURCES = r200_context.c \ r200_span.c \ r200_maos.c \ r200_sanity.c \ - r200_vtxfmt.c \ - r200_vtxfmt_c.c \ - r200_vtxfmt_sse.c \ - r200_vtxfmt_x86.c \ r200_fragshader.c \ r200_vertprog.c \ radeon_screen.c \ @@ -37,7 +33,7 @@ DRIVER_SOURCES = r200_context.c \ C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES) -X86_SOURCES = r200_vtxtmp_x86.S +X86_SOURCES = DRIVER_DEFINES = -DRADEON_COMMON=1 -DRADEON_COMMON_FOR_R200 diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c index 9cec50147d..02651587a6 100644 --- a/src/mesa/drivers/dri/r200/r200_context.c +++ b/src/mesa/drivers/dri/r200/r200_context.c @@ -45,7 +45,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -60,7 +60,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_tex.h" #include "r200_swtcl.h" #include "r200_tcl.h" -#include "r200_vtxfmt.h" #include "r200_maos.h" #include "r200_vertprog.h" @@ -434,7 +433,7 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); _ae_create_context( ctx ); @@ -447,7 +446,7 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, /* Try and keep materials and vertices separate: */ - _tnl_isolate_materials( ctx, GL_TRUE ); +/* _tnl_isolate_materials( ctx, GL_TRUE ); */ /* Configure swrast and TNL to match hardware characteristics: @@ -552,12 +551,6 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, TCL_FALLBACK(rmesa->glCtx, R200_TCL_FALLBACK_TCL_DISABLE, 1); } - if (rmesa->r200Screen->chip_flags & RADEON_CHIPSET_TCL) { - if (tcl_mode >= DRI_CONF_TCL_VTXFMT) - r200VtxfmtInit( ctx, tcl_mode >= DRI_CONF_TCL_CODEGEN ); - - _tnl_need_dlist_norm_lengths( ctx, GL_FALSE ); - } return GL_TRUE; } @@ -587,7 +580,7 @@ void r200DestroyContext( __DRIcontextPrivate *driContextPriv ) release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1); _swsetup_DestroyContext( rmesa->glCtx ); _tnl_DestroyContext( rmesa->glCtx ); - _ac_DestroyContext( rmesa->glCtx ); + _vbo_DestroyContext( rmesa->glCtx ); _swrast_DestroyContext( rmesa->glCtx ); r200DestroySwtcl( rmesa->glCtx ); @@ -598,12 +591,6 @@ void r200DestroyContext( __DRIcontextPrivate *driContextPriv ) r200FlushCmdBuf( rmesa, __FUNCTION__ ); } - if (!(rmesa->TclFallback & R200_TCL_FALLBACK_TCL_DISABLE)) { - int tcl_mode = driQueryOptioni(&rmesa->optionCache, "tcl_mode"); - if (tcl_mode >= DRI_CONF_TCL_VTXFMT) - r200VtxfmtDestroy( rmesa->glCtx ); - } - if (rmesa->state.scissor.pClipRects) { FREE(rmesa->state.scissor.pClipRects); rmesa->state.scissor.pClipRects = NULL; @@ -713,9 +700,6 @@ r200MakeCurrent( __DRIcontextPrivate *driContextPriv, (GLframebuffer *) driDrawPriv->driverPrivate, (GLframebuffer *) driReadPriv->driverPrivate ); - if (newCtx->vb.enabled) - r200VtxfmtMakeCurrent( newCtx->glCtx ); - _mesa_update_state( newCtx->glCtx ); r200ValidateState( newCtx->glCtx ); @@ -740,6 +724,5 @@ r200UnbindContext( __DRIcontextPrivate *driContextPriv ) if (R200_DEBUG & DEBUG_DRI) fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *)rmesa->glCtx); - r200VtxfmtUnbindContext( rmesa->glCtx ); return GL_TRUE; } diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c index 097fbc868a..e68f1e30f3 100644 --- a/src/mesa/drivers/dri/r200/r200_state.c +++ b/src/mesa/drivers/dri/r200/r200_state.c @@ -42,7 +42,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "light.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" #include "swrast_setup/swrast_setup.h" @@ -53,7 +53,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_tcl.h" #include "r200_tex.h" #include "r200_swtcl.h" -#include "r200_vtxfmt.h" #include "r200_vertprog.h" #include "drirenderbuffer.h" @@ -2517,11 +2516,10 @@ static void r200InvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); _ae_invalidate_state( ctx, new_state ); R200_CONTEXT(ctx)->NewGLState |= new_state; - r200VtxfmtInvalidate( ctx ); } /* A hack. The r200 can actually cope just fine with materials diff --git a/src/mesa/drivers/dri/r200/r200_state_init.c b/src/mesa/drivers/dri/r200/r200_state_init.c index d95a80c7bb..b40d0bdcb7 100644 --- a/src/mesa/drivers/dri/r200/r200_state_init.c +++ b/src/mesa/drivers/dri/r200/r200_state_init.c @@ -39,7 +39,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "api_arrayelt.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" #include "swrast_setup/swrast_setup.h" @@ -50,7 +50,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_tcl.h" #include "r200_tex.h" #include "r200_swtcl.h" -#include "r200_vtxfmt.h" #include "xmlpool.h" diff --git a/src/mesa/drivers/dri/r200/r200_swtcl.c b/src/mesa/drivers/dri/r200/r200_swtcl.c index c14a275f7a..25d229d8ed 100644 --- a/src/mesa/drivers/dri/r200/r200_swtcl.c +++ b/src/mesa/drivers/dri/r200/r200_swtcl.c @@ -48,7 +48,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" -#include "tnl/t_vtx_api.h" #include "r200_context.h" #include "r200_ioctl.h" @@ -936,13 +935,6 @@ r200PointsBitmap( GLcontext *ctx, GLint px, GLint py, } -void r200FlushVertices( GLcontext *ctx, GLuint flags ) -{ - _tnl_FlushVertices( ctx, flags ); - - if (flags & FLUSH_STORED_VERTICES) - R200_NEWPRIM( R200_CONTEXT( ctx ) ); -} /**********************************************************************/ /* Initialization. */ diff --git a/src/mesa/drivers/dri/r200/r200_tcl.c b/src/mesa/drivers/dri/r200/r200_tcl.c index dab478db92..0b3bb281e0 100644 --- a/src/mesa/drivers/dri/r200/r200_tcl.c +++ b/src/mesa/drivers/dri/r200/r200_tcl.c @@ -40,7 +40,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "colormac.h" #include "light.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" diff --git a/src/mesa/drivers/dri/r200/r200_vtxfmt.c b/src/mesa/drivers/dri/r200/r200_vtxfmt.c deleted file mode 100644 index d73fbbafd5..0000000000 --- a/src/mesa/drivers/dri/r200/r200_vtxfmt.c +++ /dev/null @@ -1,1234 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.c,v 1.4 2003/05/06 23:52:08 daenzer Exp $ */ -/* -Copyright (C) The Weather Channel, Inc. 2002. 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 - */ - -#include "glheader.h" -#include "imports.h" -#include "r200_context.h" -#include "r200_state.h" -#include "r200_ioctl.h" -#include "r200_tex.h" -#include "r200_tcl.h" -#include "r200_swtcl.h" -#include "r200_vtxfmt.h" - -#include "api_noop.h" -#include "api_arrayelt.h" -#include "context.h" -#include "mtypes.h" -#include "enums.h" -#include "glapi.h" -#include "colormac.h" -#include "light.h" -#include "state.h" -#include "vtxfmt.h" - -#include "tnl/tnl.h" -#include "tnl/t_context.h" -#include "tnl/t_array_api.h" -#include "tnl/t_save_api.h" - -#include "dispatch.h" - -static void r200VtxFmtFlushVertices( GLcontext *, GLuint ); - -static void count_func( const char *name, struct dynfn *l ) -{ - int i = 0; - struct dynfn *f; - foreach (f, l) i++; - if (i) fprintf(stderr, "%s: %d\n", name, i ); -} - -static void count_funcs( r200ContextPtr rmesa ) -{ - count_func( "Vertex2f", &rmesa->vb.dfn_cache.Vertex2f ); - count_func( "Vertex2fv", &rmesa->vb.dfn_cache.Vertex2fv ); - count_func( "Vertex3f", &rmesa->vb.dfn_cache.Vertex3f ); - count_func( "Vertex3fv", &rmesa->vb.dfn_cache.Vertex3fv ); - count_func( "Color4ub", &rmesa->vb.dfn_cache.Color4ub ); - count_func( "Color4ubv", &rmesa->vb.dfn_cache.Color4ubv ); - count_func( "Color3ub", &rmesa->vb.dfn_cache.Color3ub ); - count_func( "Color3ubv", &rmesa->vb.dfn_cache.Color3ubv ); - count_func( "Color4f", &rmesa->vb.dfn_cache.Color4f ); - count_func( "Color4fv", &rmesa->vb.dfn_cache.Color4fv ); - count_func( "Color3f", &rmesa->vb.dfn_cache.Color3f ); - count_func( "Color3fv", &rmesa->vb.dfn_cache.Color3fv ); - count_func( "SecondaryColor3f", &rmesa->vb.dfn_cache.SecondaryColor3fEXT ); - count_func( "SecondaryColor3fv", &rmesa->vb.dfn_cache.SecondaryColor3fvEXT ); - count_func( "SecondaryColor3ub", &rmesa->vb.dfn_cache.SecondaryColor3ubEXT ); - count_func( "SecondaryColor3ubv", &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT ); - count_func( "Normal3f", &rmesa->vb.dfn_cache.Normal3f ); - count_func( "Normal3fv", &rmesa->vb.dfn_cache.Normal3fv ); - count_func( "TexCoord3f", &rmesa->vb.dfn_cache.TexCoord3f ); - count_func( "TexCoord3fv", &rmesa->vb.dfn_cache.TexCoord3fv ); - count_func( "TexCoord2f", &rmesa->vb.dfn_cache.TexCoord2f ); - count_func( "TexCoord2fv", &rmesa->vb.dfn_cache.TexCoord2fv ); - count_func( "TexCoord1f", &rmesa->vb.dfn_cache.TexCoord1f ); - count_func( "TexCoord1fv", &rmesa->vb.dfn_cache.TexCoord1fv ); - count_func( "MultiTexCoord3fARB", &rmesa->vb.dfn_cache.MultiTexCoord3fARB ); - count_func( "MultiTexCoord3fvARB", &rmesa->vb.dfn_cache.MultiTexCoord3fvARB ); - count_func( "MultiTexCoord2fARB", &rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - count_func( "MultiTexCoord2fvARB", &rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - count_func( "MultiTexCoord1fARB", &rmesa->vb.dfn_cache.MultiTexCoord1fARB ); - count_func( "MultiTexCoord1fvARB", &rmesa->vb.dfn_cache.MultiTexCoord1fvARB ); -/* count_func( "FogCoordfEXT", &rmesa->vb.dfn_cache.FogCoordfEXT ); - count_func( "FogCoordfvEXT", &rmesa->vb.dfn_cache.FogCoordfvEXT );*/ -} - -static void r200NewList( GLcontext *ctx, GLuint list, GLenum mode ) -{ - VFMT_FALLBACK( __FUNCTION__ ); - _tnl_NewList( ctx, list, mode ); - return; -} - -void r200_copy_to_current( GLcontext *ctx ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - unsigned i; - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - assert(ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT); - - if (rmesa->vb.vtxfmt_0 & R200_VTX_N0) { - ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0] = rmesa->vb.normalptr[0]; - ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1] = rmesa->vb.normalptr[1]; - ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2] = rmesa->vb.normalptr[2]; - } - - if (rmesa->vb.vtxfmt_0 & R200_VTX_DISCRETE_FOG) { - ctx->Current.Attrib[VERT_ATTRIB_FOG][0] = rmesa->vb.fogptr[0]; - } - - switch( VTX_COLOR(rmesa->vb.vtxfmt_0, 0) ) { - case R200_VTX_PK_RGBA: - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->red ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->green ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->blue ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->alpha ); - break; - - case R200_VTX_FP_RGB: - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = rmesa->vb.floatcolorptr[0]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] = rmesa->vb.floatcolorptr[1]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] = rmesa->vb.floatcolorptr[2]; - break; - - case R200_VTX_FP_RGBA: - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = rmesa->vb.floatcolorptr[0]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] = rmesa->vb.floatcolorptr[1]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] = rmesa->vb.floatcolorptr[2]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = rmesa->vb.floatcolorptr[3]; - break; - - default: - break; - } - - if (VTX_COLOR(rmesa->vb.vtxfmt_0, 1) == R200_VTX_PK_RGBA) { - ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0] = UBYTE_TO_FLOAT( rmesa->vb.specptr->red ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1] = UBYTE_TO_FLOAT( rmesa->vb.specptr->green ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2] = UBYTE_TO_FLOAT( rmesa->vb.specptr->blue ); - } - - for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) { - const unsigned count = VTX_TEXn_COUNT( rmesa->vb.vtxfmt_1, i ); - GLfloat * const src = rmesa->vb.texcoordptr[i]; - - if ( count != 0 ) { - switch( count ) { - case 3: - ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][1] = src[1]; - ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][2] = src[2]; - break; - case 2: - ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][1] = src[1]; - ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][2] = 0.0F; - break; - case 1: - ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][1] = 0.0F; - ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][2] = 0.0F; - break; - } - - ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][0] = src[0]; - ctx->Current.Attrib[VERT_ATTRIB_TEX0+i][3] = 1.0F; - } - } - - ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; -} - -static GLboolean discreet_gl_prim[GL_POLYGON+1] = { - 1, /* 0 points */ - 1, /* 1 lines */ - 0, /* 2 line_strip */ - 0, /* 3 line_loop */ - 1, /* 4 tris */ - 0, /* 5 tri_fan */ - 0, /* 6 tri_strip */ - 1, /* 7 quads */ - 0, /* 8 quadstrip */ - 0, /* 9 poly */ -}; - -static void flush_prims( r200ContextPtr rmesa ) -{ - int i,j; - struct r200_dma_region tmp = rmesa->dma.current; - - tmp.buf->refcount++; - tmp.aos_size = rmesa->vb.vertex_size; - tmp.aos_stride = rmesa->vb.vertex_size; - tmp.aos_start = GET_START(&tmp); - - rmesa->dma.current.ptr = rmesa->dma.current.start += - (rmesa->vb.initial_counter - rmesa->vb.counter) * - rmesa->vb.vertex_size * 4; - - rmesa->tcl.vertex_format = rmesa->vb.vtxfmt_0; - rmesa->tcl.aos_components[0] = &tmp; - rmesa->tcl.nr_aos_components = 1; - rmesa->dma.flush = NULL; - - /* Optimize the primitive list: - */ - if (rmesa->vb.nrprims > 1) { - for (j = 0, i = 1 ; i < rmesa->vb.nrprims; i++) { - int pj = rmesa->vb.primlist[j].prim & 0xf; - int pi = rmesa->vb.primlist[i].prim & 0xf; - - if (pj == pi && discreet_gl_prim[pj] && - rmesa->vb.primlist[i].start == rmesa->vb.primlist[j].end) { - rmesa->vb.primlist[j].end = rmesa->vb.primlist[i].end; - } - else { - j++; - if (j != i) rmesa->vb.primlist[j] = rmesa->vb.primlist[i]; - } - } - rmesa->vb.nrprims = j+1; - } - - if (rmesa->vb.vtxfmt_0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] || - rmesa->vb.vtxfmt_1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) { - R200_STATECHANGE( rmesa, vtx ); - rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = rmesa->vb.vtxfmt_0; - rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = rmesa->vb.vtxfmt_1; - } - - - for (i = 0 ; i < rmesa->vb.nrprims; i++) { - if (R200_DEBUG & DEBUG_PRIMS) - fprintf(stderr, "vtxfmt prim %d: %s %d..%d\n", i, - _mesa_lookup_enum_by_nr( rmesa->vb.primlist[i].prim & - PRIM_MODE_MASK ), - rmesa->vb.primlist[i].start, - rmesa->vb.primlist[i].end); - - if (rmesa->vb.primlist[i].start < rmesa->vb.primlist[i].end) - r200EmitPrimitive( rmesa->glCtx, - rmesa->vb.primlist[i].start, - rmesa->vb.primlist[i].end, - rmesa->vb.primlist[i].prim ); - } - - rmesa->vb.nrprims = 0; - r200ReleaseDmaRegion( rmesa, &tmp, __FUNCTION__ ); -} - - -static void start_prim( r200ContextPtr rmesa, GLuint mode ) -{ - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s %d\n", __FUNCTION__, - rmesa->vb.initial_counter - rmesa->vb.counter); - - rmesa->vb.primlist[rmesa->vb.nrprims].start = - rmesa->vb.initial_counter - rmesa->vb.counter; - rmesa->vb.primlist[rmesa->vb.nrprims].prim = mode; -} - -static void note_last_prim( r200ContextPtr rmesa, GLuint flags ) -{ - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s %d\n", __FUNCTION__, - rmesa->vb.initial_counter - rmesa->vb.counter); - - if (rmesa->vb.prim[0] != GL_POLYGON+1) { - rmesa->vb.primlist[rmesa->vb.nrprims].prim |= flags; - rmesa->vb.primlist[rmesa->vb.nrprims].end = - rmesa->vb.initial_counter - rmesa->vb.counter; - - if (++(rmesa->vb.nrprims) == R200_MAX_PRIMS) - flush_prims( rmesa ); - } -} - - -static void copy_vertex( r200ContextPtr rmesa, GLuint n, GLfloat *dst ) -{ - GLuint i; - GLfloat *src = (GLfloat *)(rmesa->dma.current.address + - rmesa->dma.current.ptr + - (rmesa->vb.primlist[rmesa->vb.nrprims].start + n) * - rmesa->vb.vertex_size * 4); - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "copy_vertex %d\n", rmesa->vb.primlist[rmesa->vb.nrprims].start + n); - - for (i = 0 ; i < rmesa->vb.vertex_size; i++) { - dst[i] = src[i]; - } -} - -/* NOTE: This actually reads the copied vertices back from uncached - * memory. Could also use the counter/notify mechanism to populate - * tmp on the fly as vertices are generated. - */ -static GLuint copy_dma_verts( r200ContextPtr rmesa, GLfloat (*tmp)[R200_MAX_VERTEX_SIZE] ) -{ - GLuint ovf, i; - GLuint nr = (rmesa->vb.initial_counter - rmesa->vb.counter) - - rmesa->vb.primlist[rmesa->vb.nrprims].start; - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s %d verts\n", __FUNCTION__, nr); - - switch( rmesa->vb.prim[0] ) - { - case GL_POINTS: - return 0; - case GL_LINES: - ovf = nr&1; - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - case GL_TRIANGLES: - ovf = nr%3; - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - case GL_QUADS: - ovf = nr&3; - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - case GL_LINE_STRIP: - if (nr == 0) - return 0; - copy_vertex( rmesa, nr-1, tmp[0] ); - return 1; - case GL_LINE_LOOP: - case GL_TRIANGLE_FAN: - case GL_POLYGON: - if (nr == 0) - return 0; - else if (nr == 1) { - copy_vertex( rmesa, 0, tmp[0] ); - return 1; - } else { - copy_vertex( rmesa, 0, tmp[0] ); - copy_vertex( rmesa, nr-1, tmp[1] ); - return 2; - } - case GL_TRIANGLE_STRIP: - ovf = MIN2( nr, 2 ); - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - case GL_QUAD_STRIP: - switch (nr) { - case 0: ovf = 0; break; - case 1: ovf = 1; break; - default: ovf = 2 + (nr&1); break; - } - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - default: - assert(0); - return 0; - } -} - -static void VFMT_FALLBACK_OUTSIDE_BEGIN_END( const char *caller ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - if (R200_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS)) - fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); - - if (ctx->Driver.NeedFlush) - r200VtxFmtFlushVertices( ctx, ctx->Driver.NeedFlush ); - - if (ctx->NewState) - _mesa_update_state( ctx ); /* clear state so fell_back sticks */ - - _tnl_wakeup_exec( ctx ); - ctx->Driver.FlushVertices = r200FlushVertices; - ctx->Driver.NewList = _tnl_NewList; - - assert( rmesa->dma.flush == 0 ); - rmesa->vb.fell_back = GL_TRUE; - rmesa->vb.installed = GL_FALSE; -} - - -/** - * \todo - * An interesting optimization of this function would be to have 3 element - * table with the dispatch offsets of the TexCoord?fv functions, use count - * to look-up the table, and a specialized version of GL_CALL that used the - * offset number instead of the name. - */ -static void dispatch_multitexcoord( GLuint count, GLuint unit, GLfloat * f ) -{ - switch( count ) { - case 3: - CALL_MultiTexCoord3fvARB(GET_DISPATCH(), (GL_TEXTURE0+unit, f)); - break; - case 2: - CALL_MultiTexCoord2fvARB(GET_DISPATCH(), (GL_TEXTURE0+unit, f)); - break; - case 1: - CALL_MultiTexCoord1fvARB(GET_DISPATCH(), (GL_TEXTURE0+unit, f)); - break; - default: - assert( count == 0 ); - break; - } -} - -void VFMT_FALLBACK( const char *caller ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat tmp[3][R200_MAX_VERTEX_SIZE]; - GLuint i, prim; - GLuint ind0 = rmesa->vb.vtxfmt_0; - GLuint ind1 = rmesa->vb.vtxfmt_1; - GLuint nrverts; - GLfloat alpha = 1.0; - GLuint count; - GLuint unit; - - if (R200_DEBUG & (DEBUG_FALLBACKS|DEBUG_VFMT)) - fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); - - if (rmesa->vb.prim[0] == GL_POLYGON+1) { - VFMT_FALLBACK_OUTSIDE_BEGIN_END( __FUNCTION__ ); - return; - } - - /* Copy vertices out of dma: - */ - nrverts = copy_dma_verts( rmesa, tmp ); - - /* Finish the prim at this point: - */ - note_last_prim( rmesa, 0 ); - flush_prims( rmesa ); - - /* Update ctx->Driver.CurrentExecPrimitive and swap in swtnl. - */ - prim = rmesa->vb.prim[0]; - ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1; - _tnl_wakeup_exec( ctx ); - ctx->Driver.FlushVertices = r200FlushVertices; - - assert(rmesa->dma.flush == 0); - rmesa->vb.fell_back = GL_TRUE; - rmesa->vb.installed = GL_FALSE; - CALL_Begin(GET_DISPATCH(), (prim)); - - if (rmesa->vb.installed_color_3f_sz == 4) - alpha = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3]; - - /* Replay saved vertices - */ - for (i = 0 ; i < nrverts; i++) { - GLuint offset = 3; - - if (ind0 & R200_VTX_N0) { - CALL_Normal3fv(GET_DISPATCH(), (&tmp[i][offset])); - offset += 3; - } - - if (ind0 & R200_VTX_DISCRETE_FOG) { - CALL_FogCoordfvEXT(GET_DISPATCH(), (&tmp[i][offset])); - offset++; - } - - if (VTX_COLOR(ind0, 0) == R200_VTX_PK_RGBA) { - CALL_Color4ubv(GET_DISPATCH(), ((GLubyte *)&tmp[i][offset])); - offset++; - } - else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGBA) { - CALL_Color4fv(GET_DISPATCH(), (&tmp[i][offset])); - offset+=4; - } - else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGB) { - CALL_Color3fv(GET_DISPATCH(), (&tmp[i][offset])); - offset+=3; - } - - if (VTX_COLOR(ind0, 1) == R200_VTX_PK_RGBA) { - CALL_SecondaryColor3ubvEXT(GET_DISPATCH(), ((GLubyte *)&tmp[i][offset])); - offset++; - } - - for ( unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++ ) { - count = VTX_TEXn_COUNT( ind1, unit ); - dispatch_multitexcoord( count, unit, &tmp[i][offset] ); - offset += count; - } - - CALL_Vertex3fv(GET_DISPATCH(), (&tmp[i][0])); - } - - /* Replay current vertex - */ - if (ind0 & R200_VTX_N0) - CALL_Normal3fv(GET_DISPATCH(), (rmesa->vb.normalptr)); - if (ind0 & R200_VTX_DISCRETE_FOG) { - CALL_FogCoordfvEXT(GET_DISPATCH(), (rmesa->vb.fogptr)); - } - - if (VTX_COLOR(ind0, 0) == R200_VTX_PK_RGBA) { - CALL_Color4ub(GET_DISPATCH(), (rmesa->vb.colorptr->red, - rmesa->vb.colorptr->green, - rmesa->vb.colorptr->blue, - rmesa->vb.colorptr->alpha)); - } - else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGBA) { - CALL_Color4fv(GET_DISPATCH(), (rmesa->vb.floatcolorptr)); - } - else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGB) { - if (rmesa->vb.installed_color_3f_sz == 4 && alpha != 1.0) { - CALL_Color4f(GET_DISPATCH(), (rmesa->vb.floatcolorptr[0], - rmesa->vb.floatcolorptr[1], - rmesa->vb.floatcolorptr[2], - alpha)); - } - else { - CALL_Color3fv(GET_DISPATCH(), (rmesa->vb.floatcolorptr)); - } - } - - if (VTX_COLOR(ind0, 1) == R200_VTX_PK_RGBA) - CALL_SecondaryColor3ubEXT(GET_DISPATCH(), (rmesa->vb.specptr->red, - rmesa->vb.specptr->green, - rmesa->vb.specptr->blue)); - - for ( unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++ ) { - count = VTX_TEXn_COUNT( ind1, unit ); - dispatch_multitexcoord( count, unit, rmesa->vb.texcoordptr[unit] ); - } -} - - - -static void wrap_buffer( void ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat tmp[3][R200_MAX_VERTEX_SIZE]; - GLuint i, nrverts; - - if (R200_DEBUG & (DEBUG_VFMT|DEBUG_PRIMS)) - fprintf(stderr, "%s %d\n", __FUNCTION__, - rmesa->vb.initial_counter - rmesa->vb.counter); - - /* Don't deal with parity. - */ - if ((((rmesa->vb.initial_counter - rmesa->vb.counter) - - rmesa->vb.primlist[rmesa->vb.nrprims].start) & 1)) { - rmesa->vb.counter++; - rmesa->vb.initial_counter++; - return; - } - - /* Copy vertices out of dma: - */ - if (rmesa->vb.prim[0] == GL_POLYGON+1) - nrverts = 0; - else { - nrverts = copy_dma_verts( rmesa, tmp ); - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%d vertices to copy\n", nrverts); - - /* Finish the prim at this point: - */ - note_last_prim( rmesa, 0 ); - } - - /* Fire any buffered primitives - */ - flush_prims( rmesa ); - - /* Get new buffer - */ - r200RefillCurrentDmaRegion( rmesa ); - - /* Reset counter, dmaptr - */ - rmesa->vb.dmaptr = (int *)(rmesa->dma.current.ptr + rmesa->dma.current.address); - rmesa->vb.counter = (rmesa->dma.current.end - rmesa->dma.current.ptr) / - (rmesa->vb.vertex_size * 4); - rmesa->vb.counter--; - rmesa->vb.initial_counter = rmesa->vb.counter; - rmesa->vb.notify = wrap_buffer; - - rmesa->dma.flush = flush_prims; - - /* Restart wrapped primitive: - */ - if (rmesa->vb.prim[0] != GL_POLYGON+1) - start_prim( rmesa, rmesa->vb.prim[0] ); - - - /* Reemit saved vertices - */ - for (i = 0 ; i < nrverts; i++) { - if (R200_DEBUG & DEBUG_VERTS) { - int j; - fprintf(stderr, "re-emit vertex %d to %p\n", i, - (void *)rmesa->vb.dmaptr); - if (R200_DEBUG & DEBUG_VERBOSE) - for (j = 0 ; j < rmesa->vb.vertex_size; j++) - fprintf(stderr, "\t%08x/%f\n", *(int*)&tmp[i][j], tmp[i][j]); - } - - memcpy( rmesa->vb.dmaptr, tmp[i], rmesa->vb.vertex_size * 4 ); - rmesa->vb.dmaptr += rmesa->vb.vertex_size; - rmesa->vb.counter--; - } -} - - -/** - * Determines the hardware vertex format based on the current state vector. - * - * \returns - * If the hardware TCL unit is capable of handling the current state vector, - * \c GL_TRUE is returned. Otherwise, \c GL_FALSE is returned. - * - * \todo - * Make this color format selection data driven. If we receive only ubytes, - * send color as ubytes. Also check if converting (with free checking for - * overflow) is cheaper than sending floats directly. - * - * \todo - * When intializing texture coordinates, it might be faster to just copy the - * entire \c VERT_ATTRIB_TEX0 vector into the vertex buffer. It may mean that - * some of the data (i.e., the last texture coordinate components) get copied - * over, but that still may be faster than the conditional branching. If - * nothing else, the code will be smaller and easier to follow. - */ -static GLboolean check_vtx_fmt( GLcontext *ctx ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLuint ind0 = R200_VTX_Z0; - GLuint ind1 = 0; - GLuint i; - GLuint count[R200_MAX_TEXTURE_UNITS]; - - if (rmesa->TclFallback || rmesa->vb.fell_back || ctx->CompileFlag || - (ctx->Fog.Enabled && (ctx->Fog.FogCoordinateSource == GL_FOG_COORD)) || - /* TODO: set tcl out fmt/compsel and reenable vtxfmt code */ - ctx->VertexProgram._Enabled) - return GL_FALSE; - - if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) - ctx->Driver.FlushVertices( ctx, FLUSH_UPDATE_CURRENT ); - - /* Make all this event-driven: - */ - if (ctx->Light.Enabled) { - ind0 |= R200_VTX_N0; - - if (ctx->Light.ColorMaterialEnabled) - ind0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT; - else - ind0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT; - } - else { - /* TODO: make this data driven? - */ - ind0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT; - - if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { - ind0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT; - } - } - - if ( ctx->Fog.FogCoordinateSource == GL_FOG_COORD ) { - ind0 |= R200_VTX_DISCRETE_FOG; - } - - for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) { - count[i] = 0; - - if (ctx->Texture.Unit[i]._ReallyEnabled) { - if (rmesa->TexGenNeedNormals[i]) { - ind0 |= R200_VTX_N0; - } - else { - switch( ctx->Texture.Unit[i]._ReallyEnabled ) { - case TEXTURE_CUBE_BIT: - case TEXTURE_3D_BIT: - count[i] = 3; - break; - case TEXTURE_2D_BIT: - case TEXTURE_RECT_BIT: - count[i] = 2; - break; - case TEXTURE_1D_BIT: - count[i] = 1; - break; - } - - ind1 |= count[i] << (3 * i); - } - } - } - - if (R200_DEBUG & (DEBUG_VFMT|DEBUG_STATE)) - fprintf(stderr, "%s: format: 0x%x, 0x%x\n", __FUNCTION__, ind0, ind1 ); - - R200_NEWPRIM(rmesa); - rmesa->vb.vtxfmt_0 = ind0; - rmesa->vb.vtxfmt_1 = ind1; - rmesa->vb.prim = &ctx->Driver.CurrentExecPrimitive; - - rmesa->vb.vertex_size = 3; - rmesa->vb.normalptr = ctx->Current.Attrib[VERT_ATTRIB_NORMAL]; - rmesa->vb.colorptr = NULL; - rmesa->vb.floatcolorptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; - rmesa->vb.fogptr = ctx->Current.Attrib[VERT_ATTRIB_FOG]; - rmesa->vb.specptr = NULL; - rmesa->vb.floatspecptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR1]; - rmesa->vb.texcoordptr[0] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; - rmesa->vb.texcoordptr[1] = ctx->Current.Attrib[VERT_ATTRIB_TEX1]; - rmesa->vb.texcoordptr[2] = ctx->Current.Attrib[VERT_ATTRIB_TEX2]; - rmesa->vb.texcoordptr[3] = ctx->Current.Attrib[VERT_ATTRIB_TEX3]; - rmesa->vb.texcoordptr[4] = ctx->Current.Attrib[VERT_ATTRIB_TEX4]; - rmesa->vb.texcoordptr[5] = ctx->Current.Attrib[VERT_ATTRIB_TEX5]; - rmesa->vb.texcoordptr[6] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; /* dummy */ - rmesa->vb.texcoordptr[7] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; /* dummy */ - - /* Run through and initialize the vertex components in the order - * the hardware understands: - */ - if (ind0 & R200_VTX_N0) { - rmesa->vb.normalptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; - rmesa->vb.vertex_size += 3; - rmesa->vb.normalptr[0] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0]; - rmesa->vb.normalptr[1] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1]; - rmesa->vb.normalptr[2] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2]; - } - - if (ind0 & R200_VTX_DISCRETE_FOG) { - rmesa->vb.fogptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; - rmesa->vb.vertex_size += 1; - rmesa->vb.fogptr[0] = ctx->Current.Attrib[VERT_ATTRIB_FOG][0]; - } - - if (VTX_COLOR(ind0, 0) == R200_VTX_PK_RGBA) { - rmesa->vb.colorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].color; - rmesa->vb.vertex_size += 1; - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->red, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->green, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->blue, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->alpha, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] ); - } - else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGBA) { - rmesa->vb.floatcolorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; - rmesa->vb.vertex_size += 4; - rmesa->vb.floatcolorptr[0] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0]; - rmesa->vb.floatcolorptr[1] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1]; - rmesa->vb.floatcolorptr[2] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2]; - rmesa->vb.floatcolorptr[3] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3]; - } - else if (VTX_COLOR(ind0, 0) == R200_VTX_FP_RGB) { - rmesa->vb.floatcolorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; - rmesa->vb.vertex_size += 3; - rmesa->vb.floatcolorptr[0] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0]; - rmesa->vb.floatcolorptr[1] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1]; - rmesa->vb.floatcolorptr[2] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2]; - } - - if (VTX_COLOR(ind0, 1) == R200_VTX_PK_RGBA) { - rmesa->vb.specptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].color; - rmesa->vb.vertex_size += 1; - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->red, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->green, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->blue, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2] ); - } - - - for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) { - if ( count[i] != 0 ) { - float * const attr = ctx->Current.Attrib[VERT_ATTRIB_TEX0+i]; - unsigned j; - - rmesa->vb.texcoordptr[i] = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; - - for ( j = 0 ; j < count[i] ; j++ ) { - rmesa->vb.texcoordptr[i][j] = attr[j]; - } - - rmesa->vb.vertex_size += count[i]; - } - } - - if (rmesa->vb.installed_vertex_format != rmesa->vb.vtxfmt_0) { - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "reinstall on vertex_format change\n"); - _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); - rmesa->vb.installed_vertex_format = rmesa->vb.vtxfmt_0; - } - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s -- success\n", __FUNCTION__); - - return GL_TRUE; -} - - -void r200VtxfmtInvalidate( GLcontext *ctx ) -{ - r200ContextPtr rmesa = R200_CONTEXT( ctx ); - - rmesa->vb.recheck = GL_TRUE; - rmesa->vb.fell_back = GL_FALSE; -} - - -static void r200VtxfmtValidate( GLcontext *ctx ) -{ - r200ContextPtr rmesa = R200_CONTEXT( ctx ); - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (ctx->Driver.NeedFlush) - ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush ); - - rmesa->vb.recheck = GL_FALSE; - - if (check_vtx_fmt( ctx )) { - if (!rmesa->vb.installed) { - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "reinstall (new install)\n"); - - _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); - ctx->Driver.FlushVertices = r200VtxFmtFlushVertices; - ctx->Driver.NewList = r200NewList; - rmesa->vb.installed = GL_TRUE; - } - else if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s: already installed", __FUNCTION__); - } - else { - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s: failed\n", __FUNCTION__); - - if (rmesa->vb.installed) { - if (rmesa->dma.flush) - rmesa->dma.flush( rmesa ); - _tnl_wakeup_exec( ctx ); - ctx->Driver.FlushVertices = r200FlushVertices; - ctx->Driver.NewList =_tnl_NewList; - rmesa->vb.installed = GL_FALSE; - } - } -} - - - -/* Materials: - */ -static void r200_Materialfv( GLenum face, GLenum pname, - const GLfloat *params ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT( ctx ); - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (rmesa->vb.prim[0] != GL_POLYGON+1) { - VFMT_FALLBACK( __FUNCTION__ ); - CALL_Materialfv(GET_DISPATCH(), (face, pname, params)); - return; - } - _mesa_noop_Materialfv( face, pname, params ); - r200UpdateMaterial( ctx ); -} - - -/* Begin/End - */ -static void r200_Begin( GLenum mode ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s( %s )\n", __FUNCTION__, - _mesa_lookup_enum_by_nr( mode )); - - if (mode > GL_POLYGON) { - _mesa_error( ctx, GL_INVALID_ENUM, "glBegin" ); - return; - } - - if (rmesa->vb.prim[0] != GL_POLYGON+1) { - _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" ); - return; - } - - if (ctx->NewState) - _mesa_update_state( ctx ); - - if (rmesa->NewGLState) - r200ValidateState( ctx ); - - if (rmesa->vb.recheck) - r200VtxfmtValidate( ctx ); - - if (!rmesa->vb.installed) { - CALL_Begin(GET_DISPATCH(), (mode)); - return; - } - - - if (rmesa->dma.flush && rmesa->vb.counter < 12) { - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s: flush almost-empty buffers\n", __FUNCTION__); - flush_prims( rmesa ); - } - - /* Need to arrange to save vertices here? Or always copy from dma (yuk)? - */ - if (!rmesa->dma.flush) { - if (rmesa->dma.current.ptr + 12*rmesa->vb.vertex_size*4 > - rmesa->dma.current.end) { - R200_NEWPRIM( rmesa ); - r200RefillCurrentDmaRegion( rmesa ); - } - - rmesa->vb.dmaptr = (int *)(rmesa->dma.current.address + rmesa->dma.current.ptr); - rmesa->vb.counter = (rmesa->dma.current.end - rmesa->dma.current.ptr) / - (rmesa->vb.vertex_size * 4); - rmesa->vb.counter--; - rmesa->vb.initial_counter = rmesa->vb.counter; - rmesa->vb.notify = wrap_buffer; - rmesa->dma.flush = flush_prims; - ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; - } - - - rmesa->vb.prim[0] = mode; - start_prim( rmesa, mode | PRIM_BEGIN ); -} - - - -static void r200_End( void ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (rmesa->vb.prim[0] == GL_POLYGON+1) { - _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" ); - return; - } - - note_last_prim( rmesa, PRIM_END ); - rmesa->vb.prim[0] = GL_POLYGON+1; -} - - -/* Fallback on difficult entrypoints: - */ -#define PRE_LOOPBACK( FUNC ) \ -do { \ - if (R200_DEBUG & DEBUG_VFMT) \ - fprintf(stderr, "%s\n", __FUNCTION__); \ - VFMT_FALLBACK( __FUNCTION__ ); \ -} while (0) -#define TAG(x) r200_fallback_##x -#include "vtxfmt_tmp.h" - - - -static GLboolean r200NotifyBegin( GLcontext *ctx, GLenum p ) -{ - r200ContextPtr rmesa = R200_CONTEXT( ctx ); - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - assert(!rmesa->vb.installed); - - if (ctx->NewState) - _mesa_update_state( ctx ); - - if (rmesa->NewGLState) - r200ValidateState( ctx ); - - if (ctx->Driver.NeedFlush) - ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush ); - - if (rmesa->vb.recheck) - r200VtxfmtValidate( ctx ); - - if (!rmesa->vb.installed) { - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s -- failed\n", __FUNCTION__); - return GL_FALSE; - } - - r200_Begin( p ); - return GL_TRUE; -} - -static void r200VtxFmtFlushVertices( GLcontext *ctx, GLuint flags ) -{ - r200ContextPtr rmesa = R200_CONTEXT( ctx ); - - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - assert(rmesa->vb.installed); - - if (flags & FLUSH_UPDATE_CURRENT) { - r200_copy_to_current( ctx ); - if (R200_DEBUG & DEBUG_VFMT) - fprintf(stderr, "reinstall on update_current\n"); - _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); - ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; - } - - if (flags & FLUSH_STORED_VERTICES) { - assert (rmesa->dma.flush == 0 || - rmesa->dma.flush == flush_prims); - if (rmesa->dma.flush == flush_prims) - flush_prims( rmesa ); - ctx->Driver.NeedFlush &= ~FLUSH_STORED_VERTICES; - } -} - - - -/* At this point, don't expect very many versions of each function to - * be generated, so not concerned about freeing them? - */ - - -/** - * Called once during context creation. - */ -void r200VtxfmtInit( GLcontext *ctx, GLboolean useCodegen ) -{ - r200ContextPtr rmesa = R200_CONTEXT( ctx ); - GLvertexformat *vfmt = &(rmesa->vb.vtxfmt); - - /* start by initializing to no-op functions */ - _mesa_noop_vtxfmt_init(vfmt); - - /* Hook in chooser functions for codegen, etc: - */ - r200VtxfmtInitChoosers( vfmt ); - - /* Handled fully in supported states, but no codegen: - */ - vfmt->Materialfv = r200_Materialfv; - vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ - vfmt->Begin = r200_Begin; - vfmt->End = r200_End; - - /* Fallback for performance reasons: (Fix with cva/elt path here and - * dmatmp2.h style primitive-merging) - * - * These should call NotifyBegin(), as should _tnl_EvalMesh, to allow - * a driver-hook. - */ - vfmt->DrawArrays = r200_fallback_DrawArrays; - vfmt->DrawElements = r200_fallback_DrawElements; - vfmt->DrawRangeElements = r200_fallback_DrawRangeElements; - - /* Active but unsupported -- fallback if we receive these: - */ - vfmt->CallList = r200_fallback_CallList; - vfmt->CallLists = r200_fallback_CallLists; - vfmt->EvalCoord1f = r200_fallback_EvalCoord1f; - vfmt->EvalCoord1fv = r200_fallback_EvalCoord1fv; - vfmt->EvalCoord2f = r200_fallback_EvalCoord2f; - vfmt->EvalCoord2fv = r200_fallback_EvalCoord2fv; - vfmt->EvalMesh1 = r200_fallback_EvalMesh1; - vfmt->EvalMesh2 = r200_fallback_EvalMesh2; - vfmt->EvalPoint1 = r200_fallback_EvalPoint1; - vfmt->EvalPoint2 = r200_fallback_EvalPoint2; - vfmt->TexCoord4f = r200_fallback_TexCoord4f; - vfmt->TexCoord4fv = r200_fallback_TexCoord4fv; - vfmt->MultiTexCoord4fARB = r200_fallback_MultiTexCoord4fARB; - vfmt->MultiTexCoord4fvARB = r200_fallback_MultiTexCoord4fvARB; - vfmt->Vertex4f = r200_fallback_Vertex4f; - vfmt->Vertex4fv = r200_fallback_Vertex4fv; - vfmt->VertexAttrib1fNV = r200_fallback_VertexAttrib1fNV; - vfmt->VertexAttrib1fvNV = r200_fallback_VertexAttrib1fvNV; - vfmt->VertexAttrib2fNV = r200_fallback_VertexAttrib2fNV; - vfmt->VertexAttrib2fvNV = r200_fallback_VertexAttrib2fvNV; - vfmt->VertexAttrib3fNV = r200_fallback_VertexAttrib3fNV; - vfmt->VertexAttrib3fvNV = r200_fallback_VertexAttrib3fvNV; - vfmt->VertexAttrib4fNV = r200_fallback_VertexAttrib4fNV; - vfmt->VertexAttrib4fvNV = r200_fallback_VertexAttrib4fvNV; - vfmt->FogCoordfEXT = r200_fallback_FogCoordfEXT; - vfmt->FogCoordfvEXT = r200_fallback_FogCoordfvEXT; - - (void)r200_fallback_vtxfmt; - - TNL_CONTEXT(ctx)->Driver.NotifyBegin = r200NotifyBegin; - - rmesa->vb.enabled = 1; - rmesa->vb.prim = &ctx->Driver.CurrentExecPrimitive; - rmesa->vb.primflags = 0; - - make_empty_list( &rmesa->vb.dfn_cache.Vertex2f ); - make_empty_list( &rmesa->vb.dfn_cache.Vertex2fv ); - make_empty_list( &rmesa->vb.dfn_cache.Vertex3f ); - make_empty_list( &rmesa->vb.dfn_cache.Vertex3fv ); - make_empty_list( &rmesa->vb.dfn_cache.Color4ub ); - make_empty_list( &rmesa->vb.dfn_cache.Color4ubv ); - make_empty_list( &rmesa->vb.dfn_cache.Color3ub ); - make_empty_list( &rmesa->vb.dfn_cache.Color3ubv ); - make_empty_list( &rmesa->vb.dfn_cache.Color4f ); - make_empty_list( &rmesa->vb.dfn_cache.Color4fv ); - make_empty_list( &rmesa->vb.dfn_cache.Color3f ); - make_empty_list( &rmesa->vb.dfn_cache.Color3fv ); - make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3fEXT ); - make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3fvEXT ); - make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3ubEXT ); - make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT ); - make_empty_list( &rmesa->vb.dfn_cache.Normal3f ); - make_empty_list( &rmesa->vb.dfn_cache.Normal3fv ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord3f ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord3fv ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord2f ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord2fv ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord1f ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord1fv ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord3fARB ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord3fvARB ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord1fARB ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord1fvARB ); -/* make_empty_list( &rmesa->vb.dfn_cache.FogCoordfEXT ); - make_empty_list( &rmesa->vb.dfn_cache.FogCoordfvEXT );*/ - - r200InitCodegen( &rmesa->vb.codegen, useCodegen ); -} - -static void free_funcs( struct dynfn *l ) -{ - struct dynfn *f, *tmp; - foreach_s (f, tmp, l) { - remove_from_list( f ); - _mesa_exec_free( f->code ); - _mesa_free( f ); - } -} - -void r200VtxfmtUnbindContext( GLcontext *ctx ) -{ -} - - -void r200VtxfmtMakeCurrent( GLcontext *ctx ) -{ -} - - -void r200VtxfmtDestroy( GLcontext *ctx ) -{ - r200ContextPtr rmesa = R200_CONTEXT( ctx ); - - count_funcs( rmesa ); - free_funcs( &rmesa->vb.dfn_cache.Vertex2f ); - free_funcs( &rmesa->vb.dfn_cache.Vertex2fv ); - free_funcs( &rmesa->vb.dfn_cache.Vertex3f ); - free_funcs( &rmesa->vb.dfn_cache.Vertex3fv ); - free_funcs( &rmesa->vb.dfn_cache.Color4ub ); - free_funcs( &rmesa->vb.dfn_cache.Color4ubv ); - free_funcs( &rmesa->vb.dfn_cache.Color3ub ); - free_funcs( &rmesa->vb.dfn_cache.Color3ubv ); - free_funcs( &rmesa->vb.dfn_cache.Color4f ); - free_funcs( &rmesa->vb.dfn_cache.Color4fv ); - free_funcs( &rmesa->vb.dfn_cache.Color3f ); - free_funcs( &rmesa->vb.dfn_cache.Color3fv ); - free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3ubEXT ); - free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT ); - free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3fEXT ); - free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3fvEXT ); - free_funcs( &rmesa->vb.dfn_cache.Normal3f ); - free_funcs( &rmesa->vb.dfn_cache.Normal3fv ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord3f ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord3fv ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord2f ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord2fv ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord1f ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord1fv ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord3fARB ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord3fvARB ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord1fARB ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord1fvARB ); -/* free_funcs( &rmesa->vb.dfn_cache.FogCoordfEXT ); - free_funcs( &rmesa->vb.dfn_cache.FogCoordfvEXT );*/ -} - diff --git a/src/mesa/drivers/dri/r200/r200_vtxfmt.h b/src/mesa/drivers/dri/r200/r200_vtxfmt.h deleted file mode 100644 index 46999191e0..0000000000 --- a/src/mesa/drivers/dri/r200/r200_vtxfmt.h +++ /dev/null @@ -1,123 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt.h,v 1.1 2002/10/30 12:51:53 alanh Exp $ */ -/* -Copyright (C) The Weather Channel, Inc. 2002. 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 - */ - -#ifndef __R200_VTXFMT_H__ -#define __R200_VTXFMT_H__ - -#include "r200_context.h" - - - -extern void r200VtxfmtUpdate( GLcontext *ctx ); -extern void r200VtxfmtInit( GLcontext *ctx, GLboolean useCodegen ); -extern void r200VtxfmtInvalidate( GLcontext *ctx ); -extern void r200VtxfmtDestroy( GLcontext *ctx ); -extern void r200VtxfmtInitChoosers( GLvertexformat *vfmt ); - -extern void r200VtxfmtMakeCurrent( GLcontext *ctx ); -extern void r200VtxfmtUnbindContext( GLcontext *ctx ); - -extern void r200_copy_to_current( GLcontext *ctx ); -extern void VFMT_FALLBACK( const char *caller ); - -#define DFN( FUNC, CACHE) \ -do { \ - char *start = (char *)&FUNC; \ - char *end = (char *)&FUNC##_end; \ - insert_at_head( &CACHE, dfn ); \ - dfn->key[0] = key[0]; \ - dfn->key[1] = key[1]; \ - dfn->code = _mesa_exec_malloc( end - start ); \ - _mesa_memcpy(dfn->code, start, end - start); \ -} \ -while ( 0 ) - -#define FIXUP( CODE, OFFSET, CHECKVAL, NEWVAL ) \ -do { \ - int *icode = (int *)(CODE+OFFSET); \ - assert (*icode == CHECKVAL); \ - *icode = (int)NEWVAL; \ -} while (0) - - -/* Useful for figuring out the offsets: - */ -#define FIXUP2( CODE, OFFSET, CHECKVAL, NEWVAL ) \ -do { \ - while (*(int *)(CODE+OFFSET) != CHECKVAL) OFFSET++; \ - /*fprintf(stderr, "%s/%d CVAL %x OFFSET %d VAL %x\n", __FUNCTION__,*/ \ - /* __LINE__, CHECKVAL, OFFSET, (int)(NEWVAL));*/ \ - *(int *)(CODE+OFFSET) = (int)(NEWVAL); \ - OFFSET += 4; \ -} while (0) - -/* - */ -void r200InitCodegen( struct dfn_generators *gen, GLboolean useCodegen ); -void r200InitX86Codegen( struct dfn_generators *gen ); -void r200InitSSECodegen( struct dfn_generators *gen ); - - - -/* Defined in r200_vtxfmt_x86.c - */ -struct dynfn *r200_makeX86Vertex2f( GLcontext *, const int * ); -struct dynfn *r200_makeX86Vertex2fv( GLcontext *, const int * ); -struct dynfn *r200_makeX86Vertex3f( GLcontext *, const int * ); -struct dynfn *r200_makeX86Vertex3fv( GLcontext *, const int * ); -struct dynfn *r200_makeX86Color4ub( GLcontext *, const int * ); -struct dynfn *r200_makeX86Color4ubv( GLcontext *, const int * ); -struct dynfn *r200_makeX86Color3ub( GLcontext *, const int * ); -struct dynfn *r200_makeX86Color3ubv( GLcontext *, const int * ); -struct dynfn *r200_makeX86Color4f( GLcontext *, const int * ); -struct dynfn *r200_makeX86Color4fv( GLcontext *, const int * ); -struct dynfn *r200_makeX86Color3f( GLcontext *, const int * ); -struct dynfn *r200_makeX86Color3fv( GLcontext *, const int * ); -struct dynfn *r200_makeX86SecondaryColor3ubEXT( GLcontext *, const int * ); -struct dynfn *r200_makeX86SecondaryColor3ubvEXT( GLcontext *, const int * ); -struct dynfn *r200_makeX86SecondaryColor3fEXT( GLcontext *, const int * ); -struct dynfn *r200_makeX86SecondaryColor3fvEXT( GLcontext *, const int * ); -struct dynfn *r200_makeX86Normal3f( GLcontext *, const int * ); -struct dynfn *r200_makeX86Normal3fv( GLcontext *, const int * ); -struct dynfn *r200_makeX86TexCoord2f( GLcontext *, const int * ); -struct dynfn *r200_makeX86TexCoord2fv( GLcontext *, const int * ); -struct dynfn *r200_makeX86TexCoord1f( GLcontext *, const int * ); -struct dynfn *r200_makeX86TexCoord1fv( GLcontext *, const int * ); -struct dynfn *r200_makeX86MultiTexCoord2fARB( GLcontext *, const int * ); -struct dynfn *r200_makeX86MultiTexCoord2fvARB( GLcontext *, const int * ); -struct dynfn *r200_makeX86MultiTexCoord1fARB( GLcontext *, const int * ); -struct dynfn *r200_makeX86MultiTexCoord1fvARB( GLcontext *, const int * ); - -#endif diff --git a/src/mesa/drivers/dri/r200/r200_vtxfmt_c.c b/src/mesa/drivers/dri/r200/r200_vtxfmt_c.c deleted file mode 100644 index 1db5950c8f..0000000000 --- a/src/mesa/drivers/dri/r200/r200_vtxfmt_c.c +++ /dev/null @@ -1,1002 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_c.c,v 1.2 2002/12/16 16:18:56 dawes Exp $ */ -/* -Copyright (C) The Weather Channel, Inc. 2002. 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 - */ - -#include "glheader.h" -#include "imports.h" -#include "mtypes.h" -#include "colormac.h" -#include "simple_list.h" -#include "api_noop.h" -#include "vtxfmt.h" - -#include "r200_vtxfmt.h" -#include "r200_tcl.h" - -#include "dispatch.h" - -/* Fallback versions of all the entrypoints for situations where - * codegen isn't available. This is still a lot faster than the - * vb/pipeline implementation in Mesa. - */ -static void r200_Vertex3f( GLfloat x, GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - int i; - - *rmesa->vb.dmaptr++ = *(int *)&x; - *rmesa->vb.dmaptr++ = *(int *)&y; - *rmesa->vb.dmaptr++ = *(int *)&z; - - for (i = 3; i < rmesa->vb.vertex_size; i++) - *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i; - - if (--rmesa->vb.counter == 0) - rmesa->vb.notify(); -} - - -static void r200_Vertex3fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - int i; - - *rmesa->vb.dmaptr++ = *(int *)&v[0]; - *rmesa->vb.dmaptr++ = *(int *)&v[1]; - *rmesa->vb.dmaptr++ = *(int *)&v[2]; - - for (i = 3; i < rmesa->vb.vertex_size; i++) - *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i; - - if (--rmesa->vb.counter == 0) - rmesa->vb.notify(); -} - - -static void r200_Vertex2f( GLfloat x, GLfloat y ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - int i; - - *rmesa->vb.dmaptr++ = *(int *)&x; - *rmesa->vb.dmaptr++ = *(int *)&y; - *rmesa->vb.dmaptr++ = 0; - - for (i = 3; i < rmesa->vb.vertex_size; i++) - *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i; - - if (--rmesa->vb.counter == 0) - rmesa->vb.notify(); -} - - -static void r200_Vertex2fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - int i; - - *rmesa->vb.dmaptr++ = *(int *)&v[0]; - *rmesa->vb.dmaptr++ = *(int *)&v[1]; - *rmesa->vb.dmaptr++ = 0; - - for (i = 3; i < rmesa->vb.vertex_size; i++) - *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i; - - if (--rmesa->vb.counter == 0) - rmesa->vb.notify(); -} - - - -/* Color for ubyte (packed) color formats: - */ -#if 0 -static void r200_Color3ub_ub( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.colorptr; - dest->red = r; - dest->green = g; - dest->blue = b; - dest->alpha = 0xff; -} - -static void r200_Color3ubv_ub( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.colorptr; - dest->red = v[0]; - dest->green = v[1]; - dest->blue = v[2]; - dest->alpha = 0xff; -} - -static void r200_Color4ub_ub( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.colorptr; - dest->red = r; - dest->green = g; - dest->blue = b; - dest->alpha = a; -} - -static void r200_Color4ubv_ub( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - *(GLuint *)rmesa->vb.colorptr = LE32_TO_CPU(*(GLuint *)v); -} -#endif /* 0 */ - -static void r200_Color3f_ub( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.colorptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); - dest->alpha = 255; -} - -static void r200_Color3fv_ub( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.colorptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); - dest->alpha = 255; -} - -static void r200_Color4f_ub( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.colorptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, a ); -} - -static void r200_Color4fv_ub( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.colorptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, v[3] ); -} - - -/* Color for float color+alpha formats: - */ -#if 0 -static void r200_Color3ub_4f( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); - dest[3] = 1.0; -} - -static void r200_Color3ubv_4f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); - dest[3] = 1.0; -} - -static void r200_Color4ub_4f( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); - dest[3] = UBYTE_TO_FLOAT(a); -} - -static void r200_Color4ubv_4f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); - dest[3] = UBYTE_TO_FLOAT(v[3]); -} -#endif /* 0 */ - - -static void r200_Color3f_4f( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; - dest[3] = 1.0; -} - -static void r200_Color3fv_4f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - dest[3] = 1.0; -} - -static void r200_Color4f_4f( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; - dest[3] = a; -} - -static void r200_Color4fv_4f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - dest[3] = v[3]; -} - - -/* Color for float color formats: - */ -#if 0 -static void r200_Color3ub_3f( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); -} - -static void r200_Color3ubv_3f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); -} - -static void r200_Color4ub_3f( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT(a); -} - -static void r200_Color4ubv_3f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT(v[3]); -} -#endif /* 0 */ - - -static void r200_Color3f_3f( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; -} - -static void r200_Color3fv_3f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; -} - -static void r200_Color4f_3f( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = a; -} - -static void r200_Color4fv_3f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = v[3]; -} - - -/* Secondary Color: - */ -#if 0 -static void r200_SecondaryColor3ubEXT_ub( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.specptr; - dest->red = r; - dest->green = g; - dest->blue = b; - dest->alpha = 0xff; -} - -static void r200_SecondaryColor3ubvEXT_ub( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.specptr; - dest->red = v[0]; - dest->green = v[1]; - dest->blue = v[2]; - dest->alpha = 0xff; -} -#endif /* 0 */ - -static void r200_SecondaryColor3fEXT_ub( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.specptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); - dest->alpha = 255; -} - -static void r200_SecondaryColor3fvEXT_ub( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - r200_color_t *dest = rmesa->vb.specptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); - dest->alpha = 255; -} - -#if 0 -static void r200_SecondaryColor3ubEXT_3f( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatspecptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); - dest[3] = 1.0; -} - -static void r200_SecondaryColor3ubvEXT_3f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatspecptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); - dest[3] = 1.0; -} -#endif /* 0 */ - -static void r200_SecondaryColor3fEXT_3f( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatspecptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; - dest[3] = 1.0; -} - -static void r200_SecondaryColor3fvEXT_3f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatspecptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - dest[3] = 1.0; -} - - - -/* Normal - */ -static void r200_Normal3f( GLfloat n0, GLfloat n1, GLfloat n2 ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.normalptr; - dest[0] = n0; - dest[1] = n1; - dest[2] = n2; -} - -static void r200_Normal3fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.normalptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; -} - - -/* FogCoord - */ -static void r200_FogCoordfEXT( GLfloat f ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.fogptr; - dest[0] = r200ComputeFogBlendFactor( ctx, f ); -/* ctx->Current.Attrib[VERT_ATTRIB_FOG][0] = f;*/ -} - -static void r200_FogCoordfvEXT( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.fogptr; - dest[0] = r200ComputeFogBlendFactor( ctx, v[0] ); -/* ctx->Current.Attrib[VERT_ATTRIB_FOG][0] = v[0];*/ -} - - -/* TexCoord - */ - -/* \todo maybe (target & 4 ? target & 5 : target & 3) is more save than (target & 7) */ -static void r200_MultiTexCoord1fARB(GLenum target, GLfloat s) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLint unit = (target & 7); - GLfloat * const dest = rmesa->vb.texcoordptr[unit]; - - switch( ctx->Texture.Unit[unit]._ReallyEnabled ) { - case TEXTURE_CUBE_BIT: - case TEXTURE_3D_BIT: - dest[2] = 0.0; - /* FALLTHROUGH */ - case TEXTURE_2D_BIT: - case TEXTURE_RECT_BIT: - dest[1] = 0.0; - /* FALLTHROUGH */ - case TEXTURE_1D_BIT: - dest[0] = s; - } -} - -static void r200_MultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLint unit = (target & 7); - GLfloat * const dest = rmesa->vb.texcoordptr[unit]; - - switch( ctx->Texture.Unit[unit]._ReallyEnabled ) { - case TEXTURE_CUBE_BIT: - case TEXTURE_3D_BIT: - dest[2] = 0.0; - /* FALLTHROUGH */ - case TEXTURE_2D_BIT: - case TEXTURE_RECT_BIT: - dest[1] = t; - dest[0] = s; - break; - default: - VFMT_FALLBACK(__FUNCTION__); - CALL_MultiTexCoord2fARB(GET_DISPATCH(), (target, s, t)); - return; - } -} - -static void r200_MultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLint unit = (target & 7); - GLfloat * const dest = rmesa->vb.texcoordptr[unit]; - - switch( ctx->Texture.Unit[unit]._ReallyEnabled ) { - case TEXTURE_CUBE_BIT: - case TEXTURE_3D_BIT: - dest[2] = r; - dest[1] = t; - dest[0] = s; - break; - default: - VFMT_FALLBACK(__FUNCTION__); - CALL_MultiTexCoord3fARB(GET_DISPATCH(), (target, s, t, r)); - return; - } -} - -static void r200_TexCoord1f(GLfloat s) -{ - r200_MultiTexCoord1fARB(GL_TEXTURE0, s); -} - -static void r200_TexCoord2f(GLfloat s, GLfloat t) -{ - r200_MultiTexCoord2fARB(GL_TEXTURE0, s, t); -} - -static void r200_TexCoord3f(GLfloat s, GLfloat t, GLfloat r) -{ - r200_MultiTexCoord3fARB(GL_TEXTURE0, s, t, r); -} - -static void r200_TexCoord1fv(const GLfloat *v) -{ - r200_MultiTexCoord1fARB(GL_TEXTURE0, v[0]); -} - -static void r200_TexCoord2fv(const GLfloat *v) -{ - r200_MultiTexCoord2fARB(GL_TEXTURE0, v[0], v[1]); -} - -static void r200_TexCoord3fv(const GLfloat *v) -{ - r200_MultiTexCoord3fARB(GL_TEXTURE0, v[0], v[1], v[2]); -} - -static void r200_MultiTexCoord1fvARB(GLenum target, const GLfloat *v) -{ - r200_MultiTexCoord1fARB(target, v[0]); -} - -static void r200_MultiTexCoord2fvARB(GLenum target, const GLfloat *v) -{ - r200_MultiTexCoord2fARB(target, v[0], v[1]); -} - -static void r200_MultiTexCoord3fvARB(GLenum target, const GLfloat *v) -{ - r200_MultiTexCoord3fARB(target, v[0], v[1], v[2]); -} - - -static struct dynfn *lookup( struct dynfn *l, const int *key ) -{ - struct dynfn *f; - - foreach( f, l ) { - if (f->key[0] == key[0] && f->key[1] == key[1]) - return f; - } - - return NULL; -} - -/* Can't use the loopback template for this: - */ - -#define CHOOSE(FN, FNTYPE, MASK0, MASK1, ARGS1, ARGS2 ) \ -static void choose_##FN ARGS1 \ -{ \ - GET_CURRENT_CONTEXT(ctx); \ - r200ContextPtr rmesa = R200_CONTEXT(ctx); \ - int key[2]; \ - struct dynfn *dfn; \ - \ - key[0] = rmesa->vb.vtxfmt_0 & MASK0; \ - key[1] = rmesa->vb.vtxfmt_1 & MASK1; \ - \ - dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \ - if (dfn == 0) \ - dfn = rmesa->vb.codegen.FN( ctx, key ); \ - else if (R200_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- cached codegen\n", __FUNCTION__ ); \ - \ - if (dfn) \ - SET_ ## FN (ctx->Exec, (FNTYPE)(dfn->code)); \ - else { \ - if (R200_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \ - SET_ ## FN (ctx->Exec, r200_##FN); \ - } \ - \ - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \ - CALL_ ## FN (ctx->Exec, ARGS2); \ -} - - - -/* For the _3f case, only allow one color function to be hooked in at - * a time. Eventually, use a similar mechanism to allow selecting the - * color component of the vertex format based on client behaviour. - * - * Note: Perform these actions even if there is a codegen or cached - * codegen version of the chosen function. - */ -#define CHOOSE_COLOR(FN, FNTYPE, NR, MASK0, MASK1, ARGS1, ARGS2 ) \ -static void choose_##FN ARGS1 \ -{ \ - GET_CURRENT_CONTEXT(ctx); \ - r200ContextPtr rmesa = R200_CONTEXT(ctx); \ - int key[2]; \ - struct dynfn *dfn; \ - \ - key[0] = rmesa->vb.vtxfmt_0 & MASK0; \ - key[1] = rmesa->vb.vtxfmt_1 & MASK1; \ - \ - if (VTX_COLOR(rmesa->vb.vtxfmt_0,0) == R200_VTX_PK_RGBA) { \ - SET_ ## FN (ctx->Exec, r200_##FN##_ub); \ - } \ - else if (VTX_COLOR(rmesa->vb.vtxfmt_0,0) == R200_VTX_FP_RGB) { \ - \ - if (rmesa->vb.installed_color_3f_sz != NR) { \ - rmesa->vb.installed_color_3f_sz = NR; \ - if (NR == 3) ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = 1.0; \ - if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) { \ - r200_copy_to_current( ctx ); \ - _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); \ - CALL_ ## FN (ctx->Exec, ARGS2); \ - return; \ - } \ - } \ - \ - SET_ ## FN (ctx->Exec, r200_##FN##_3f); \ - } \ - else { \ - SET_ ## FN (ctx->Exec, r200_##FN##_4f); \ - } \ - \ - \ - dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \ - if (!dfn) dfn = rmesa->vb.codegen.FN( ctx, key ); \ - \ - if (dfn) { \ - if (R200_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- codegen version\n", __FUNCTION__ ); \ - SET_ ## FN (ctx->Exec, (FNTYPE)dfn->code); \ - } \ - else if (R200_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- 'c' version\n", __FUNCTION__ ); \ - \ - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \ - CALL_ ## FN (ctx->Exec, ARGS2); \ -} - - - -/* Right now there are both _ub and _3f versions of the secondary color - * functions. Currently, we only set-up the hardware to use the _ub versions. - * The _3f versions are needed for the cases where secondary color isn't used - * in the vertex format, but it still needs to be stored in the context - * state vector. - */ -#define CHOOSE_SECONDARY_COLOR(FN, FNTYPE, MASK0, MASK1, ARGS1, ARGS2 ) \ -static void choose_##FN ARGS1 \ -{ \ - GET_CURRENT_CONTEXT(ctx); \ - r200ContextPtr rmesa = R200_CONTEXT(ctx); \ - int key[2]; \ - struct dynfn *dfn; \ - \ - key[0] = rmesa->vb.vtxfmt_0 & MASK0; \ - key[1] = rmesa->vb.vtxfmt_1 & MASK1; \ - \ - dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \ - if (dfn == 0) \ - dfn = rmesa->vb.codegen.FN( ctx, key ); \ - else if (R200_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- cached version\n", __FUNCTION__ ); \ - \ - if (dfn) \ - SET_ ## FN (ctx->Exec, (FNTYPE)(dfn->code)); \ - else { \ - if (R200_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \ - SET_ ## FN (ctx->Exec, (VTX_COLOR(rmesa->vb.vtxfmt_0,1) == R200_VTX_PK_RGBA) \ - ? r200_##FN##_ub : r200_##FN##_3f); \ - } \ - \ - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \ - CALL_ ## FN (ctx->Exec, ARGS2); \ -} - - - - - - - -/* VTXFMT_0 - */ -#define MASK_XYZW (R200_VTX_W0|R200_VTX_Z0) -#define MASK_NORM (MASK_XYZW|R200_VTX_N0) -#define MASK_FOG (MASK_NORM |R200_VTX_DISCRETE_FOG) -#define MASK_COLOR (MASK_FOG |(R200_VTX_COLOR_MASK<Color3f = choose_Color3f; - vfmt->Color3fv = choose_Color3fv; - vfmt->Color4f = choose_Color4f; - vfmt->Color4fv = choose_Color4fv; - vfmt->SecondaryColor3fEXT = choose_SecondaryColor3fEXT; - vfmt->SecondaryColor3fvEXT = choose_SecondaryColor3fvEXT; - vfmt->MultiTexCoord1fARB = choose_MultiTexCoord1fARB; - vfmt->MultiTexCoord1fvARB = choose_MultiTexCoord1fvARB; - vfmt->MultiTexCoord2fARB = choose_MultiTexCoord2fARB; - vfmt->MultiTexCoord2fvARB = choose_MultiTexCoord2fvARB; - vfmt->MultiTexCoord3fARB = choose_MultiTexCoord3fARB; - vfmt->MultiTexCoord3fvARB = choose_MultiTexCoord3fvARB; - vfmt->Normal3f = choose_Normal3f; - vfmt->Normal3fv = choose_Normal3fv; - vfmt->TexCoord1f = choose_TexCoord1f; - vfmt->TexCoord1fv = choose_TexCoord1fv; - vfmt->TexCoord2f = choose_TexCoord2f; - vfmt->TexCoord2fv = choose_TexCoord2fv; - vfmt->TexCoord3f = choose_TexCoord3f; - vfmt->TexCoord3fv = choose_TexCoord3fv; - vfmt->Vertex2f = choose_Vertex2f; - vfmt->Vertex2fv = choose_Vertex2fv; - vfmt->Vertex3f = choose_Vertex3f; - vfmt->Vertex3fv = choose_Vertex3fv; -/* vfmt->FogCoordfEXT = choose_FogCoordfEXT; - vfmt->FogCoordfvEXT = choose_FogCoordfvEXT;*/ - - /* TODO: restore ubyte colors to vtxfmt. - */ -#if 0 - vfmt->Color3ub = choose_Color3ub; - vfmt->Color3ubv = choose_Color3ubv; - vfmt->Color4ub = choose_Color4ub; - vfmt->Color4ubv = choose_Color4ubv; - vfmt->SecondaryColor3ubEXT = choose_SecondaryColor3ubEXT; - vfmt->SecondaryColor3ubvEXT = choose_SecondaryColor3ubvEXT; -#endif -} - - -static struct dynfn *codegen_noop( GLcontext *ctx, const int *key ) -{ - (void) ctx; (void) key; - return NULL; -} - -void r200InitCodegen( struct dfn_generators *gen, GLboolean useCodegen ) -{ - gen->Vertex3f = codegen_noop; - gen->Vertex3fv = codegen_noop; - gen->Color4ub = codegen_noop; - gen->Color4ubv = codegen_noop; - gen->Normal3f = codegen_noop; - gen->Normal3fv = codegen_noop; - - gen->TexCoord3f = codegen_noop; - gen->TexCoord3fv = codegen_noop; - gen->TexCoord2f = codegen_noop; - gen->TexCoord2fv = codegen_noop; - gen->TexCoord1f = codegen_noop; - gen->TexCoord1fv = codegen_noop; - - gen->MultiTexCoord3fARB = codegen_noop; - gen->MultiTexCoord3fvARB = codegen_noop; - gen->MultiTexCoord2fARB = codegen_noop; - gen->MultiTexCoord2fvARB = codegen_noop; - gen->MultiTexCoord1fARB = codegen_noop; - gen->MultiTexCoord1fvARB = codegen_noop; -/* gen->FogCoordfEXT = codegen_noop; - gen->FogCoordfvEXT = codegen_noop;*/ - - gen->Vertex2f = codegen_noop; - gen->Vertex2fv = codegen_noop; - gen->Color3ub = codegen_noop; - gen->Color3ubv = codegen_noop; - gen->Color4f = codegen_noop; - gen->Color4fv = codegen_noop; - gen->Color3f = codegen_noop; - gen->Color3fv = codegen_noop; - gen->SecondaryColor3fEXT = codegen_noop; - gen->SecondaryColor3fvEXT = codegen_noop; - gen->SecondaryColor3ubEXT = codegen_noop; - gen->SecondaryColor3ubvEXT = codegen_noop; - - if (useCodegen) { -#if defined(USE_X86_ASM) - r200InitX86Codegen( gen ); -#endif - -#if defined(USE_SSE_ASM) - r200InitSSECodegen( gen ); -#endif - } -} diff --git a/src/mesa/drivers/dri/r200/r200_vtxfmt_sse.c b/src/mesa/drivers/dri/r200/r200_vtxfmt_sse.c deleted file mode 100644 index 5901730494..0000000000 --- a/src/mesa/drivers/dri/r200/r200_vtxfmt_sse.c +++ /dev/null @@ -1,234 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_sse.c,v 1.1 2002/10/30 12:51:53 alanh Exp $ */ -/* -Copyright (C) The Weather Channel, Inc. 2002. 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 - */ - -#include "glheader.h" -#include "imports.h" -#include "simple_list.h" -#include "r200_vtxfmt.h" - -#if defined(USE_SSE_ASM) -#include "x86/common_x86_asm.h" - -#define EXTERN( FUNC ) \ -extern const char *FUNC; \ -extern const char *FUNC##_end - -EXTERN( _sse_Attribute2fv ); -EXTERN( _sse_Attribute2f ); -EXTERN( _sse_Attribute3fv ); -EXTERN( _sse_Attribute3f ); -EXTERN( _sse_MultiTexCoord2fv ); -EXTERN( _sse_MultiTexCoord2f ); -EXTERN( _sse_MultiTexCoord2fv_2 ); -EXTERN( _sse_MultiTexCoord2f_2 ); - -/* Build specialized versions of the immediate calls on the fly for - * the current state. - */ - -static struct dynfn *r200_makeSSEAttribute2fv( struct dynfn * cache, const int * key, - const char * name, void * dest) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key[0] ); - - DFN ( _sse_Attribute2fv, (*cache) ); - FIXUP(dfn->code, 10, 0x0, (int)dest); - return dfn; -} - -static struct dynfn *r200_makeSSEAttribute2f( struct dynfn * cache, const int * key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key[0] ); - - DFN ( _sse_Attribute2f, (*cache) ); - FIXUP(dfn->code, 8, 0x0, (int)dest); - return dfn; -} - -static struct dynfn *r200_makeSSEAttribute3fv( struct dynfn * cache, const int * key, - const char * name, void * dest) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key[0] ); - - DFN ( _sse_Attribute3fv, (*cache) ); - FIXUP(dfn->code, 13, 0x0, (int)dest); - FIXUP(dfn->code, 18, 0x8, 8+(int)dest); - return dfn; -} - -static struct dynfn *r200_makeSSEAttribute3f( struct dynfn * cache, const int * key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key[0] ); - - DFN ( _sse_Attribute3f, (*cache) ); - FIXUP(dfn->code, 12, 0x0, (int)dest); - FIXUP(dfn->code, 17, 0x8, 8+(int)dest); - return dfn; -} - -static struct dynfn *r200_makeSSENormal3fv( GLcontext *ctx, const int *key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeSSEAttribute3fv( & rmesa->vb.dfn_cache.Normal3fv, key, - __FUNCTION__, rmesa->vb.normalptr ); -} - -static struct dynfn *r200_makeSSENormal3f( GLcontext *ctx, const int * key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeSSEAttribute3f( & rmesa->vb.dfn_cache.Normal3f, key, - __FUNCTION__, rmesa->vb.normalptr ); -} - -static struct dynfn *r200_makeSSEColor3fv( GLcontext *ctx, const int * key ) -{ - if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB) - return NULL; - else - { - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeSSEAttribute3fv( & rmesa->vb.dfn_cache.Color3fv, key, - __FUNCTION__, rmesa->vb.floatcolorptr ); - } -} - -static struct dynfn *r200_makeSSEColor3f( GLcontext *ctx, const int * key ) -{ - if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB) - return NULL; - else - { - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeSSEAttribute3f( & rmesa->vb.dfn_cache.Color3f, key, - __FUNCTION__, rmesa->vb.floatcolorptr ); - } -} - -#if 0 /* Temporarily disabled as it is broken w/the new cubemap code. - idr */ -static struct dynfn *r200_makeSSETexCoord2fv( GLcontext *ctx, const int * key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeSSEAttribute2fv( & rmesa->vb.dfn_cache.TexCoord2fv, key, - __FUNCTION__, rmesa->vb.texcoordptr[0] ); -} - -static struct dynfn *r200_makeSSETexCoord2f( GLcontext *ctx, const int * key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeSSEAttribute2f( & rmesa->vb.dfn_cache.TexCoord2f, key, - __FUNCTION__, rmesa->vb.texcoordptr[0] ); -} - -static struct dynfn *r200_makeSSEMultiTexCoord2fv( GLcontext *ctx, const int * key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); - - if (rmesa->vb.texcoordptr[1] == rmesa->vb.texcoordptr[0]+4) { - DFN ( _sse_MultiTexCoord2fv, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 18, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - } else { - DFN ( _sse_MultiTexCoord2fv_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 14, 0x0, (int)rmesa->vb.texcoordptr); - } - return dfn; -} - -static struct dynfn *r200_makeSSEMultiTexCoord2f( GLcontext *ctx, const int * key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); - - if (rmesa->vb.texcoordptr[1] == rmesa->vb.texcoordptr[0]+4) { - DFN ( _sse_MultiTexCoord2f, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 16, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - } else { - DFN ( _sse_MultiTexCoord2f_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 15, 0x0, (int)rmesa->vb.texcoordptr); - } - return dfn; -} -#endif - -void r200InitSSECodegen( struct dfn_generators *gen ) -{ - if ( cpu_has_xmm ) { - gen->Normal3fv = (void *) r200_makeSSENormal3fv; - gen->Normal3f = (void *) r200_makeSSENormal3f; - gen->Color3fv = (void *) r200_makeSSEColor3fv; - gen->Color3f = (void *) r200_makeSSEColor3f; -#if 0 /* Temporarily disabled as it is broken w/the new cubemap code. - idr */ - gen->TexCoord2fv = (void *) r200_makeSSETexCoord2fv; - gen->TexCoord2f = (void *) r200_makeSSETexCoord2f; - gen->MultiTexCoord2fvARB = (void *) r200_makeSSEMultiTexCoord2fv; - gen->MultiTexCoord2fARB = (void *) r200_makeSSEMultiTexCoord2f; -#endif - } -} - -#else - -void r200InitSSECodegen( struct dfn_generators *gen ) -{ - (void) gen; -} - -#endif diff --git a/src/mesa/drivers/dri/r200/r200_vtxfmt_x86.c b/src/mesa/drivers/dri/r200/r200_vtxfmt_x86.c deleted file mode 100644 index b78a55c31f..0000000000 --- a/src/mesa/drivers/dri/r200/r200_vtxfmt_x86.c +++ /dev/null @@ -1,440 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxfmt_x86.c,v 1.2 2002/12/16 16:18:56 dawes Exp $ */ -/* -Copyright (C) The Weather Channel, Inc. 2002. 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 - */ - -#include "glheader.h" -#include "imports.h" -#include "simple_list.h" -#include "r200_vtxfmt.h" - -#if defined(USE_X86_ASM) - -#define EXTERN( FUNC ) \ -extern const char *FUNC; \ -extern const char *FUNC##_end - -EXTERN ( _x86_Attribute2fv ); -EXTERN ( _x86_Attribute2f ); -EXTERN ( _x86_Attribute3fv ); -EXTERN ( _x86_Attribute3f ); -EXTERN ( _x86_Vertex3fv_6 ); -EXTERN ( _x86_Vertex3fv_8 ); -EXTERN ( _x86_Vertex3fv ); -EXTERN ( _x86_Vertex3f_4 ); -EXTERN ( _x86_Vertex3f_6 ); -EXTERN ( _x86_Vertex3f ); -EXTERN ( _x86_Color4ubv_ub ); -EXTERN ( _x86_Color4ubv_4f ); -EXTERN ( _x86_Color4ub_ub ); -EXTERN ( _x86_MultiTexCoord2fv ); -EXTERN ( _x86_MultiTexCoord2fv_2 ); -EXTERN ( _x86_MultiTexCoord2f ); -EXTERN ( _x86_MultiTexCoord2f_2 ); - - -/* Build specialized versions of the immediate calls on the fly for - * the current state. Generic x86 versions. - */ - -struct dynfn *r200_makeX86Vertex3f( GLcontext *ctx, const int *key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x 0x%08x %d\n", __FUNCTION__, - key[0], key[1], rmesa->vb.vertex_size ); - - switch (rmesa->vb.vertex_size) { - case 4: { - - DFN ( _x86_Vertex3f_4, rmesa->vb.dfn_cache.Vertex3f ); - FIXUP(dfn->code, 2, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 25, 0x0, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 36, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 46, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 51, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 60, 0x0, (int)&rmesa->vb.notify); - break; - } - case 6: { - - DFN ( _x86_Vertex3f_6, rmesa->vb.dfn_cache.Vertex3f ); - FIXUP(dfn->code, 3, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 28, 0x0, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 34, 0x0, (int)&rmesa->vb.vertex[4]); - FIXUP(dfn->code, 40, 0x0, (int)&rmesa->vb.vertex[5]); - FIXUP(dfn->code, 57, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 63, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 70, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 79, 0x0, (int)&rmesa->vb.notify); - break; - } - default: { - - DFN ( _x86_Vertex3f, rmesa->vb.dfn_cache.Vertex3f ); - FIXUP(dfn->code, 3, 0x0, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 9, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 37, 0x0, rmesa->vb.vertex_size-3); - FIXUP(dfn->code, 44, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 50, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 56, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 67, 0x0, (int)&rmesa->vb.notify); - break; - } - } - - return dfn; -} - - - -struct dynfn *r200_makeX86Vertex3fv( GLcontext *ctx, const int *key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x 0x%08x %d\n", __FUNCTION__, - key[0], key[1], rmesa->vb.vertex_size ); - - switch (rmesa->vb.vertex_size) { - case 6: { - - DFN ( _x86_Vertex3fv_6, rmesa->vb.dfn_cache.Vertex3fv ); - FIXUP(dfn->code, 1, 0x00000000, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 27, 0x0000001c, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 33, 0x00000020, (int)&rmesa->vb.vertex[4]); - FIXUP(dfn->code, 45, 0x00000024, (int)&rmesa->vb.vertex[5]); - FIXUP(dfn->code, 56, 0x00000000, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 61, 0x00000004, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 67, 0x00000004, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 76, 0x00000008, (int)&rmesa->vb.notify); - break; - } - - - case 8: { - - DFN ( _x86_Vertex3fv_8, rmesa->vb.dfn_cache.Vertex3fv ); - FIXUP(dfn->code, 1, 0x00000000, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 27, 0x0000001c, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 33, 0x00000020, (int)&rmesa->vb.vertex[4]); - FIXUP(dfn->code, 45, 0x0000001c, (int)&rmesa->vb.vertex[5]); - FIXUP(dfn->code, 51, 0x00000020, (int)&rmesa->vb.vertex[6]); - FIXUP(dfn->code, 63, 0x00000024, (int)&rmesa->vb.vertex[7]); - FIXUP(dfn->code, 74, 0x00000000, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 79, 0x00000004, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 85, 0x00000004, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 94, 0x00000008, (int)&rmesa->vb.notify); - break; - } - - - - default: { - - DFN ( _x86_Vertex3fv, rmesa->vb.dfn_cache.Vertex3fv ); - FIXUP(dfn->code, 8, 0x01010101, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 32, 0x00000006, rmesa->vb.vertex_size-3); - FIXUP(dfn->code, 37, 0x00000058, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 45, 0x01010101, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 50, 0x02020202, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 58, 0x02020202, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 67, 0x0, (int)&rmesa->vb.notify); - break; - } - } - - return dfn; -} - -static struct dynfn * -r200_makeX86Attribute2fv( struct dynfn * cache, const int *key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key[0] ); - - DFN ( _x86_Attribute2fv, (*cache) ); - FIXUP(dfn->code, 11, 0x0, (int)dest); - FIXUP(dfn->code, 16, 0x4, 4+(int)dest); - - return dfn; -} - -static struct dynfn * -r200_makeX86Attribute2f( struct dynfn * cache, const int *key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key[0] ); - - DFN ( _x86_Attribute2f, (*cache) ); - FIXUP(dfn->code, 1, 0x0, (int)dest); - - return dfn; -} - - -static struct dynfn * -r200_makeX86Attribute3fv( struct dynfn * cache, const int *key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key[0] ); - - DFN ( _x86_Attribute3fv, (*cache) ); - FIXUP(dfn->code, 14, 0x0, (int)dest); - FIXUP(dfn->code, 20, 0x4, 4+(int)dest); - FIXUP(dfn->code, 25, 0x8, 8+(int)dest); - - return dfn; -} - -static struct dynfn * -r200_makeX86Attribute3f( struct dynfn * cache, const int *key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key[0] ); - - DFN ( _x86_Attribute3f, (*cache) ); - FIXUP(dfn->code, 14, 0x0, (int)dest); - FIXUP(dfn->code, 20, 0x4, 4+(int)dest); - FIXUP(dfn->code, 25, 0x8, 8+(int)dest); - - return dfn; -} - -struct dynfn *r200_makeX86Normal3fv( GLcontext *ctx, const int *key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeX86Attribute3fv( & rmesa->vb.dfn_cache.Normal3fv, key, - __FUNCTION__, rmesa->vb.normalptr ); -} - -struct dynfn *r200_makeX86Normal3f( GLcontext *ctx, const int *key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeX86Attribute3f( & rmesa->vb.dfn_cache.Normal3f, key, - __FUNCTION__, rmesa->vb.normalptr ); -} - -struct dynfn *r200_makeX86Color4ubv( GLcontext *ctx, const int *key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); - - if (VTX_COLOR(key[0],0) == R200_VTX_PK_RGBA) { - DFN ( _x86_Color4ubv_ub, rmesa->vb.dfn_cache.Color4ubv); - FIXUP(dfn->code, 5, 0x12345678, (int)rmesa->vb.colorptr); - return dfn; - } - else { - - DFN ( _x86_Color4ubv_4f, rmesa->vb.dfn_cache.Color4ubv); - FIXUP(dfn->code, 2, 0x00000000, (int)_mesa_ubyte_to_float_color_tab); - FIXUP(dfn->code, 27, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr); - FIXUP(dfn->code, 33, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr+4); - FIXUP(dfn->code, 55, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr+8); - FIXUP(dfn->code, 61, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr+12); - return dfn; - } -} - -struct dynfn *r200_makeX86Color4ub( GLcontext *ctx, const int *key ) -{ - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key[0] ); - - if (VTX_COLOR(key[0],0) == R200_VTX_PK_RGBA) { - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - DFN ( _x86_Color4ub_ub, rmesa->vb.dfn_cache.Color4ub ); - FIXUP(dfn->code, 18, 0x0, (int)rmesa->vb.colorptr); - FIXUP(dfn->code, 24, 0x0, (int)rmesa->vb.colorptr+1); - FIXUP(dfn->code, 30, 0x0, (int)rmesa->vb.colorptr+2); - FIXUP(dfn->code, 36, 0x0, (int)rmesa->vb.colorptr+3); - return dfn; - } - else - return NULL; -} - - -struct dynfn *r200_makeX86Color3fv( GLcontext *ctx, const int *key ) -{ - if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB) - return NULL; - else - { - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeX86Attribute3fv( & rmesa->vb.dfn_cache.Color3fv, key, - __FUNCTION__, rmesa->vb.floatcolorptr ); - } -} - -struct dynfn *r200_makeX86Color3f( GLcontext *ctx, const int *key ) -{ - if (VTX_COLOR(key[0],0) != R200_VTX_FP_RGB) - return NULL; - else - { - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeX86Attribute3f( & rmesa->vb.dfn_cache.Color3f, key, - __FUNCTION__, rmesa->vb.floatcolorptr ); - } -} - - - -#if 0 /* Temporarily disabled as it is broken w/the new cubemap code. - idr */ -struct dynfn *r200_makeX86TexCoord2fv( GLcontext *ctx, const int *key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeX86Attribute2fv( & rmesa->vb.dfn_cache.TexCoord2fv, key, - __FUNCTION__, rmesa->vb.texcoordptr[0] ); -} - -struct dynfn *r200_makeX86TexCoord2f( GLcontext *ctx, const int *key ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - return r200_makeX86Attribute2f( & rmesa->vb.dfn_cache.TexCoord2f, key, - __FUNCTION__, rmesa->vb.texcoordptr[0] ); -} - -struct dynfn *r200_makeX86MultiTexCoord2fvARB( GLcontext *ctx, const int *key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x 0x%08x\n", __FUNCTION__, key[0], key[1] ); - - if (rmesa->vb.texcoordptr[1] == rmesa->vb.texcoordptr[0]+4) { - DFN ( _x86_MultiTexCoord2fv, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 21, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - FIXUP(dfn->code, 27, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]+4); - } else { - DFN ( _x86_MultiTexCoord2fv_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 14, 0x0, (int)rmesa->vb.texcoordptr); - } - return dfn; -} - -struct dynfn *r200_makeX86MultiTexCoord2fARB( GLcontext *ctx, - const int *key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - if (R200_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x 0x%08x\n", __FUNCTION__, key[0], key[1] ); - - if (rmesa->vb.texcoordptr[1] == rmesa->vb.texcoordptr[0]+4) { - DFN ( _x86_MultiTexCoord2f, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 20, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - FIXUP(dfn->code, 26, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]+4); - } - else { - /* Note: this might get generated multiple times, even though the - * actual emitted code is the same. - */ - DFN ( _x86_MultiTexCoord2f_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 18, 0x0, (int)rmesa->vb.texcoordptr); - } - return dfn; -} -#endif - -void r200InitX86Codegen( struct dfn_generators *gen ) -{ - gen->Vertex3f = r200_makeX86Vertex3f; - gen->Vertex3fv = r200_makeX86Vertex3fv; - gen->Color4ub = r200_makeX86Color4ub; /* PKCOLOR only */ - gen->Color4ubv = r200_makeX86Color4ubv; /* PKCOLOR only */ - gen->Normal3f = r200_makeX86Normal3f; - gen->Normal3fv = r200_makeX86Normal3fv; -#if 0 /* Temporarily disabled as it is broken w/the new cubemap code. - idr */ - gen->TexCoord2f = r200_makeX86TexCoord2f; - gen->TexCoord2fv = r200_makeX86TexCoord2fv; - gen->MultiTexCoord2fARB = r200_makeX86MultiTexCoord2fARB; - gen->MultiTexCoord2fvARB = r200_makeX86MultiTexCoord2fvARB; -#endif - gen->Color3f = r200_makeX86Color3f; - gen->Color3fv = r200_makeX86Color3fv; - - /* Not done: - */ -/* gen->Vertex2f = r200_makeX86Vertex2f; */ -/* gen->Vertex2fv = r200_makeX86Vertex2fv; */ -/* gen->Color3ub = r200_makeX86Color3ub; */ -/* gen->Color3ubv = r200_makeX86Color3ubv; */ -/* gen->Color4f = r200_makeX86Color4f; */ -/* gen->Color4fv = r200_makeX86Color4fv; */ -/* gen->TexCoord1f = r200_makeX86TexCoord1f; */ -/* gen->TexCoord1fv = r200_makeX86TexCoord1fv; */ -/* gen->MultiTexCoord1fARB = r200_makeX86MultiTexCoord1fARB; */ -/* gen->MultiTexCoord1fvARB = r200_makeX86MultiTexCoord1fvARB; */ -} - - -#else - -void r200InitX86Codegen( struct dfn_generators *gen ) -{ - (void) gen; -} - -#endif diff --git a/src/mesa/drivers/dri/r200/r200_vtxtmp_x86.S b/src/mesa/drivers/dri/r200/r200_vtxtmp_x86.S deleted file mode 100644 index 5e33c7bdee..0000000000 --- a/src/mesa/drivers/dri/r200/r200_vtxtmp_x86.S +++ /dev/null @@ -1,499 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_vtxtmp_x86.S,v 1.2 2002/11/07 18:31:59 tsi Exp $ */ -/************************************************************************** - -Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. - -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 -ATI, TUNGSTEN GRAPHICS AND/OR THEIR 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. - -**************************************************************************/ - -#define GLOBL( x ) \ -.globl x; \ -x: - -.data -.align 4 - -/* - vertex 3f vertex size 4 -*/ - -GLOBL ( _x86_Vertex3f_4 ) - movl (0), %ecx - movl 4(%esp), %eax - movl 8(%esp), %edx - movl %eax, (%ecx) - movl %edx, 4(%ecx) - movl 12(%esp), %eax - movl (0), %edx - movl %eax, 8(%ecx) - movl %edx, 12(%ecx) - movl (0), %eax - addl $16, %ecx - dec %eax - movl %ecx, (0) - movl %eax, (0) - je .1 - ret -.1: jmp *0 - -GLOBL ( _x86_Vertex3f_4_end ) - -/* - vertex 3f vertex size 6 -*/ -GLOBL ( _x86_Vertex3f_6 ) - push %edi - movl (0), %edi - movl 8(%esp), %eax - movl 12(%esp), %edx - movl 16(%esp), %ecx - movl %eax, (%edi) - movl %edx, 4(%edi) - movl %ecx, 8(%edi) - movl (0), %eax - movl (0), %edx - movl (0), %ecx - movl %eax, 12(%edi) - movl %edx, 16(%edi) - movl %ecx, 20(%edi) - addl $24, %edi - movl (0), %eax - movl %edi, (0) - dec %eax - pop %edi - movl %eax, (0) - je .2 - ret -.2: jmp *0 -GLOBL ( _x86_Vertex3f_6_end ) -/* - vertex 3f generic size -*/ -GLOBL ( _x86_Vertex3f ) - push %edi - push %esi - movl $0, %esi - movl (0), %edi - movl 12(%esp), %eax - movl 16(%esp), %edx - movl 20(%esp), %ecx - movl %eax, (%edi) - movl %edx, 4(%edi) - movl %ecx, 8(%edi) - addl $12, %edi - movl $0, %ecx - repz - movsl %ds:(%esi), %es:(%edi) - movl (0), %eax - movl %edi, (0) - dec %eax - movl %eax, (0) - pop %esi - pop %edi - je .3 - ret -.3: jmp *0 - -GLOBL ( _x86_Vertex3f_end ) - -/* - Vertex 3fv vertex size 6 -*/ -GLOBL ( _x86_Vertex3fv_6 ) - movl (0), %eax - movl 4(%esp), %ecx - movl (%ecx), %edx - movl %edx, (%eax) - movl 4(%ecx), %edx - movl 8(%ecx), %ecx - movl %edx, 4(%eax) - movl %ecx, 8(%eax) - movl (28), %edx - movl (32), %ecx - movl %edx, 12(%eax) - movl %ecx, 16(%eax) - movl (36), %edx - movl %edx, 20(%eax) - addl $24, %eax - movl %eax, 0 - movl 4, %eax - dec %eax - movl %eax, 4 - je .4 - ret -.4: jmp *8 - -GLOBL ( _x86_Vertex3fv_6_end ) - -/* - Vertex 3fv vertex size 8 -*/ -GLOBL ( _x86_Vertex3fv_8 ) - movl (0), %eax - movl 4(%esp), %ecx - movl (%ecx), %edx - movl %edx ,(%eax) - movl 4(%ecx) ,%edx - movl 8(%ecx) ,%ecx - movl %edx, 4(%eax) - movl %ecx, 8(%eax) - movl (28), %edx - movl (32), %ecx - movl %edx, 12(%eax) - movl %ecx, 16(%eax) - movl (28), %edx - movl (32), %ecx - movl %edx, 20(%eax) - movl %ecx, 24(%eax) - movl (36), %edx - movl %edx, 28(%eax) - addl $32, %eax - movl %eax, (0) - movl 4, %eax - dec %eax - movl %eax, (4) - je .5 - ret -.5: jmp *8 - -GLOBL ( _x86_Vertex3fv_8_end ) - -/* - Vertex 3fv generic vertex size -*/ -GLOBL ( _x86_Vertex3fv ) - movl 4(%esp), %edx - push %edi - push %esi - movl (0x1010101), %edi - movl (%edx), %eax - movl 4(%edx), %ecx - movl 8(%edx), %esi - movl %eax, (%edi) - movl %ecx, 4(%edi) - movl %esi, 8(%edi) - addl $12, %edi - movl $6, %ecx - movl $0x58, %esi - repz - movsl %ds:(%esi), %es:(%edi) - movl %edi, (0x1010101) - movl (0x2020202), %eax - pop %esi - pop %edi - dec %eax - movl %eax, (0x2020202) - je .6 - ret -.6: jmp *0 -GLOBL ( _x86_Vertex3fv_end ) - - -/** - * Generic handler for 2 float format data. This can be used for - * TexCoord2f and possibly other functions. - */ - -GLOBL ( _x86_Attribute2f ) - movl $0x0, %edx - movl 4(%esp), %eax - movl 8(%esp), %ecx - movl %eax, (%edx) - movl %ecx, 4(%edx) - ret -GLOBL ( _x86_Attribute2f_end ) - - -/** - * Generic handler for 2 float vector format data. This can be used for - * TexCoord2fv and possibly other functions. - */ - -GLOBL( _x86_Attribute2fv) - movl 4(%esp), %eax /* load 'v' off stack */ - movl (%eax), %ecx /* load v[0] */ - movl 4(%eax), %eax /* load v[1] */ - movl %ecx, 0 /* store v[0] to current vertex */ - movl %eax, 4 /* store v[1] to current vertex */ - ret -GLOBL ( _x86_Attribute2fv_end ) - - -/** - * Generic handler for 3 float format data. This can be used for - * Normal3f, Color3f (when the color target is also float), or - * TexCoord3f. - */ - -GLOBL ( _x86_Attribute3f ) - movl 4(%esp), %ecx - movl 8(%esp), %edx - movl 12(%esp), %eax - movl %ecx, 0 - movl %edx, 4 - movl %eax, 8 - ret -GLOBL ( _x86_Attribute3f_end ) - -/** - * Generic handler for 3 float vector format data. This can be used for - * Normal3f, Color3f (when the color target is also float), or - * TexCoord3f. - */ - -GLOBL( _x86_Attribute3fv) - movl 4(%esp), %eax /* load 'v' off stack */ - movl (%eax), %ecx /* load v[0] */ - movl 4(%eax), %edx /* load v[1] */ - movl 8(%eax), %eax /* load v[2] */ - movl %ecx, 0 /* store v[0] to current vertex */ - movl %edx, 4 /* store v[1] to current vertex */ - movl %eax, 8 /* store v[2] to current vertex */ - ret -GLOBL ( _x86_Attribute3fv_end ) - - -/* - Color 4ubv_ub -*/ -GLOBL ( _x86_Color4ubv_ub ) - movl 4(%esp), %eax - movl $0x12345678, %edx - movl (%eax), %eax - movl %eax, (%edx) - ret -GLOBL ( _x86_Color4ubv_ub_end ) - -/* - Color 4ubv 4f -*/ -GLOBL ( _x86_Color4ubv_4f ) - push %ebx - movl $0, %edx - xor %eax, %eax - xor %ecx, %ecx - movl 8(%esp), %ebx - movl (%ebx), %ebx - mov %bl, %al - mov %bh, %cl - movl (%edx,%eax,4),%eax - movl (%edx,%ecx,4),%ecx - movl %eax, (0xdeadbeaf) - movl %ecx, (0xdeadbeaf) - xor %eax, %eax - xor %ecx, %ecx - shr $16, %ebx - mov %bl, %al - mov %bh, %cl - movl (%edx,%eax,4), %eax - movl (%edx,%ecx,4), %ecx - movl %eax, (0xdeadbeaf) - movl %ecx, (0xdeadbeaf) - pop %ebx - ret -GLOBL ( _x86_Color4ubv_4f_end ) - -/* - - Color4ub_ub -*/ -GLOBL( _x86_Color4ub_ub ) - push %ebx - movl 8(%esp), %eax - movl 12(%esp), %edx - movl 16(%esp), %ecx - movl 20(%esp), %ebx - mov %al, (0) - mov %dl, (0) - mov %cl, (0) - mov %bl, (0) - pop %ebx - ret -GLOBL( _x86_Color4ub_ub_end ) - - -/* \todo: change the "and $7, %eax" to something like "target & 4 ? target & 5 : target & 3)" */ -/* - MultiTexCoord2fv st0/st1 -*/ -GLOBL( _x86_MultiTexCoord2fv ) - movl 4(%esp), %eax - movl 8(%esp), %ecx - and $7, %eax - movl (%ecx), %edx - shl $3, %eax - movl 4(%ecx), %ecx - movl %edx, 0xdeadbeef(%eax) - movl %ecx, 0xdeadbeef(%eax) - ret -GLOBL( _x86_MultiTexCoord2fv_end ) - -/* - MultiTexCoord2fv -*/ - -GLOBL( _x86_MultiTexCoord2fv_2 ) - movl 4(%esp,1), %eax - movl 8(%esp,1), %ecx - and $0x7, %eax - movl 0(,%eax,4), %edx - movl (%ecx), %eax - movl %eax, (%edx) - movl 4(%ecx), %eax - movl %eax, 4(%edx) - ret -GLOBL( _x86_MultiTexCoord2fv_2_end ) - -/* - MultiTexCoord2f st0/st1 -*/ -GLOBL( _x86_MultiTexCoord2f ) - movl 4(%esp), %eax - movl 8(%esp), %edx - movl 12(%esp), %ecx - and $7, %eax - shl $3, %eax - movl %edx, 0xdeadbeef(%eax) - movl %ecx, 0xdeadbeef(%eax) - ret -GLOBL( _x86_MultiTexCoord2f_end ) - -/* - MultiTexCoord2f -*/ -GLOBL( _x86_MultiTexCoord2f_2 ) - movl 4(%esp), %eax - movl 8(%esp), %edx - movl 12(%esp,1), %ecx - and $7,%eax - movl 0(,%eax,4), %eax - movl %edx, (%eax) - movl %ecx, 4(%eax) - ret -GLOBL( _x86_MultiTexCoord2f_2_end ) - -#if defined(USE_SSE_ASM) -/** - * This can be used as a template for either Color3fv (when the color - * target is also a 3f) or Normal3fv. - */ - -GLOBL( _sse_Attribute3fv ) - movl 4(%esp), %eax - movlps (%eax), %xmm0 - movl 8(%eax), %eax - movlps %xmm0, 0 - movl %eax, 8 - ret -GLOBL( _sse_Attribute3fv_end ) - -/** - * This can be used as a template for either Color3f (when the color - * target is also a 3f) or Normal3f. - */ - -GLOBL( _sse_Attribute3f ) - movlps 4(%esp), %xmm0 - movl 12(%esp), %eax - movlps %xmm0, 0 - movl %eax, 8 - ret -GLOBL( _sse_Attribute3f_end ) - - -/** - * Generic handler for 2 float vector format data. This can be used for - * TexCoord2fv and possibly other functions. - */ - -GLOBL( _sse_Attribute2fv ) - movl 4(%esp), %eax - movlps (%eax), %xmm0 - movlps %xmm0, 0 - ret -GLOBL( _sse_Attribute2fv_end ) - - -/** - * Generic handler for 2 float format data. This can be used for - * TexCoord2f and possibly other functions. - */ - -GLOBL( _sse_Attribute2f ) - movlps 4(%esp), %xmm0 - movlps %xmm0, 0 - ret -GLOBL( _sse_Attribute2f_end ) - -/* - MultiTexCoord2fv st0/st1 -*/ -GLOBL( _sse_MultiTexCoord2fv ) - movl 4(%esp), %eax - movl 8(%esp), %ecx - and $7, %eax - movlps (%ecx), %xmm0 - movlps %xmm0, 0xdeadbeef(,%eax,8) - ret -GLOBL( _sse_MultiTexCoord2fv_end ) - -/* - MultiTexCoord2fv -*/ -GLOBL( _sse_MultiTexCoord2fv_2 ) - movl 4(%esp), %eax - movl 8(%esp), %ecx - and $0x7, %eax - movl 0(,%eax,4), %edx - movlps (%ecx), %xmm0 - movlps %xmm0, (%edx) - ret -GLOBL( _sse_MultiTexCoord2fv_2_end ) - -/* - MultiTexCoord2f st0/st1 -*/ -GLOBL( _sse_MultiTexCoord2f ) - movl 4(%esp), %eax - and $7, %eax - movlps 8(%esp), %xmm0 - movlps %xmm0, 0xdeadbeef(,%eax,8) - ret -GLOBL( _sse_MultiTexCoord2f_end ) - -/* - MultiTexCoord2f -*/ -GLOBL( _sse_MultiTexCoord2f_2 ) - movl 4(%esp), %eax - movlps 8(%esp), %xmm0 - and $7,%eax - movl 0(,%eax,4), %eax - movlps %xmm0, (%eax) - ret -GLOBL( _sse_MultiTexCoord2f_2_end ) -#endif - -#if defined (__ELF__) && defined (__linux__) - .section .note.GNU-stack,"",%progbits -#endif diff --git a/src/mesa/drivers/dri/radeon/Makefile b/src/mesa/drivers/dri/radeon/Makefile index 6e46620b39..f223b2d922 100644 --- a/src/mesa/drivers/dri/radeon/Makefile +++ b/src/mesa/drivers/dri/radeon/Makefile @@ -22,11 +22,7 @@ DRIVER_SOURCES = \ radeon_swtcl.c \ radeon_span.c \ radeon_maos.c \ - radeon_sanity.c \ - radeon_vtxfmt.c \ - radeon_vtxfmt_c.c \ - radeon_vtxfmt_sse.c \ - radeon_vtxfmt_x86.c + radeon_sanity.c C_SOURCES = \ $(COMMON_SOURCES) \ @@ -34,8 +30,7 @@ C_SOURCES = \ DRIVER_DEFINES = -DRADEON_COMMON=0 -X86_SOURCES = \ - radeon_vtxtmp_x86.S +X86_SOURCES = include ../Makefile.template diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c index e4dcc96466..8845881e3f 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_context.c @@ -46,7 +46,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -60,7 +60,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_tex.h" #include "radeon_swtcl.h" #include "radeon_tcl.h" -#include "radeon_vtxfmt.h" #include "radeon_maos.h" #define need_GL_ARB_multisample @@ -362,7 +361,7 @@ radeonCreateContext( const __GLcontextModes *glVisual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); _ae_create_context( ctx ); @@ -371,13 +370,10 @@ radeonCreateContext( const __GLcontextModes *glVisual, */ _tnl_destroy_pipeline( ctx ); _tnl_install_pipeline( ctx, radeon_pipeline ); - ctx->Driver.FlushVertices = radeonFlushVertices; /* Try and keep materials and vertices separate: */ - _tnl_isolate_materials( ctx, GL_TRUE ); - -/* _mesa_allow_light_in_model( ctx, GL_FALSE ); */ +/* _tnl_isolate_materials( ctx, GL_TRUE ); */ /* Configure swrast and T&L to match hardware characteristics: */ @@ -451,10 +447,7 @@ radeonCreateContext( const __GLcontextModes *glVisual, } if (rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_TCL) { - if (tcl_mode >= DRI_CONF_TCL_VTXFMT) - radeonVtxfmtInit( ctx, tcl_mode >= DRI_CONF_TCL_CODEGEN ); - - _tnl_need_dlist_norm_lengths( ctx, GL_FALSE ); +/* _tnl_need_dlist_norm_lengths( ctx, GL_FALSE ); */ } return GL_TRUE; } @@ -485,7 +478,7 @@ void radeonDestroyContext( __DRIcontextPrivate *driContextPriv ) release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1); _swsetup_DestroyContext( rmesa->glCtx ); _tnl_DestroyContext( rmesa->glCtx ); - _ac_DestroyContext( rmesa->glCtx ); + _vbo_DestroyContext( rmesa->glCtx ); _swrast_DestroyContext( rmesa->glCtx ); radeonDestroySwtcl( rmesa->glCtx ); @@ -495,12 +488,6 @@ void radeonDestroyContext( __DRIcontextPrivate *driContextPriv ) radeonFlushCmdBuf( rmesa, __FUNCTION__ ); } - if (!(rmesa->TclFallback & RADEON_TCL_FALLBACK_TCL_DISABLE)) { - int tcl_mode = driQueryOptioni(&rmesa->optionCache, "tcl_mode"); - if (tcl_mode >= DRI_CONF_TCL_VTXFMT) - radeonVtxfmtDestroy( rmesa->glCtx ); - } - _mesa_vector4f_free( &rmesa->tcl.ObjClean ); if (rmesa->state.scissor.pClipRects) { @@ -622,9 +609,6 @@ radeonMakeCurrent( __DRIcontextPrivate *driContextPriv, (GLframebuffer *) driDrawPriv->driverPrivate, (GLframebuffer *) driReadPriv->driverPrivate ); - if (newCtx->vb.enabled) - radeonVtxfmtMakeCurrent( newCtx->glCtx ); - } else { if (RADEON_DEBUG & DEBUG_DRI) fprintf(stderr, "%s ctx is null\n", __FUNCTION__); diff --git a/src/mesa/drivers/dri/radeon/radeon_maos_verts.c b/src/mesa/drivers/dri/radeon/radeon_maos_verts.c index 91a60bb9f1..65dbecf7a6 100644 --- a/src/mesa/drivers/dri/radeon/radeon_maos_verts.c +++ b/src/mesa/drivers/dri/radeon/radeon_maos_verts.c @@ -37,7 +37,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "imports.h" #include "mtypes.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "math/m_translate.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c index 86d8c4d963..f1a1728eaa 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.c +++ b/src/mesa/drivers/dri/radeon/radeon_state.c @@ -41,7 +41,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "state.h" #include "context.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" #include "swrast_setup/swrast_setup.h" @@ -52,7 +52,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_tcl.h" #include "radeon_tex.h" #include "radeon_swtcl.h" -#include "radeon_vtxfmt.h" #include "drirenderbuffer.h" static void radeonUpdateSpecular( GLcontext *ctx ); @@ -2302,11 +2301,10 @@ static void radeonInvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); _ae_invalidate_state( ctx, new_state ); RADEON_CONTEXT(ctx)->NewGLState |= new_state; - radeonVtxfmtInvalidate( ctx ); } diff --git a/src/mesa/drivers/dri/radeon/radeon_state_init.c b/src/mesa/drivers/dri/radeon/radeon_state_init.c index 5682d95ae1..5fc34f0933 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state_init.c +++ b/src/mesa/drivers/dri/radeon/radeon_state_init.c @@ -33,7 +33,7 @@ #include "api_arrayelt.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" #include "swrast_setup/swrast_setup.h" @@ -44,7 +44,6 @@ #include "radeon_tcl.h" #include "radeon_tex.h" #include "radeon_swtcl.h" -#include "radeon_vtxfmt.h" #include "xmlpool.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_swtcl.c b/src/mesa/drivers/dri/radeon/radeon_swtcl.c index e36a710d33..7ce1fa67cf 100644 --- a/src/mesa/drivers/dri/radeon/radeon_swtcl.c +++ b/src/mesa/drivers/dri/radeon/radeon_swtcl.c @@ -45,7 +45,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" -#include "tnl/t_vtx_api.h" /* for _tnl_FlushVertices */ #include "radeon_context.h" #include "radeon_ioctl.h" @@ -848,14 +847,6 @@ void radeonFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) } -void radeonFlushVertices( GLcontext *ctx, GLuint flags ) -{ - _tnl_FlushVertices( ctx, flags ); - - if (flags & FLUSH_STORED_VERTICES) - RADEON_NEWPRIM( RADEON_CONTEXT( ctx ) ); -} - /**********************************************************************/ /* Initialization. */ /**********************************************************************/ diff --git a/src/mesa/drivers/dri/radeon/radeon_swtcl.h b/src/mesa/drivers/dri/radeon/radeon_swtcl.h index f95a52c0b8..64f9019513 100644 --- a/src/mesa/drivers/dri/radeon/radeon_swtcl.h +++ b/src/mesa/drivers/dri/radeon/radeon_swtcl.h @@ -43,7 +43,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. extern void radeonInitSwtcl( GLcontext *ctx ); extern void radeonDestroySwtcl( GLcontext *ctx ); -extern void radeonFlushVertices( GLcontext *ctx, GLuint flags ); extern void radeonChooseRenderState( GLcontext *ctx ); extern void radeonChooseVertexState( GLcontext *ctx ); diff --git a/src/mesa/drivers/dri/radeon/radeon_tcl.c b/src/mesa/drivers/dri/radeon/radeon_tcl.c index ffd49b525b..5ad044c262 100644 --- a/src/mesa/drivers/dri/radeon/radeon_tcl.c +++ b/src/mesa/drivers/dri/radeon/radeon_tcl.c @@ -39,7 +39,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "mtypes.h" #include "enums.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" diff --git a/src/mesa/drivers/dri/radeon/radeon_vtxfmt.c b/src/mesa/drivers/dri/radeon/radeon_vtxfmt.c deleted file mode 100644 index a5a9eb144b..0000000000 --- a/src/mesa/drivers/dri/radeon/radeon_vtxfmt.c +++ /dev/null @@ -1,1086 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.c,v 1.6 2003/05/06 23:52:08 daenzer Exp $ */ -/************************************************************************** - -Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and - Tungsten Graphics Inc., Cedar Park, Texas. - -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, 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 - */ -#include "glheader.h" -#include "imports.h" -#include "api_noop.h" -#include "api_arrayelt.h" -#include "context.h" -#include "mtypes.h" -#include "enums.h" -#include "glapi.h" -#include "colormac.h" -#include "light.h" -#include "state.h" -#include "vtxfmt.h" - -#include "tnl/tnl.h" -#include "tnl/t_context.h" -#include "tnl/t_array_api.h" -#include "tnl/t_save_api.h" - -#include "radeon_context.h" -#include "radeon_state.h" -#include "radeon_ioctl.h" -#include "radeon_tex.h" -#include "radeon_tcl.h" -#include "radeon_swtcl.h" -#include "radeon_vtxfmt.h" - -#define VERT_ATTRIB_TEX(u) (VERT_ATTRIB_TEX0 + (u)) - -#include "dispatch.h" - -static void radeonVtxfmtFlushVertices( GLcontext *, GLuint ); - -static void count_func( const char *name, struct dynfn *l ) -{ - int i = 0; - struct dynfn *f; - foreach (f, l) i++; - if (i) fprintf(stderr, "%s: %d\n", name, i ); -} - -static void count_funcs( radeonContextPtr rmesa ) -{ - count_func( "Vertex2f", &rmesa->vb.dfn_cache.Vertex2f ); - count_func( "Vertex2fv", &rmesa->vb.dfn_cache.Vertex2fv ); - count_func( "Vertex3f", &rmesa->vb.dfn_cache.Vertex3f ); - count_func( "Vertex3fv", &rmesa->vb.dfn_cache.Vertex3fv ); - count_func( "Color4ub", &rmesa->vb.dfn_cache.Color4ub ); - count_func( "Color4ubv", &rmesa->vb.dfn_cache.Color4ubv ); - count_func( "Color3ub", &rmesa->vb.dfn_cache.Color3ub ); - count_func( "Color3ubv", &rmesa->vb.dfn_cache.Color3ubv ); - count_func( "Color4f", &rmesa->vb.dfn_cache.Color4f ); - count_func( "Color4fv", &rmesa->vb.dfn_cache.Color4fv ); - count_func( "Color3f", &rmesa->vb.dfn_cache.Color3f ); - count_func( "Color3fv", &rmesa->vb.dfn_cache.Color3fv ); - count_func( "SecondaryColor3f", &rmesa->vb.dfn_cache.SecondaryColor3fEXT ); - count_func( "SecondaryColor3fv", &rmesa->vb.dfn_cache.SecondaryColor3fvEXT ); - count_func( "SecondaryColor3ub", &rmesa->vb.dfn_cache.SecondaryColor3ubEXT ); - count_func( "SecondaryColor3ubv", &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT ); - count_func( "Normal3f", &rmesa->vb.dfn_cache.Normal3f ); - count_func( "Normal3fv", &rmesa->vb.dfn_cache.Normal3fv ); - count_func( "TexCoord2f", &rmesa->vb.dfn_cache.TexCoord2f ); - count_func( "TexCoord2fv", &rmesa->vb.dfn_cache.TexCoord2fv ); - count_func( "TexCoord1f", &rmesa->vb.dfn_cache.TexCoord1f ); - count_func( "TexCoord1fv", &rmesa->vb.dfn_cache.TexCoord1fv ); - count_func( "MultiTexCoord2fARB", &rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - count_func( "MultiTexCoord2fvARB", &rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - count_func( "MultiTexCoord1fARB", &rmesa->vb.dfn_cache.MultiTexCoord1fARB ); - count_func( "MultiTexCoord1fvARB", &rmesa->vb.dfn_cache.MultiTexCoord1fvARB ); -} - - -void radeon_copy_to_current( GLcontext *ctx ) -{ - GLuint unit; - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - assert(ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT); - - if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_N0) { - ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0] = rmesa->vb.normalptr[0]; - ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1] = rmesa->vb.normalptr[1]; - ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2] = rmesa->vb.normalptr[2]; - } - - if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_PKCOLOR) { - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->red ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->green ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->blue ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT( rmesa->vb.colorptr->alpha ); - } - - if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_FPCOLOR) { - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = rmesa->vb.floatcolorptr[0]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] = rmesa->vb.floatcolorptr[1]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] = rmesa->vb.floatcolorptr[2]; - } - - if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_FPALPHA) - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = rmesa->vb.floatcolorptr[3]; - - if (rmesa->vb.vertex_format & RADEON_CP_VC_FRMT_PKSPEC) { - ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0] = UBYTE_TO_FLOAT( rmesa->vb.specptr->red ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1] = UBYTE_TO_FLOAT( rmesa->vb.specptr->green ); - ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2] = UBYTE_TO_FLOAT( rmesa->vb.specptr->blue ); - } - - for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) { - if (rmesa->vb.vertex_format & RADEON_ST_BIT(unit)) { - ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][0] = rmesa->vb.texcoordptr[unit][0]; - ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][1] = rmesa->vb.texcoordptr[unit][1]; - ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][2] = 0.0F; - ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][3] = 1.0F; - } - } - - ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; -} - -static GLboolean discreet_gl_prim[GL_POLYGON+1] = { - 1, /* 0 points */ - 1, /* 1 lines */ - 0, /* 2 line_strip */ - 0, /* 3 line_loop */ - 1, /* 4 tris */ - 0, /* 5 tri_fan */ - 0, /* 6 tri_strip */ - 1, /* 7 quads */ - 0, /* 8 quadstrip */ - 0, /* 9 poly */ -}; - -static void flush_prims( radeonContextPtr rmesa ) -{ - int i,j; - struct radeon_dma_region tmp = rmesa->dma.current; - - tmp.buf->refcount++; - tmp.aos_size = rmesa->vb.vertex_size; - tmp.aos_stride = rmesa->vb.vertex_size; - tmp.aos_start = GET_START(&tmp); - - rmesa->dma.current.ptr = rmesa->dma.current.start += - (rmesa->vb.initial_counter - rmesa->vb.counter) * rmesa->vb.vertex_size * 4; - - rmesa->tcl.vertex_format = rmesa->vb.vertex_format; - rmesa->tcl.aos_components[0] = &tmp; - rmesa->tcl.nr_aos_components = 1; - rmesa->dma.flush = NULL; - - /* Optimize the primitive list: - */ - if (rmesa->vb.nrprims > 1) { - for (j = 0, i = 1 ; i < rmesa->vb.nrprims; i++) { - int pj = rmesa->vb.primlist[j].prim & 0xf; - int pi = rmesa->vb.primlist[i].prim & 0xf; - - if (pj == pi && discreet_gl_prim[pj] && - rmesa->vb.primlist[i].start == rmesa->vb.primlist[j].end) { - rmesa->vb.primlist[j].end = rmesa->vb.primlist[i].end; - } - else { - j++; - if (j != i) rmesa->vb.primlist[j] = rmesa->vb.primlist[i]; - } - } - rmesa->vb.nrprims = j+1; - } - - for (i = 0 ; i < rmesa->vb.nrprims; i++) { - if (RADEON_DEBUG & DEBUG_PRIMS) - fprintf(stderr, "vtxfmt prim %d: %s %d..%d\n", i, - _mesa_lookup_enum_by_nr( rmesa->vb.primlist[i].prim & - PRIM_MODE_MASK ), - rmesa->vb.primlist[i].start, - rmesa->vb.primlist[i].end); - - radeonEmitPrimitive( rmesa->glCtx, - rmesa->vb.primlist[i].start, - rmesa->vb.primlist[i].end, - rmesa->vb.primlist[i].prim ); - } - - rmesa->vb.nrprims = 0; - radeonReleaseDmaRegion( rmesa, &tmp, __FUNCTION__ ); -} - - -static void start_prim( radeonContextPtr rmesa, GLuint mode ) -{ - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s %d\n", __FUNCTION__, rmesa->vb.initial_counter - rmesa->vb.counter); - - rmesa->vb.primlist[rmesa->vb.nrprims].start = rmesa->vb.initial_counter - rmesa->vb.counter; - rmesa->vb.primlist[rmesa->vb.nrprims].prim = mode; -} - -static void note_last_prim( radeonContextPtr rmesa, GLuint flags ) -{ - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s %d\n", __FUNCTION__, rmesa->vb.initial_counter - rmesa->vb.counter); - - if (rmesa->vb.prim[0] != GL_POLYGON+1) { - rmesa->vb.primlist[rmesa->vb.nrprims].prim |= flags; - rmesa->vb.primlist[rmesa->vb.nrprims].end = rmesa->vb.initial_counter - rmesa->vb.counter; - - if (++(rmesa->vb.nrprims) == RADEON_MAX_PRIMS) - flush_prims( rmesa ); - } -} - - -static void copy_vertex( radeonContextPtr rmesa, GLuint n, GLfloat *dst ) -{ - GLuint i; - GLfloat *src = (GLfloat *)(rmesa->dma.current.address + - rmesa->dma.current.ptr + - (rmesa->vb.primlist[rmesa->vb.nrprims].start + n) * - rmesa->vb.vertex_size * 4); - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "copy_vertex %d\n", rmesa->vb.primlist[rmesa->vb.nrprims].start + n); - - for (i = 0 ; i < rmesa->vb.vertex_size; i++) { - dst[i] = src[i]; - } -} - -/* NOTE: This actually reads the copied vertices back from uncached - * memory. Could also use the counter/notify mechanism to populate - * tmp on the fly as vertices are generated. - */ -static GLuint copy_dma_verts( radeonContextPtr rmesa, GLfloat (*tmp)[RADEON_MAX_VERTEX_SIZE] ) -{ - GLuint ovf, i; - GLuint nr = (rmesa->vb.initial_counter - rmesa->vb.counter) - rmesa->vb.primlist[rmesa->vb.nrprims].start; - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s %d verts\n", __FUNCTION__, nr); - - switch( rmesa->vb.prim[0] ) - { - case GL_POINTS: - return 0; - case GL_LINES: - ovf = nr&1; - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - case GL_TRIANGLES: - ovf = nr%3; - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - case GL_QUADS: - ovf = nr&3; - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - case GL_LINE_STRIP: - if (nr == 0) - return 0; - copy_vertex( rmesa, nr-1, tmp[0] ); - return 1; - case GL_LINE_LOOP: - case GL_TRIANGLE_FAN: - case GL_POLYGON: - if (nr == 0) - return 0; - else if (nr == 1) { - copy_vertex( rmesa, 0, tmp[0] ); - return 1; - } else { - copy_vertex( rmesa, 0, tmp[0] ); - copy_vertex( rmesa, nr-1, tmp[1] ); - return 2; - } - case GL_TRIANGLE_STRIP: - ovf = MIN2(nr, 2); - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - case GL_QUAD_STRIP: - switch (nr) { - case 0: ovf = 0; break; - case 1: ovf = 1; break; - default: ovf = 2 + (nr&1); break; - } - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - default: - assert(0); - return 0; - } -} - -static void VFMT_FALLBACK_OUTSIDE_BEGIN_END( const char *caller ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS)) - fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); - - if (ctx->Driver.NeedFlush) - radeonVtxfmtFlushVertices( ctx, ctx->Driver.NeedFlush ); - - if (ctx->NewState) - _mesa_update_state( ctx ); /* clear state so fell_back sticks */ - - _tnl_wakeup_exec( ctx ); - ctx->Driver.FlushVertices = radeonFlushVertices; - ctx->Driver.NewList =_tnl_NewList; - - assert( rmesa->dma.flush == 0 ); - rmesa->vb.fell_back = GL_TRUE; - rmesa->vb.installed = GL_FALSE; -} - - -static void VFMT_FALLBACK( const char *caller ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat tmp[3][RADEON_MAX_VERTEX_SIZE]; - GLuint i, prim; - GLuint ind = rmesa->vb.vertex_format; - GLuint nrverts; - GLfloat alpha = 1.0; - GLuint unit; - - if (RADEON_DEBUG & (DEBUG_FALLBACKS|DEBUG_VFMT)) - fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); - - if (rmesa->vb.prim[0] == GL_POLYGON+1) { - VFMT_FALLBACK_OUTSIDE_BEGIN_END( __FUNCTION__ ); - return; - } - - /* Copy vertices out of dma: - */ - nrverts = copy_dma_verts( rmesa, tmp ); - - /* Finish the prim at this point: - */ - note_last_prim( rmesa, 0 ); - flush_prims( rmesa ); - - /* Update ctx->Driver.CurrentExecPrimitive and swap in swtnl. - */ - prim = rmesa->vb.prim[0]; - ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1; - _tnl_wakeup_exec( ctx ); - ctx->Driver.FlushVertices = radeonFlushVertices; - - assert(rmesa->dma.flush == 0); - rmesa->vb.fell_back = GL_TRUE; - rmesa->vb.installed = GL_FALSE; - CALL_Begin(GET_DISPATCH(), (prim)); - - if (rmesa->vb.installed_color_3f_sz == 4) - alpha = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3]; - - /* Replay saved vertices - */ - for (i = 0 ; i < nrverts; i++) { - GLuint offset = 3; - if (ind & RADEON_CP_VC_FRMT_N0) { - CALL_Normal3fv(GET_DISPATCH(), (&tmp[i][offset])); - offset += 3; - } - - if (ind & RADEON_CP_VC_FRMT_PKCOLOR) { - radeon_color_t *col = (radeon_color_t *)&tmp[i][offset]; - CALL_Color4ub(GET_DISPATCH(), (col->red, col->green, col->blue, col->alpha)); - offset++; - } - else if (ind & RADEON_CP_VC_FRMT_FPALPHA) { - CALL_Color4fv(GET_DISPATCH(), (&tmp[i][offset])); - offset+=4; - } - else if (ind & RADEON_CP_VC_FRMT_FPCOLOR) { - CALL_Color3fv(GET_DISPATCH(), (&tmp[i][offset])); - offset+=3; - } - - if (ind & RADEON_CP_VC_FRMT_PKSPEC) { - radeon_color_t *spec = (radeon_color_t *)&tmp[i][offset]; - CALL_SecondaryColor3ubEXT(GET_DISPATCH(), (spec->red, spec->green, spec->blue)); - offset++; - } - - for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) { - if (ind & RADEON_ST_BIT(unit)) { - CALL_MultiTexCoord2fvARB(GET_DISPATCH(), ((GL_TEXTURE0 + unit), &tmp[i][offset])); - offset += 2; - } - } - CALL_Vertex3fv(GET_DISPATCH(), (&tmp[i][0])); - } - - /* Replay current vertex - */ - if (ind & RADEON_CP_VC_FRMT_N0) - CALL_Normal3fv(GET_DISPATCH(), (rmesa->vb.normalptr)); - - if (ind & RADEON_CP_VC_FRMT_PKCOLOR) - CALL_Color4ub(GET_DISPATCH(), (rmesa->vb.colorptr->red, rmesa->vb.colorptr->green, - rmesa->vb.colorptr->blue, rmesa->vb.colorptr->alpha)); - else if (ind & RADEON_CP_VC_FRMT_FPALPHA) - CALL_Color4fv(GET_DISPATCH(), (rmesa->vb.floatcolorptr)); - else if (ind & RADEON_CP_VC_FRMT_FPCOLOR) { - if (rmesa->vb.installed_color_3f_sz == 4 && alpha != 1.0) - CALL_Color4f(GET_DISPATCH(), (rmesa->vb.floatcolorptr[0], - rmesa->vb.floatcolorptr[1], - rmesa->vb.floatcolorptr[2], - alpha)); - else - CALL_Color3fv(GET_DISPATCH(), (rmesa->vb.floatcolorptr)); - } - - if (ind & RADEON_CP_VC_FRMT_PKSPEC) - CALL_SecondaryColor3ubEXT(GET_DISPATCH(), (rmesa->vb.specptr->red, - rmesa->vb.specptr->green, - rmesa->vb.specptr->blue)); - - for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) { - if (ind & RADEON_ST_BIT(unit)) { - CALL_MultiTexCoord2fvARB(GET_DISPATCH(), ((GL_TEXTURE0 + unit), - rmesa->vb.texcoordptr[unit])); - } - } -} - -static void radeonNewList( GLcontext *ctx, GLuint list, GLenum mode ) -{ - VFMT_FALLBACK( __FUNCTION__ ); - _tnl_NewList( ctx, list, mode ); - return; -} - - -static void wrap_buffer( void ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat tmp[3][RADEON_MAX_VERTEX_SIZE]; - GLuint i, nrverts; - - if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_PRIMS)) - fprintf(stderr, "%s %d\n", __FUNCTION__, rmesa->vb.initial_counter - rmesa->vb.counter); - - /* Don't deal with parity. - */ - if ((((rmesa->vb.initial_counter - rmesa->vb.counter) - - rmesa->vb.primlist[rmesa->vb.nrprims].start) & 1)) { - rmesa->vb.counter++; - rmesa->vb.initial_counter++; - return; - } - - /* Copy vertices out of dma: - */ - if (rmesa->vb.prim[0] == GL_POLYGON+1) - nrverts = 0; - else { - nrverts = copy_dma_verts( rmesa, tmp ); - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%d vertices to copy\n", nrverts); - - /* Finish the prim at this point: - */ - note_last_prim( rmesa, 0 ); - } - - /* Fire any buffered primitives - */ - flush_prims( rmesa ); - - /* Get new buffer - */ - radeonRefillCurrentDmaRegion( rmesa ); - - /* Reset counter, dmaptr - */ - rmesa->vb.dmaptr = (int *)(rmesa->dma.current.ptr + rmesa->dma.current.address); - rmesa->vb.counter = (rmesa->dma.current.end - rmesa->dma.current.ptr) / - (rmesa->vb.vertex_size * 4); - rmesa->vb.counter--; - rmesa->vb.initial_counter = rmesa->vb.counter; - rmesa->vb.notify = wrap_buffer; - - rmesa->dma.flush = flush_prims; - - /* Restart wrapped primitive: - */ - if (rmesa->vb.prim[0] != GL_POLYGON+1) - start_prim( rmesa, rmesa->vb.prim[0] ); - - /* Reemit saved vertices - */ - for (i = 0 ; i < nrverts; i++) { - if (RADEON_DEBUG & DEBUG_VERTS) { - int j; - fprintf(stderr, "re-emit vertex %d to %p\n", i, (void *)rmesa->vb.dmaptr); - if (RADEON_DEBUG & DEBUG_VERBOSE) - for (j = 0 ; j < rmesa->vb.vertex_size; j++) - fprintf(stderr, "\t%08x/%f\n", *(int*)&tmp[i][j], tmp[i][j]); - } - - memcpy( rmesa->vb.dmaptr, tmp[i], rmesa->vb.vertex_size * 4 ); - rmesa->vb.dmaptr += rmesa->vb.vertex_size; - rmesa->vb.counter--; - } -} - - - -static GLboolean check_vtx_fmt( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLuint ind = RADEON_CP_VC_FRMT_Z; - GLuint unit; - - if (rmesa->TclFallback || rmesa->vb.fell_back || ctx->CompileFlag || - (ctx->Fog.Enabled && (ctx->Fog.FogCoordinateSource == GL_FOG_COORD))) - return GL_FALSE; - - if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) - ctx->Driver.FlushVertices( ctx, FLUSH_UPDATE_CURRENT ); - - /* Make all this event-driven: - */ - if (ctx->Light.Enabled) { - ind |= RADEON_CP_VC_FRMT_N0; - - /* TODO: make this data driven: If we receive only ubytes, send - * color as ubytes. Also check if converting (with free - * checking for overflow) is cheaper than sending floats - * directly. - */ - if (ctx->Light.ColorMaterialEnabled) { - ind |= (RADEON_CP_VC_FRMT_FPCOLOR | - RADEON_CP_VC_FRMT_FPALPHA); - } - else - ind |= RADEON_CP_VC_FRMT_PKCOLOR; /* for alpha? */ - } - else { - /* TODO: make this data driven? - */ - ind |= RADEON_CP_VC_FRMT_PKCOLOR; - - if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { - ind |= RADEON_CP_VC_FRMT_PKSPEC; - } - } - - if ( ctx->Fog.FogCoordinateSource == GL_FOG_COORD ) { - ind |= RADEON_CP_VC_FRMT_PKSPEC; - } - - for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) { - if (ctx->Texture.Unit[unit]._ReallyEnabled) { - if (ctx->Texture.Unit[unit].TexGenEnabled) { - if (rmesa->TexGenNeedNormals[unit]) { - ind |= RADEON_CP_VC_FRMT_N0; - } - } else { - if (ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][3] != 1.0) { - if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_FALLBACKS)) - fprintf(stderr, "%s: q%u\n", __FUNCTION__, unit); - return GL_FALSE; - } - ind |= RADEON_ST_BIT(unit); - } - } - } - - if (RADEON_DEBUG & (DEBUG_VFMT|DEBUG_STATE)) - fprintf(stderr, "%s: format: 0x%x\n", __FUNCTION__, ind ); - - RADEON_NEWPRIM(rmesa); - rmesa->vb.vertex_format = ind; - rmesa->vb.vertex_size = 3; - rmesa->vb.prim = &ctx->Driver.CurrentExecPrimitive; - - rmesa->vb.normalptr = ctx->Current.Attrib[VERT_ATTRIB_NORMAL]; - rmesa->vb.colorptr = NULL; - rmesa->vb.floatcolorptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; - rmesa->vb.specptr = NULL; - rmesa->vb.floatspecptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR1]; - rmesa->vb.texcoordptr[0] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; - rmesa->vb.texcoordptr[1] = ctx->Current.Attrib[VERT_ATTRIB_TEX1]; - rmesa->vb.texcoordptr[2] = ctx->Current.Attrib[VERT_ATTRIB_TEX2]; - rmesa->vb.texcoordptr[3] = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; /* dummy */ - - /* Run through and initialize the vertex components in the order - * the hardware understands: - */ - if (ind & RADEON_CP_VC_FRMT_N0) { - rmesa->vb.normalptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; - rmesa->vb.vertex_size += 3; - rmesa->vb.normalptr[0] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0]; - rmesa->vb.normalptr[1] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1]; - rmesa->vb.normalptr[2] = ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2]; - } - - if (ind & RADEON_CP_VC_FRMT_PKCOLOR) { - rmesa->vb.colorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].color; - rmesa->vb.vertex_size += 1; - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->red, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->green, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->blue, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.colorptr->alpha, ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] ); - } - - if (ind & RADEON_CP_VC_FRMT_FPCOLOR) { - assert(!(ind & RADEON_CP_VC_FRMT_PKCOLOR)); - rmesa->vb.floatcolorptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; - rmesa->vb.vertex_size += 3; - rmesa->vb.floatcolorptr[0] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0]; - rmesa->vb.floatcolorptr[1] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1]; - rmesa->vb.floatcolorptr[2] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2]; - - if (ind & RADEON_CP_VC_FRMT_FPALPHA) { - rmesa->vb.vertex_size += 1; - rmesa->vb.floatcolorptr[3] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3]; - } - } - - if (ind & RADEON_CP_VC_FRMT_PKSPEC) { - rmesa->vb.specptr = &rmesa->vb.vertex[rmesa->vb.vertex_size].color; - rmesa->vb.vertex_size += 1; - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->red, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->green, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1] ); - UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->blue, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2] ); - /* fog ??? */ -/* UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->alpha, - radeonComputeFogFactor(ctx->Current.Attrib[VERT_ATTRIB_FOG][0]) ); */ - } - - for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) { - if (ind & RADEON_ST_BIT(unit)) { - rmesa->vb.texcoordptr[unit] = &rmesa->vb.vertex[rmesa->vb.vertex_size].f; - rmesa->vb.vertex_size += 2; - rmesa->vb.texcoordptr[unit][0] = ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][0]; - rmesa->vb.texcoordptr[unit][1] = ctx->Current.Attrib[VERT_ATTRIB_TEX(unit)][1]; - } - } - - if (rmesa->vb.installed_vertex_format != rmesa->vb.vertex_format) { - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "reinstall on vertex_format change\n"); - _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); - rmesa->vb.installed_vertex_format = rmesa->vb.vertex_format; - } - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s -- success\n", __FUNCTION__); - - return GL_TRUE; -} - -void radeonVtxfmtInvalidate( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); - - rmesa->vb.recheck = GL_TRUE; - rmesa->vb.fell_back = GL_FALSE; -} - - -static void radeonVtxfmtValidate( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (ctx->Driver.NeedFlush) - ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush ); - - rmesa->vb.recheck = GL_FALSE; - - if (check_vtx_fmt( ctx )) { - if (!rmesa->vb.installed) { - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "reinstall (new install)\n"); - - _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); - ctx->Driver.FlushVertices = radeonVtxfmtFlushVertices; - ctx->Driver.NewList = radeonNewList; - rmesa->vb.installed = GL_TRUE; - } - else if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s: already installed", __FUNCTION__); - } - else { - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s: failed\n", __FUNCTION__); - - if (rmesa->vb.installed) { - if (rmesa->dma.flush) - rmesa->dma.flush( rmesa ); - _tnl_wakeup_exec( ctx ); - ctx->Driver.FlushVertices = radeonFlushVertices; - ctx->Driver.NewList =_tnl_NewList; - rmesa->vb.installed = GL_FALSE; - } - } -} - - - -/* Materials: - */ -static void radeon_Materialfv( GLenum face, GLenum pname, - const GLfloat *params ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (rmesa->vb.prim[0] != GL_POLYGON+1) { - VFMT_FALLBACK( __FUNCTION__ ); - CALL_Materialfv(GET_DISPATCH(), (face, pname, params)); - return; - } - _mesa_noop_Materialfv( face, pname, params ); - radeonUpdateMaterial( ctx ); -} - - -/* Begin/End - */ -static void radeon_Begin( GLenum mode ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s( %s )\n", __FUNCTION__, - _mesa_lookup_enum_by_nr( mode )); - - if (mode > GL_POLYGON) { - _mesa_error( ctx, GL_INVALID_ENUM, "glBegin" ); - return; - } - - if (rmesa->vb.prim[0] != GL_POLYGON+1) { - _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" ); - return; - } - - if (ctx->NewState) - _mesa_update_state( ctx ); - - if (rmesa->NewGLState) - radeonValidateState( ctx ); - - if (rmesa->vb.recheck) - radeonVtxfmtValidate( ctx ); - - if (!rmesa->vb.installed) { - CALL_Begin(GET_DISPATCH(), (mode)); - return; - } - - - if (rmesa->dma.flush && rmesa->vb.counter < 12) { - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s: flush almost-empty buffers\n", __FUNCTION__); - flush_prims( rmesa ); - } - - /* Need to arrange to save vertices here? Or always copy from dma (yuk)? - */ - if (!rmesa->dma.flush) { -/* FIXME: what are these constants? */ - if (rmesa->dma.current.ptr + 12*rmesa->vb.vertex_size*4 > - rmesa->dma.current.end) { - RADEON_NEWPRIM( rmesa ); - radeonRefillCurrentDmaRegion( rmesa ); - } - - rmesa->vb.dmaptr = (int *)(rmesa->dma.current.address + rmesa->dma.current.ptr); - rmesa->vb.counter = (rmesa->dma.current.end - rmesa->dma.current.ptr) / - (rmesa->vb.vertex_size * 4); - rmesa->vb.counter--; - rmesa->vb.initial_counter = rmesa->vb.counter; - rmesa->vb.notify = wrap_buffer; - rmesa->dma.flush = flush_prims; - ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; - } - - - rmesa->vb.prim[0] = mode; - start_prim( rmesa, mode | PRIM_BEGIN ); -} - - - -static void radeon_End( void ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (rmesa->vb.prim[0] == GL_POLYGON+1) { - _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" ); - return; - } - - note_last_prim( rmesa, PRIM_END ); - rmesa->vb.prim[0] = GL_POLYGON+1; -} - - -/* Fallback on difficult entrypoints: - */ -#define PRE_LOOPBACK( FUNC ) \ -do { \ - if (RADEON_DEBUG & DEBUG_VFMT) \ - fprintf(stderr, "%s\n", __FUNCTION__); \ - VFMT_FALLBACK( __FUNCTION__ ); \ -} while (0) -#define TAG(x) radeon_fallback_##x -#include "vtxfmt_tmp.h" - - - -static GLboolean radeonNotifyBegin( GLcontext *ctx, GLenum p ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - assert(!rmesa->vb.installed); - - if (ctx->NewState) - _mesa_update_state( ctx ); - - if (rmesa->NewGLState) - radeonValidateState( ctx ); - - if (ctx->Driver.NeedFlush) - ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush ); - - if (rmesa->vb.recheck) - radeonVtxfmtValidate( ctx ); - - if (!rmesa->vb.installed) { - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s -- failed\n", __FUNCTION__); - return GL_FALSE; - } - - radeon_Begin( p ); - return GL_TRUE; -} - -static void radeonVtxfmtFlushVertices( GLcontext *ctx, GLuint flags ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); - - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "%s\n", __FUNCTION__); - - assert(rmesa->vb.installed); - - if (flags & FLUSH_UPDATE_CURRENT) { - radeon_copy_to_current( ctx ); - if (RADEON_DEBUG & DEBUG_VFMT) - fprintf(stderr, "reinstall on update_current\n"); - _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); - ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT; - } - - if (flags & FLUSH_STORED_VERTICES) { - radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); - assert (rmesa->dma.flush == 0 || - rmesa->dma.flush == flush_prims); - if (rmesa->dma.flush == flush_prims) - flush_prims( RADEON_CONTEXT( ctx ) ); - ctx->Driver.NeedFlush &= ~FLUSH_STORED_VERTICES; - } -} - - - -/* At this point, don't expect very many versions of each function to - * be generated, so not concerned about freeing them? - */ - - -void radeonVtxfmtInit( GLcontext *ctx, GLboolean useCodegen ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); - GLvertexformat *vfmt = &(rmesa->vb.vtxfmt); - - /* start by initializing to no-op functions */ - _mesa_noop_vtxfmt_init(vfmt); - - /* Hook in chooser functions for codegen, etc: - */ - radeonVtxfmtInitChoosers( vfmt ); - - /* Handled fully in supported states, but no codegen: - */ - vfmt->Materialfv = radeon_Materialfv; - vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ - vfmt->Begin = radeon_Begin; - vfmt->End = radeon_End; - - /* Fallback for performance reasons: (Fix with cva/elt path here and - * dmatmp2.h style primitive-merging) - * - * These should call NotifyBegin(), as should _tnl_EvalMesh, to allow - * a driver-hook. - */ - vfmt->DrawArrays = radeon_fallback_DrawArrays; - vfmt->DrawElements = radeon_fallback_DrawElements; - vfmt->DrawRangeElements = radeon_fallback_DrawRangeElements; - - /* Active but unsupported -- fallback if we receive these: - */ - vfmt->CallList = radeon_fallback_CallList; - vfmt->CallLists = radeon_fallback_CallLists; - vfmt->EvalCoord1f = radeon_fallback_EvalCoord1f; - vfmt->EvalCoord1fv = radeon_fallback_EvalCoord1fv; - vfmt->EvalCoord2f = radeon_fallback_EvalCoord2f; - vfmt->EvalCoord2fv = radeon_fallback_EvalCoord2fv; - vfmt->EvalMesh1 = radeon_fallback_EvalMesh1; - vfmt->EvalMesh2 = radeon_fallback_EvalMesh2; - vfmt->EvalPoint1 = radeon_fallback_EvalPoint1; - vfmt->EvalPoint2 = radeon_fallback_EvalPoint2; - vfmt->TexCoord3f = radeon_fallback_TexCoord3f; - vfmt->TexCoord3fv = radeon_fallback_TexCoord3fv; - vfmt->TexCoord4f = radeon_fallback_TexCoord4f; - vfmt->TexCoord4fv = radeon_fallback_TexCoord4fv; - vfmt->MultiTexCoord3fARB = radeon_fallback_MultiTexCoord3fARB; - vfmt->MultiTexCoord3fvARB = radeon_fallback_MultiTexCoord3fvARB; - vfmt->MultiTexCoord4fARB = radeon_fallback_MultiTexCoord4fARB; - vfmt->MultiTexCoord4fvARB = radeon_fallback_MultiTexCoord4fvARB; - vfmt->Vertex4f = radeon_fallback_Vertex4f; - vfmt->Vertex4fv = radeon_fallback_Vertex4fv; - vfmt->VertexAttrib1fNV = radeon_fallback_VertexAttrib1fNV; - vfmt->VertexAttrib1fvNV = radeon_fallback_VertexAttrib1fvNV; - vfmt->VertexAttrib2fNV = radeon_fallback_VertexAttrib2fNV; - vfmt->VertexAttrib2fvNV = radeon_fallback_VertexAttrib2fvNV; - vfmt->VertexAttrib3fNV = radeon_fallback_VertexAttrib3fNV; - vfmt->VertexAttrib3fvNV = radeon_fallback_VertexAttrib3fvNV; - vfmt->VertexAttrib4fNV = radeon_fallback_VertexAttrib4fNV; - vfmt->VertexAttrib4fvNV = radeon_fallback_VertexAttrib4fvNV; - vfmt->FogCoordfEXT = radeon_fallback_FogCoordfEXT; - vfmt->FogCoordfvEXT = radeon_fallback_FogCoordfvEXT; - - (void)radeon_fallback_vtxfmt; - - TNL_CONTEXT(ctx)->Driver.NotifyBegin = radeonNotifyBegin; - - rmesa->vb.enabled = 1; - rmesa->vb.prim = &ctx->Driver.CurrentExecPrimitive; - rmesa->vb.primflags = 0; - - make_empty_list( &rmesa->vb.dfn_cache.Vertex2f ); - make_empty_list( &rmesa->vb.dfn_cache.Vertex2fv ); - make_empty_list( &rmesa->vb.dfn_cache.Vertex3f ); - make_empty_list( &rmesa->vb.dfn_cache.Vertex3fv ); - make_empty_list( &rmesa->vb.dfn_cache.Color4ub ); - make_empty_list( &rmesa->vb.dfn_cache.Color4ubv ); - make_empty_list( &rmesa->vb.dfn_cache.Color3ub ); - make_empty_list( &rmesa->vb.dfn_cache.Color3ubv ); - make_empty_list( &rmesa->vb.dfn_cache.Color4f ); - make_empty_list( &rmesa->vb.dfn_cache.Color4fv ); - make_empty_list( &rmesa->vb.dfn_cache.Color3f ); - make_empty_list( &rmesa->vb.dfn_cache.Color3fv ); - make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3fEXT ); - make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3fvEXT ); - make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3ubEXT ); - make_empty_list( &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT ); - make_empty_list( &rmesa->vb.dfn_cache.Normal3f ); - make_empty_list( &rmesa->vb.dfn_cache.Normal3fv ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord2f ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord2fv ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord1f ); - make_empty_list( &rmesa->vb.dfn_cache.TexCoord1fv ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord1fARB ); - make_empty_list( &rmesa->vb.dfn_cache.MultiTexCoord1fvARB ); - - radeonInitCodegen( &rmesa->vb.codegen, useCodegen ); -} - -static void free_funcs( struct dynfn *l ) -{ - struct dynfn *f, *tmp; - foreach_s (f, tmp, l) { - remove_from_list( f ); - _mesa_exec_free( f->code ); - _mesa_free( f ); - } -} - - - -void radeonVtxfmtMakeCurrent( GLcontext *ctx ) -{ -} - - -void radeonVtxfmtDestroy( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); - - count_funcs( rmesa ); - free_funcs( &rmesa->vb.dfn_cache.Vertex2f ); - free_funcs( &rmesa->vb.dfn_cache.Vertex2fv ); - free_funcs( &rmesa->vb.dfn_cache.Vertex3f ); - free_funcs( &rmesa->vb.dfn_cache.Vertex3fv ); - free_funcs( &rmesa->vb.dfn_cache.Color4ub ); - free_funcs( &rmesa->vb.dfn_cache.Color4ubv ); - free_funcs( &rmesa->vb.dfn_cache.Color3ub ); - free_funcs( &rmesa->vb.dfn_cache.Color3ubv ); - free_funcs( &rmesa->vb.dfn_cache.Color4f ); - free_funcs( &rmesa->vb.dfn_cache.Color4fv ); - free_funcs( &rmesa->vb.dfn_cache.Color3f ); - free_funcs( &rmesa->vb.dfn_cache.Color3fv ); - free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3ubEXT ); - free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3ubvEXT ); - free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3fEXT ); - free_funcs( &rmesa->vb.dfn_cache.SecondaryColor3fvEXT ); - free_funcs( &rmesa->vb.dfn_cache.Normal3f ); - free_funcs( &rmesa->vb.dfn_cache.Normal3fv ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord2f ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord2fv ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord1f ); - free_funcs( &rmesa->vb.dfn_cache.TexCoord1fv ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord1fARB ); - free_funcs( &rmesa->vb.dfn_cache.MultiTexCoord1fvARB ); -} - diff --git a/src/mesa/drivers/dri/radeon/radeon_vtxfmt.h b/src/mesa/drivers/dri/radeon/radeon_vtxfmt.h deleted file mode 100644 index a656e49e44..0000000000 --- a/src/mesa/drivers/dri/radeon/radeon_vtxfmt.h +++ /dev/null @@ -1,120 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt.h,v 1.3 2002/12/21 17:02:16 dawes Exp $ */ -/************************************************************************** - -Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and - Tungsten Graphics Inc., Cedar Park, Texas. - -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, 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 - */ - -#ifndef __RADEON_VTXFMT_H__ -#define __RADEON_VTXFMT_H__ - -#include "radeon_context.h" - - -extern void radeonVtxfmtUpdate( GLcontext *ctx ); -extern void radeonVtxfmtInit( GLcontext *ctx, GLboolean useCodegen ); -extern void radeonVtxfmtInvalidate( GLcontext *ctx ); -extern void radeonVtxfmtDestroy( GLcontext *ctx ); -extern void radeonVtxfmtInitChoosers( GLvertexformat *vfmt ); - -extern void radeonVtxfmtMakeCurrent( GLcontext *ctx ); -extern void radeonVtxfmtUnbindContext( GLcontext *ctx ); - -extern void radeon_copy_to_current( GLcontext *ctx ); - -#define DFN( FUNC, CACHE) \ -do { \ - char *start = (char *)&FUNC; \ - char *end = (char *)&FUNC##_end; \ - insert_at_head( &CACHE, dfn ); \ - dfn->key = key; \ - dfn->code = _mesa_exec_malloc( end - start ); \ - _mesa_memcpy(dfn->code, start, end - start); \ -} \ -while ( 0 ) - -#define FIXUP( CODE, OFFSET, CHECKVAL, NEWVAL ) \ -do { \ - int *icode = (int *)(CODE+OFFSET); \ - assert (*icode == CHECKVAL); \ - *icode = (int)NEWVAL; \ -} while (0) - - -/* Useful for figuring out the offsets: - */ -#define FIXUP2( CODE, OFFSET, CHECKVAL, NEWVAL ) \ -do { \ - while (*(int *)(CODE+OFFSET) != CHECKVAL) OFFSET++; \ - fprintf(stderr, "%s/%d CVAL %x OFFSET %d VAL %x\n", __FUNCTION__, \ - __LINE__, CHECKVAL, OFFSET, (int)(NEWVAL)); \ - *(int *)(CODE+OFFSET) = (int)(NEWVAL); \ - OFFSET += 4; \ -} while (0) - -/* - */ -void radeonInitCodegen( struct dfn_generators *gen, GLboolean useCodegen ); -void radeonInitX86Codegen( struct dfn_generators *gen ); -void radeonInitSSECodegen( struct dfn_generators *gen ); - - - -/* Defined in radeon_vtxfmt_x86.c - */ -struct dynfn *radeon_makeX86Vertex2f( GLcontext *, int ); -struct dynfn *radeon_makeX86Vertex2fv( GLcontext *, int ); -struct dynfn *radeon_makeX86Vertex3f( GLcontext *, int ); -struct dynfn *radeon_makeX86Vertex3fv( GLcontext *, int ); -struct dynfn *radeon_makeX86Color4ub( GLcontext *, int ); -struct dynfn *radeon_makeX86Color4ubv( GLcontext *, int ); -struct dynfn *radeon_makeX86Color3ub( GLcontext *, int ); -struct dynfn *radeon_makeX86Color3ubv( GLcontext *, int ); -struct dynfn *radeon_makeX86Color4f( GLcontext *, int ); -struct dynfn *radeon_makeX86Color4fv( GLcontext *, int ); -struct dynfn *radeon_makeX86Color3f( GLcontext *, int ); -struct dynfn *radeon_makeX86Color3fv( GLcontext *, int ); -struct dynfn *radeon_makeX86SecondaryColor3ubEXT( GLcontext *, int ); -struct dynfn *radeon_makeX86SecondaryColor3ubvEXT( GLcontext *, int ); -struct dynfn *radeon_makeX86SecondaryColor3fEXT( GLcontext *, int ); -struct dynfn *radeon_makeX86SecondaryColor3fvEXT( GLcontext *, int ); -struct dynfn *radeon_makeX86Normal3f( GLcontext *, int ); -struct dynfn *radeon_makeX86Normal3fv( GLcontext *, int ); -struct dynfn *radeon_makeX86TexCoord2f( GLcontext *, int ); -struct dynfn *radeon_makeX86TexCoord2fv( GLcontext *, int ); -struct dynfn *radeon_makeX86TexCoord1f( GLcontext *, int ); -struct dynfn *radeon_makeX86TexCoord1fv( GLcontext *, int ); -struct dynfn *radeon_makeX86MultiTexCoord2fARB( GLcontext *, int ); -struct dynfn *radeon_makeX86MultiTexCoord2fvARB( GLcontext *, int ); -struct dynfn *radeon_makeX86MultiTexCoord1fARB( GLcontext *, int ); -struct dynfn *radeon_makeX86MultiTexCoord1fvARB( GLcontext *, int ); - -#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_vtxfmt_c.c b/src/mesa/drivers/dri/radeon/radeon_vtxfmt_c.c deleted file mode 100644 index aac029aa0e..0000000000 --- a/src/mesa/drivers/dri/radeon/radeon_vtxfmt_c.c +++ /dev/null @@ -1,924 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_c.c,v 1.2 2002/12/16 16:18:59 dawes Exp $ */ -/************************************************************************** - -Copyright 2002 ATI Technologies Inc., Ontario, Canada, and - Tungsten Graphics Inc., Cedar Park, Texas. - -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, 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 - */ -#include "glheader.h" -#include "mtypes.h" -#include "colormac.h" -#include "simple_list.h" -#include "api_noop.h" -#include "vtxfmt.h" - -#include "radeon_vtxfmt.h" - -#include "dispatch.h" - -/* Fallback versions of all the entrypoints for situations where - * codegen isn't available. This is still a lot faster than the - * vb/pipeline implementation in Mesa. - */ -static void radeon_Vertex3f( GLfloat x, GLfloat y, GLfloat z ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - int i; - - *rmesa->vb.dmaptr++ = *(int *)&x; - *rmesa->vb.dmaptr++ = *(int *)&y; - *rmesa->vb.dmaptr++ = *(int *)&z; - - for (i = 3; i < rmesa->vb.vertex_size; i++) - *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i; - - if (--rmesa->vb.counter == 0) - rmesa->vb.notify(); -} - - -static void radeon_Vertex3fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - int i; - - *rmesa->vb.dmaptr++ = *(int *)&v[0]; - *rmesa->vb.dmaptr++ = *(int *)&v[1]; - *rmesa->vb.dmaptr++ = *(int *)&v[2]; - - for (i = 3; i < rmesa->vb.vertex_size; i++) - *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i; - - if (--rmesa->vb.counter == 0) - rmesa->vb.notify(); -} - - -static void radeon_Vertex2f( GLfloat x, GLfloat y ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - int i; - - *rmesa->vb.dmaptr++ = *(int *)&x; - *rmesa->vb.dmaptr++ = *(int *)&y; - *rmesa->vb.dmaptr++ = 0; - - for (i = 3; i < rmesa->vb.vertex_size; i++) - *rmesa->vb.dmaptr++ = *(int *)&rmesa->vb.vertex[i]; - - if (--rmesa->vb.counter == 0) - rmesa->vb.notify(); -} - - -static void radeon_Vertex2fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - int i; - - *rmesa->vb.dmaptr++ = *(int *)&v[0]; - *rmesa->vb.dmaptr++ = *(int *)&v[1]; - *rmesa->vb.dmaptr++ = 0; - - for (i = 3; i < rmesa->vb.vertex_size; i++) - *rmesa->vb.dmaptr++ = rmesa->vb.vertex[i].i; - - if (--rmesa->vb.counter == 0) - rmesa->vb.notify(); -} - - -#if 0 -/* Color for ubyte (packed) color formats: - */ -static void radeon_Color3ub_ub( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.colorptr; - dest->red = r; - dest->green = g; - dest->blue = b; - dest->alpha = 0xff; -} - -static void radeon_Color3ubv_ub( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.colorptr; - dest->red = v[0]; - dest->green = v[1]; - dest->blue = v[2]; - dest->alpha = 0xff; -} - -static void radeon_Color4ub_ub( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.colorptr; - dest->red = r; - dest->green = g; - dest->blue = b; - dest->alpha = a; -} - -static void radeon_Color4ubv_ub( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - *(GLuint *)rmesa->vb.colorptr = LE32_TO_CPU(*(GLuint *)v); -} -#endif /* 0 */ - -static void radeon_Color3f_ub( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.colorptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); - dest->alpha = 255; -} - -static void radeon_Color3fv_ub( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.colorptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); - dest->alpha = 255; -} - -static void radeon_Color4f_ub( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.colorptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, a ); -} - -static void radeon_Color4fv_ub( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.colorptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->alpha, v[3] ); -} - - -/* Color for float color+alpha formats: - */ -#if 0 -static void radeon_Color3ub_4f( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); - dest[3] = 1.0; -} - -static void radeon_Color3ubv_4f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); - dest[3] = 1.0; -} - -static void radeon_Color4ub_4f( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); - dest[3] = UBYTE_TO_FLOAT(a); -} - -static void radeon_Color4ubv_4f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); - dest[3] = UBYTE_TO_FLOAT(v[3]); -} -#endif /* 0 */ - - -static void radeon_Color3f_4f( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; - dest[3] = 1.0; -} - -static void radeon_Color3fv_4f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - dest[3] = 1.0; -} - -static void radeon_Color4f_4f( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; - dest[3] = a; -} - -static void radeon_Color4fv_4f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - dest[3] = v[3]; -} - - -/* Color for float color formats: - */ -#if 0 -static void radeon_Color3ub_3f( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); -} - -static void radeon_Color3ubv_3f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); -} - -static void radeon_Color4ub_3f( GLubyte r, GLubyte g, GLubyte b, GLubyte a ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT(a); -} - -static void radeon_Color4ubv_3f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = UBYTE_TO_FLOAT(v[3]); -} -#endif /* 0 */ - - -static void radeon_Color3f_3f( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; -} - -static void radeon_Color3fv_3f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; -} - -static void radeon_Color4f_3f( GLfloat r, GLfloat g, GLfloat b, GLfloat a ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = a; -} - -static void radeon_Color4fv_3f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatcolorptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = v[3]; -} - - -/* Secondary Color: - */ -#if 0 -static void radeon_SecondaryColor3ubEXT_ub( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.specptr; - dest->red = r; - dest->green = g; - dest->blue = b; - dest->alpha = 0xff; -} - -static void radeon_SecondaryColor3ubvEXT_ub( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.specptr; - dest->red = v[0]; - dest->green = v[1]; - dest->blue = v[2]; - dest->alpha = 0xff; -} -#endif /* 0 */ - -static void radeon_SecondaryColor3fEXT_ub( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.specptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, r ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, g ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, b ); - dest->alpha = 255; -} - -static void radeon_SecondaryColor3fvEXT_ub( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeon_color_t *dest = rmesa->vb.specptr; - UNCLAMPED_FLOAT_TO_UBYTE( dest->red, v[0] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->green, v[1] ); - UNCLAMPED_FLOAT_TO_UBYTE( dest->blue, v[2] ); - dest->alpha = 255; -} - -#if 0 -static void radeon_SecondaryColor3ubEXT_3f( GLubyte r, GLubyte g, GLubyte b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatspecptr; - dest[0] = UBYTE_TO_FLOAT(r); - dest[1] = UBYTE_TO_FLOAT(g); - dest[2] = UBYTE_TO_FLOAT(b); - dest[3] = 1.0; -} - -static void radeon_SecondaryColor3ubvEXT_3f( const GLubyte *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatspecptr; - dest[0] = UBYTE_TO_FLOAT(v[0]); - dest[1] = UBYTE_TO_FLOAT(v[1]); - dest[2] = UBYTE_TO_FLOAT(v[2]); - dest[3] = 1.0; -} -#endif /* 0 */ - -static void radeon_SecondaryColor3fEXT_3f( GLfloat r, GLfloat g, GLfloat b ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatspecptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; - dest[3] = 1.0; -} - -static void radeon_SecondaryColor3fvEXT_3f( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.floatspecptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; - dest[3] = 1.0; -} - - -/* Normal - */ -static void radeon_Normal3f( GLfloat n0, GLfloat n1, GLfloat n2 ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.normalptr; - dest[0] = n0; - dest[1] = n1; - dest[2] = n2; -} - -static void radeon_Normal3fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.normalptr; - dest[0] = v[0]; - dest[1] = v[1]; - dest[2] = v[2]; -} - - -/* TexCoord - */ -static void radeon_TexCoord1f( GLfloat s ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[0]; - dest[0] = s; - dest[1] = 0; -} - -static void radeon_TexCoord1fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[0]; - dest[0] = v[0]; - dest[1] = 0; -} - -static void radeon_TexCoord2f( GLfloat s, GLfloat t ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[0]; - dest[0] = s; - dest[1] = t; -} - -static void radeon_TexCoord2fv( const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[0]; - dest[0] = v[0]; - dest[1] = v[1]; -} - - -/* MultiTexcoord - * - * Technically speaking, these functions should subtract GL_TEXTURE0 from - * \c target before masking and using it. The value of GL_TEXTURE0 is 0x84C0, - * which has the low-order 5 bits 0. For all possible valid values of - * \c target. Subtracting GL_TEXTURE0 has the net effect of masking \c target - * with 0x1F. Masking with 0x1F and then masking with 0x01 is redundant, so - * the subtraction has been omitted. - */ - -static void radeon_MultiTexCoord1fARB( GLenum target, GLfloat s ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[target & 3]; - dest[0] = s; - dest[1] = 0; -} - -static void radeon_MultiTexCoord1fvARB( GLenum target, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[target & 3]; - dest[0] = v[0]; - dest[1] = 0; -} - -static void radeon_MultiTexCoord2fARB( GLenum target, GLfloat s, GLfloat t ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[target & 3]; - dest[0] = s; - dest[1] = t; -} - -static void radeon_MultiTexCoord2fvARB( GLenum target, const GLfloat *v ) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat *dest = rmesa->vb.texcoordptr[target & 3]; - dest[0] = v[0]; - dest[1] = v[1]; -} - -static struct dynfn *lookup( struct dynfn *l, int key ) -{ - struct dynfn *f; - - foreach( f, l ) { - if (f->key == key) - return f; - } - - return NULL; -} - -/* Can't use the loopback template for this: - */ - -#define CHOOSE(FN, FNTYPE, MASK, ACTIVE, ARGS1, ARGS2 ) \ -static void choose_##FN ARGS1 \ -{ \ - GET_CURRENT_CONTEXT(ctx); \ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ - int key = rmesa->vb.vertex_format & (MASK|ACTIVE); \ - struct dynfn *dfn; \ - \ - dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \ - if (dfn == 0) \ - dfn = rmesa->vb.codegen.FN( ctx, key ); \ - else if (RADEON_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- cached codegen\n", __FUNCTION__ ); \ - \ - if (dfn) \ - SET_ ## FN (ctx->Exec, (FNTYPE)(dfn->code)); \ - else { \ - if (RADEON_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \ - SET_ ## FN (ctx->Exec, radeon_##FN); \ - } \ - \ - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \ - CALL_ ## FN (ctx->Exec, ARGS2); \ -} - - - -/* For the _3f case, only allow one color function to be hooked in at - * a time. Eventually, use a similar mechanism to allow selecting the - * color component of the vertex format based on client behaviour. - * - * Note: Perform these actions even if there is a codegen or cached - * codegen version of the chosen function. - */ -#define CHOOSE_COLOR(FN, FNTYPE, NR, MASK, ACTIVE, ARGS1, ARGS2 ) \ -static void choose_##FN ARGS1 \ -{ \ - GET_CURRENT_CONTEXT(ctx); \ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ - int key = rmesa->vb.vertex_format & (MASK|ACTIVE); \ - struct dynfn *dfn; \ - \ - if (rmesa->vb.vertex_format & ACTIVE_PKCOLOR) { \ - SET_ ## FN (ctx->Exec, radeon_##FN##_ub); \ - } \ - else if ((rmesa->vb.vertex_format & \ - (ACTIVE_FPCOLOR|ACTIVE_FPALPHA)) == ACTIVE_FPCOLOR) { \ - \ - if (rmesa->vb.installed_color_3f_sz != NR) { \ - rmesa->vb.installed_color_3f_sz = NR; \ - if (NR == 3) ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = 1.0; \ - if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) { \ - radeon_copy_to_current( ctx ); \ - _mesa_install_exec_vtxfmt( ctx, &rmesa->vb.vtxfmt ); \ - CALL_ ## FN (ctx->Exec, ARGS2); \ - return; \ - } \ - } \ - \ - SET_ ## FN (ctx->Exec, radeon_##FN##_3f); \ - } \ - else { \ - SET_ ## FN (ctx->Exec, radeon_##FN##_4f); \ - } \ - \ - \ - dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \ - if (!dfn) dfn = rmesa->vb.codegen.FN( ctx, key ); \ - \ - if (dfn) { \ - if (RADEON_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- codegen version\n", __FUNCTION__ ); \ - SET_ ## FN (ctx->Exec, (FNTYPE)dfn->code); \ - } \ - else if (RADEON_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- 'c' version\n", __FUNCTION__ ); \ - \ - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \ - CALL_ ## FN (ctx->Exec, ARGS2); \ -} - - - -/* Right now there are both _ub and _3f versions of the secondary color - * functions. Currently, we only set-up the hardware to use the _ub versions. - * The _3f versions are needed for the cases where secondary color isn't used - * in the vertex format, but it still needs to be stored in the context - * state vector. - */ -#define CHOOSE_SECONDARY_COLOR(FN, FNTYPE, MASK, ACTIVE, ARGS1, ARGS2 ) \ -static void choose_##FN ARGS1 \ -{ \ - GET_CURRENT_CONTEXT(ctx); \ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ - int key = rmesa->vb.vertex_format & (MASK|ACTIVE); \ - struct dynfn *dfn = lookup( &rmesa->vb.dfn_cache.FN, key ); \ - \ - if (dfn == 0) \ - dfn = rmesa->vb.codegen.FN( ctx, key ); \ - else if (RADEON_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- cached version\n", __FUNCTION__ ); \ - \ - if (dfn) \ - SET_ ## FN (ctx->Exec, (FNTYPE)(dfn->code)); \ - else { \ - if (RADEON_DEBUG & DEBUG_CODEGEN) \ - fprintf(stderr, "%s -- generic version\n", __FUNCTION__ ); \ - SET_ ## FN (ctx->Exec, ((rmesa->vb.vertex_format & ACTIVE_PKSPEC) != 0) \ - ? radeon_##FN##_ub : radeon_##FN##_3f); \ - } \ - \ - ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; \ - CALL_ ## FN (ctx->Exec, ARGS2); \ -} - - - - - -/* Shorthands - */ -#define ACTIVE_XYZW (RADEON_CP_VC_FRMT_W0|RADEON_CP_VC_FRMT_Z) -#define ACTIVE_NORM RADEON_CP_VC_FRMT_N0 - -#define ACTIVE_PKCOLOR RADEON_CP_VC_FRMT_PKCOLOR -#define ACTIVE_FPCOLOR RADEON_CP_VC_FRMT_FPCOLOR -#define ACTIVE_FPALPHA RADEON_CP_VC_FRMT_FPALPHA -#define ACTIVE_COLOR (ACTIVE_FPCOLOR|ACTIVE_PKCOLOR) - -#define ACTIVE_PKSPEC RADEON_CP_VC_FRMT_PKSPEC -#define ACTIVE_FPSPEC RADEON_CP_VC_FRMT_FPSPEC -#define ACTIVE_SPEC (ACTIVE_FPSPEC|ACTIVE_PKSPEC) - -#define ACTIVE_ST0 RADEON_CP_VC_FRMT_ST0 -#define ACTIVE_ST1 RADEON_CP_VC_FRMT_ST1 -#define ACTIVE_ST2 RADEON_CP_VC_FRMT_ST2 -#define ACTIVE_ST_ALL (RADEON_CP_VC_FRMT_ST1|RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST2) - -/* Each codegen function should be able to be fully specified by a - * subsetted version of rmesa->vb.vertex_format. - */ -#define MASK_NORM (ACTIVE_XYZW) -#define MASK_COLOR (MASK_NORM|ACTIVE_NORM) -#define MASK_SPEC (MASK_COLOR|ACTIVE_COLOR) -#define MASK_ST0 (MASK_SPEC|ACTIVE_SPEC) -#define MASK_ST1 (MASK_ST0|ACTIVE_ST0) -#define MASK_ST2 (MASK_ST1|ACTIVE_ST1) -#define MASK_ST_ALL (MASK_ST2|ACTIVE_ST2) -#define MASK_VERTEX (MASK_ST_ALL|ACTIVE_FPALPHA) - - -typedef void (*p4f)( GLfloat, GLfloat, GLfloat, GLfloat ); -typedef void (*p3f)( GLfloat, GLfloat, GLfloat ); -typedef void (*p2f)( GLfloat, GLfloat ); -typedef void (*p1f)( GLfloat ); -typedef void (*pe2f)( GLenum, GLfloat, GLfloat ); -typedef void (*pe1f)( GLenum, GLfloat ); -typedef void (*p4ub)( GLubyte, GLubyte, GLubyte, GLubyte ); -typedef void (*p3ub)( GLubyte, GLubyte, GLubyte ); -typedef void (*pfv)( const GLfloat * ); -typedef void (*pefv)( GLenum, const GLfloat * ); -typedef void (*pubv)( const GLubyte * ); - - -CHOOSE(Normal3f, p3f, MASK_NORM, ACTIVE_NORM, - (GLfloat a,GLfloat b,GLfloat c), (a,b,c)) -CHOOSE(Normal3fv, pfv, MASK_NORM, ACTIVE_NORM, - (const GLfloat *v), (v)) - -#if 0 -CHOOSE_COLOR(Color4ub, p4ub, 4, MASK_COLOR, ACTIVE_COLOR, - (GLubyte a,GLubyte b, GLubyte c, GLubyte d), (a,b,c,d)) -CHOOSE_COLOR(Color4ubv, pubv, 4, MASK_COLOR, ACTIVE_COLOR, - (const GLubyte *v), (v)) -CHOOSE_COLOR(Color3ub, p3ub, 3, MASK_COLOR, ACTIVE_COLOR, - (GLubyte a,GLubyte b, GLubyte c), (a,b,c)) -CHOOSE_COLOR(Color3ubv, pubv, 3, MASK_COLOR, ACTIVE_COLOR, - (const GLubyte *v), (v)) -#endif - -CHOOSE_COLOR(Color4f, p4f, 4, MASK_COLOR, ACTIVE_COLOR, - (GLfloat a,GLfloat b, GLfloat c, GLfloat d), (a,b,c,d)) -CHOOSE_COLOR(Color4fv, pfv, 4, MASK_COLOR, ACTIVE_COLOR, - (const GLfloat *v), (v)) -CHOOSE_COLOR(Color3f, p3f, 3, MASK_COLOR, ACTIVE_COLOR, - (GLfloat a,GLfloat b, GLfloat c), (a,b,c)) -CHOOSE_COLOR(Color3fv, pfv, 3, MASK_COLOR, ACTIVE_COLOR, - (const GLfloat *v), (v)) - - -#if 0 -CHOOSE_SECONDARY_COLOR(SecondaryColor3ubEXT, p3ub, MASK_SPEC, ACTIVE_SPEC, - (GLubyte a,GLubyte b, GLubyte c), (a,b,c)) -CHOOSE_SECONDARY_COLOR(SecondaryColor3ubvEXT, pubv, MASK_SPEC, ACTIVE_SPEC, - (const GLubyte *v), (v)) -#endif -CHOOSE_SECONDARY_COLOR(SecondaryColor3fEXT, p3f, MASK_SPEC, ACTIVE_SPEC, - (GLfloat a,GLfloat b, GLfloat c), (a,b,c)) -CHOOSE_SECONDARY_COLOR(SecondaryColor3fvEXT, pfv, MASK_SPEC, ACTIVE_SPEC, - (const GLfloat *v), (v)) - -CHOOSE(TexCoord2f, p2f, MASK_ST0, ACTIVE_ST0, - (GLfloat a,GLfloat b), (a,b)) -CHOOSE(TexCoord2fv, pfv, MASK_ST0, ACTIVE_ST0, - (const GLfloat *v), (v)) -CHOOSE(TexCoord1f, p1f, MASK_ST0, ACTIVE_ST0, - (GLfloat a), (a)) -CHOOSE(TexCoord1fv, pfv, MASK_ST0, ACTIVE_ST0, - (const GLfloat *v), (v)) - -CHOOSE(MultiTexCoord2fARB, pe2f, MASK_ST_ALL, ACTIVE_ST_ALL, - (GLenum u,GLfloat a,GLfloat b), (u,a,b)) -CHOOSE(MultiTexCoord2fvARB, pefv, MASK_ST_ALL, ACTIVE_ST_ALL, - (GLenum u,const GLfloat *v), (u,v)) -CHOOSE(MultiTexCoord1fARB, pe1f, MASK_ST_ALL, ACTIVE_ST_ALL, - (GLenum u,GLfloat a), (u,a)) -CHOOSE(MultiTexCoord1fvARB, pefv, MASK_ST_ALL, ACTIVE_ST_ALL, - (GLenum u,const GLfloat *v), (u,v)) - -CHOOSE(Vertex3f, p3f, MASK_VERTEX, MASK_VERTEX, - (GLfloat a,GLfloat b,GLfloat c), (a,b,c)) -CHOOSE(Vertex3fv, pfv, MASK_VERTEX, MASK_VERTEX, - (const GLfloat *v), (v)) -CHOOSE(Vertex2f, p2f, MASK_VERTEX, MASK_VERTEX, - (GLfloat a,GLfloat b), (a,b)) -CHOOSE(Vertex2fv, pfv, MASK_VERTEX, MASK_VERTEX, - (const GLfloat *v), (v)) - - - - - -void radeonVtxfmtInitChoosers( GLvertexformat *vfmt ) -{ - vfmt->Color3f = choose_Color3f; - vfmt->Color3fv = choose_Color3fv; - vfmt->Color4f = choose_Color4f; - vfmt->Color4fv = choose_Color4fv; - vfmt->SecondaryColor3fEXT = choose_SecondaryColor3fEXT; - vfmt->SecondaryColor3fvEXT = choose_SecondaryColor3fvEXT; - vfmt->MultiTexCoord1fARB = choose_MultiTexCoord1fARB; - vfmt->MultiTexCoord1fvARB = choose_MultiTexCoord1fvARB; - vfmt->MultiTexCoord2fARB = choose_MultiTexCoord2fARB; - vfmt->MultiTexCoord2fvARB = choose_MultiTexCoord2fvARB; - vfmt->Normal3f = choose_Normal3f; - vfmt->Normal3fv = choose_Normal3fv; - vfmt->TexCoord1f = choose_TexCoord1f; - vfmt->TexCoord1fv = choose_TexCoord1fv; - vfmt->TexCoord2f = choose_TexCoord2f; - vfmt->TexCoord2fv = choose_TexCoord2fv; - vfmt->Vertex2f = choose_Vertex2f; - vfmt->Vertex2fv = choose_Vertex2fv; - vfmt->Vertex3f = choose_Vertex3f; - vfmt->Vertex3fv = choose_Vertex3fv; - -#if 0 - vfmt->Color3ub = choose_Color3ub; - vfmt->Color3ubv = choose_Color3ubv; - vfmt->Color4ub = choose_Color4ub; - vfmt->Color4ubv = choose_Color4ubv; - vfmt->SecondaryColor3ubEXT = choose_SecondaryColor3ubEXT; - vfmt->SecondaryColor3ubvEXT = choose_SecondaryColor3ubvEXT; -#endif -} - - -static struct dynfn *codegen_noop( GLcontext *ctx, int key ) -{ - (void) ctx; (void) key; - return NULL; -} - -void radeonInitCodegen( struct dfn_generators *gen, GLboolean useCodegen ) -{ - gen->Vertex3f = codegen_noop; - gen->Vertex3fv = codegen_noop; - gen->Color4ub = codegen_noop; - gen->Color4ubv = codegen_noop; - gen->Normal3f = codegen_noop; - gen->Normal3fv = codegen_noop; - gen->TexCoord2f = codegen_noop; - gen->TexCoord2fv = codegen_noop; - gen->MultiTexCoord2fARB = codegen_noop; - gen->MultiTexCoord2fvARB = codegen_noop; - gen->Vertex2f = codegen_noop; - gen->Vertex2fv = codegen_noop; - gen->Color3ub = codegen_noop; - gen->Color3ubv = codegen_noop; - gen->Color4f = codegen_noop; - gen->Color4fv = codegen_noop; - gen->Color3f = codegen_noop; - gen->Color3fv = codegen_noop; - gen->SecondaryColor3fEXT = codegen_noop; - gen->SecondaryColor3fvEXT = codegen_noop; - gen->SecondaryColor3ubEXT = codegen_noop; - gen->SecondaryColor3ubvEXT = codegen_noop; - gen->TexCoord1f = codegen_noop; - gen->TexCoord1fv = codegen_noop; - gen->MultiTexCoord1fARB = codegen_noop; - gen->MultiTexCoord1fvARB = codegen_noop; - - if (useCodegen) { -#if defined(USE_X86_ASM) - radeonInitX86Codegen( gen ); -#endif - -#if defined(USE_SSE_ASM) - radeonInitSSECodegen( gen ); -#endif - } -} diff --git a/src/mesa/drivers/dri/radeon/radeon_vtxfmt_sse.c b/src/mesa/drivers/dri/radeon/radeon_vtxfmt_sse.c deleted file mode 100644 index 0f0fc9e065..0000000000 --- a/src/mesa/drivers/dri/radeon/radeon_vtxfmt_sse.c +++ /dev/null @@ -1,236 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_sse.c,v 1.1 2002/10/30 12:51:58 alanh Exp $ */ -/************************************************************************** - -Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and - Tungsten Graphics Inc., Cedar Park, Texas. - -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, 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 - */ - -#include "glheader.h" -#include "imports.h" -#include "simple_list.h" -#include "radeon_vtxfmt.h" - -#if defined(USE_SSE_ASM) -#include "x86/common_x86_asm.h" - -#define EXTERN( FUNC ) \ -extern const char *FUNC; \ -extern const char *FUNC##_end - -EXTERN( _sse_Attribute2fv ); -EXTERN( _sse_Attribute2f ); -EXTERN( _sse_Attribute3fv ); -EXTERN( _sse_Attribute3f ); -EXTERN( _sse_MultiTexCoord2fv ); -EXTERN( _sse_MultiTexCoord2f ); -EXTERN( _sse_MultiTexCoord2fv_2 ); -EXTERN( _sse_MultiTexCoord2f_2 ); - -/* Build specialized versions of the immediate calls on the fly for - * the current state. - */ - -static struct dynfn *radeon_makeSSEAttribute2fv( struct dynfn * cache, int key, - const char * name, void * dest) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key ); - - DFN ( _sse_Attribute2fv, (*cache) ); - FIXUP(dfn->code, 10, 0x0, (int)dest); - return dfn; -} - -static struct dynfn *radeon_makeSSEAttribute2f( struct dynfn * cache, int key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key ); - - DFN ( _sse_Attribute2f, (*cache) ); - FIXUP(dfn->code, 8, 0x0, (int)dest); - return dfn; -} - -static struct dynfn *radeon_makeSSEAttribute3fv( struct dynfn * cache, int key, - const char * name, void * dest) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key ); - - DFN ( _sse_Attribute3fv, (*cache) ); - FIXUP(dfn->code, 13, 0x0, (int)dest); - FIXUP(dfn->code, 18, 0x8, 8+(int)dest); - return dfn; -} - -static struct dynfn *radeon_makeSSEAttribute3f( struct dynfn * cache, int key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key ); - - DFN ( _sse_Attribute3f, (*cache) ); - FIXUP(dfn->code, 12, 0x0, (int)dest); - FIXUP(dfn->code, 17, 0x8, 8+(int)dest); - return dfn; -} - -static struct dynfn * radeon_makeSSENormal3fv( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeSSEAttribute3fv( & rmesa->vb.dfn_cache.Normal3fv, key, - __FUNCTION__, rmesa->vb.normalptr ); -} - -static struct dynfn *radeon_makeSSENormal3f( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeSSEAttribute3f( & rmesa->vb.dfn_cache.Normal3f, key, - __FUNCTION__, rmesa->vb.normalptr ); -} - -static struct dynfn *radeon_makeSSEColor3fv( GLcontext *ctx, int key ) -{ - if (key & (RADEON_CP_VC_FRMT_PKCOLOR|RADEON_CP_VC_FRMT_FPALPHA)) - return NULL; - else - { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeSSEAttribute3fv( & rmesa->vb.dfn_cache.Color3fv, key, - __FUNCTION__, rmesa->vb.floatcolorptr ); - } -} - -static struct dynfn *radeon_makeSSEColor3f( GLcontext *ctx, int key ) -{ - if (key & (RADEON_CP_VC_FRMT_PKCOLOR|RADEON_CP_VC_FRMT_FPALPHA)) - return NULL; - else - { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeSSEAttribute3f( & rmesa->vb.dfn_cache.Color3f, key, - __FUNCTION__, rmesa->vb.floatcolorptr ); - } -} - -static struct dynfn *radeon_makeSSETexCoord2fv( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeSSEAttribute2fv( & rmesa->vb.dfn_cache.TexCoord2fv, key, - __FUNCTION__, rmesa->vb.texcoordptr[0] ); -} - -static struct dynfn *radeon_makeSSETexCoord2f( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeSSEAttribute2f( & rmesa->vb.dfn_cache.TexCoord2f, key, - __FUNCTION__, rmesa->vb.texcoordptr[0] ); -} - -#if 0 /* Temporarily disabled - probably needs adjustments for more than 2 tex units -rs */ -static struct dynfn *radeon_makeSSEMultiTexCoord2fv( GLcontext *ctx, int key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); - - if ((key & (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) == - (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) { - DFN ( _sse_MultiTexCoord2fv, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 18, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - } else { - DFN ( _sse_MultiTexCoord2fv_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 14, 0x0, (int)rmesa->vb.texcoordptr); - } - return dfn; -} - -static struct dynfn *radeon_makeSSEMultiTexCoord2f( GLcontext *ctx, int key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); - - if ((key & (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) == - (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) { - DFN ( _sse_MultiTexCoord2f, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 16, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - } else { - DFN ( _sse_MultiTexCoord2f_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 15, 0x0, (int)rmesa->vb.texcoordptr); - } - return dfn; -} -#endif - -void radeonInitSSECodegen( struct dfn_generators *gen ) -{ - if ( cpu_has_xmm ) { - gen->Normal3fv = (void *) radeon_makeSSENormal3fv; - gen->Normal3f = (void *) radeon_makeSSENormal3f; - gen->Color3fv = (void *) radeon_makeSSEColor3fv; - gen->Color3f = (void *) radeon_makeSSEColor3f; - gen->TexCoord2fv = (void *) radeon_makeSSETexCoord2fv; - gen->TexCoord2f = (void *) radeon_makeSSETexCoord2f; -#if 0 /* Temporarily disabled - probably needs adjustments for more than 2 tex units -rs */ - gen->MultiTexCoord2fvARB = (void *) radeon_makeSSEMultiTexCoord2fv; - gen->MultiTexCoord2fARB = (void *) radeon_makeSSEMultiTexCoord2f; -#endif - } -} - -#else - -void radeonInitSSECodegen( struct dfn_generators *gen ) -{ - (void) gen; -} - -#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_vtxfmt_x86.c b/src/mesa/drivers/dri/radeon/radeon_vtxfmt_x86.c deleted file mode 100644 index 529e79065e..0000000000 --- a/src/mesa/drivers/dri/radeon/radeon_vtxfmt_x86.c +++ /dev/null @@ -1,440 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxfmt_x86.c,v 1.2 2002/12/21 17:02:16 dawes Exp $ */ -/************************************************************************** - -Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and - Tungsten Graphics Inc., Cedar Park, Texas. - -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, 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 - */ - -#include "glheader.h" -#include "imports.h" -#include "simple_list.h" -#include "radeon_vtxfmt.h" - -#if defined(USE_X86_ASM) - -#define EXTERN( FUNC ) \ -extern const char *FUNC; \ -extern const char *FUNC##_end - -EXTERN ( _x86_Attribute2fv ); -EXTERN ( _x86_Attribute2f ); -EXTERN ( _x86_Attribute3fv ); -EXTERN ( _x86_Attribute3f ); -EXTERN ( _x86_Vertex3fv_6 ); -EXTERN ( _x86_Vertex3fv_8 ); -EXTERN ( _x86_Vertex3fv ); -EXTERN ( _x86_Vertex3f_4 ); -EXTERN ( _x86_Vertex3f_6 ); -EXTERN ( _x86_Vertex3f ); -EXTERN ( _x86_Color4ubv_ub ); -EXTERN ( _x86_Color4ubv_4f ); -EXTERN ( _x86_Color4ub_ub ); -EXTERN ( _x86_MultiTexCoord2fv ); -EXTERN ( _x86_MultiTexCoord2fv_2 ); -EXTERN ( _x86_MultiTexCoord2f ); -EXTERN ( _x86_MultiTexCoord2f_2 ); - - -/* Build specialized versions of the immediate calls on the fly for - * the current state. Generic x86 versions. - */ - -struct dynfn *radeon_makeX86Vertex3f( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x %d\n", __FUNCTION__, key, rmesa->vb.vertex_size ); - - switch (rmesa->vb.vertex_size) { - case 4: { - - DFN ( _x86_Vertex3f_4, rmesa->vb.dfn_cache.Vertex3f ); - FIXUP(dfn->code, 2, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 25, 0x0, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 36, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 46, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 51, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 60, 0x0, (int)&rmesa->vb.notify); - break; - } - case 6: { - - DFN ( _x86_Vertex3f_6, rmesa->vb.dfn_cache.Vertex3f ); - FIXUP(dfn->code, 3, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 28, 0x0, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 34, 0x0, (int)&rmesa->vb.vertex[4]); - FIXUP(dfn->code, 40, 0x0, (int)&rmesa->vb.vertex[5]); - FIXUP(dfn->code, 57, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 63, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 70, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 79, 0x0, (int)&rmesa->vb.notify); - break; - } - default: { - - DFN ( _x86_Vertex3f, rmesa->vb.dfn_cache.Vertex3f ); - FIXUP(dfn->code, 3, 0x0, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 9, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 37, 0x0, rmesa->vb.vertex_size-3); - FIXUP(dfn->code, 44, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 50, 0x0, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 56, 0x0, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 67, 0x0, (int)&rmesa->vb.notify); - break; - } - } - - return dfn; -} - - - -struct dynfn *radeon_makeX86Vertex3fv( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x %d\n", __FUNCTION__, key, rmesa->vb.vertex_size ); - - switch (rmesa->vb.vertex_size) { - case 6: { - - DFN ( _x86_Vertex3fv_6, rmesa->vb.dfn_cache.Vertex3fv ); - FIXUP(dfn->code, 1, 0x00000000, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 27, 0x0000001c, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 33, 0x00000020, (int)&rmesa->vb.vertex[4]); - FIXUP(dfn->code, 45, 0x00000024, (int)&rmesa->vb.vertex[5]); - FIXUP(dfn->code, 56, 0x00000000, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 61, 0x00000004, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 67, 0x00000004, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 76, 0x00000008, (int)&rmesa->vb.notify); - break; - } - - - case 8: { - - DFN ( _x86_Vertex3fv_8, rmesa->vb.dfn_cache.Vertex3fv ); - FIXUP(dfn->code, 1, 0x00000000, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 27, 0x0000001c, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 33, 0x00000020, (int)&rmesa->vb.vertex[4]); - FIXUP(dfn->code, 45, 0x0000001c, (int)&rmesa->vb.vertex[5]); - FIXUP(dfn->code, 51, 0x00000020, (int)&rmesa->vb.vertex[6]); - FIXUP(dfn->code, 63, 0x00000024, (int)&rmesa->vb.vertex[7]); - FIXUP(dfn->code, 74, 0x00000000, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 79, 0x00000004, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 85, 0x00000004, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 94, 0x00000008, (int)&rmesa->vb.notify); - break; - } - - - - default: { - - DFN ( _x86_Vertex3fv, rmesa->vb.dfn_cache.Vertex3fv ); - FIXUP(dfn->code, 8, 0x01010101, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 32, 0x00000006, rmesa->vb.vertex_size-3); - FIXUP(dfn->code, 37, 0x00000058, (int)&rmesa->vb.vertex[3]); - FIXUP(dfn->code, 45, 0x01010101, (int)&rmesa->vb.dmaptr); - FIXUP(dfn->code, 50, 0x02020202, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 58, 0x02020202, (int)&rmesa->vb.counter); - FIXUP(dfn->code, 67, 0x0, (int)&rmesa->vb.notify); - break; - } - } - - return dfn; -} - -static struct dynfn * -radeon_makeX86Attribute2fv( struct dynfn * cache, int key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key ); - - DFN ( _x86_Attribute2fv, (*cache) ); - FIXUP(dfn->code, 11, 0x0, (int)dest); - FIXUP(dfn->code, 16, 0x4, 4+(int)dest); - - return dfn; -} - -static struct dynfn * -radeon_makeX86Attribute2f( struct dynfn * cache, int key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key ); - - DFN ( _x86_Attribute2f, (*cache) ); - FIXUP(dfn->code, 1, 0x0, (int)dest); - - return dfn; -} - - -static struct dynfn * -radeon_makeX86Attribute3fv( struct dynfn * cache, int key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key ); - - DFN ( _x86_Attribute3fv, (*cache) ); - FIXUP(dfn->code, 14, 0x0, (int)dest); - FIXUP(dfn->code, 20, 0x4, 4+(int)dest); - FIXUP(dfn->code, 25, 0x8, 8+(int)dest); - - return dfn; -} - -static struct dynfn * -radeon_makeX86Attribute3f( struct dynfn * cache, int key, - const char * name, void * dest ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", name, key ); - - DFN ( _x86_Attribute3f, (*cache) ); - FIXUP(dfn->code, 14, 0x0, (int)dest); - FIXUP(dfn->code, 20, 0x4, 4+(int)dest); - FIXUP(dfn->code, 25, 0x8, 8+(int)dest); - - return dfn; -} - -struct dynfn *radeon_makeX86Normal3fv( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeX86Attribute3fv( & rmesa->vb.dfn_cache.Normal3fv, key, - __FUNCTION__, rmesa->vb.normalptr ); -} - -struct dynfn *radeon_makeX86Normal3f( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeX86Attribute3f( & rmesa->vb.dfn_cache.Normal3f, key, - __FUNCTION__, rmesa->vb.normalptr ); -} - -struct dynfn *radeon_makeX86Color4ubv( GLcontext *ctx, int key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); - - if (key & RADEON_CP_VC_FRMT_PKCOLOR) { - DFN ( _x86_Color4ubv_ub, rmesa->vb.dfn_cache.Color4ubv); - FIXUP(dfn->code, 5, 0x12345678, (int)rmesa->vb.colorptr); - return dfn; - } - else { - - DFN ( _x86_Color4ubv_4f, rmesa->vb.dfn_cache.Color4ubv); - FIXUP(dfn->code, 2, 0x00000000, (int)_mesa_ubyte_to_float_color_tab); - FIXUP(dfn->code, 27, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr); - FIXUP(dfn->code, 33, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr+4); - FIXUP(dfn->code, 55, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr+8); - FIXUP(dfn->code, 61, 0xdeadbeaf, (int)rmesa->vb.floatcolorptr+12); - return dfn; - } -} - -struct dynfn *radeon_makeX86Color4ub( GLcontext *ctx, int key ) -{ - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); - - if (key & RADEON_CP_VC_FRMT_PKCOLOR) { - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - DFN ( _x86_Color4ub_ub, rmesa->vb.dfn_cache.Color4ub ); - FIXUP(dfn->code, 18, 0x0, (int)rmesa->vb.colorptr); - FIXUP(dfn->code, 24, 0x0, (int)rmesa->vb.colorptr+1); - FIXUP(dfn->code, 30, 0x0, (int)rmesa->vb.colorptr+2); - FIXUP(dfn->code, 36, 0x0, (int)rmesa->vb.colorptr+3); - return dfn; - } - else - return NULL; -} - - -struct dynfn *radeon_makeX86Color3fv( GLcontext *ctx, int key ) -{ - if (key & (RADEON_CP_VC_FRMT_PKCOLOR|RADEON_CP_VC_FRMT_FPALPHA)) - return NULL; - else - { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeX86Attribute3fv( & rmesa->vb.dfn_cache.Color3fv, key, - __FUNCTION__, rmesa->vb.floatcolorptr ); - } -} - -struct dynfn *radeon_makeX86Color3f( GLcontext *ctx, int key ) -{ - if (key & (RADEON_CP_VC_FRMT_PKCOLOR|RADEON_CP_VC_FRMT_FPALPHA)) - return NULL; - else - { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeX86Attribute3f( & rmesa->vb.dfn_cache.Color3f, key, - __FUNCTION__, rmesa->vb.floatcolorptr ); - } -} - - - -struct dynfn *radeon_makeX86TexCoord2fv( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeX86Attribute2fv( & rmesa->vb.dfn_cache.TexCoord2fv, key, - __FUNCTION__, rmesa->vb.texcoordptr[0] ); -} - -struct dynfn *radeon_makeX86TexCoord2f( GLcontext *ctx, int key ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - return radeon_makeX86Attribute2f( & rmesa->vb.dfn_cache.TexCoord2f, key, - __FUNCTION__, rmesa->vb.texcoordptr[0] ); -} - -#if 0 /* Temporarily disabled - probably needs adjustments for more than 2 tex units -rs */ -struct dynfn *radeon_makeX86MultiTexCoord2fvARB( GLcontext *ctx, int key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); - - if ((key & (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) == - (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) { - DFN ( _x86_MultiTexCoord2fv, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 21, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - FIXUP(dfn->code, 27, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]+4); - } else { - DFN ( _x86_MultiTexCoord2fv_2, rmesa->vb.dfn_cache.MultiTexCoord2fvARB ); - FIXUP(dfn->code, 14, 0x0, (int)rmesa->vb.texcoordptr); - } - return dfn; -} - -struct dynfn *radeon_makeX86MultiTexCoord2fARB( GLcontext *ctx, - int key ) -{ - struct dynfn *dfn = MALLOC_STRUCT( dynfn ); - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - if (RADEON_DEBUG & DEBUG_CODEGEN) - fprintf(stderr, "%s 0x%08x\n", __FUNCTION__, key ); - - if ((key & (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) == - (RADEON_CP_VC_FRMT_ST0|RADEON_CP_VC_FRMT_ST1)) { - DFN ( _x86_MultiTexCoord2f, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 20, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]); - FIXUP(dfn->code, 26, 0xdeadbeef, (int)rmesa->vb.texcoordptr[0]+4); - } - else { - /* Note: this might get generated multiple times, even though the - * actual emitted code is the same. - */ - DFN ( _x86_MultiTexCoord2f_2, rmesa->vb.dfn_cache.MultiTexCoord2fARB ); - FIXUP(dfn->code, 18, 0x0, (int)rmesa->vb.texcoordptr); - } - return dfn; -} -#endif - -void radeonInitX86Codegen( struct dfn_generators *gen ) -{ - gen->Vertex3f = radeon_makeX86Vertex3f; - gen->Vertex3fv = radeon_makeX86Vertex3fv; - gen->Color4ub = radeon_makeX86Color4ub; /* PKCOLOR only */ - gen->Color4ubv = radeon_makeX86Color4ubv; /* PKCOLOR only */ - gen->Normal3f = radeon_makeX86Normal3f; - gen->Normal3fv = radeon_makeX86Normal3fv; - gen->TexCoord2f = radeon_makeX86TexCoord2f; - gen->TexCoord2fv = radeon_makeX86TexCoord2fv; -#if 0 /* Temporarily disabled - probably needs adjustments for more than 2 tex units -rs */ - gen->MultiTexCoord2fARB = radeon_makeX86MultiTexCoord2fARB; - gen->MultiTexCoord2fvARB = radeon_makeX86MultiTexCoord2fvARB; -#endif - gen->Color3f = radeon_makeX86Color3f; - gen->Color3fv = radeon_makeX86Color3fv; - - /* Not done: - */ -/* gen->Vertex2f = radeon_makeX86Vertex2f; */ -/* gen->Vertex2fv = radeon_makeX86Vertex2fv; */ -/* gen->Color3ub = radeon_makeX86Color3ub; */ -/* gen->Color3ubv = radeon_makeX86Color3ubv; */ -/* gen->Color4f = radeon_makeX86Color4f; */ -/* gen->Color4fv = radeon_makeX86Color4fv; */ -/* gen->TexCoord1f = radeon_makeX86TexCoord1f; */ -/* gen->TexCoord1fv = radeon_makeX86TexCoord1fv; */ -/* gen->MultiTexCoord1fARB = radeon_makeX86MultiTexCoord1fARB; */ -/* gen->MultiTexCoord1fvARB = radeon_makeX86MultiTexCoord1fvARB; */ -} - - -#else - -void radeonInitX86Codegen( struct dfn_generators *gen ) -{ - (void) gen; -} - -#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_vtxtmp_x86.S b/src/mesa/drivers/dri/radeon/radeon_vtxtmp_x86.S deleted file mode 100644 index 1b433491aa..0000000000 --- a/src/mesa/drivers/dri/radeon/radeon_vtxtmp_x86.S +++ /dev/null @@ -1,498 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vtxtmp_x86.S,v 1.1 2002/10/30 12:51:58 alanh Exp $ */ -/************************************************************************** - -Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. - -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 -ATI, TUNGSTEN GRAPHICS AND/OR THEIR 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. - -**************************************************************************/ - -#define GLOBL( x ) \ -.globl x; \ -x: - -.data -.align 4 - -/* - vertex 3f vertex size 4 -*/ - -GLOBL ( _x86_Vertex3f_4 ) - movl (0), %ecx - movl 4(%esp), %eax - movl 8(%esp), %edx - movl %eax, (%ecx) - movl %edx, 4(%ecx) - movl 12(%esp), %eax - movl (0), %edx - movl %eax, 8(%ecx) - movl %edx, 12(%ecx) - movl (0), %eax - addl $16, %ecx - dec %eax - movl %ecx, (0) - movl %eax, (0) - je .1 - ret -.1: jmp *0 - -GLOBL ( _x86_Vertex3f_4_end ) - -/* - vertex 3f vertex size 6 -*/ -GLOBL ( _x86_Vertex3f_6 ) - push %edi - movl (0), %edi - movl 8(%esp), %eax - movl 12(%esp), %edx - movl 16(%esp), %ecx - movl %eax, (%edi) - movl %edx, 4(%edi) - movl %ecx, 8(%edi) - movl (0), %eax - movl (0), %edx - movl (0), %ecx - movl %eax, 12(%edi) - movl %edx, 16(%edi) - movl %ecx, 20(%edi) - addl $24, %edi - movl (0), %eax - movl %edi, (0) - dec %eax - pop %edi - movl %eax, (0) - je .2 - ret -.2: jmp *0 -GLOBL ( _x86_Vertex3f_6_end ) -/* - vertex 3f generic size -*/ -GLOBL ( _x86_Vertex3f ) - push %edi - push %esi - movl $0, %esi - movl (0), %edi - movl 12(%esp), %eax - movl 16(%esp), %edx - movl 20(%esp), %ecx - movl %eax, (%edi) - movl %edx, 4(%edi) - movl %ecx, 8(%edi) - addl $12, %edi - movl $0, %ecx - repz - movsl %ds:(%esi), %es:(%edi) - movl (0), %eax - movl %edi, (0) - dec %eax - movl %eax, (0) - pop %esi - pop %edi - je .3 - ret -.3: jmp *0 - -GLOBL ( _x86_Vertex3f_end ) - -/* - Vertex 3fv vertex size 6 -*/ -GLOBL ( _x86_Vertex3fv_6 ) - movl (0), %eax - movl 4(%esp), %ecx - movl (%ecx), %edx - movl %edx, (%eax) - movl 4(%ecx), %edx - movl 8(%ecx), %ecx - movl %edx, 4(%eax) - movl %ecx, 8(%eax) - movl (28), %edx - movl (32), %ecx - movl %edx, 12(%eax) - movl %ecx, 16(%eax) - movl (36), %edx - movl %edx, 20(%eax) - addl $24, %eax - movl %eax, 0 - movl 4, %eax - dec %eax - movl %eax, 4 - je .4 - ret -.4: jmp *8 - -GLOBL ( _x86_Vertex3fv_6_end ) - -/* - Vertex 3fv vertex size 8 -*/ -GLOBL ( _x86_Vertex3fv_8 ) - movl (0), %eax - movl 4(%esp), %ecx - movl (%ecx), %edx - movl %edx ,(%eax) - movl 4(%ecx) ,%edx - movl 8(%ecx) ,%ecx - movl %edx, 4(%eax) - movl %ecx, 8(%eax) - movl (28), %edx - movl (32), %ecx - movl %edx, 12(%eax) - movl %ecx, 16(%eax) - movl (28), %edx - movl (32), %ecx - movl %edx, 20(%eax) - movl %ecx, 24(%eax) - movl (36), %edx - movl %edx, 28(%eax) - addl $32, %eax - movl %eax, (0) - movl 4, %eax - dec %eax - movl %eax, (4) - je .5 - ret -.5: jmp *8 - -GLOBL ( _x86_Vertex3fv_8_end ) - -/* - Vertex 3fv generic vertex size -*/ -GLOBL ( _x86_Vertex3fv ) - movl 4(%esp), %edx - push %edi - push %esi - movl (0x1010101), %edi - movl (%edx), %eax - movl 4(%edx), %ecx - movl 8(%edx), %esi - movl %eax, (%edi) - movl %ecx, 4(%edi) - movl %esi, 8(%edi) - addl $12, %edi - movl $6, %ecx - movl $0x58, %esi - repz - movsl %ds:(%esi), %es:(%edi) - movl %edi, (0x1010101) - movl (0x2020202), %eax - pop %esi - pop %edi - dec %eax - movl %eax, (0x2020202) - je .6 - ret -.6: jmp *0 -GLOBL ( _x86_Vertex3fv_end ) - - -/** - * Generic handler for 2 float format data. This can be used for - * TexCoord2f and possibly other functions. - */ - -GLOBL ( _x86_Attribute2f ) - movl $0x0, %edx - movl 4(%esp), %eax - movl 8(%esp), %ecx - movl %eax, (%edx) - movl %ecx, 4(%edx) - ret -GLOBL ( _x86_Attribute2f_end ) - - -/** - * Generic handler for 2 float vector format data. This can be used for - * TexCoord2fv and possibly other functions. - */ - -GLOBL( _x86_Attribute2fv) - movl 4(%esp), %eax /* load 'v' off stack */ - movl (%eax), %ecx /* load v[0] */ - movl 4(%eax), %eax /* load v[1] */ - movl %ecx, 0 /* store v[0] to current vertex */ - movl %eax, 4 /* store v[1] to current vertex */ - ret -GLOBL ( _x86_Attribute2fv_end ) - - -/** - * Generic handler for 3 float format data. This can be used for - * Normal3f, Color3f (when the color target is also float), or - * TexCoord3f. - */ - -GLOBL ( _x86_Attribute3f ) - movl 4(%esp), %ecx - movl 8(%esp), %edx - movl 12(%esp), %eax - movl %ecx, 0 - movl %edx, 4 - movl %eax, 8 - ret -GLOBL ( _x86_Attribute3f_end ) - -/** - * Generic handler for 3 float vector format data. This can be used for - * Normal3f, Color3f (when the color target is also float), or - * TexCoord3f. - */ - -GLOBL( _x86_Attribute3fv) - movl 4(%esp), %eax /* load 'v' off stack */ - movl (%eax), %ecx /* load v[0] */ - movl 4(%eax), %edx /* load v[1] */ - movl 8(%eax), %eax /* load v[2] */ - movl %ecx, 0 /* store v[0] to current vertex */ - movl %edx, 4 /* store v[1] to current vertex */ - movl %eax, 8 /* store v[2] to current vertex */ - ret -GLOBL ( _x86_Attribute3fv_end ) - - -/* - Color 4ubv_ub -*/ -GLOBL ( _x86_Color4ubv_ub ) - movl 4(%esp), %eax - movl $0x12345678, %edx - movl (%eax), %eax - movl %eax, (%edx) - ret -GLOBL ( _x86_Color4ubv_ub_end ) - -/* - Color 4ubv 4f -*/ -GLOBL ( _x86_Color4ubv_4f ) - push %ebx - movl $0, %edx - xor %eax, %eax - xor %ecx, %ecx - movl 8(%esp), %ebx - movl (%ebx), %ebx - mov %bl, %al - mov %bh, %cl - movl (%edx,%eax,4),%eax - movl (%edx,%ecx,4),%ecx - movl %eax, (0xdeadbeaf) - movl %ecx, (0xdeadbeaf) - xor %eax, %eax - xor %ecx, %ecx - shr $16, %ebx - mov %bl, %al - mov %bh, %cl - movl (%edx,%eax,4), %eax - movl (%edx,%ecx,4), %ecx - movl %eax, (0xdeadbeaf) - movl %ecx, (0xdeadbeaf) - pop %ebx - ret -GLOBL ( _x86_Color4ubv_4f_end ) - -/* - - Color4ub_ub -*/ -GLOBL( _x86_Color4ub_ub ) - push %ebx - movl 8(%esp), %eax - movl 12(%esp), %edx - movl 16(%esp), %ecx - movl 20(%esp), %ebx - mov %al, (0) - mov %dl, (0) - mov %cl, (0) - mov %bl, (0) - pop %ebx - ret -GLOBL( _x86_Color4ub_ub_end ) - - -/* - MultiTexCoord2fv st0/st1 -*/ -GLOBL( _x86_MultiTexCoord2fv ) - movl 4(%esp), %eax - movl 8(%esp), %ecx - and $3, %eax - movl (%ecx), %edx - shl $3, %eax - movl 4(%ecx), %ecx - movl %edx, 0xdeadbeef(%eax) - movl %ecx, 0xdeadbeef(%eax) - ret -GLOBL( _x86_MultiTexCoord2fv_end ) - -/* - MultiTexCoord2fv -*/ - -GLOBL( _x86_MultiTexCoord2fv_2 ) - movl 4(%esp,1), %eax - movl 8(%esp,1), %ecx - and $3, %eax - movl 0(,%eax,4), %edx - movl (%ecx), %eax - movl %eax, (%edx) - movl 4(%ecx), %eax - movl %eax, 4(%edx) - ret -GLOBL( _x86_MultiTexCoord2fv_2_end ) - -/* - MultiTexCoord2f st0/st1 -*/ -GLOBL( _x86_MultiTexCoord2f ) - movl 4(%esp), %eax - movl 8(%esp), %edx - movl 12(%esp), %ecx - and $3, %eax - shl $3, %eax - movl %edx, 0xdeadbeef(%eax) - movl %ecx, 0xdeadbeef(%eax) - ret -GLOBL( _x86_MultiTexCoord2f_end ) - -/* - MultiTexCoord2f -*/ -GLOBL( _x86_MultiTexCoord2f_2 ) - movl 4(%esp), %eax - movl 8(%esp), %edx - movl 12(%esp,1), %ecx - and $3,%eax - movl 0(,%eax,4), %eax - movl %edx, (%eax) - movl %ecx, 4(%eax) - ret -GLOBL( _x86_MultiTexCoord2f_2_end ) - -#if defined(USE_SSE_ASM) -/** - * This can be used as a template for either Color3fv (when the color - * target is also a 3f) or Normal3fv. - */ - -GLOBL( _sse_Attribute3fv ) - movl 4(%esp), %eax - movlps (%eax), %xmm0 - movl 8(%eax), %eax - movlps %xmm0, 0 - movl %eax, 8 - ret -GLOBL( _sse_Attribute3fv_end ) - -/** - * This can be used as a template for either Color3f (when the color - * target is also a 3f) or Normal3f. - */ - -GLOBL( _sse_Attribute3f ) - movlps 4(%esp), %xmm0 - movl 12(%esp), %eax - movlps %xmm0, 0 - movl %eax, 8 - ret -GLOBL( _sse_Attribute3f_end ) - - -/** - * Generic handler for 2 float vector format data. This can be used for - * TexCoord2fv and possibly other functions. - */ - -GLOBL( _sse_Attribute2fv ) - movl 4(%esp), %eax - movlps (%eax), %xmm0 - movlps %xmm0, 0 - ret -GLOBL( _sse_Attribute2fv_end ) - - -/** - * Generic handler for 2 float format data. This can be used for - * TexCoord2f and possibly other functions. - */ - -GLOBL( _sse_Attribute2f ) - movlps 4(%esp), %xmm0 - movlps %xmm0, 0 - ret -GLOBL( _sse_Attribute2f_end ) - -/* - MultiTexCoord2fv st0/st1 -*/ -GLOBL( _sse_MultiTexCoord2fv ) - movl 4(%esp), %eax - movl 8(%esp), %ecx - and $3, %eax - movlps (%ecx), %xmm0 - movlps %xmm0, 0xdeadbeef(,%eax,8) - ret -GLOBL( _sse_MultiTexCoord2fv_end ) - -/* - MultiTexCoord2fv -*/ -GLOBL( _sse_MultiTexCoord2fv_2 ) - movl 4(%esp), %eax - movl 8(%esp), %ecx - and $3, %eax - movl 0(,%eax,4), %edx - movlps (%ecx), %xmm0 - movlps %xmm0, (%edx) - ret -GLOBL( _sse_MultiTexCoord2fv_2_end ) - -/* - MultiTexCoord2f st0/st1 -*/ -GLOBL( _sse_MultiTexCoord2f ) - movl 4(%esp), %eax - and $3, %eax - movlps 8(%esp), %xmm0 - movlps %xmm0, 0xdeadbeef(,%eax,8) - ret -GLOBL( _sse_MultiTexCoord2f_end ) - -/* - MultiTexCoord2f -*/ -GLOBL( _sse_MultiTexCoord2f_2 ) - movl 4(%esp), %eax - movlps 8(%esp), %xmm0 - and $3,%eax - movl 0(,%eax,4), %eax - movlps %xmm0, (%eax) - ret -GLOBL( _sse_MultiTexCoord2f_2_end ) -#endif - -#if defined (__ELF__) && defined (__linux__) - .section .note.GNU-stack,"",%progbits -#endif -- cgit v1.2.3 From 851d15ef3ae8e7f78f1d0ef1cf8a3ff6765354b0 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 31 Oct 2006 12:11:56 +0000 Subject: disable vtxfmt_a code, switch over to vbo --- src/mesa/drivers/dri/r300/r300_context.c | 8 ++++---- src/mesa/drivers/dri/r300/r300_context.h | 7 +++++-- src/mesa/drivers/dri/r300/r300_render.c | 4 ++-- src/mesa/drivers/dri/r300/r300_state.c | 4 ++-- src/mesa/drivers/dri/r300/radeon_state.c | 4 +--- 5 files changed, 14 insertions(+), 13 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index 54eb081d05..b58c6075c7 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -44,7 +44,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -287,7 +287,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext(ctx); - _ac_CreateContext(ctx); + _vbo_CreateContext(ctx); _tnl_CreateContext(ctx); _swsetup_CreateContext(ctx); _swsetup_Wakeup(ctx); @@ -300,7 +300,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, /* Try and keep materials and vertices separate: */ - _tnl_isolate_materials(ctx, GL_TRUE); +/* _tnl_isolate_materials(ctx, GL_TRUE); */ /* Configure swrast and TNL to match hardware characteristics: */ @@ -478,7 +478,7 @@ void r300DestroyContext(__DRIcontextPrivate * driContextPriv) _swsetup_DestroyContext(r300->radeon.glCtx); _tnl_ProgramCacheDestroy(r300->radeon.glCtx); _tnl_DestroyContext(r300->radeon.glCtx); - _ac_DestroyContext(r300->radeon.glCtx); + _vbo_DestroyContext(r300->radeon.glCtx); _swrast_DestroyContext(r300->radeon.glCtx); if (r300->dma.current.buf) { diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index df73cdedc1..02ffbfcbef 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -48,7 +48,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_context.h" #define USER_BUFFERS -#define RADEON_VTXFMT_A +/* KW: Disable this code. Driver should hook into vbo module + * directly, see i965 driver for example. + */ +/* #define RADEON_VTXFMT_A */ #define HW_VBOS /* We don't handle 16 bits elts swapping yet */ @@ -739,7 +742,7 @@ struct radeon_vertex_buffer { struct dt AttribPtr[VERT_ATTRIB_MAX]; - struct tnl_prim *Primitive; + const struct _mesa_prim *Primitive; GLuint PrimitiveCount; GLint LockFirst; GLsizei LockCount; diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index 03f168365d..8c259d345c 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -42,7 +42,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "api_arrayelt.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_vp_build.h" @@ -352,7 +352,7 @@ GLboolean r300_run_vb_render(GLcontext *ctx, r300EmitState(rmesa); for(i=0; i < VB->PrimitiveCount; i++){ - GLuint prim = VB->Primitive[i].mode; + GLuint prim = _tnl_translate_prim(&VB->Primitive[i]); GLuint start = VB->Primitive[i].start; GLuint length = VB->Primitive[i].count; diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 29ffa7a017..5a98226300 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -46,7 +46,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "api_arrayelt.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "texformat.h" @@ -1806,7 +1806,7 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state) _swrast_InvalidateState(ctx, new_state); _swsetup_InvalidateState(ctx, new_state); - _ac_InvalidateState(ctx, new_state); + _vbo_InvalidateState(ctx, new_state); _tnl_InvalidateState(ctx, new_state); _ae_invalidate_state(ctx, new_state); diff --git a/src/mesa/drivers/dri/r300/radeon_state.c b/src/mesa/drivers/dri/r300/radeon_state.c index 917acb7243..7726c22f42 100644 --- a/src/mesa/drivers/dri/r300/radeon_state.c +++ b/src/mesa/drivers/dri/r300/radeon_state.c @@ -41,7 +41,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "light.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" #include "swrast_setup/swrast_setup.h" @@ -134,8 +134,6 @@ void radeonUpdateScissor(GLcontext* ctx) static void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h) { - radeonContextPtr radeon = RADEON_CONTEXT(ctx); - if (ctx->Scissor.Enabled) { /* We don't pipeline cliprect changes */ r300Flush(ctx); -- cgit v1.2.3 From 35ee4affc5bd2c7be3005725ce74a016a3da8b59 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 31 Oct 2006 12:12:15 +0000 Subject: switch remaining drivers over to vbo --- src/mesa/drivers/directfb/idirectfbgl_mesa.c | 2 +- src/mesa/drivers/dri/fb/fb_dri.c | 8 ++++---- src/mesa/drivers/dri/fb/fb_egl.c | 6 +++--- src/mesa/drivers/dri/ffb/ffb_state.c | 4 ++-- src/mesa/drivers/dri/ffb/ffb_xmesa.c | 6 +++--- src/mesa/drivers/dri/gamma/gamma_context.c | 4 ++-- src/mesa/drivers/dri/gamma/gamma_state.c | 4 ++-- src/mesa/drivers/dri/gamma/gamma_xmesa.c | 4 ++-- src/mesa/drivers/dri/mach64/mach64_context.c | 6 +++--- src/mesa/drivers/dri/mach64/mach64_state.c | 4 ++-- src/mesa/drivers/dri/mga/mga_xmesa.c | 6 +++--- src/mesa/drivers/dri/mga/mgastate.c | 4 ++-- src/mesa/drivers/dri/r128/r128_context.c | 6 +++--- src/mesa/drivers/dri/r128/r128_state.c | 4 ++-- src/mesa/drivers/dri/s3v/s3v_context.c | 4 ++-- src/mesa/drivers/dri/s3v/s3v_state.c | 4 ++-- src/mesa/drivers/dri/s3v/s3v_xmesa.c | 4 ++-- src/mesa/drivers/dri/savage/savage_xmesa.c | 6 +++--- src/mesa/drivers/dri/savage/savagestate.c | 4 ++-- src/mesa/drivers/dri/sis/sis6326_state.c | 4 ++-- src/mesa/drivers/dri/sis/sis_context.c | 6 +++--- src/mesa/drivers/dri/sis/sis_state.c | 4 ++-- src/mesa/drivers/dri/tdfx/tdfx_context.c | 6 +++--- src/mesa/drivers/dri/tdfx/tdfx_state.c | 4 ++-- src/mesa/drivers/dri/trident/trident_context.c | 6 +++--- src/mesa/drivers/dri/trident/trident_state.c | 4 ++-- src/mesa/drivers/dri/unichrome/via_context.c | 6 +++--- src/mesa/drivers/dri/unichrome/via_state.c | 4 ++-- src/mesa/drivers/glide/fxdd.c | 2 +- 29 files changed, 68 insertions(+), 68 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/directfb/idirectfbgl_mesa.c b/src/mesa/drivers/directfb/idirectfbgl_mesa.c index 3c2a77b5bc..524249e8a5 100644 --- a/src/mesa/drivers/directfb/idirectfbgl_mesa.c +++ b/src/mesa/drivers/directfb/idirectfbgl_mesa.c @@ -53,7 +53,7 @@ #include "texformat.h" #include "teximage.h" #include "texstore.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" diff --git a/src/mesa/drivers/dri/fb/fb_dri.c b/src/mesa/drivers/dri/fb/fb_dri.c index d6ba23bc6e..08b52b4d8f 100644 --- a/src/mesa/drivers/dri/fb/fb_dri.c +++ b/src/mesa/drivers/dri/fb/fb_dri.c @@ -50,7 +50,7 @@ #include "extensions.h" #include "framebuffer.h" #include "renderbuffer.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" @@ -93,7 +93,7 @@ update_state( GLcontext *ctx, GLuint new_state ) /* not much to do here - pass it on */ _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); } @@ -365,7 +365,7 @@ fbCreateContext( const __GLcontextModes *glVisual, /* Create module contexts */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); _swsetup_Wakeup( ctx ); @@ -399,7 +399,7 @@ fbDestroyContext( __DRIcontextPrivate *driContextPriv ) if ( fbmesa ) { _swsetup_DestroyContext( fbmesa->glCtx ); _tnl_DestroyContext( fbmesa->glCtx ); - _ac_DestroyContext( fbmesa->glCtx ); + _vbo_DestroyContext( fbmesa->glCtx ); _swrast_DestroyContext( fbmesa->glCtx ); /* free the Mesa context */ diff --git a/src/mesa/drivers/dri/fb/fb_egl.c b/src/mesa/drivers/dri/fb/fb_egl.c index 5c74b0b0f4..517e71f888 100644 --- a/src/mesa/drivers/dri/fb/fb_egl.c +++ b/src/mesa/drivers/dri/fb/fb_egl.c @@ -17,7 +17,7 @@ #include "extensions.h" #include "framebuffer.h" #include "renderbuffer.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" @@ -388,7 +388,7 @@ update_state( GLcontext *ctx, GLuint new_state ) /* not much to do here - pass it on */ _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); } @@ -491,7 +491,7 @@ fbCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext sh /* Create module contexts */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); _swsetup_Wakeup( ctx ); diff --git a/src/mesa/drivers/dri/ffb/ffb_state.c b/src/mesa/drivers/dri/ffb/ffb_state.c index b81d94de25..eb13478166 100644 --- a/src/mesa/drivers/dri/ffb/ffb_state.c +++ b/src/mesa/drivers/dri/ffb/ffb_state.c @@ -40,7 +40,7 @@ #include "enums.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" @@ -1034,7 +1034,7 @@ static void ffbDDUpdateState(GLcontext *ctx, GLuint newstate) _swrast_InvalidateState( ctx, newstate ); _swsetup_InvalidateState( ctx, newstate ); - _ac_InvalidateState( ctx, newstate ); + _vbo_InvalidateState( ctx, newstate ); _tnl_InvalidateState( ctx, newstate ); if (newstate & _NEW_TEXTURE) diff --git a/src/mesa/drivers/dri/ffb/ffb_xmesa.c b/src/mesa/drivers/dri/ffb/ffb_xmesa.c index ab2a6688ba..7c1e439364 100644 --- a/src/mesa/drivers/dri/ffb/ffb_xmesa.c +++ b/src/mesa/drivers/dri/ffb/ffb_xmesa.c @@ -38,7 +38,7 @@ #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "drivers/common/driverfuncs.h" #include "ffb_context.h" @@ -277,7 +277,7 @@ ffbCreateContext(const __GLcontextModes *mesaVis, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -313,7 +313,7 @@ ffbDestroyContext(__DRIcontextPrivate *driContextPriv) _swsetup_DestroyContext( fmesa->glCtx ); _tnl_DestroyContext( fmesa->glCtx ); - _ac_DestroyContext( fmesa->glCtx ); + _vbo_DestroyContext( fmesa->glCtx ); _swrast_DestroyContext( fmesa->glCtx ); /* free the Mesa context */ diff --git a/src/mesa/drivers/dri/gamma/gamma_context.c b/src/mesa/drivers/dri/gamma/gamma_context.c index ffaf45459b..b1dcbfcdcf 100644 --- a/src/mesa/drivers/dri/gamma/gamma_context.c +++ b/src/mesa/drivers/dri/gamma/gamma_context.c @@ -28,7 +28,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -147,7 +147,7 @@ GLboolean gammaCreateContext( const __GLcontextModes *glVisual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); diff --git a/src/mesa/drivers/dri/gamma/gamma_state.c b/src/mesa/drivers/dri/gamma/gamma_state.c index 026ff5efbf..1d5ce20995 100644 --- a/src/mesa/drivers/dri/gamma/gamma_state.c +++ b/src/mesa/drivers/dri/gamma/gamma_state.c @@ -33,7 +33,7 @@ #include "colormac.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #define ENABLELIGHTING 0 @@ -1664,7 +1664,7 @@ static void gammaDDUpdateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); GAMMA_CONTEXT(ctx)->new_gl_state |= new_state; } diff --git a/src/mesa/drivers/dri/gamma/gamma_xmesa.c b/src/mesa/drivers/dri/gamma/gamma_xmesa.c index 00f6aa32ae..e8922b1503 100644 --- a/src/mesa/drivers/dri/gamma/gamma_xmesa.c +++ b/src/mesa/drivers/dri/gamma/gamma_xmesa.c @@ -34,7 +34,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" static GLboolean gammaInitDriver(__DRIscreenPrivate *sPriv) @@ -57,7 +57,7 @@ gammaDestroyContext(__DRIcontextPrivate *driContextPriv) if (gmesa) { _swsetup_DestroyContext( gmesa->glCtx ); _tnl_DestroyContext( gmesa->glCtx ); - _ac_DestroyContext( gmesa->glCtx ); + _vbo_DestroyContext( gmesa->glCtx ); _swrast_DestroyContext( gmesa->glCtx ); gammaFreeVB( gmesa->glCtx ); diff --git a/src/mesa/drivers/dri/mach64/mach64_context.c b/src/mesa/drivers/dri/mach64/mach64_context.c index 03ec96a222..eeb4cbcf71 100644 --- a/src/mesa/drivers/dri/mach64/mach64_context.c +++ b/src/mesa/drivers/dri/mach64/mach64_context.c @@ -38,7 +38,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -203,7 +203,7 @@ GLboolean mach64CreateContext( const __GLcontextModes *glVisual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -272,7 +272,7 @@ void mach64DestroyContext( __DRIcontextPrivate *driContextPriv ) _swsetup_DestroyContext( mmesa->glCtx ); _tnl_DestroyContext( mmesa->glCtx ); - _ac_DestroyContext( mmesa->glCtx ); + _vbo_DestroyContext( mmesa->glCtx ); _swrast_DestroyContext( mmesa->glCtx ); mach64FreeVB( mmesa->glCtx ); diff --git a/src/mesa/drivers/dri/mach64/mach64_state.c b/src/mesa/drivers/dri/mach64/mach64_state.c index d4804a2c55..667a394520 100644 --- a/src/mesa/drivers/dri/mach64/mach64_state.c +++ b/src/mesa/drivers/dri/mach64/mach64_state.c @@ -40,7 +40,7 @@ #include "enums.h" #include "colormac.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" @@ -1023,7 +1023,7 @@ static void mach64DDInvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); MACH64_CONTEXT(ctx)->NewGLState |= new_state; } diff --git a/src/mesa/drivers/dri/mga/mga_xmesa.c b/src/mesa/drivers/dri/mga/mga_xmesa.c index 73bcfcce73..32cfbc6a1c 100644 --- a/src/mesa/drivers/dri/mga/mga_xmesa.c +++ b/src/mesa/drivers/dri/mga/mga_xmesa.c @@ -45,7 +45,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/t_pipeline.h" @@ -593,7 +593,7 @@ mgaCreateContext( const __GLcontextModes *mesaVis, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -676,7 +676,7 @@ mgaDestroyContext(__DRIcontextPrivate *driContextPriv) release_texture_heaps = (mmesa->glCtx->Shared->RefCount == 1); _swsetup_DestroyContext( mmesa->glCtx ); _tnl_DestroyContext( mmesa->glCtx ); - _ac_DestroyContext( mmesa->glCtx ); + _vbo_DestroyContext( mmesa->glCtx ); _swrast_DestroyContext( mmesa->glCtx ); mgaFreeVB( mmesa->glCtx ); diff --git a/src/mesa/drivers/dri/mga/mgastate.c b/src/mesa/drivers/dri/mga/mgastate.c index 783de53197..69f85d62a5 100644 --- a/src/mesa/drivers/dri/mga/mgastate.c +++ b/src/mesa/drivers/dri/mga/mgastate.c @@ -42,7 +42,7 @@ #include "mgaregs.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" @@ -1062,7 +1062,7 @@ static void mgaDDInvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); MGA_CONTEXT(ctx)->NewGLState |= new_state; } diff --git a/src/mesa/drivers/dri/r128/r128_context.c b/src/mesa/drivers/dri/r128/r128_context.c index 8ec027542a..89ddafa02a 100644 --- a/src/mesa/drivers/dri/r128/r128_context.c +++ b/src/mesa/drivers/dri/r128/r128_context.c @@ -42,7 +42,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -235,7 +235,7 @@ GLboolean r128CreateContext( const __GLcontextModes *glVisual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -293,7 +293,7 @@ void r128DestroyContext( __DRIcontextPrivate *driContextPriv ) _swsetup_DestroyContext( rmesa->glCtx ); _tnl_DestroyContext( rmesa->glCtx ); - _ac_DestroyContext( rmesa->glCtx ); + _vbo_DestroyContext( rmesa->glCtx ); _swrast_DestroyContext( rmesa->glCtx ); if ( release_texture_heaps ) { diff --git a/src/mesa/drivers/dri/r128/r128_state.c b/src/mesa/drivers/dri/r128/r128_state.c index 1bfd370937..e476afa5d8 100644 --- a/src/mesa/drivers/dri/r128/r128_state.c +++ b/src/mesa/drivers/dri/r128/r128_state.c @@ -44,7 +44,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "enums.h" #include "colormac.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" @@ -1250,7 +1250,7 @@ static void r128DDInvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); R128_CONTEXT(ctx)->NewGLState |= new_state; } diff --git a/src/mesa/drivers/dri/s3v/s3v_context.c b/src/mesa/drivers/dri/s3v/s3v_context.c index 7b0aa0daee..2d2f704ad7 100644 --- a/src/mesa/drivers/dri/s3v/s3v_context.c +++ b/src/mesa/drivers/dri/s3v/s3v_context.c @@ -6,7 +6,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -139,7 +139,7 @@ GLboolean s3vCreateContext(const __GLcontextModes *glVisual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); diff --git a/src/mesa/drivers/dri/s3v/s3v_state.c b/src/mesa/drivers/dri/s3v/s3v_state.c index 4f412edf09..08ce0f565c 100644 --- a/src/mesa/drivers/dri/s3v/s3v_state.c +++ b/src/mesa/drivers/dri/s3v/s3v_state.c @@ -10,7 +10,7 @@ #include "colormac.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" /* #define DEBUG(str) printf str */ @@ -826,7 +826,7 @@ static void s3vDDUpdateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); S3V_CONTEXT(ctx)->new_gl_state |= new_state; } diff --git a/src/mesa/drivers/dri/s3v/s3v_xmesa.c b/src/mesa/drivers/dri/s3v/s3v_xmesa.c index 533424cdea..c451f7452b 100644 --- a/src/mesa/drivers/dri/s3v/s3v_xmesa.c +++ b/src/mesa/drivers/dri/s3v/s3v_xmesa.c @@ -13,7 +13,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" /* #define DEBUG(str) printf str */ @@ -38,7 +38,7 @@ s3vDestroyContext(__DRIcontextPrivate *driContextPriv) if (vmesa) { _swsetup_DestroyContext( vmesa->glCtx ); _tnl_DestroyContext( vmesa->glCtx ); - _ac_DestroyContext( vmesa->glCtx ); + _vbo_DestroyContext( vmesa->glCtx ); _swrast_DestroyContext( vmesa->glCtx ); s3vFreeVB( vmesa->glCtx ); diff --git a/src/mesa/drivers/dri/savage/savage_xmesa.c b/src/mesa/drivers/dri/savage/savage_xmesa.c index aaba58ed33..3557ce0118 100644 --- a/src/mesa/drivers/dri/savage/savage_xmesa.c +++ b/src/mesa/drivers/dri/savage/savage_xmesa.c @@ -40,7 +40,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/t_pipeline.h" @@ -501,7 +501,7 @@ savageCreateContext( const __GLcontextModes *mesaVis, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -591,7 +591,7 @@ savageDestroyContext(__DRIcontextPrivate *driContextPriv) _swsetup_DestroyContext(imesa->glCtx ); _tnl_DestroyContext( imesa->glCtx ); - _ac_DestroyContext( imesa->glCtx ); + _vbo_DestroyContext( imesa->glCtx ); _swrast_DestroyContext( imesa->glCtx ); /* free the Mesa context */ diff --git a/src/mesa/drivers/dri/savage/savagestate.c b/src/mesa/drivers/dri/savage/savagestate.c index e554afdbb7..5c2b397bde 100644 --- a/src/mesa/drivers/dri/savage/savagestate.c +++ b/src/mesa/drivers/dri/savage/savagestate.c @@ -41,7 +41,7 @@ #include "savage_bci.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" @@ -1676,7 +1676,7 @@ static void savageDDInvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); SAVAGE_CONTEXT(ctx)->new_gl_state |= new_state; } diff --git a/src/mesa/drivers/dri/sis/sis6326_state.c b/src/mesa/drivers/dri/sis/sis6326_state.c index 6bc2c6de3b..08402fb3e2 100644 --- a/src/mesa/drivers/dri/sis/sis6326_state.c +++ b/src/mesa/drivers/dri/sis/sis6326_state.c @@ -37,7 +37,7 @@ #include "enums.h" #include "colormac.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" @@ -645,7 +645,7 @@ sis6326DDInvalidateState( GLcontext *ctx, GLuint new_state ) _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); smesa->NewGLState |= new_state; } diff --git a/src/mesa/drivers/dri/sis/sis_context.c b/src/mesa/drivers/dri/sis/sis_context.c index a300a080ec..89b81da347 100644 --- a/src/mesa/drivers/dri/sis/sis_context.c +++ b/src/mesa/drivers/dri/sis/sis_context.c @@ -53,7 +53,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -306,7 +306,7 @@ sisCreateContext( const __GLcontextModes *glVisual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -353,7 +353,7 @@ sisDestroyContext ( __DRIcontextPrivate *driContextPriv ) if ( smesa != NULL ) { _swsetup_DestroyContext( smesa->glCtx ); _tnl_DestroyContext( smesa->glCtx ); - _ac_DestroyContext( smesa->glCtx ); + _vbo_DestroyContext( smesa->glCtx ); _swrast_DestroyContext( smesa->glCtx ); if (smesa->using_agp) diff --git a/src/mesa/drivers/dri/sis/sis_state.c b/src/mesa/drivers/dri/sis/sis_state.c index 2a10a5fbf6..33a2f089b8 100644 --- a/src/mesa/drivers/dri/sis/sis_state.c +++ b/src/mesa/drivers/dri/sis/sis_state.c @@ -42,7 +42,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "enums.h" #include "colormac.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" @@ -707,7 +707,7 @@ sisDDInvalidateState( GLcontext *ctx, GLuint new_state ) _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); smesa->NewGLState |= new_state; } diff --git a/src/mesa/drivers/dri/tdfx/tdfx_context.c b/src/mesa/drivers/dri/tdfx/tdfx_context.c index dd40544d49..07d2cb1db5 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_context.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_context.c @@ -54,7 +54,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -331,7 +331,7 @@ GLboolean tdfxCreateContext( const __GLcontextModes *mesaVis, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -612,7 +612,7 @@ tdfxDestroyContext( __DRIcontextPrivate *driContextPriv ) _swsetup_DestroyContext( fxMesa->glCtx ); _tnl_DestroyContext( fxMesa->glCtx ); - _ac_DestroyContext( fxMesa->glCtx ); + _vbo_DestroyContext( fxMesa->glCtx ); _swrast_DestroyContext( fxMesa->glCtx ); tdfxFreeVB( fxMesa->glCtx ); diff --git a/src/mesa/drivers/dri/tdfx/tdfx_state.c b/src/mesa/drivers/dri/tdfx/tdfx_state.c index 59e6549e5e..42cb5dfaa3 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_state.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_state.c @@ -46,7 +46,7 @@ #include "teximage.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" #include "swrast_setup/swrast_setup.h" @@ -1234,7 +1234,7 @@ static void tdfxDDInvalidateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); TDFX_CONTEXT(ctx)->new_gl_state |= new_state; } diff --git a/src/mesa/drivers/dri/trident/trident_context.c b/src/mesa/drivers/dri/trident/trident_context.c index 9c8f7ef01f..a07b40fd5d 100644 --- a/src/mesa/drivers/dri/trident/trident_context.c +++ b/src/mesa/drivers/dri/trident/trident_context.c @@ -30,7 +30,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -142,7 +142,7 @@ tridentCreateContext( const __GLcontextModes *glVisual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); - _ac_CreateContext( ctx ); + _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); @@ -182,7 +182,7 @@ tridentDestroyContext(__DRIcontextPrivate *driContextPriv) if (tmesa) { _swsetup_DestroyContext( tmesa->glCtx ); _tnl_DestroyContext( tmesa->glCtx ); - _ac_DestroyContext( tmesa->glCtx ); + _vbo_DestroyContext( tmesa->glCtx ); _swrast_DestroyContext( tmesa->glCtx ); /* free the Mesa context */ diff --git a/src/mesa/drivers/dri/trident/trident_state.c b/src/mesa/drivers/dri/trident/trident_state.c index a9be50688b..6cdf23092a 100644 --- a/src/mesa/drivers/dri/trident/trident_state.c +++ b/src/mesa/drivers/dri/trident/trident_state.c @@ -26,7 +26,7 @@ */ #include "trident_context.h" #include "trident_lock.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" @@ -469,7 +469,7 @@ tridentDDUpdateState( GLcontext *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); TRIDENT_CONTEXT(ctx)->new_gl_state |= new_state; } diff --git a/src/mesa/drivers/dri/unichrome/via_context.c b/src/mesa/drivers/dri/unichrome/via_context.c index fa143186c1..38dcf458db 100644 --- a/src/mesa/drivers/dri/unichrome/via_context.c +++ b/src/mesa/drivers/dri/unichrome/via_context.c @@ -42,7 +42,7 @@ #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/t_pipeline.h" @@ -588,7 +588,7 @@ viaCreateContext(const __GLcontextModes *visual, /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext(ctx); - _ac_CreateContext(ctx); + _vbo_CreateContext(ctx); _tnl_CreateContext(ctx); _swsetup_CreateContext(ctx); @@ -713,7 +713,7 @@ viaDestroyContext(__DRIcontextPrivate *driContextPriv) _swsetup_DestroyContext(vmesa->glCtx); _tnl_DestroyContext(vmesa->glCtx); - _ac_DestroyContext(vmesa->glCtx); + _vbo_DestroyContext(vmesa->glCtx); _swrast_DestroyContext(vmesa->glCtx); /* free the Mesa context */ _mesa_destroy_context(vmesa->glCtx); diff --git a/src/mesa/drivers/dri/unichrome/via_state.c b/src/mesa/drivers/dri/unichrome/via_state.c index c001661d0b..102a333068 100644 --- a/src/mesa/drivers/dri/unichrome/via_state.c +++ b/src/mesa/drivers/dri/unichrome/via_state.c @@ -40,7 +40,7 @@ #include "via_3d_reg.h" #include "swrast/swrast.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" #include "tnl/tnl.h" #include "swrast_setup/swrast_setup.h" @@ -1501,7 +1501,7 @@ static void viaInvalidateState(GLcontext *ctx, GLuint newState) _swrast_InvalidateState(ctx, newState); _swsetup_InvalidateState(ctx, newState); - _ac_InvalidateState(ctx, newState); + _vbo_InvalidateState(ctx, newState); _tnl_InvalidateState(ctx, newState); } diff --git a/src/mesa/drivers/glide/fxdd.c b/src/mesa/drivers/glide/fxdd.c index 0ee0e0cae0..e218a316aa 100644 --- a/src/mesa/drivers/glide/fxdd.c +++ b/src/mesa/drivers/glide/fxdd.c @@ -55,7 +55,7 @@ #include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" -#include "array_cache/acache.h" +#include "vbo/vbo.h" -- cgit v1.2.3 From 2581ba7f1e0352ad7ed5e863647a545a0eec851c Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Wed, 1 Nov 2006 02:44:27 +0000 Subject: Fix compile errors. Add vblank_seq to nouveau_context. --- src/mesa/drivers/dri/nouveau/nouveau_context.c | 2 +- src/mesa/drivers/dri/nouveau/nouveau_ioctl.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 3ca5edf782..4bb4116026 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -188,7 +188,7 @@ GLboolean nouveauMakeCurrent( __DRIcontextPrivate *driContextPriv, nouveauContextPtr oldNOUVEAUCtx = ctx ? NOUVEAU_CONTEXT(ctx) : NULL; nouveauContextPtr newNOUVEAUCtx = (nouveauContextPtr) driContextPriv->driverPrivate; - driDrawableInitVBlank( driDrawPriv, newNOUVEAUCtx->vblank_flags ); + driDrawableInitVBlank(driDrawPriv, newNOUVEAUCtx->vblank_flags, &newNOUVEAUCtx->vblank_seq ); newNOUVEAUCtx->driDrawable = driDrawPriv; _mesa_make_current( newNOUVEAUCtx->glCtx, diff --git a/src/mesa/drivers/dri/nouveau/nouveau_ioctl.c b/src/mesa/drivers/dri/nouveau/nouveau_ioctl.c index ce55373934..3f6e3076e2 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_ioctl.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_ioctl.c @@ -39,9 +39,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. void nouveauIoctlInitFifo(nouveauContextPtr nmesa) { int ret; - drm_nouveau_fifo_init_t fifo_init; + drm_nouveau_fifo_alloc_t fifo_init; - ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_FIFO_INIT, &fifo_init, sizeof(fifo_init)); + ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_FIFO_ALLOC, &fifo_init, sizeof(fifo_init)); if (ret) FATAL("Fifo initialization ioctl failed (returned %d)\n",ret); MESSAGE("Fifo init ok. Using context %d\n", fifo_init.channel); -- cgit v1.2.3 From 2d2d617dbc17817f214e0b523f929de1f5d8f48a Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Wed, 1 Nov 2006 02:45:12 +0000 Subject: Oops. Forgot to check in the context change. --- src/mesa/drivers/dri/nouveau/nouveau_context.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index c5783993c7..21aa1a6313 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -129,7 +129,9 @@ typedef struct nouveau_context { /* Configuration cache */ driOptionCache optionCache; + /* vblank stuff */ uint32_t vblank_flags; + uint32_t vblank_seq; GLuint new_state; GLuint new_render_state; -- cgit v1.2.3 From 1ebe921228ef896804384002d8a3acd0885afc98 Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Wed, 1 Nov 2006 02:48:34 +0000 Subject: Added OUT_RING* debugging macros. Compile with NOUVEAU_RING_DEBUG to use. --- src/mesa/drivers/dri/nouveau/nouveau_fifo.h | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h index bf528a24ca..95c78b5675 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h @@ -48,9 +48,28 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * - WAIT_RING waits for size (in uint32_ts) to be available in the fifo */ +/* Enable for ring debugging. Prints out writes to the ring buffer + * but does not actually write to it. + */ +#ifdef NOUVEAU_RING_DEBUG + +#define OUT_RINGp(ptr,sz) do { \ +int i; printf("OUT_RINGp:\n"); for(i=0;ififo.buffer+nmesa->fifo.current,ptr,sz); \ - nmesa->fifo.current+=sz; \ + nmesa->fifo.current+=(sz/sizeof(*ptr)); \ }while(0) #define OUT_RING(n) do { \ @@ -61,6 +80,8 @@ nmesa->fifo.buffer[nmesa->fifo.current++]=n; \ *((float*)(nmesa->fifo.buffer+nmesa->fifo.current++))=n; \ }while(0) +#endif + extern void WAIT_RING(nouveauContextPtr nmesa,u_int32_t size); #define BEGIN_RING_PRIM(subchannel,tag,size) do { \ -- cgit v1.2.3 From 6d104cb932080c5c0d951fbc0ec6d30fb7ebef45 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Thu, 2 Nov 2006 12:02:13 +0000 Subject: merge current trunk into vbo branch --- configs/linux-dri | 2 +- docs/relnotes-6.5.2.html | 3 + progs/demos/Makefile | 1 + progs/demos/streaming_rect.c | 322 +++++ progs/demos/texdown.c | 133 +- progs/trivial/Makefile | 2 + progs/trivial/quad-tex-pbo.c | 181 +++ src/glx/x11/glxext.c | 70 +- src/mesa/drivers/directfb/idirectfbgl_mesa.c | 10 +- src/mesa/drivers/dri/Makefile.template | 7 +- src/mesa/drivers/dri/common/dri_bufmgr.c | 493 ++++++++ src/mesa/drivers/dri/common/dri_bufmgr.h | 99 ++ src/mesa/drivers/dri/common/dri_bufpool.h | 86 ++ src/mesa/drivers/dri/common/dri_drmpool.c | 227 ++++ src/mesa/drivers/dri/common/dri_util.c | 2 +- src/mesa/drivers/dri/common/dri_util.h | 8 +- src/mesa/drivers/dri/ffb/ffb_clear.c | 5 +- src/mesa/drivers/dri/ffb/ffb_clear.h | 5 +- src/mesa/drivers/dri/ffb/ffb_xmesa.c | 3 +- src/mesa/drivers/dri/gamma/gamma_state.c | 5 +- src/mesa/drivers/dri/i810/i810ioctl.c | 5 +- src/mesa/drivers/dri/i915/i830_metaops.c | 14 +- src/mesa/drivers/dri/i915/i915_fragprog.c | 3 + src/mesa/drivers/dri/i915/i915_metaops.c | 22 +- src/mesa/drivers/dri/i915/intel_batchbuffer.c | 41 +- src/mesa/drivers/dri/i915/intel_ioctl.c | 9 +- src/mesa/drivers/dri/i915/intel_ioctl.h | 3 +- src/mesa/drivers/dri/i915tex/Makefile | 66 + src/mesa/drivers/dri/i915tex/i830_context.c | 104 ++ src/mesa/drivers/dri/i915tex/i830_context.h | 208 ++++ src/mesa/drivers/dri/i915tex/i830_metaops.c | 485 ++++++++ src/mesa/drivers/dri/i915tex/i830_reg.h | 641 ++++++++++ src/mesa/drivers/dri/i915tex/i830_state.c | 1113 +++++++++++++++++ src/mesa/drivers/dri/i915tex/i830_tex.c | 100 ++ src/mesa/drivers/dri/i915tex/i830_texblend.c | 463 +++++++ src/mesa/drivers/dri/i915tex/i830_texstate.c | 316 +++++ src/mesa/drivers/dri/i915tex/i830_vtbl.c | 606 +++++++++ src/mesa/drivers/dri/i915tex/i915_context.c | 175 +++ src/mesa/drivers/dri/i915tex/i915_context.h | 367 ++++++ src/mesa/drivers/dri/i915tex/i915_debug.c | 334 +++++ src/mesa/drivers/dri/i915tex/i915_fragprog.c | 1072 ++++++++++++++++ src/mesa/drivers/dri/i915tex/i915_metaops.c | 509 ++++++++ src/mesa/drivers/dri/i915tex/i915_program.c | 518 ++++++++ src/mesa/drivers/dri/i915tex/i915_program.h | 160 +++ src/mesa/drivers/dri/i915tex/i915_reg.h | 841 +++++++++++++ src/mesa/drivers/dri/i915tex/i915_state.c | 1019 ++++++++++++++++ src/mesa/drivers/dri/i915tex/i915_tex.c | 113 ++ src/mesa/drivers/dri/i915tex/i915_tex_layout.c | 380 ++++++ src/mesa/drivers/dri/i915tex/i915_texstate.c | 338 ++++++ src/mesa/drivers/dri/i915tex/i915_vtbl.c | 549 +++++++++ src/mesa/drivers/dri/i915tex/intel_batchbuffer.c | 342 ++++++ src/mesa/drivers/dri/i915tex/intel_batchbuffer.h | 124 ++ src/mesa/drivers/dri/i915tex/intel_batchpool.c | 418 +++++++ src/mesa/drivers/dri/i915tex/intel_blit.c | 552 +++++++++ src/mesa/drivers/dri/i915tex/intel_blit.h | 61 + .../drivers/dri/i915tex/intel_buffer_objects.c | 250 ++++ .../drivers/dri/i915tex/intel_buffer_objects.h | 86 ++ src/mesa/drivers/dri/i915tex/intel_buffers.c | 956 +++++++++++++++ src/mesa/drivers/dri/i915tex/intel_buffers.h | 56 + src/mesa/drivers/dri/i915tex/intel_context.c | 707 +++++++++++ src/mesa/drivers/dri/i915tex/intel_context.h | 502 ++++++++ src/mesa/drivers/dri/i915tex/intel_depthstencil.c | 282 +++++ src/mesa/drivers/dri/i915tex/intel_depthstencil.h | 14 + src/mesa/drivers/dri/i915tex/intel_fbo.c | 622 ++++++++++ src/mesa/drivers/dri/i915tex/intel_fbo.h | 80 ++ src/mesa/drivers/dri/i915tex/intel_ioctl.c | 138 +++ src/mesa/drivers/dri/i915tex/intel_ioctl.h | 40 + src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c | 341 ++++++ src/mesa/drivers/dri/i915tex/intel_mipmap_tree.h | 198 +++ src/mesa/drivers/dri/i915tex/intel_pixel.c | 119 ++ src/mesa/drivers/dri/i915tex/intel_pixel.h | 63 + src/mesa/drivers/dri/i915tex/intel_pixel_bitmap.c | 350 ++++++ src/mesa/drivers/dri/i915tex/intel_pixel_copy.c | 380 ++++++ src/mesa/drivers/dri/i915tex/intel_pixel_draw.c | 365 ++++++ src/mesa/drivers/dri/i915tex/intel_pixel_read.c | 317 +++++ src/mesa/drivers/dri/i915tex/intel_reg.h | 84 ++ src/mesa/drivers/dri/i915tex/intel_regions.c | 466 +++++++ src/mesa/drivers/dri/i915tex/intel_regions.h | 141 +++ src/mesa/drivers/dri/i915tex/intel_render.c | 242 ++++ src/mesa/drivers/dri/i915tex/intel_rotate.c | 237 ++++ src/mesa/drivers/dri/i915tex/intel_rotate.h | 39 + src/mesa/drivers/dri/i915tex/intel_screen.c | 864 +++++++++++++ src/mesa/drivers/dri/i915tex/intel_screen.h | 132 ++ src/mesa/drivers/dri/i915tex/intel_span.c | 409 +++++++ src/mesa/drivers/dri/i915tex/intel_span.h | 38 + src/mesa/drivers/dri/i915tex/intel_state.c | 363 ++++++ src/mesa/drivers/dri/i915tex/intel_structs.h | 132 ++ src/mesa/drivers/dri/i915tex/intel_tex.c | 182 +++ src/mesa/drivers/dri/i915tex/intel_tex.h | 134 ++ src/mesa/drivers/dri/i915tex/intel_tex_copy.c | 301 +++++ src/mesa/drivers/dri/i915tex/intel_tex_format.c | 146 +++ src/mesa/drivers/dri/i915tex/intel_tex_image.c | 626 ++++++++++ src/mesa/drivers/dri/i915tex/intel_tex_subimage.c | 183 +++ src/mesa/drivers/dri/i915tex/intel_tex_validate.c | 252 ++++ src/mesa/drivers/dri/i915tex/intel_tris.c | 1149 ++++++++++++++++++ src/mesa/drivers/dri/i915tex/intel_tris.h | 69 ++ src/mesa/drivers/dri/i915tex/server/i830_common.h | 212 ++++ src/mesa/drivers/dri/i915tex/server/i830_dri.h | 73 ++ src/mesa/drivers/dri/i915tex/server/intel.h | 328 +++++ src/mesa/drivers/dri/i915tex/server/intel_dri.c | 1282 ++++++++++++++++++++ src/mesa/drivers/dri/i965/intel_blit.c | 27 +- src/mesa/drivers/dri/i965/intel_blit.h | 3 +- src/mesa/drivers/dri/i965/intel_buffers.c | 39 +- src/mesa/drivers/dri/mach64/mach64_ioctl.c | 5 +- src/mesa/drivers/dri/mga/mga_xmesa.c | 1 - src/mesa/drivers/dri/mga/mgacontext.h | 7 - src/mesa/drivers/dri/mga/mgadd.c | 19 +- src/mesa/drivers/dri/mga/mgaioctl.c | 5 +- src/mesa/drivers/dri/mga/mgaspan.c | 4 +- src/mesa/drivers/dri/mga/mgastate.c | 52 +- src/mesa/drivers/dri/r128/r128_ioctl.c | 5 +- src/mesa/drivers/dri/r200/r200_ioctl.c | 5 +- src/mesa/drivers/dri/r300/r300_fragprog.c | 102 +- src/mesa/drivers/dri/r300/r300_fragprog.h | 3 +- src/mesa/drivers/dri/r300/r300_ioctl.c | 5 +- src/mesa/drivers/dri/r300/r300_reg.h | 2 + src/mesa/drivers/dri/r300/r300_state.c | 1 - src/mesa/drivers/dri/r300/r300_texstate.c | 1 - src/mesa/drivers/dri/r300/radeon_context.c | 28 +- src/mesa/drivers/dri/r300/radeon_context.h | 10 +- src/mesa/drivers/dri/r300/radeon_lock.c | 44 +- src/mesa/drivers/dri/r300/radeon_state.c | 62 +- src/mesa/drivers/dri/r300/radeon_state.h | 2 +- src/mesa/drivers/dri/radeon/radeon_ioctl.c | 5 +- src/mesa/drivers/dri/radeon/radeon_state.c | 5 +- src/mesa/drivers/dri/s3v/s3v_state.c | 5 +- src/mesa/drivers/dri/savage/savageioctl.c | 5 +- src/mesa/drivers/dri/sis/sis6326_clear.c | 5 +- src/mesa/drivers/dri/sis/sis_clear.c | 9 +- src/mesa/drivers/dri/sis/sis_screen.c | 2 +- src/mesa/drivers/dri/sis/sis_state.h | 6 +- src/mesa/drivers/dri/tdfx/tdfx_render.c | 6 +- src/mesa/drivers/dri/tdfx/tdfx_tex.c | 6 +- src/mesa/drivers/dri/trident/trident_state.c | 5 +- src/mesa/drivers/dri/unichrome/via_ioctl.c | 7 +- src/mesa/drivers/ggi/ggimesa.c | 10 +- src/mesa/drivers/glide/fxdd.c | 9 +- src/mesa/drivers/svga/svgamesa15.c | 12 +- src/mesa/drivers/svga/svgamesa16.c | 12 +- src/mesa/drivers/svga/svgamesa24.c | 12 +- src/mesa/drivers/svga/svgamesa32.c | 12 +- src/mesa/drivers/svga/svgamesa8.c | 12 +- src/mesa/drivers/windows/gdi/wmesa.c | 13 +- src/mesa/drivers/x11/xm_dd.c | 16 +- src/mesa/main/attrib.c | 5 + src/mesa/main/buffers.c | 7 +- src/mesa/main/context.c | 11 + src/mesa/main/dd.h | 34 +- src/mesa/main/extensions.c | 7 +- src/mesa/main/fbobject.c | 6 +- src/mesa/main/get.c | 24 +- src/mesa/main/get_gen.py | 10 +- src/mesa/main/getstring.c | 4 +- src/mesa/main/mipmap.c | 4 +- src/mesa/main/mtypes.h | 37 +- src/mesa/main/state.c | 15 +- src/mesa/main/state.h | 6 + src/mesa/main/stencil.c | 101 +- src/mesa/main/texcompress_s3tc.c | 6 +- src/mesa/main/texenvprogram.c | 55 +- src/mesa/main/teximage.c | 1080 ++++++++++------- src/mesa/main/teximage.h | 21 +- src/mesa/main/texobj.c | 39 +- src/mesa/main/texobj.h | 4 + src/mesa/main/texstate.c | 125 +- src/mesa/shader/arbprogparse.c | 14 +- src/mesa/shader/nvfragparse.c | 2 +- src/mesa/shader/nvprogram.c | 7 +- src/mesa/shader/nvvertexec.c | 349 +++--- src/mesa/shader/nvvertexec.h | 34 +- src/mesa/shader/nvvertparse.c | 2 +- src/mesa/shader/program.c | 98 +- src/mesa/shader/program_instruction.h | 2 +- src/mesa/shader/programopt.c | 7 +- src/mesa/swrast/s_arbshader.c | 11 +- src/mesa/swrast/s_buffers.c | 21 +- src/mesa/swrast/s_context.c | 19 +- src/mesa/swrast/s_nvfragprog.c | 232 ++-- src/mesa/swrast/s_span.c | 52 +- src/mesa/swrast/s_texstore.c | 10 +- src/mesa/swrast/swrast.h | 3 +- src/mesa/tnl/t_context.c | 5 +- src/mesa/tnl/t_vb_program.c | 14 +- 183 files changed, 29322 insertions(+), 1452 deletions(-) create mode 100644 progs/demos/streaming_rect.c create mode 100644 progs/trivial/quad-tex-pbo.c create mode 100644 src/mesa/drivers/dri/common/dri_bufmgr.c create mode 100644 src/mesa/drivers/dri/common/dri_bufmgr.h create mode 100644 src/mesa/drivers/dri/common/dri_bufpool.h create mode 100644 src/mesa/drivers/dri/common/dri_drmpool.c create mode 100644 src/mesa/drivers/dri/i915tex/Makefile create mode 100644 src/mesa/drivers/dri/i915tex/i830_context.c create mode 100644 src/mesa/drivers/dri/i915tex/i830_context.h create mode 100644 src/mesa/drivers/dri/i915tex/i830_metaops.c create mode 100644 src/mesa/drivers/dri/i915tex/i830_reg.h create mode 100644 src/mesa/drivers/dri/i915tex/i830_state.c create mode 100644 src/mesa/drivers/dri/i915tex/i830_tex.c create mode 100644 src/mesa/drivers/dri/i915tex/i830_texblend.c create mode 100644 src/mesa/drivers/dri/i915tex/i830_texstate.c create mode 100644 src/mesa/drivers/dri/i915tex/i830_vtbl.c create mode 100644 src/mesa/drivers/dri/i915tex/i915_context.c create mode 100644 src/mesa/drivers/dri/i915tex/i915_context.h create mode 100644 src/mesa/drivers/dri/i915tex/i915_debug.c create mode 100644 src/mesa/drivers/dri/i915tex/i915_fragprog.c create mode 100644 src/mesa/drivers/dri/i915tex/i915_metaops.c create mode 100644 src/mesa/drivers/dri/i915tex/i915_program.c create mode 100644 src/mesa/drivers/dri/i915tex/i915_program.h create mode 100644 src/mesa/drivers/dri/i915tex/i915_reg.h create mode 100644 src/mesa/drivers/dri/i915tex/i915_state.c create mode 100644 src/mesa/drivers/dri/i915tex/i915_tex.c create mode 100644 src/mesa/drivers/dri/i915tex/i915_tex_layout.c create mode 100644 src/mesa/drivers/dri/i915tex/i915_texstate.c create mode 100644 src/mesa/drivers/dri/i915tex/i915_vtbl.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_batchbuffer.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_batchbuffer.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_batchpool.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_blit.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_blit.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_buffer_objects.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_buffer_objects.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_buffers.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_buffers.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_context.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_context.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_depthstencil.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_depthstencil.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_fbo.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_fbo.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_ioctl.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_ioctl.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_mipmap_tree.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_pixel.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_pixel.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_pixel_bitmap.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_pixel_copy.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_pixel_draw.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_pixel_read.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_reg.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_regions.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_regions.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_render.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_rotate.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_rotate.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_screen.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_screen.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_span.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_span.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_state.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_structs.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_tex.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_tex.h create mode 100644 src/mesa/drivers/dri/i915tex/intel_tex_copy.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_tex_format.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_tex_image.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_tex_subimage.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_tex_validate.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_tris.c create mode 100644 src/mesa/drivers/dri/i915tex/intel_tris.h create mode 100644 src/mesa/drivers/dri/i915tex/server/i830_common.h create mode 100644 src/mesa/drivers/dri/i915tex/server/i830_dri.h create mode 100644 src/mesa/drivers/dri/i915tex/server/intel.h create mode 100644 src/mesa/drivers/dri/i915tex/server/intel_dri.c (limited to 'src/mesa/drivers/dri') diff --git a/configs/linux-dri b/configs/linux-dri index 8504297d0e..7e822e2eb6 100644 --- a/configs/linux-dri +++ b/configs/linux-dri @@ -65,5 +65,5 @@ WINDOW_SYSTEM=dri # gamma are missing because they have not been converted to use the new # interface. -DRI_DIRS = i810 i915 i965 mach64 mga r128 r200 r300 radeon s3v \ +DRI_DIRS = i810 i915tex i915 i965 mach64 mga r128 r200 r300 radeon s3v \ savage sis tdfx trident unichrome ffb diff --git a/docs/relnotes-6.5.2.html b/docs/relnotes-6.5.2.html index 5b69daf0c5..06a4763c67 100644 --- a/docs/relnotes-6.5.2.html +++ b/docs/relnotes-6.5.2.html @@ -23,6 +23,8 @@ Mesa 6.5.2 is a 6.5 follow-on development release mostly consisting of

New Features

    +
  • New minstall script to replace normal install program +
  • Faster fragment program execution in software

Changes

@@ -36,6 +38,7 @@ Mesa 6.5.2 is a 6.5 follow-on development release mostly consisting of
  • OPTION NV_position_invariant didn't work in NV vertex programs
  • glDrawPixels into a user-created framebuffer object could crash Xlib driver
  • Line clipping was broken in some circumstances +
  • fragment.fogcoord register didn't always contain the correct value diff --git a/progs/demos/Makefile b/progs/demos/Makefile index 43d0f17c85..feb2abd6cf 100644 --- a/progs/demos/Makefile +++ b/progs/demos/Makefile @@ -47,6 +47,7 @@ PROGS = \ renormal \ shadowtex \ singlebuffer \ + streaming_rect \ spectex \ spriteblast \ stex3d \ diff --git a/progs/demos/streaming_rect.c b/progs/demos/streaming_rect.c new file mode 100644 index 0000000000..86e00803c0 --- /dev/null +++ b/progs/demos/streaming_rect.c @@ -0,0 +1,322 @@ + +/* + * GL_ARB_multitexture demo + * + * Command line options: + * -info print GL implementation information + * + * + * Brian Paul November 1998 This program is in the public domain. + * Modified on 12 Feb 2002 for > 2 texture units. + */ + +#define GL_GLEXT_PROTOTYPES + +#include +#include +#include +#include +#include + +#include "readtex.h" + + +#define ANIMATE 10 +#define PBO 11 +#define QUIT 100 + +static GLboolean Animate = GL_TRUE; +static GLboolean use_pbo = 1; +static GLboolean whole_rect = 1; + +static GLfloat Drift = 0.0; +static GLfloat drift_increment = 1/255.0; +static GLfloat Xrot = 20.0, Yrot = 30.0; + +static GLuint Width = 1024; +static GLuint Height = 512; + + +static void Idle( void ) +{ + if (Animate) { + + Drift += drift_increment; + if (Drift >= 1.0) + Drift = 0.0; + + glutPostRedisplay(); + } +} + +static int max( int a, int b ) { return a > b ? a : b; } +static int min( int a, int b ) { return a < b ? a : b; } + +static void DrawObject() +{ + GLint size = Width * Height * 4; + + if (use_pbo) { + /* XXX: This is extremely important - semantically makes the buffer + * contents undefined, but in practice means that the driver can + * release the old copy of the texture and allocate a new one + * without waiting for outstanding rendering to complete. + */ + glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, size, NULL, GL_STREAM_DRAW_ARB); + + { + char *image = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, GL_WRITE_ONLY_ARB); + + printf("char %d\n", (unsigned char)(Drift * 255)); + + memset(image, size, (unsigned char)(Drift * 255)); + + glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT); + } + + + /* BGRA is required for most hardware paths: + */ + glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, Width, Height, 0, + GL_BGRA, GL_UNSIGNED_BYTE, NULL); + } + else { + static char *image = NULL; + + if (image == NULL) + image = malloc(size); + + memset(image, size, (unsigned char)(Drift * 255)); + + /* BGRA should be the fast path for regular uploads as well. + */ + glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, Width, Height, 0, + GL_BGRA, GL_UNSIGNED_BYTE, image); + } + + { + int x,y,w,h; + + if (whole_rect) { + x = y = 0; + w = Width; + h = Height; + } + else { + x = y = 0; + w = min(10, Width); + h = min(10, Height); + } + + glBegin(GL_QUADS); + + glTexCoord2f( x, y); + glVertex2f( x, y ); + + glTexCoord2f( x, y + h); + glVertex2f( x, y + h); + + glTexCoord2f( x + w + .5, y + h); + glVertex2f( x + w, y + h ); + + glTexCoord2f( x + w, y + .5); + glVertex2f( x + w, y ); + + glEnd(); + } +} + + + +static void Display( void ) +{ + static GLint T0 = 0; + static GLint Frames = 0; + GLint t; + + glClear( GL_COLOR_BUFFER_BIT ); + + glPushMatrix(); + DrawObject(); + glPopMatrix(); + + glutSwapBuffers(); + + Frames++; + + t = glutGet(GLUT_ELAPSED_TIME); + if (t - T0 >= 1000) { + GLfloat seconds = (t - T0) / 1000.0; + + GLfloat fps = Frames / seconds; + printf("%d frames in %6.3f seconds = %6.3f FPS\n", Frames, seconds, fps); + + drift_increment = 2.2 * seconds / Frames; + T0 = t; + Frames = 0; + } +} + + +static void Reshape( int width, int height ) +{ + glViewport( 0, 0, width, height ); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); +/* glFrustum( -1.0, 1.0, -1.0, 1.0, 10.0, 100.0 ); */ + gluOrtho2D( 0, width, height, 0 ); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + glTranslatef(0.375, 0.375, 0); +} + + +static void ModeMenu(int entry) +{ + if (entry==ANIMATE) { + Animate = !Animate; + } + else if (entry==PBO) { + use_pbo = !use_pbo; + } + else if (entry==QUIT) { + exit(0); + } + + glutPostRedisplay(); +} + + +static void Key( unsigned char key, int x, int y ) +{ + (void) x; + (void) y; + switch (key) { + case 27: + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void SpecialKey( int key, int x, int y ) +{ + float step = 3.0; + (void) x; + (void) y; + + switch (key) { + case GLUT_KEY_UP: + Xrot += step; + break; + case GLUT_KEY_DOWN: + Xrot -= step; + break; + case GLUT_KEY_LEFT: + Yrot += step; + break; + case GLUT_KEY_RIGHT: + Yrot -= step; + break; + } + glutPostRedisplay(); +} + + +static void Init( int argc, char *argv[] ) +{ + const char *exten = (const char *) glGetString(GL_EXTENSIONS); + GLuint texObj, DrawPBO; + GLint size; + + + if (!strstr(exten, "GL_ARB_multitexture")) { + printf("Sorry, GL_ARB_multitexture not supported by this renderer.\n"); + exit(1); + } + + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size); + printf("%d x %d max texture size\n", size, size); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + /* allocate two texture objects */ + glGenTextures(1, &texObj); + + /* setup the texture objects */ + glActiveTextureARB(GL_TEXTURE0_ARB); + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texObj); + + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glGenBuffersARB(1, &DrawPBO); + + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, DrawPBO); + glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, + Width * Height * 4, NULL, GL_STREAM_DRAW); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + glEnable(GL_TEXTURE_RECTANGLE_ARB); + + glShadeModel(GL_SMOOTH); + glClearColor(0.3, 0.3, 0.4, 1.0); + + if (argc > 1 && strcmp(argv[1], "-info")==0) { + printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); + printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); + printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); + } +} + + +int main( int argc, char *argv[] ) +{ + GLint i; + + glutInit( &argc, argv ); + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-w") == 0) { + Width = atoi(argv[i+1]); + if (Width <= 0) { + printf("Error, bad width\n"); + exit(1); + } + i++; + } + else if (strcmp(argv[i], "-h") == 0) { + Height = atoi(argv[i+1]); + if (Height <= 0) { + printf("Error, bad height\n"); + exit(1); + } + i++; + } + } + + glutInitWindowSize( Width, Height ); + glutInitWindowPosition( 0, 0 ); + glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); + glutCreateWindow(argv[0] ); + + Init( argc, argv ); + + glutReshapeFunc( Reshape ); + glutKeyboardFunc( Key ); + glutSpecialFunc( SpecialKey ); + glutDisplayFunc( Display ); + glutIdleFunc( Idle ); + + glutCreateMenu(ModeMenu); + glutAddMenuEntry("Toggle Animation", ANIMATE); + glutAddMenuEntry("Toggle PBO", PBO); + glutAddMenuEntry("Quit", QUIT); + glutAttachMenu(GLUT_RIGHT_BUTTON); + + glutMainLoop(); + return 0; +} diff --git a/progs/demos/texdown.c b/progs/demos/texdown.c index 79525a0395..fc98fddb31 100644 --- a/progs/demos/texdown.c +++ b/progs/demos/texdown.c @@ -38,8 +38,8 @@ #include -static GLsizei MaxSize = 1024; -static GLsizei TexWidth = 256, TexHeight = 256, TexBorder = 0; +static GLsizei MaxSize = 2048; +static GLsizei TexWidth = 1024, TexHeight = 1024, TexBorder = 0; static GLboolean ScaleAndBias = GL_FALSE; static GLboolean SubImage = GL_FALSE; static GLdouble DownloadRate = 0.0; /* texels/sec */ @@ -47,6 +47,32 @@ static GLdouble DownloadRate = 0.0; /* texels/sec */ static GLuint Mode = 0; +/* Try and avoid L2 cache effects by cycling through a small number of + * textures. + * + * At the initial size of 1024x1024x4 == 4mbyte, say 8 textures will + * keep us out of most caches at 32mb total. + * + * This turns into a fairly interesting question of what exactly you + * expect to be in cache in normal usage, and what you think should be + * outside. There's no rules for this, no reason to favour one usage + * over another except what the application you care about happens to + * resemble most closely. + * + * - Should the client texture image be in L2 cache? Has it just been + * generated or read from disk? + * - Does the application really use >1 texture, or is it constantly + * updating one image in-place? + * + * Different answers will favour different texture upload mechanisms. + * To upload an image that is purely outside of cache, a DMA-based + * upload will probably win, whereas for small, in-cache textures, + * copying looks good. + */ +#define NR_TEXOBJ 4 +static GLuint TexObj[NR_TEXOBJ]; + + struct FormatRec { GLenum Format; GLenum Type; @@ -116,25 +142,57 @@ TypeStr(GLenum type) } } +/* On x86, there is a performance cliff for memcpy to texture memory + * for sources below 64 byte alignment. We do our best with this in + * the driver, but it is better if the images are correctly aligned to + * start with: + */ +#define ALIGN (1<<12) + +static unsigned align(unsigned value, unsigned a) +{ + return (value + a - 1) & ~(a-1); +} + +static int MIN2(int a, int b) +{ + return a < b ? a : b; +} static void MeasureDownloadRate(void) { const int w = TexWidth + 2 * TexBorder; const int h = TexHeight + 2 * TexBorder; - const int bytes = w * h * BytesPerTexel(Format); + const int image_bytes = align(w * h * BytesPerTexel(Format), ALIGN); + const int bytes = image_bytes * NR_TEXOBJ; + GLubyte *orig_texImage, *orig_getImage; GLubyte *texImage, *getImage; GLdouble t0, t1, time; int count; int i; + int offset = 0; + GLdouble total = 0; /* ints will tend to overflow */ + + printf("allocating %d bytes for %d %dx%d images\n", + bytes, NR_TEXOBJ, w, h); - texImage = (GLubyte *) malloc(bytes); - getImage = (GLubyte *) malloc(bytes); - if (!texImage || !getImage) { + orig_texImage = (GLubyte *) malloc(bytes + ALIGN); + orig_getImage = (GLubyte *) malloc(image_bytes + ALIGN); + if (!orig_texImage || !orig_getImage) { DownloadRate = 0.0; return; } + printf("alloc %p %p\n", orig_texImage, orig_getImage); + + texImage = (GLubyte *)align((unsigned)orig_texImage, ALIGN); + getImage = (GLubyte *)align((unsigned)orig_getImage, ALIGN); + + for (i = 1; !(((unsigned)texImage) & i); i<<=1) + ; + printf("texture image alignment: %d bytes (%p)\n", i, texImage); + for (i = 0; i < bytes; i++) { texImage[i] = i & 0xff; } @@ -166,16 +224,50 @@ MeasureDownloadRate(void) count = 0; t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001; do { + int img = count%NR_TEXOBJ; + GLubyte *img_ptr = texImage + img * image_bytes; + + glBindTexture(GL_TEXTURE_2D, TexObj[img]); + if (SubImage && count > 0) { - glTexSubImage2D(GL_TEXTURE_2D, 0, -TexBorder, -TexBorder, w, h, + /* Only update a portion of the image each iteration. This + * is presumably why you'd want to use texsubimage, otherwise + * you may as well just call teximage again. + * + * A bigger question is whether to use a pointer that moves + * with each call, ie does the incoming data come from L2 + * cache under normal circumstances, or is it pulled from + * uncached memory? + * + * There's a good argument to say L2 cache, ie you'd expect + * the data to have been recently generated. It's possible + * that it could have come from a file read, which may or may + * not have gone through the cpu. + */ + glTexSubImage2D(GL_TEXTURE_2D, 0, + -TexBorder, + -TexBorder + offset * h/8, + w, + h/8, FormatTable[Format].Format, - FormatTable[Format].Type, texImage); + FormatTable[Format].Type, +#if 1 + texImage /* likely in L2$ */ +#else + img_ptr + offset * bytes/8 /* unlikely in L2$ */ +#endif + ); + offset += 1; + offset %= 8; + total += w * h / 8; } else { glTexImage2D(GL_TEXTURE_2D, 0, FormatTable[Format].IntFormat, w, h, TexBorder, FormatTable[Format].Format, - FormatTable[Format].Type, texImage); + FormatTable[Format].Type, + img_ptr); + total += w*h; } /* draw a tiny polygon to force texture into texram */ @@ -192,25 +284,12 @@ MeasureDownloadRate(void) glDisable(GL_TEXTURE_2D); - printf("w*h=%d count=%d time=%f\n", w*h, count, time); - DownloadRate = w * h * count / time; - -#if 0 - if (!ScaleAndBias) { - /* verify texture readback */ - glGetTexImage(GL_TEXTURE_2D, 0, - FormatTable[Format].Format, - FormatTable[Format].Type, getImage); - for (i = 0; i < w * h; i++) { - if (texImage[i] != getImage[i]) { - printf("[%d] %d != %d\n", i, texImage[i], getImage[i]); - } - } - } -#endif + printf("total texels=%f time=%f\n", total, time); + DownloadRate = total / time; + - free(texImage); - free(getImage); + free(orig_texImage); + free(orig_getImage); { GLint err = glGetError(); diff --git a/progs/trivial/Makefile b/progs/trivial/Makefile index cdc6328353..b9ed5c70dc 100644 --- a/progs/trivial/Makefile +++ b/progs/trivial/Makefile @@ -38,7 +38,9 @@ SOURCES = \ quad-offset-unfilled.c \ quad-unfilled.c \ quad-tex-2d.c \ + quad-tex-pbo.c \ quad-tex-3d.c \ + quad-tex-dep.c \ quad.c \ quads.c \ quadstrip.c \ diff --git a/progs/trivial/quad-tex-pbo.c b/progs/trivial/quad-tex-pbo.c new file mode 100644 index 0000000000..5b63c698a7 --- /dev/null +++ b/progs/trivial/quad-tex-pbo.c @@ -0,0 +1,181 @@ +/* + * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the name of + * Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF + * ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#define GL_GLEXT_PROTOTYPES + +#include +#include +#include +#include + + +#define CI_OFFSET_1 16 +#define CI_OFFSET_2 32 + +GLenum doubleBuffer; + +static GLuint DrawPBO; + +static void Init(void) +{ + fprintf(stderr, "GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + fprintf(stderr, "GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); + fprintf(stderr, "GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); + + glClearColor(0.0, 0.0, 1.0, 0.0); + +#define SIZE 16 + { + GLubyte tex2d[SIZE][SIZE][4]; + GLint s, t; + + for (s = 0; s < SIZE; s++) { + for (t = 0; t < SIZE; t++) { + /* bgra: + */ + tex2d[t][s][0] = 0x30; + tex2d[t][s][1] = t*255/(SIZE-1); + tex2d[t][s][2] = s*255/(SIZE-1); + tex2d[t][s][3] = 0xff; + } + } + + + /* put image into DrawPBO */ + glGenBuffersARB(1, &DrawPBO); + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, DrawPBO); + glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT, + SIZE * SIZE * 4, tex2d, GL_STATIC_DRAW); + glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0); + + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, DrawPBO); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SIZE, SIZE, 0, + GL_BGRA, GL_UNSIGNED_BYTE, NULL); + glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, 0); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + glEnable(GL_TEXTURE_2D); + } + +} + +static void Reshape(int width, int height) +{ + + glViewport(0, 0, (GLint)width, (GLint)height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0); + glMatrixMode(GL_MODELVIEW); +} + +static void Key(unsigned char key, int x, int y) +{ + + switch (key) { + case 27: + exit(1); + default: + return; + } + + glutPostRedisplay(); +} + +static void Draw(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + + glBegin(GL_QUADS); + glTexCoord2f(1,0); + glVertex3f( 0.9, -0.9, -30.0); + glTexCoord2f(1,1); + glVertex3f( 0.9, 0.9, -30.0); + glTexCoord2f(0,1); + glVertex3f(-0.9, 0.9, -30.0); + glTexCoord2f(0,0); + glVertex3f(-0.9, -0.9, -30.0); + glEnd(); + + glFlush(); + + if (doubleBuffer) { + glutSwapBuffers(); + } +} + +static GLenum Args(int argc, char **argv) +{ + GLint i; + + doubleBuffer = GL_FALSE; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-sb") == 0) { + doubleBuffer = GL_FALSE; + } else if (strcmp(argv[i], "-db") == 0) { + doubleBuffer = GL_TRUE; + } else { + fprintf(stderr, "%s (Bad option).\n", argv[i]); + return GL_FALSE; + } + } + return GL_TRUE; +} + +int main(int argc, char **argv) +{ + GLenum type; + + glutInit(&argc, argv); + + if (Args(argc, argv) == GL_FALSE) { + exit(1); + } + + glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250); + + type = GLUT_RGB; + type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE; + glutInitDisplayMode(type); + + if (glutCreateWindow("First Tri") == GL_FALSE) { + exit(1); + } + + Init(); + + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutDisplayFunc(Draw); + glutMainLoop(); + return 0; +} diff --git a/src/glx/x11/glxext.c b/src/glx/x11/glxext.c index d386436396..bad09ce4cc 100644 --- a/src/glx/x11/glxext.c +++ b/src/glx/x11/glxext.c @@ -722,6 +722,69 @@ static const __DRIinterfaceMethods interface_methods = { __glXGetMscRateOML, }; +#define DRM_MAX_FDS 16 +static struct { + char *BusID; + int fd; + int refcount; +} connection[DRM_MAX_FDS]; + +static int nr_fds = 0; + +int drmOpenOnce(void *unused, + const char *BusID, + int *newlyopened) +{ + int i; + int fd; + + for (i = 0; i < nr_fds; i++) + if (strcmp(BusID, connection[i].BusID) == 0) { + connection[i].refcount++; + *newlyopened = 0; + return connection[i].fd; + } + + fd = drmOpen(unused, BusID); + if (fd <= 0 || nr_fds == DRM_MAX_FDS) + return fd; + + connection[nr_fds].BusID = strdup(BusID); + connection[nr_fds].fd = fd; + connection[nr_fds].refcount = 1; + *newlyopened = 1; + + if (0) + fprintf(stderr, "saved connection %d for %s %d\n", + nr_fds, connection[nr_fds].BusID, + strcmp(BusID, connection[nr_fds].BusID)); + + nr_fds++; + + return fd; +} + +void drmCloseOnce(int fd) +{ + int i; + + + + for (i = 0; i < nr_fds; i++) { + if (fd == connection[i].fd) { + if (--connection[i].refcount == 0) { + drmClose(connection[i].fd); + free(connection[i].BusID); + + if (i < --nr_fds) + connection[i] = connection[nr_fds]; + + return; + } + } + } +} + /** * Perform the required libGL-side initialization and call the client-side @@ -773,7 +836,8 @@ CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc, framebuffer.dev_priv = NULL; if (XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) { - fd = drmOpen(NULL,BusID); + int newlyopened; + fd = drmOpenOnce(NULL,BusID, &newlyopened); Xfree(BusID); /* No longer needed */ err_msg = "open DRM"; @@ -800,7 +864,7 @@ CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc, } err_msg = "XF86DRIAuthConnection"; - if (XF86DRIAuthConnection(dpy, scrn, magic)) { + if (!newlyopened || XF86DRIAuthConnection(dpy, scrn, magic)) { char *driverName; /* @@ -904,7 +968,7 @@ CallCreateNewScreen(Display *dpy, int scrn, __DRIscreen *psc, } if ( fd >= 0 ) { - (void)drmClose(fd); + (void)drmCloseOnce(fd); } (void)XF86DRICloseConnection(dpy, scrn); diff --git a/src/mesa/drivers/directfb/idirectfbgl_mesa.c b/src/mesa/drivers/directfb/idirectfbgl_mesa.c index 524249e8a5..2a20bddb1b 100644 --- a/src/mesa/drivers/directfb/idirectfbgl_mesa.c +++ b/src/mesa/drivers/directfb/idirectfbgl_mesa.c @@ -372,10 +372,14 @@ dfbSetViewport( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h ) } static void -dfbClear( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height ) +dfbClear( GLcontext *ctx, GLbitfield mask ) { IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx; + int x = ctx->DrawBuffer->_Xmin; + int y = ctx->DrawBuffer->_Ymin; + int width = ctx->DrawBuffer->_Xmax - x; + int height = ctx->DrawBuffer->_Ymax - y; + GLboolean all = (width == ctx->DrawBuffer->Width && height == ctx->DrawBuffer->height) if (mask & BUFFER_BIT_FRONT_LEFT && ctx->Color.ColorMask[0] && @@ -420,7 +424,7 @@ dfbClear( GLcontext *ctx, GLbitfield mask, GLboolean all, } if (mask) - _swrast_Clear( ctx, mask, all, x, y, width, height ); + _swrast_Clear( ctx, mask ); } diff --git a/src/mesa/drivers/dri/Makefile.template b/src/mesa/drivers/dri/Makefile.template index 1040194d0d..5261a4b55d 100644 --- a/src/mesa/drivers/dri/Makefile.template +++ b/src/mesa/drivers/dri/Makefile.template @@ -9,7 +9,12 @@ COMMON_SOURCES = \ ../common/vblank.c \ ../common/dri_util.c \ ../common/xmlconfig.c \ - ../common/drirenderbuffer.c + ../common/drirenderbuffer.c + +COMMON_BM_SOURCES = \ + ../common/dri_bufmgr.c \ + ../common/dri_drmpool.c + ifeq ($(WINDOW_SYSTEM),dri) WINOBJ= diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.c b/src/mesa/drivers/dri/common/dri_bufmgr.c new file mode 100644 index 0000000000..370b56c3a3 --- /dev/null +++ b/src/mesa/drivers/dri/common/dri_bufmgr.c @@ -0,0 +1,493 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * THE COPYRIGHT HOLDERS, AUTHORS 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + * Keith Whitwell + */ + +#include +#include +#include "glthread.h" +#include "errno.h" +#include "dri_bufmgr.h" +#include "string.h" +#include "imports.h" +#include "dri_bufpool.h" + +_glthread_DECLARE_STATIC_MUTEX(bmMutex); + +/* + * TODO: Introduce fence pools in the same way as + * buffer object pools. + */ + + + +typedef struct _DriFenceObject +{ + int fd; + _glthread_Mutex mutex; + int refCount; + const char *name; + drmFence fence; +} DriFenceObject; + +typedef struct _DriBufferObject +{ + DriBufferPool *pool; + _glthread_Mutex mutex; + int refCount; + const char *name; + unsigned flags; + unsigned hint; + unsigned alignment; + void *private; +} DriBufferObject; + + +void +bmError(int val, const char *file, const char *function, int line) +{ + _mesa_printf("Fatal video memory manager error \"%s\".\n" + "Check kernel logs or set the LIBGL_DEBUG\n" + "environment variable to \"verbose\" for more info.\n" + "Detected in file %s, line %d, function %s.\n", + strerror(-val), file, line, function); +#ifndef NDEBUG + abort(); +#else + abort(); +#endif +} + +DriFenceObject * +driFenceBuffers(int fd, char *name, unsigned flags) +{ + DriFenceObject *fence = (DriFenceObject *) malloc(sizeof(*fence)); + int ret; + + if (!fence) + BM_CKFATAL(-EINVAL); + + _glthread_LOCK_MUTEX(bmMutex); + fence->refCount = 1; + fence->name = name; + fence->fd = fd; + _glthread_INIT_MUTEX(fence->mutex); + ret = drmFenceBuffers(fd, flags, &fence->fence); + _glthread_UNLOCK_MUTEX(bmMutex); + if (ret) { + free(fence); + BM_CKFATAL(ret); + } + return fence; +} + + +unsigned +driFenceType(DriFenceObject * fence) +{ + unsigned ret; + + _glthread_LOCK_MUTEX(bmMutex); + ret = fence->fence.flags; + _glthread_UNLOCK_MUTEX(bmMutex); + + return ret; +} + + +DriFenceObject * +driFenceReference(DriFenceObject * fence) +{ + _glthread_LOCK_MUTEX(bmMutex); + ++fence->refCount; + _glthread_UNLOCK_MUTEX(bmMutex); + return fence; +} + +void +driFenceUnReference(DriFenceObject * fence) +{ + if (!fence) + return; + + _glthread_LOCK_MUTEX(bmMutex); + if (--fence->refCount == 0) { + drmFenceDestroy(fence->fd, &fence->fence); + free(fence); + } + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void +driFenceFinish(DriFenceObject * fence, unsigned type, int lazy) +{ + int ret; + unsigned flags = (lazy) ? DRM_FENCE_FLAG_WAIT_LAZY : 0; + + _glthread_LOCK_MUTEX(fence->mutex); + ret = drmFenceWait(fence->fd, flags, &fence->fence, type); + _glthread_UNLOCK_MUTEX(fence->mutex); + BM_CKFATAL(ret); +} + +int +driFenceSignaled(DriFenceObject * fence, unsigned type) +{ + int signaled; + int ret; + + if (fence == NULL) + return GL_TRUE; + + _glthread_LOCK_MUTEX(fence->mutex); + ret = drmFenceSignaled(fence->fd, &fence->fence, type, &signaled); + _glthread_UNLOCK_MUTEX(fence->mutex); + BM_CKFATAL(ret); + return signaled; +} + + +extern drmBO * +driBOKernel(struct _DriBufferObject *buf) +{ + drmBO *ret; + + assert(buf->private != NULL); + ret = buf->pool->kernel(buf->pool, buf->private); + if (!ret) + BM_CKFATAL(-EINVAL); + + return ret; +} + +void +driBOWaitIdle(struct _DriBufferObject *buf, int lazy) +{ + assert(buf->private != NULL); + + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(buf->pool->waitIdle(buf->pool, buf->private, lazy)); + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void * +driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint) +{ + void *virtual; + + assert(buf->private != NULL); + + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(buf->pool->map(buf->pool, buf->private, flags, hint, &virtual)); + _glthread_UNLOCK_MUTEX(buf->mutex); + return virtual; +} + +void +driBOUnmap(struct _DriBufferObject *buf) +{ + assert(buf->private != NULL); + + buf->pool->unmap(buf->pool, buf->private); +} + +unsigned long +driBOOffset(struct _DriBufferObject *buf) +{ + unsigned long ret; + + assert(buf->private != NULL); + + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->offset(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + return ret; +} + +unsigned +driBOFlags(struct _DriBufferObject *buf) +{ + unsigned ret; + + assert(buf->private != NULL); + + _glthread_LOCK_MUTEX(buf->mutex); + ret = buf->pool->flags(buf->pool, buf->private); + _glthread_UNLOCK_MUTEX(buf->mutex); + return ret; +} + +struct _DriBufferObject * +driBOReference(struct _DriBufferObject *buf) +{ + _glthread_LOCK_MUTEX(bmMutex); + if (++buf->refCount == 1) { + BM_CKFATAL(-EINVAL); + } + _glthread_UNLOCK_MUTEX(bmMutex); + return buf; +} + +void +driBOUnReference(struct _DriBufferObject *buf) +{ + int tmp; + + if (!buf) + return; + + _glthread_LOCK_MUTEX(bmMutex); + tmp = --buf->refCount; + _glthread_UNLOCK_MUTEX(bmMutex); + if (!tmp) { + buf->pool->destroy(buf->pool, buf->private); + free(buf); + } +} + +void +driBOData(struct _DriBufferObject *buf, + unsigned size, const void *data, unsigned flags) +{ + void *virtual; + int newBuffer; + struct _DriBufferPool *pool; + + _glthread_LOCK_MUTEX(buf->mutex); + pool = buf->pool; + if (!pool->create) { + _mesa_error(NULL, GL_INVALID_OPERATION, + "driBOData called on invalid buffer\n"); + BM_CKFATAL(-EINVAL); + } + newBuffer = !buf->private || (pool->size(pool, buf->private) < size) || + pool->map(pool, buf->private, DRM_BO_FLAG_WRITE, + DRM_BO_HINT_DONT_BLOCK, &virtual); + + if (newBuffer) { + if (buf->private) + pool->destroy(pool, buf->private); + if (!flags) + flags = buf->flags; + buf->private = pool->create(pool, size, flags, 0, buf->alignment); + if (!buf->private) + BM_CKFATAL(-ENOMEM); + BM_CKFATAL(pool->map(pool, buf->private, + DRM_BO_FLAG_WRITE, + DRM_BO_HINT_DONT_BLOCK, &virtual)); + } + + if (data != NULL) + memcpy(virtual, data, size); + + BM_CKFATAL(pool->unmap(pool, buf->private)); + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void +driBOSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, const void *data) +{ + void *virtual; + + _glthread_LOCK_MUTEX(buf->mutex); + if (size && data) { + BM_CKFATAL(buf->pool->map(buf->pool, buf->private, + DRM_BO_FLAG_WRITE, 0, &virtual)); + memcpy((unsigned char *) virtual + offset, data, size); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + } + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void +driBOGetSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, void *data) +{ + void *virtual; + + _glthread_LOCK_MUTEX(buf->mutex); + if (size && data) { + BM_CKFATAL(buf->pool->map(buf->pool, buf->private, + DRM_BO_FLAG_READ, 0, &virtual)); + memcpy(data, (unsigned char *) virtual + offset, size); + BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private)); + } + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void +driBOSetStatic(struct _DriBufferObject *buf, + unsigned long offset, + unsigned long size, void *virtual, unsigned flags) +{ + _glthread_LOCK_MUTEX(buf->mutex); + if (buf->private != NULL) { + _mesa_error(NULL, GL_INVALID_OPERATION, + "Invalid buffer for setStatic\n"); + BM_CKFATAL(-EINVAL); + } + if (buf->pool->setstatic == NULL) { + _mesa_error(NULL, GL_INVALID_OPERATION, + "Invalid buffer pool for setStatic\n"); + BM_CKFATAL(-EINVAL); + } + + if (!flags) + flags = buf->flags; + + buf->private = buf->pool->setstatic(buf->pool, offset, size, + virtual, flags); + if (!buf->private) { + _mesa_error(NULL, GL_OUT_OF_MEMORY, + "Invalid buffer pool for setStatic\n"); + BM_CKFATAL(-ENOMEM); + } + _glthread_UNLOCK_MUTEX(buf->mutex); +} + + + +void +driGenBuffers(struct _DriBufferPool *pool, + const char *name, + unsigned n, + struct _DriBufferObject *buffers[], + unsigned alignment, unsigned flags, unsigned hint) +{ + struct _DriBufferObject *buf; + int i; + + flags = (flags) ? flags : DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM | + DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE; + + + for (i = 0; i < n; ++i) { + buf = (struct _DriBufferObject *) calloc(1, sizeof(*buf)); + if (!buf) + BM_CKFATAL(-ENOMEM); + + _glthread_INIT_MUTEX(buf->mutex); + _glthread_LOCK_MUTEX(buf->mutex); + _glthread_LOCK_MUTEX(bmMutex); + buf->refCount = 1; + _glthread_UNLOCK_MUTEX(bmMutex); + buf->flags = flags; + buf->hint = hint; + buf->name = name; + buf->alignment = alignment; + buf->pool = pool; + _glthread_UNLOCK_MUTEX(buf->mutex); + buffers[i] = buf; + } +} + +void +driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]) +{ + int i; + + for (i = 0; i < n; ++i) { + driBOUnReference(buffers[i]); + } +} + + +void +driInitBufMgr(int fd) +{ + ; +} + + +void +driBOCreateList(int target, drmBOList * list) +{ + _glthread_LOCK_MUTEX(bmMutex); + BM_CKFATAL(drmBOCreateList(20, list)); + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void +driBOResetList(drmBOList * list) +{ + _glthread_LOCK_MUTEX(bmMutex); + BM_CKFATAL(drmBOResetList(list)); + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void +driBOAddListItem(drmBOList * list, struct _DriBufferObject *buf, + unsigned flags, unsigned mask) +{ + int newItem; + + _glthread_LOCK_MUTEX(buf->mutex); + _glthread_LOCK_MUTEX(bmMutex); + BM_CKFATAL(drmAddValidateItem(list, driBOKernel(buf), + flags, mask, &newItem)); + _glthread_UNLOCK_MUTEX(bmMutex); + + /* + * Tell userspace pools to validate the buffer. This should be a + * noop if the pool is already validated. + * FIXME: We should have a list for this as well. + */ + + if (buf->pool->validate) { + BM_CKFATAL(buf->pool->validate(buf->pool, buf->private)); + } + + _glthread_UNLOCK_MUTEX(buf->mutex); +} + +void +driBOFence(struct _DriBufferObject *buf, struct _DriFenceObject *fence) +{ + _glthread_LOCK_MUTEX(buf->mutex); + BM_CKFATAL(buf->pool->fence(buf->pool, buf->private, fence)); + _glthread_UNLOCK_MUTEX(buf->mutex); + +} + +void +driBOValidateList(int fd, drmBOList * list) +{ + _glthread_LOCK_MUTEX(bmMutex); + BM_CKFATAL(drmBOValidateList(fd, list)); + _glthread_UNLOCK_MUTEX(bmMutex); +} + +void +driPoolTakeDown(struct _DriBufferPool *pool) +{ + pool->takeDown(pool); + +} diff --git a/src/mesa/drivers/dri/common/dri_bufmgr.h b/src/mesa/drivers/dri/common/dri_bufmgr.h new file mode 100644 index 0000000000..01f149ae4e --- /dev/null +++ b/src/mesa/drivers/dri/common/dri_bufmgr.h @@ -0,0 +1,99 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * THE COPYRIGHT HOLDERS, AUTHORS 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + * Keith Whitwell + */ + +#ifndef _DRI_BUFMGR_H_ +#define _DRI_BUFMGR_H_ +#include + + +struct _DriFenceObject; +struct _DriBufferObject; +struct _DriBufferPool; + +extern struct _DriFenceObject *driFenceBuffers(int fd, char *name, + unsigned flags); + +extern struct _DriFenceObject *driFenceReference(struct _DriFenceObject *fence); + +extern void driFenceUnReference(struct _DriFenceObject *fence); + +extern void +driFenceFinish(struct _DriFenceObject *fence, unsigned type, int lazy); + +extern int driFenceSignaled(struct _DriFenceObject *fence, unsigned type); +extern unsigned driFenceType(struct _DriFenceObject *fence); + +/* + * Return a pointer to the libdrm buffer object this DriBufferObject + * uses. + */ + +extern drmBO *driBOKernel(struct _DriBufferObject *buf); +extern void *driBOMap(struct _DriBufferObject *buf, unsigned flags, + unsigned hint); +extern void driBOUnmap(struct _DriBufferObject *buf); +extern unsigned long driBOOffset(struct _DriBufferObject *buf); +extern unsigned driBOFlags(struct _DriBufferObject *buf); +extern struct _DriBufferObject *driBOReference(struct _DriBufferObject *buf); +extern void driBOUnReference(struct _DriBufferObject *buf); +extern void driBOData(struct _DriBufferObject *r_buf, + unsigned size, const void *data, unsigned flags); +extern void driBOSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, + const void *data); +extern void driBOGetSubData(struct _DriBufferObject *buf, + unsigned long offset, unsigned long size, + void *data); +extern void driGenBuffers(struct _DriBufferPool *pool, + const char *name, + unsigned n, + struct _DriBufferObject *buffers[], + unsigned alignment, unsigned flags, unsigned hint); +extern void driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]); +extern void driInitBufMgr(int fd); +extern void driBOCreateList(int target, drmBOList * list); +extern void driBOResetList(drmBOList * list); +extern void driBOAddListItem(drmBOList * list, struct _DriBufferObject *buf, + unsigned flags, unsigned mask); +extern void driBOValidateList(int fd, drmBOList * list); + +extern void driBOFence(struct _DriBufferObject *buf, + struct _DriFenceObject *fence); + +extern void driPoolTakeDown(struct _DriBufferPool *pool); +extern void driBOSetStatic(struct _DriBufferObject *buf, + unsigned long offset, + unsigned long size, void *virtual, unsigned flags); +extern void driBOWaitIdle(struct _DriBufferObject *buf, int lazy); +extern void driPoolTakeDown(struct _DriBufferPool *pool); + +#endif diff --git a/src/mesa/drivers/dri/common/dri_bufpool.h b/src/mesa/drivers/dri/common/dri_bufpool.h new file mode 100644 index 0000000000..c6fb2c3ce0 --- /dev/null +++ b/src/mesa/drivers/dri/common/dri_bufpool.h @@ -0,0 +1,86 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * THE COPYRIGHT HOLDERS, AUTHORS 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + */ + +#ifndef _DRI_BUFPOOL_H_ +#define _DRI_BUFPOOL_H_ + +#include +struct _DriFenceObject; + +typedef struct _DriBufferPool +{ + int fd; + int (*map) (struct _DriBufferPool * pool, void *private, + unsigned flags, int hint, void **virtual); + int (*unmap) (struct _DriBufferPool * pool, void *private); + int (*destroy) (struct _DriBufferPool * pool, void *private); + unsigned long (*offset) (struct _DriBufferPool * pool, void *private); + unsigned (*flags) (struct _DriBufferPool * pool, void *private); + unsigned long (*size) (struct _DriBufferPool * pool, void *private); + void *(*create) (struct _DriBufferPool * pool, unsigned long size, + unsigned flags, unsigned hint, unsigned alignment); + int (*fence) (struct _DriBufferPool * pool, void *private, + struct _DriFenceObject * fence); + drmBO *(*kernel) (struct _DriBufferPool * pool, void *private); + int (*validate) (struct _DriBufferPool * pool, void *private); + void *(*setstatic) (struct _DriBufferPool * pool, unsigned long offset, + unsigned long size, void *virtual, unsigned flags); + int (*waitIdle) (struct _DriBufferPool *pool, void *private, + int lazy); + void (*takeDown) (struct _DriBufferPool * pool); + void *data; +} DriBufferPool; + +extern void bmError(int val, const char *file, const char *function, + int line); +#define BM_CKFATAL(val) \ + do{ \ + int tstVal = (val); \ + if (tstVal) \ + bmError(tstVal, __FILE__, __FUNCTION__, __LINE__); \ + } while(0); + + + + + +/* + * Builtin pools. + */ + +/* + * Kernel buffer objects. Size in multiples of page size. Page size aligned. + */ + +extern struct _DriBufferPool *driDRMPoolInit(int fd); +extern struct _DriBufferPool *driDRMStaticPoolInit(int fd); + +#endif diff --git a/src/mesa/drivers/dri/common/dri_drmpool.c b/src/mesa/drivers/dri/common/dri_drmpool.c new file mode 100644 index 0000000000..b5b324be50 --- /dev/null +++ b/src/mesa/drivers/dri/common/dri_drmpool.c @@ -0,0 +1,227 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * THE COPYRIGHT HOLDERS, AUTHORS 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + */ + +#include +#include +#include +#include "dri_bufpool.h" + +/* + * Buffer pool implementation using DRM buffer objects as DRI buffer objects. + */ + +static void * +pool_create(struct _DriBufferPool *pool, + unsigned long size, unsigned flags, unsigned hint, + unsigned alignment) +{ + drmBO *buf = (drmBO *) malloc(sizeof(*buf)); + int ret; + unsigned pageSize = getpagesize(); + + if (!buf) + return NULL; + + if ((alignment > pageSize) && (alignment % pageSize)) { + return NULL; + } + + ret = drmBOCreate(pool->fd, 0, size, alignment / pageSize, + NULL, drm_bo_type_dc, + flags, hint, buf); + if (ret) { + free(buf); + return NULL; + } + + return (void *) buf; +} + +static int +pool_destroy(struct _DriBufferPool *pool, void *private) +{ + int ret; + drmBO *buf = (drmBO *) private; + ret = drmBODestroy(pool->fd, buf); + free(buf); + return ret; +} + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, void **virtual) +{ + drmBO *buf = (drmBO *) private; + + return drmBOMap(pool->fd, buf, flags, hint, virtual); +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + return drmBOUnmap(pool->fd, buf); +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + return buf->offset; +} + +static unsigned +pool_flags(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + return buf->flags; +} + + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + drmBO *buf = (drmBO *) private; + return buf->size; +} + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + /* + * Noop. The kernel handles all fencing. + */ + + return 0; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + return (drmBO *) private; +} + +static int +pool_waitIdle(struct _DriBufferPool *pool, void *private, int lazy) +{ + drmBO *buf = (drmBO *) private; + return drmBOWaitIdle(pool->fd, buf, (lazy) ? DRM_BO_HINT_WAIT_LAZY:0); +} + + +static void +pool_takedown(struct _DriBufferPool *pool) +{ + free(pool); +} + + +struct _DriBufferPool * +driDRMPoolInit(int fd) +{ + struct _DriBufferPool *pool; + + pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); + + if (!pool) + return NULL; + + pool->fd = fd; + pool->map = &pool_map; + pool->unmap = &pool_unmap; + pool->destroy = &pool_destroy; + pool->offset = &pool_offset; + pool->flags = &pool_flags; + pool->size = &pool_size; + pool->create = &pool_create; + pool->fence = &pool_fence; + pool->kernel = &pool_kernel; + pool->validate = NULL; + pool->setstatic = NULL; + pool->waitIdle = &pool_waitIdle; + pool->takeDown = &pool_takedown; + pool->data = NULL; + return pool; +} + + +static void * +pool_setstatic(struct _DriBufferPool *pool, unsigned long offset, + unsigned long size, void *virtual, unsigned flags) +{ + drmBO *buf = (drmBO *) malloc(sizeof(*buf)); + int ret; + + if (!buf) + return NULL; + + ret = drmBOCreate(pool->fd, offset, size, 0, NULL, drm_bo_type_fake, + flags, 0, buf); + + if (ret) { + free(buf); + return NULL; + } + + buf->virtual = virtual; + + return (void *) buf; +} + + +struct _DriBufferPool * +driDRMStaticPoolInit(int fd) +{ + struct _DriBufferPool *pool; + + pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); + + if (!pool) + return NULL; + + pool->fd = fd; + pool->map = &pool_map; + pool->unmap = &pool_unmap; + pool->destroy = &pool_destroy; + pool->offset = &pool_offset; + pool->flags = &pool_flags; + pool->size = &pool_size; + pool->create = NULL; + pool->fence = &pool_fence; + pool->kernel = &pool_kernel; + pool->validate = NULL; + pool->setstatic = &pool_setstatic; + pool->waitIdle = &pool_waitIdle; + pool->takeDown = &pool_takedown; + pool->data = NULL; + return pool; +} diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index 1ca2756e01..e7f07569f4 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -849,7 +849,7 @@ static void driDestroyScreen(__DRInativeDisplay *dpy, int scrn, void *screenPriv (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX); (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize); _mesa_free(psp->pDevPriv); - (void)drmClose(psp->fd); + (void)drmCloseOnce(psp->fd); if ( psp->modes != NULL ) { (*dri_interface->destroyContextModes)( psp->modes ); } diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h index 885d5899e0..e43e653250 100644 --- a/src/mesa/drivers/dri/common/dri_util.h +++ b/src/mesa/drivers/dri/common/dri_util.h @@ -87,15 +87,15 @@ typedef struct __DRIutilversionRec2 __DRIutilversion2; #define DRI_VALIDATE_DRAWABLE_INFO(psp, pdp) \ do { \ while (*(pdp->pStamp) != pdp->lastStamp) { \ - DRM_UNLOCK(psp->fd, &psp->pSAREA->lock, \ - pdp->driContextPriv->hHWContext); \ + register unsigned int hwContext = psp->pSAREA->lock.lock & \ + ~(DRM_LOCK_HELD | DRM_LOCK_CONT); \ + DRM_UNLOCK(psp->fd, &psp->pSAREA->lock, hwContext); \ \ DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); \ DRI_VALIDATE_DRAWABLE_INFO_ONCE(pdp); \ DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); \ \ - DRM_LIGHT_LOCK(psp->fd, &psp->pSAREA->lock, \ - pdp->driContextPriv->hHWContext); \ + DRM_LIGHT_LOCK(psp->fd, &psp->pSAREA->lock, hwContext); \ } \ } while (0) diff --git a/src/mesa/drivers/dri/ffb/ffb_clear.c b/src/mesa/drivers/dri/ffb/ffb_clear.c index 9cd5a12b7d..e8dfcbe254 100644 --- a/src/mesa/drivers/dri/ffb/ffb_clear.c +++ b/src/mesa/drivers/dri/ffb/ffb_clear.c @@ -249,8 +249,7 @@ ffb_do_clear(GLcontext *ctx, __DRIdrawablePrivate *dPriv) } } -void ffbDDClear(GLcontext *ctx, GLbitfield mask, GLboolean allFoo, - GLint cxFoo, GLint cyFoo, GLint cwidthFoo, GLint cheightFoo) +void ffbDDClear(GLcontext *ctx, GLbitfield mask) { ffbContextPtr fmesa = FFB_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = fmesa->driDrawable; @@ -334,6 +333,6 @@ void ffbDDClear(GLcontext *ctx, GLbitfield mask, GLboolean allFoo, } if (mask) - _swrast_Clear(ctx, mask, 0, 0, 0, 0, 0); + _swrast_Clear(ctx, mask); } diff --git a/src/mesa/drivers/dri/ffb/ffb_clear.h b/src/mesa/drivers/dri/ffb/ffb_clear.h index 4b707f19b2..c3b8ce714b 100644 --- a/src/mesa/drivers/dri/ffb/ffb_clear.h +++ b/src/mesa/drivers/dri/ffb/ffb_clear.h @@ -1,9 +1,6 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_clear.h,v 1.2 2002/02/22 21:32:58 dawes Exp $ */ - #ifndef _FFB_CLEAR_H #define _FFB_CLEAR_H -extern void ffbDDClear(GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint cx, GLint cy, GLint cwidth, GLint cheight); +extern void ffbDDClear(GLcontext *ctx, GLbitfield mask); #endif /* !(_FFB_CLEAR_H) */ diff --git a/src/mesa/drivers/dri/ffb/ffb_xmesa.c b/src/mesa/drivers/dri/ffb/ffb_xmesa.c index 7c1e439364..215aaf8ffb 100644 --- a/src/mesa/drivers/dri/ffb/ffb_xmesa.c +++ b/src/mesa/drivers/dri/ffb/ffb_xmesa.c @@ -568,8 +568,7 @@ ffbMakeCurrent(__DRIcontextPrivate *driContextPriv, */ ffbDDClear(fmesa->glCtx, (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT | - BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL), - 1, 0, 0, 0, 0); + BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)); } } else { _mesa_make_current(NULL, NULL, NULL); diff --git a/src/mesa/drivers/dri/gamma/gamma_state.c b/src/mesa/drivers/dri/gamma/gamma_state.c index 1d5ce20995..8dbe0a97ca 100644 --- a/src/mesa/drivers/dri/gamma/gamma_state.c +++ b/src/mesa/drivers/dri/gamma/gamma_state.c @@ -205,8 +205,7 @@ static void gammaDDBlendFuncSeparate( GLcontext *ctx, * Buffer clear */ -static void gammaDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint cx, GLint cy, GLint cw, GLint ch ) +static void gammaDDClear( GLcontext *ctx, GLbitfield mask ) { gammaContextPtr gmesa = GAMMA_CONTEXT(ctx); GLINTDRIPtr gDRIPriv = (GLINTDRIPtr)gmesa->driScreen->pDevPriv; @@ -410,7 +409,7 @@ static void gammaDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, #endif if ( mask ) - _swrast_Clear( ctx, mask, all, cx, cy, cw, ch ); + _swrast_Clear( ctx, mask ); } /* ============================================================= diff --git a/src/mesa/drivers/dri/i810/i810ioctl.c b/src/mesa/drivers/dri/i810/i810ioctl.c index 9e52d80a8b..57c84193fa 100644 --- a/src/mesa/drivers/dri/i810/i810ioctl.c +++ b/src/mesa/drivers/dri/i810/i810ioctl.c @@ -48,8 +48,7 @@ static drmBufPtr i810_get_buffer_ioctl( i810ContextPtr imesa ) #define DEPTH_SCALE ((1<<16)-1) -static void i810Clear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, - GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo ) +static void i810Clear( GLcontext *ctx, GLbitfield mask ) { i810ContextPtr imesa = I810_CONTEXT( ctx ); __DRIdrawablePrivate *dPriv = imesa->driDrawable; @@ -142,7 +141,7 @@ static void i810Clear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, } if (mask) - _swrast_Clear( ctx, mask, 0, 0, 0, 0, 0 ); + _swrast_Clear( ctx, mask ); } diff --git a/src/mesa/drivers/dri/i915/i830_metaops.c b/src/mesa/drivers/dri/i915/i830_metaops.c index 17fde2f480..dbf5f04349 100644 --- a/src/mesa/drivers/dri/i915/i830_metaops.c +++ b/src/mesa/drivers/dri/i915/i830_metaops.c @@ -395,13 +395,15 @@ static void draw_poly(i830ContextPtr i830, void i830ClearWithTris(intelContextPtr intel, GLbitfield mask, - GLboolean all, - GLint cx, GLint cy, GLint cw, GLint ch) + GLboolean allFoo, + GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo) { i830ContextPtr i830 = I830_CONTEXT( intel ); __DRIdrawablePrivate *dPriv = intel->driDrawable; intelScreenPrivate *screen = intel->intelScreen; int x0, y0, x1, y1; + GLint cx, cy, cw, ch; + GLboolean all; INTEL_FIREVERTICES(intel); SET_STATE( i830, meta ); @@ -411,6 +413,14 @@ i830ClearWithTris(intelContextPtr intel, GLbitfield mask, LOCK_HARDWARE(intel); + /* get clear bounds after locking */ + cx = intel->ctx.DrawBuffer->_Xmin; + cy = intel->ctx.DrawBuffer->_Ymin; + cw = intel->ctx.DrawBuffer->_Xmax - cx; + ch = intel->ctx.DrawBuffer->_Ymax - cy; + all = (cw == intel->ctx.DrawBuffer->Width && + ch == intel->ctx.DrawBuffer->Height); + if(!all) { x0 = cx; y0 = cy; diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c index 0f3e6885f3..7160234bce 100644 --- a/src/mesa/drivers/dri/i915/i915_fragprog.c +++ b/src/mesa/drivers/dri/i915/i915_fragprog.c @@ -29,6 +29,7 @@ #include "macros.h" #include "enums.h" +#include "tnl/tnl.h" #include "tnl/t_context.h" #include "intel_batchbuffer.h" @@ -937,6 +938,8 @@ static void i915ProgramStringNotify( GLcontext *ctx, ctx->Driver.Enable( ctx, GL_FRAGMENT_PROGRAM_ARB, ctx->FragmentProgram.Enabled ); } + + _tnl_program_string(ctx, target, prog); } diff --git a/src/mesa/drivers/dri/i915/i915_metaops.c b/src/mesa/drivers/dri/i915/i915_metaops.c index 3ab5dbfd68..1be7ac4c48 100644 --- a/src/mesa/drivers/dri/i915/i915_metaops.c +++ b/src/mesa/drivers/dri/i915/i915_metaops.c @@ -493,14 +493,16 @@ static void draw_poly(i915ContextPtr i915, void -i915ClearWithTris(intelContextPtr intel, GLbitfield mask, - GLboolean all, - GLint cx, GLint cy, GLint cw, GLint ch) +i915ClearWithTris(intelContextPtr intel, GLbitfield buffers, + GLboolean allFoo, + GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo) { i915ContextPtr i915 = I915_CONTEXT( intel ); __DRIdrawablePrivate *dPriv = intel->driDrawable; intelScreenPrivate *screen = intel->intelScreen; int x0, y0, x1, y1; + GLint cx, cy, cw, ch; + GLboolean all; SET_STATE( i915, meta ); set_initial_state( i915 ); @@ -509,6 +511,14 @@ i915ClearWithTris(intelContextPtr intel, GLbitfield mask, LOCK_HARDWARE(intel); + /* get clear bounds after locking */ + cx = intel->ctx.DrawBuffer->_Xmin; + cy = intel->ctx.DrawBuffer->_Ymin; + cw = intel->ctx.DrawBuffer->_Xmax - cx; + ch = intel->ctx.DrawBuffer->_Ymax - cy; + all = (cw == intel->ctx.DrawBuffer->Width && + ch == intel->ctx.DrawBuffer->Height); + if (!all) { x0 = cx; y0 = cy; @@ -525,7 +535,7 @@ i915ClearWithTris(intelContextPtr intel, GLbitfield mask, * The active cliprects will be applied as for any other geometry. */ - if (mask & BUFFER_BIT_FRONT_LEFT) { + if (buffers & BUFFER_BIT_FRONT_LEFT) { set_no_depth_stencil_write( i915 ); set_color_mask( i915, GL_TRUE ); set_draw_region( i915, &screen->front ); @@ -536,7 +546,7 @@ i915ClearWithTris(intelContextPtr intel, GLbitfield mask, 0, 0, 0, 0); } - if (mask & BUFFER_BIT_BACK_LEFT) { + if (buffers & BUFFER_BIT_BACK_LEFT) { set_no_depth_stencil_write( i915 ); set_color_mask( i915, GL_TRUE ); set_draw_region( i915, &screen->back ); @@ -547,7 +557,7 @@ i915ClearWithTris(intelContextPtr intel, GLbitfield mask, 0, 0, 0, 0); } - if (mask & BUFFER_BIT_STENCIL) { + if (buffers & BUFFER_BIT_STENCIL) { set_stencil_replace( i915, intel->ctx.Stencil.WriteMask[0], intel->ctx.Stencil.Clear); diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.c b/src/mesa/drivers/dri/i915/intel_batchbuffer.c index 865f15e79f..803b41b256 100644 --- a/src/mesa/drivers/dri/i915/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915/intel_batchbuffer.c @@ -621,13 +621,14 @@ void intelEmitCopyBlitLocked( intelContextPtr intel, -void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, - GLint cx1, GLint cy1, GLint cw, GLint ch) +void intelClearWithBlit(GLcontext *ctx, GLbitfield buffers, GLboolean allFoo, + GLint cx1Foo, GLint cy1Foo, GLint cwFoo, GLint chFoo) { intelContextPtr intel = INTEL_CONTEXT( ctx ); intelScreenPrivate *intelScreen = intel->intelScreen; GLuint clear_depth, clear_color; - GLint cx, cy; + GLint cx, cy, cw, ch; + GLboolean all; GLint pitch; GLint cpp = intelScreen->cpp; GLint i; @@ -637,16 +638,24 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, intelFlush( &intel->ctx ); LOCK_HARDWARE( intel ); + /* get clear bounds after locking */ + cx = intel->ctx.DrawBuffer->_Xmin; + cy = intel->ctx.DrawBuffer->_Ymin; + cw = intel->ctx.DrawBuffer->_Xmax - cx; + ch = intel->ctx.DrawBuffer->_Ymax - cy; + all = (cw == intel->ctx.DrawBuffer->Width && + ch == intel->ctx.DrawBuffer->Height); + pitch = intelScreen->front.pitch; clear_color = intel->ClearColor; clear_depth = 0; - if (flags & BUFFER_BIT_DEPTH) { + if (buffers & BUFFER_BIT_DEPTH) { clear_depth = (GLuint)(ctx->Depth.Clear * intel->ClearDepth); } - if (flags & BUFFER_BIT_STENCIL) { + if (buffers & BUFFER_BIT_STENCIL) { clear_depth |= (ctx->Stencil.Clear & 0xff) << 24; } @@ -661,8 +670,8 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB); D_CMD = XY_COLOR_BLT_CMD; - if (flags & BUFFER_BIT_DEPTH) D_CMD |= XY_COLOR_BLT_WRITE_RGB; - if (flags & BUFFER_BIT_STENCIL) D_CMD |= XY_COLOR_BLT_WRITE_ALPHA; + if (buffers & BUFFER_BIT_DEPTH) D_CMD |= XY_COLOR_BLT_WRITE_RGB; + if (buffers & BUFFER_BIT_STENCIL) D_CMD |= XY_COLOR_BLT_WRITE_ALPHA; break; default: BR13 = (0xF0 << 16) | (pitch) | (1<<24); @@ -672,17 +681,17 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, { /* flip top to bottom */ - cy = intel->driDrawable->h-cy1-ch; - cx = cx1 + intel->drawX; + cy = intel->driDrawable->h - cy - ch; + cx = cx + intel->drawX; cy += intel->drawY; /* adjust for page flipping */ if ( intel->sarea->pf_current_page == 1 ) { - GLuint tmp = flags; + GLuint tmp = buffers; - flags &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT); - if ( tmp & BUFFER_BIT_FRONT_LEFT ) flags |= BUFFER_BIT_BACK_LEFT; - if ( tmp & BUFFER_BIT_BACK_LEFT ) flags |= BUFFER_BIT_FRONT_LEFT; + buffers &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT); + if ( tmp & BUFFER_BIT_FRONT_LEFT ) buffers |= BUFFER_BIT_BACK_LEFT; + if ( tmp & BUFFER_BIT_BACK_LEFT ) buffers |= BUFFER_BIT_FRONT_LEFT; } for (i = 0 ; i < intel->numClipRects ; i++) @@ -718,7 +727,7 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, b.y2 > intelScreen->height) continue; - if ( flags & BUFFER_BIT_FRONT_LEFT ) { + if ( buffers & BUFFER_BIT_FRONT_LEFT ) { BEGIN_BATCH( 6); OUT_BATCH( CMD ); OUT_BATCH( BR13 ); @@ -729,7 +738,7 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, ADVANCE_BATCH(); } - if ( flags & BUFFER_BIT_BACK_LEFT ) { + if ( buffers & BUFFER_BIT_BACK_LEFT ) { BEGIN_BATCH( 6); OUT_BATCH( CMD ); OUT_BATCH( BR13 ); @@ -740,7 +749,7 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, ADVANCE_BATCH(); } - if ( flags & (BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH) ) { + if ( buffers & (BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH) ) { BEGIN_BATCH( 6); OUT_BATCH( D_CMD ); OUT_BATCH( BR13 ); diff --git a/src/mesa/drivers/dri/i915/intel_ioctl.c b/src/mesa/drivers/dri/i915/intel_ioctl.c index d853036766..ede3b6378f 100644 --- a/src/mesa/drivers/dri/i915/intel_ioctl.c +++ b/src/mesa/drivers/dri/i915/intel_ioctl.c @@ -375,8 +375,7 @@ void intelFinish( GLcontext *ctx ) } -void intelClear(GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint cx, GLint cy, GLint cw, GLint ch) +void intelClear(GLcontext *ctx, GLbitfield mask) { intelContextPtr intel = INTEL_CONTEXT( ctx ); const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); @@ -429,13 +428,13 @@ void intelClear(GLcontext *ctx, GLbitfield mask, GLboolean all, swrast_mask |= (mask & BUFFER_BIT_ACCUM); if (blit_mask) - intelClearWithBlit( ctx, blit_mask, all, cx, cy, cw, ch ); + intelClearWithBlit( ctx, blit_mask, 0, 0, 0, 0, 0); if (tri_mask) - intel->vtbl.clear_with_tris( intel, tri_mask, all, cx, cy, cw, ch); + intel->vtbl.clear_with_tris( intel, tri_mask, 0, 0, 0, 0, 0); if (swrast_mask) - _swrast_Clear( ctx, swrast_mask, all, cx, cy, cw, ch ); + _swrast_Clear( ctx, swrast_mask ); } diff --git a/src/mesa/drivers/dri/i915/intel_ioctl.h b/src/mesa/drivers/dri/i915/intel_ioctl.h index 099a7e1a44..6ea47e462e 100644 --- a/src/mesa/drivers/dri/i915/intel_ioctl.h +++ b/src/mesa/drivers/dri/i915/intel_ioctl.h @@ -32,8 +32,7 @@ extern void intelWaitAgeLocked( intelContextPtr intel, int age, GLboolean unlock ); -extern void intelClear(GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint cx, GLint cy, GLint cw, GLint ch); +extern void intelClear(GLcontext *ctx, GLbitfield mask); extern void intelPageFlip( const __DRIdrawablePrivate *dpriv ); diff --git a/src/mesa/drivers/dri/i915tex/Makefile b/src/mesa/drivers/dri/i915tex/Makefile new file mode 100644 index 0000000000..94879d209f --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/Makefile @@ -0,0 +1,66 @@ + +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = i915tex_dri.so + +MINIGLX_SOURCES = server/intel_dri.c + +DRIVER_SOURCES = \ + i830_context.c \ + i830_metaops.c \ + i830_state.c \ + i830_texblend.c \ + i830_tex.c \ + i830_texstate.c \ + i830_vtbl.c \ + intel_render.c \ + intel_regions.c \ + intel_buffer_objects.c \ + intel_batchbuffer.c \ + intel_mipmap_tree.c \ + i915_tex_layout.c \ + intel_tex_image.c \ + intel_tex_subimage.c \ + intel_tex_copy.c \ + intel_tex_validate.c \ + intel_tex_format.c \ + intel_tex.c \ + intel_pixel.c \ + intel_pixel_copy.c \ + intel_pixel_read.c \ + intel_pixel_draw.c \ + intel_buffers.c \ + intel_blit.c \ + i915_tex.c \ + i915_texstate.c \ + i915_context.c \ + i915_debug.c \ + i915_fragprog.c \ + i915_metaops.c \ + i915_program.c \ + i915_state.c \ + i915_vtbl.c \ + intel_context.c \ + intel_ioctl.c \ + intel_rotate.c \ + intel_screen.c \ + intel_span.c \ + intel_state.c \ + intel_tris.c \ + intel_fbo.c \ + intel_depthstencil.c \ + intel_batchpool.c + +C_SOURCES = \ + $(COMMON_SOURCES) \ + $(COMMON_BM_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + + + +include ../Makefile.template + +symlinks: diff --git a/src/mesa/drivers/dri/i915tex/i830_context.c b/src/mesa/drivers/dri/i915tex/i830_context.c new file mode 100644 index 0000000000..2ff8621c42 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i830_context.c @@ -0,0 +1,104 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "i830_context.h" +#include "imports.h" +#include "texmem.h" +#include "intel_tex.h" +#include "tnl/tnl.h" +#include "tnl/t_vertex.h" +#include "tnl/t_context.h" +#include "utils.h" + +/*************************************** + * Mesa's Driver Functions + ***************************************/ + +static const struct dri_extension i830_extensions[] = { + {"GL_ARB_texture_env_crossbar", NULL}, + {NULL, NULL} +}; + + +static void +i830InitDriverFunctions(struct dd_function_table *functions) +{ + intelInitDriverFunctions(functions); + i830InitStateFuncs(functions); + i830InitTextureFuncs(functions); +} + + +GLboolean +i830CreateContext(const __GLcontextModes * mesaVis, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate) +{ + struct dd_function_table functions; + struct i830_context *i830 = CALLOC_STRUCT(i830_context); + struct intel_context *intel = &i830->intel; + GLcontext *ctx = &intel->ctx; + if (!i830) + return GL_FALSE; + + i830InitVtbl(i830); + i830InitDriverFunctions(&functions); + + if (!intelInitContext(intel, mesaVis, driContextPriv, + sharedContextPrivate, &functions)) { + FREE(i830); + return GL_FALSE; + } + + intel->ctx.Const.MaxTextureUnits = I830_TEX_UNITS; + intel->ctx.Const.MaxTextureImageUnits = I830_TEX_UNITS; + intel->ctx.Const.MaxTextureCoordUnits = I830_TEX_UNITS; + + /* Advertise the full hardware capabilities. The new memory + * manager should cope much better with overload situations: + */ + ctx->Const.MaxTextureLevels = 12; + ctx->Const.Max3DTextureLevels = 9; + ctx->Const.MaxCubeTextureLevels = 11; + ctx->Const.MaxTextureRectSize = (1 << 11); + ctx->Const.MaxTextureUnits = I830_TEX_UNITS; + + _tnl_init_vertices(ctx, ctx->Const.MaxArrayLockSize + 12, + 18 * sizeof(GLfloat)); + + intel->verts = TNL_CONTEXT(ctx)->clipspace.vertex_buf; + + driInitExtensions(ctx, i830_extensions, GL_FALSE); + + i830InitState(i830); + i830InitMetaFuncs(i830); + + _tnl_allow_vertex_fog(ctx, 1); + _tnl_allow_pixel_fog(ctx, 0); + + return GL_TRUE; +} diff --git a/src/mesa/drivers/dri/i915tex/i830_context.h b/src/mesa/drivers/dri/i915tex/i830_context.h new file mode 100644 index 0000000000..e5377b300a --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i830_context.h @@ -0,0 +1,208 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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. + * + **************************************************************************/ + +#ifndef I830CONTEXT_INC +#define I830CONTEXT_INC + +#include "intel_context.h" + +#define I830_FALLBACK_TEXTURE 0x1000 +#define I830_FALLBACK_COLORMASK 0x2000 +#define I830_FALLBACK_STENCIL 0x4000 +#define I830_FALLBACK_STIPPLE 0x8000 +#define I830_FALLBACK_LOGICOP 0x10000 + +#define I830_UPLOAD_CTX 0x1 +#define I830_UPLOAD_BUFFERS 0x2 +#define I830_UPLOAD_STIPPLE 0x4 +#define I830_UPLOAD_INVARIENT 0x8 +#define I830_UPLOAD_TEX(i) (0x10<<(i)) +#define I830_UPLOAD_TEXBLEND(i) (0x100<<(i)) +#define I830_UPLOAD_TEX_ALL (0x0f0) +#define I830_UPLOAD_TEXBLEND_ALL (0xf00) + +/* State structure offsets - these will probably disappear. + */ +#define I830_DESTREG_CBUFADDR0 0 +#define I830_DESTREG_CBUFADDR1 1 +#define I830_DESTREG_DBUFADDR0 2 +#define I830_DESTREG_DBUFADDR1 3 +#define I830_DESTREG_DV0 4 +#define I830_DESTREG_DV1 5 +#define I830_DESTREG_SENABLE 6 +#define I830_DESTREG_SR0 7 +#define I830_DESTREG_SR1 8 +#define I830_DESTREG_SR2 9 +#define I830_DEST_SETUP_SIZE 10 + +#define I830_CTXREG_STATE1 0 +#define I830_CTXREG_STATE2 1 +#define I830_CTXREG_STATE3 2 +#define I830_CTXREG_STATE4 3 +#define I830_CTXREG_STATE5 4 +#define I830_CTXREG_IALPHAB 5 +#define I830_CTXREG_STENCILTST 6 +#define I830_CTXREG_ENABLES_1 7 +#define I830_CTXREG_ENABLES_2 8 +#define I830_CTXREG_AA 9 +#define I830_CTXREG_FOGCOLOR 10 +#define I830_CTXREG_BLENDCOLOR0 11 +#define I830_CTXREG_BLENDCOLOR1 12 +#define I830_CTXREG_VF 13 +#define I830_CTXREG_VF2 14 +#define I830_CTXREG_MCSB0 15 +#define I830_CTXREG_MCSB1 16 +#define I830_CTX_SETUP_SIZE 17 + +#define I830_STPREG_ST0 0 +#define I830_STPREG_ST1 1 +#define I830_STP_SETUP_SIZE 2 + +#define I830_TEXREG_TM0LI 0 /* load immediate 2 texture map n */ +#define I830_TEXREG_TM0S1 1 +#define I830_TEXREG_TM0S2 2 +#define I830_TEXREG_TM0S3 3 +#define I830_TEXREG_TM0S4 4 +#define I830_TEXREG_MCS 5 /* _3DSTATE_MAP_COORD_SETS */ +#define I830_TEXREG_CUBE 6 /* _3DSTATE_MAP_SUBE */ +#define I830_TEX_SETUP_SIZE 7 + +#define I830_TEXBLEND_SIZE 12 /* (4 args + op) * 2 + COLOR_FACTOR */ + +struct i830_texture_object +{ + struct intel_texture_object intel; + GLuint Setup[I830_TEX_SETUP_SIZE]; +}; + +#define I830_TEX_UNITS 4 + +struct i830_hw_state +{ + GLuint Ctx[I830_CTX_SETUP_SIZE]; + GLuint Buffer[I830_DEST_SETUP_SIZE]; + GLuint Stipple[I830_STP_SETUP_SIZE]; + GLuint Tex[I830_TEX_UNITS][I830_TEX_SETUP_SIZE]; + GLuint TexBlend[I830_TEX_UNITS][I830_TEXBLEND_SIZE]; + GLuint TexBlendWordsUsed[I830_TEX_UNITS]; + + struct intel_region *draw_region; + struct intel_region *depth_region; + + /* Regions aren't actually that appropriate here as the memory may + * be from a PBO or FBO. Just use the buffer id. Will have to do + * this for draw and depth for FBO's... + */ + struct _DriBufferObject *tex_buffer[I830_TEX_UNITS]; + GLuint tex_offset[I830_TEX_UNITS]; + + GLuint emitted; /* I810_UPLOAD_* */ + GLuint active; +}; + +struct i830_context +{ + struct intel_context intel; + + GLuint lodbias_tm0s3[MAX_TEXTURE_UNITS]; + DECLARE_RENDERINPUTS(last_index_bitset); + + struct i830_hw_state meta, initial, state, *current; +}; + + + + +#define I830_STATECHANGE(i830, flag) \ +do { \ + INTEL_FIREVERTICES( &i830->intel ); \ + i830->state.emitted &= ~flag; \ +} while (0) + +#define I830_ACTIVESTATE(i830, flag, mode) \ +do { \ + INTEL_FIREVERTICES( &i830->intel ); \ + if (mode) \ + i830->state.active |= flag; \ + else \ + i830->state.active &= ~flag; \ +} while (0) + +/* i830_vtbl.c + */ +extern void i830InitVtbl(struct i830_context *i830); + +/* i830_context.c + */ +extern GLboolean +i830CreateContext(const __GLcontextModes * mesaVis, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate); + +/* i830_tex.c, i830_texstate.c + */ +extern void i830UpdateTextureState(struct intel_context *intel); + +extern void i830InitTextureFuncs(struct dd_function_table *functions); + +/* i830_texblend.c + */ +extern GLuint i830SetTexEnvCombine(struct i830_context *i830, + const struct gl_tex_env_combine_state + *combine, GLint blendUnit, GLuint texel_op, + GLuint * state, const GLfloat * factor); + +extern void i830EmitTextureBlend(struct i830_context *i830); + + +/* i830_state.c + */ +extern void i830InitStateFuncs(struct dd_function_table *functions); + +extern void i830EmitState(struct i830_context *i830); + +extern void i830InitState(struct i830_context *i830); + +/* i830_metaops.c + */ +extern void i830InitMetaFuncs(struct i830_context *i830); + +extern void +i830RotateWindow(struct intel_context *intel, __DRIdrawablePrivate * dPriv, + GLuint srcBuf); + +/*====================================================================== + * Inline conversion functions. These are better-typed than the + * macros used previously: + */ +static INLINE struct i830_context * +i830_context(GLcontext * ctx) +{ + return (struct i830_context *) ctx; +} + +#endif diff --git a/src/mesa/drivers/dri/i915tex/i830_metaops.c b/src/mesa/drivers/dri/i915tex/i830_metaops.c new file mode 100644 index 0000000000..c90f502222 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i830_metaops.c @@ -0,0 +1,485 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "glheader.h" +#include "enums.h" +#include "mtypes.h" +#include "macros.h" +#include "utils.h" + +#include "intel_screen.h" +#include "intel_batchbuffer.h" +#include "intel_ioctl.h" +#include "intel_regions.h" + +#include "i830_context.h" +#include "i830_reg.h" + +/* A large amount of state doesn't need to be uploaded. + */ +#define ACTIVE (I830_UPLOAD_INVARIENT | \ + I830_UPLOAD_CTX | \ + I830_UPLOAD_BUFFERS | \ + I830_UPLOAD_STIPPLE | \ + I830_UPLOAD_TEXBLEND(0) | \ + I830_UPLOAD_TEX(0)) + + +#define SET_STATE( i830, STATE ) \ +do { \ + i830->current->emitted &= ~ACTIVE; \ + i830->current = &i830->STATE; \ + i830->current->emitted &= ~ACTIVE; \ +} while (0) + + +static void +set_no_stencil_write(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + + /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE ) + */ + i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_STENCIL_WRITE; + i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_STENCIL_TEST; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_STENCIL_WRITE; + + i830->meta.emitted &= ~I830_UPLOAD_CTX; +} + +static void +set_no_depth_write(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + + /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) + */ + i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; + i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE; + + i830->meta.emitted &= ~I830_UPLOAD_CTX; +} + +/* Set depth unit to replace. + */ +static void +set_depth_replace(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + + /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) + * ctx->Driver.DepthMask( ctx, GL_TRUE ) + */ + i830->meta.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; + i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_DEPTH_TEST; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_DEPTH_WRITE; + + /* ctx->Driver.DepthFunc( ctx, GL_ALWAYS ) + */ + i830->meta.Ctx[I830_CTXREG_STATE3] &= ~DEPTH_TEST_FUNC_MASK; + i830->meta.Ctx[I830_CTXREG_STATE3] |= (ENABLE_DEPTH_TEST_FUNC | + DEPTH_TEST_FUNC + (COMPAREFUNC_ALWAYS)); + + i830->meta.emitted &= ~I830_UPLOAD_CTX; +} + + +/* Set stencil unit to replace always with the reference value. + */ +static void +set_stencil_replace(struct intel_context *intel, + GLuint s_mask, GLuint s_clear) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + + /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_TRUE ) + */ + i830->meta.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_STENCIL_WRITE; + + /* ctx->Driver.StencilMask( ctx, s_mask ) + */ + i830->meta.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; + i830->meta.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | + STENCIL_WRITE_MASK((s_mask & + 0xff))); + + /* ctx->Driver.StencilOp( ctx, GL_REPLACE, GL_REPLACE, GL_REPLACE ) + */ + i830->meta.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_OPS_MASK); + i830->meta.Ctx[I830_CTXREG_STENCILTST] |= + (ENABLE_STENCIL_PARMS | + STENCIL_FAIL_OP(STENCILOP_REPLACE) | + STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_REPLACE) | + STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_REPLACE)); + + /* ctx->Driver.StencilFunc( ctx, GL_ALWAYS, s_clear, ~0 ) + */ + i830->meta.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; + i830->meta.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | + STENCIL_TEST_MASK(0xff)); + + i830->meta.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_REF_VALUE_MASK | + ENABLE_STENCIL_TEST_FUNC_MASK); + i830->meta.Ctx[I830_CTXREG_STENCILTST] |= + (ENABLE_STENCIL_REF_VALUE | + ENABLE_STENCIL_TEST_FUNC | + STENCIL_REF_VALUE((s_clear & 0xff)) | + STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS)); + + + + i830->meta.emitted &= ~I830_UPLOAD_CTX; +} + + +static void +set_color_mask(struct intel_context *intel, GLboolean state) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + + const GLuint mask = ((1 << WRITEMASK_RED_SHIFT) | + (1 << WRITEMASK_GREEN_SHIFT) | + (1 << WRITEMASK_BLUE_SHIFT) | + (1 << WRITEMASK_ALPHA_SHIFT)); + + i830->meta.Ctx[I830_CTXREG_ENABLES_2] &= ~mask; + + if (state) { + i830->meta.Ctx[I830_CTXREG_ENABLES_2] |= + (i830->state.Ctx[I830_CTXREG_ENABLES_2] & mask); + } + + i830->meta.emitted &= ~I830_UPLOAD_CTX; +} + +/* Installs a one-stage passthrough texture blend pipeline. Is there + * more that can be done to turn off texturing? + */ +static void +set_no_texture(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + static const struct gl_tex_env_combine_state comb = { + GL_NONE, GL_NONE, + {GL_TEXTURE, 0, 0,}, {GL_TEXTURE, 0, 0,}, + {GL_SRC_COLOR, 0, 0}, {GL_SRC_ALPHA, 0, 0}, + 0, 0, 0, 0 + }; + + i830->meta.TexBlendWordsUsed[0] = + i830SetTexEnvCombine(i830, &comb, 0, TEXBLENDARG_TEXEL0, + i830->meta.TexBlend[0], NULL); + + i830->meta.TexBlend[0][0] |= TEXOP_LAST_STAGE; + i830->meta.emitted &= ~I830_UPLOAD_TEXBLEND(0); +} + +/* Set up a single element blend stage for 'replace' texturing with no + * funny ops. + */ +static void +set_texture_blend_replace(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + static const struct gl_tex_env_combine_state comb = { + GL_REPLACE, GL_REPLACE, + {GL_TEXTURE, GL_TEXTURE, GL_TEXTURE,}, {GL_TEXTURE, GL_TEXTURE, + GL_TEXTURE,}, + {GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_COLOR}, {GL_SRC_ALPHA, GL_SRC_ALPHA, + GL_SRC_ALPHA}, + 0, 0, 1, 1 + }; + + i830->meta.TexBlendWordsUsed[0] = + i830SetTexEnvCombine(i830, &comb, 0, TEXBLENDARG_TEXEL0, + i830->meta.TexBlend[0], NULL); + + i830->meta.TexBlend[0][0] |= TEXOP_LAST_STAGE; + i830->meta.emitted &= ~I830_UPLOAD_TEXBLEND(0); + +/* fprintf(stderr, "%s: TexBlendWordsUsed[0]: %d\n", */ +/* __FUNCTION__, i830->meta.TexBlendWordsUsed[0]); */ +} + + + +/* Set up an arbitary piece of memory as a rectangular texture + * (including the front or back buffer). + */ +static GLboolean +set_tex_rect_source(struct intel_context *intel, + struct _DriBufferObject *buffer, + GLuint offset, + GLuint pitch, GLuint height, GLenum format, GLenum type) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + GLuint *setup = i830->meta.Tex[0]; + GLint numLevels = 1; + GLuint textureFormat; + GLuint cpp; + + /* A full implementation of this would do the upload through + * glTexImage2d, and get all the conversion operations at that + * point. We are restricted, but still at least have access to the + * fragment program swizzle. + */ + switch (format) { + case GL_BGRA: + switch (type) { + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_BYTE: + textureFormat = (MAPSURF_32BIT | MT_32BIT_ARGB8888); + cpp = 4; + break; + default: + return GL_FALSE; + } + break; + case GL_RGBA: + switch (type) { + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_BYTE: + textureFormat = (MAPSURF_32BIT | MT_32BIT_ABGR8888); + cpp = 4; + break; + default: + return GL_FALSE; + } + break; + case GL_BGR: + switch (type) { + case GL_UNSIGNED_SHORT_5_6_5_REV: + textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); + cpp = 2; + break; + default: + return GL_FALSE; + } + break; + case GL_RGB: + switch (type) { + case GL_UNSIGNED_SHORT_5_6_5: + textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); + cpp = 2; + break; + default: + return GL_FALSE; + } + break; + + default: + return GL_FALSE; + } + + i830->meta.tex_buffer[0] = buffer; + i830->meta.tex_offset[0] = offset; + + setup[I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 | + (LOAD_TEXTURE_MAP0 << 0) | 4); + setup[I830_TEXREG_TM0S1] = (((height - 1) << TM0S1_HEIGHT_SHIFT) | + ((pitch - 1) << TM0S1_WIDTH_SHIFT) | + textureFormat); + setup[I830_TEXREG_TM0S2] = + (((((pitch * cpp) / 4) - + 1) << TM0S2_PITCH_SHIFT) | TM0S2_CUBE_FACE_ENA_MASK); + + setup[I830_TEXREG_TM0S3] = + ((((numLevels - + 1) * + 4) << TM0S3_MIN_MIP_SHIFT) | (FILTER_NEAREST << + TM0S3_MIN_FILTER_SHIFT) | + (MIPFILTER_NONE << TM0S3_MIP_FILTER_SHIFT) | (FILTER_NEAREST << + TM0S3_MAG_FILTER_SHIFT)); + + setup[I830_TEXREG_CUBE] = (_3DSTATE_MAP_CUBE | MAP_UNIT(0)); + + setup[I830_TEXREG_MCS] = (_3DSTATE_MAP_COORD_SET_CMD | + MAP_UNIT(0) | + ENABLE_TEXCOORD_PARAMS | + TEXCOORDS_ARE_IN_TEXELUNITS | + TEXCOORDTYPE_CARTESIAN | + ENABLE_ADDR_V_CNTL | + TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP) | + ENABLE_ADDR_U_CNTL | + TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP)); + + i830->meta.emitted &= ~I830_UPLOAD_TEX(0); + return GL_TRUE; +} + + +static void +set_vertex_format(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + i830->meta.Ctx[I830_CTXREG_VF] = (_3DSTATE_VFT0_CMD | + VFT0_TEX_COUNT(1) | + VFT0_DIFFUSE | VFT0_XYZ); + i830->meta.Ctx[I830_CTXREG_VF2] = (_3DSTATE_VFT1_CMD | + VFT1_TEX0_FMT(TEXCOORDFMT_2D) | + VFT1_TEX1_FMT(TEXCOORDFMT_2D) | + VFT1_TEX2_FMT(TEXCOORDFMT_2D) | + VFT1_TEX3_FMT(TEXCOORDFMT_2D)); + i830->meta.emitted &= ~I830_UPLOAD_CTX; +} + + +static void +meta_import_pixel_state(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + + i830->meta.Ctx[I830_CTXREG_STATE1] = i830->state.Ctx[I830_CTXREG_STATE1]; + i830->meta.Ctx[I830_CTXREG_STATE2] = i830->state.Ctx[I830_CTXREG_STATE2]; + i830->meta.Ctx[I830_CTXREG_STATE3] = i830->state.Ctx[I830_CTXREG_STATE3]; + i830->meta.Ctx[I830_CTXREG_STATE4] = i830->state.Ctx[I830_CTXREG_STATE4]; + i830->meta.Ctx[I830_CTXREG_STATE5] = i830->state.Ctx[I830_CTXREG_STATE5]; + i830->meta.Ctx[I830_CTXREG_IALPHAB] = i830->state.Ctx[I830_CTXREG_IALPHAB]; + i830->meta.Ctx[I830_CTXREG_STENCILTST] = + i830->state.Ctx[I830_CTXREG_STENCILTST]; + i830->meta.Ctx[I830_CTXREG_ENABLES_1] = + i830->state.Ctx[I830_CTXREG_ENABLES_1]; + i830->meta.Ctx[I830_CTXREG_ENABLES_2] = + i830->state.Ctx[I830_CTXREG_ENABLES_2]; + i830->meta.Ctx[I830_CTXREG_AA] = i830->state.Ctx[I830_CTXREG_AA]; + i830->meta.Ctx[I830_CTXREG_FOGCOLOR] = + i830->state.Ctx[I830_CTXREG_FOGCOLOR]; + i830->meta.Ctx[I830_CTXREG_BLENDCOLOR0] = + i830->state.Ctx[I830_CTXREG_BLENDCOLOR0]; + i830->meta.Ctx[I830_CTXREG_BLENDCOLOR1] = + i830->state.Ctx[I830_CTXREG_BLENDCOLOR1]; + i830->meta.Ctx[I830_CTXREG_MCSB0] = i830->state.Ctx[I830_CTXREG_MCSB0]; + i830->meta.Ctx[I830_CTXREG_MCSB1] = i830->state.Ctx[I830_CTXREG_MCSB1]; + + + i830->meta.Ctx[I830_CTXREG_STATE3] &= ~CULLMODE_MASK; + i830->meta.Stipple[I830_STPREG_ST1] &= ~ST1_ENABLE; + i830->meta.emitted &= ~I830_UPLOAD_CTX; + + + i830->meta.Buffer[I830_DESTREG_SENABLE] = + i830->state.Buffer[I830_DESTREG_SENABLE]; + i830->meta.Buffer[I830_DESTREG_SR1] = i830->state.Buffer[I830_DESTREG_SR1]; + i830->meta.Buffer[I830_DESTREG_SR2] = i830->state.Buffer[I830_DESTREG_SR2]; + i830->meta.emitted &= ~I830_UPLOAD_BUFFERS; +} + + + +/* Select between front and back draw buffers. + */ +static void +meta_draw_region(struct intel_context *intel, + struct intel_region *draw_region, + struct intel_region *depth_region) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + GLuint format; + GLuint depth_format = DEPTH_FRMT_16_FIXED; + + intel_region_release(&i830->meta.draw_region); + intel_region_reference(&i830->meta.draw_region, draw_region); + + intel_region_release(&i830->meta.depth_region); + intel_region_reference(&i830->meta.depth_region, depth_region); + + /* XXX FBO: grab code from i915 meta_draw_region */ + + /* XXX: 555 support? + */ + if (draw_region->cpp == 2) + format = DV_PF_565; + else + format = DV_PF_8888; + + if (depth_region) { + if (depth_region->cpp == 2) + depth_format = DEPTH_FRMT_16_FIXED; + else + depth_format = DEPTH_FRMT_24_FIXED_8_OTHER; + } + + i830->meta.Buffer[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | /* .5 */ + format | DEPTH_IS_Z | depth_format); + + i830->meta.emitted &= ~I830_UPLOAD_BUFFERS; +} + + +/* Operations where the 3D engine is decoupled temporarily from the + * current GL state and used for other purposes than simply rendering + * incoming triangles. + */ +static void +install_meta_state(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + memcpy(&i830->meta, &i830->initial, sizeof(i830->meta)); + + i830->meta.active = ACTIVE; + i830->meta.emitted = 0; + + SET_STATE(i830, meta); + set_vertex_format(intel); + set_no_texture(intel); +} + +static void +leave_meta_state(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + intel_region_release(&i830->meta.draw_region); + intel_region_release(&i830->meta.depth_region); +/* intel_region_release(intel, &i830->meta.tex_region[0]); */ + SET_STATE(i830, state); +} + + + +void +i830InitMetaFuncs(struct i830_context *i830) +{ + i830->intel.vtbl.install_meta_state = install_meta_state; + i830->intel.vtbl.leave_meta_state = leave_meta_state; + i830->intel.vtbl.meta_no_depth_write = set_no_depth_write; + i830->intel.vtbl.meta_no_stencil_write = set_no_stencil_write; + i830->intel.vtbl.meta_stencil_replace = set_stencil_replace; + i830->intel.vtbl.meta_depth_replace = set_depth_replace; + i830->intel.vtbl.meta_color_mask = set_color_mask; + i830->intel.vtbl.meta_no_texture = set_no_texture; + i830->intel.vtbl.meta_texture_blend_replace = set_texture_blend_replace; + i830->intel.vtbl.meta_tex_rect_source = set_tex_rect_source; + i830->intel.vtbl.meta_draw_region = meta_draw_region; + i830->intel.vtbl.meta_import_pixel_state = meta_import_pixel_state; +} diff --git a/src/mesa/drivers/dri/i915tex/i830_reg.h b/src/mesa/drivers/dri/i915tex/i830_reg.h new file mode 100644 index 0000000000..24ac524500 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i830_reg.h @@ -0,0 +1,641 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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. + * + **************************************************************************/ + + +#ifndef _I830_REG_H_ +#define _I830_REG_H_ + + +#include "intel_reg.h" + +#define I830_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value) + +#define _3DSTATE_AA_CMD (CMD_3D | (0x06<<24)) +#define AA_LINE_ECAAR_WIDTH_ENABLE (1<<16) +#define AA_LINE_ECAAR_WIDTH_0_5 0 +#define AA_LINE_ECAAR_WIDTH_1_0 (1<<14) +#define AA_LINE_ECAAR_WIDTH_2_0 (2<<14) +#define AA_LINE_ECAAR_WIDTH_4_0 (3<<14) +#define AA_LINE_REGION_WIDTH_ENABLE (1<<8) +#define AA_LINE_REGION_WIDTH_0_5 0 +#define AA_LINE_REGION_WIDTH_1_0 (1<<6) +#define AA_LINE_REGION_WIDTH_2_0 (2<<6) +#define AA_LINE_REGION_WIDTH_4_0 (3<<6) +#define AA_LINE_ENABLE ((1<<1) | 1) +#define AA_LINE_DISABLE (1<<1) + +#define _3DSTATE_BUF_INFO_CMD (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1) +/* Dword 1 */ +#define BUF_3D_ID_COLOR_BACK (0x3<<24) +#define BUF_3D_ID_DEPTH (0x7<<24) +#define BUF_3D_USE_FENCE (1<<23) +#define BUF_3D_TILED_SURFACE (1<<22) +#define BUF_3D_TILE_WALK_X 0 +#define BUF_3D_TILE_WALK_Y (1<<21) +#define BUF_3D_PITCH(x) (((x)/4)<<2) +/* Dword 2 */ +#define BUF_3D_ADDR(x) ((x) & ~0x3) + + +#define _3DSTATE_COLOR_FACTOR_CMD (CMD_3D | (0x1d<<24) | (0x1<<16)) + +#define _3DSTATE_COLOR_FACTOR_N_CMD(stage) (CMD_3D | (0x1d<<24) | \ + ((0x90+(stage))<<16)) + +#define _3DSTATE_CONST_BLEND_COLOR_CMD (CMD_3D | (0x1d<<24) | (0x88<<16)) + +#define _3DSTATE_DFLT_DIFFUSE_CMD (CMD_3D | (0x1d<<24) | (0x99<<16)) + +#define _3DSTATE_DFLT_SPEC_CMD (CMD_3D | (0x1d<<24) | (0x9a<<16)) + +#define _3DSTATE_DFLT_Z_CMD (CMD_3D | (0x1d<<24) | (0x98<<16)) + + +#define _3DSTATE_DST_BUF_VARS_CMD (CMD_3D | (0x1d<<24) | (0x85<<16)) +/* Dword 1 */ +#define DSTORG_HORT_BIAS(x) ((x)<<20) +#define DSTORG_VERT_BIAS(x) ((x)<<16) +#define COLOR_4_2_2_CHNL_WRT_ALL 0 +#define COLOR_4_2_2_CHNL_WRT_Y (1<<12) +#define COLOR_4_2_2_CHNL_WRT_CR (2<<12) +#define COLOR_4_2_2_CHNL_WRT_CB (3<<12) +#define COLOR_4_2_2_CHNL_WRT_CRCB (4<<12) +#define COLR_BUF_8BIT 0 +#define COLR_BUF_RGB555 (1<<8) +#define COLR_BUF_RGB565 (2<<8) +#define COLR_BUF_ARGB8888 (3<<8) +#define DEPTH_IS_Z 0 +#define DEPTH_IS_W (1<<6) +#define DEPTH_FRMT_16_FIXED 0 +#define DEPTH_FRMT_16_FLOAT (1<<2) +#define DEPTH_FRMT_24_FIXED_8_OTHER (2<<2) +#define DEPTH_FRMT_24_FLOAT_8_OTHER (3<<2) +#define VERT_LINE_STRIDE_1 (1<<1) +#define VERT_LINE_STRIDE_0 0 +#define VERT_LINE_STRIDE_OFS_1 1 +#define VERT_LINE_STRIDE_OFS_0 0 + + +#define _3DSTATE_DRAW_RECT_CMD (CMD_3D|(0x1d<<24)|(0x80<<16)|3) +/* Dword 1 */ +#define DRAW_RECT_DIS_DEPTH_OFS (1<<30) +#define DRAW_DITHER_OFS_X(x) ((x)<<26) +#define DRAW_DITHER_OFS_Y(x) ((x)<<24) +/* Dword 2 */ +#define DRAW_YMIN(x) ((x)<<16) +#define DRAW_XMIN(x) (x) +/* Dword 3 */ +#define DRAW_YMAX(x) ((x)<<16) +#define DRAW_XMAX(x) (x) +/* Dword 4 */ +#define DRAW_YORG(x) ((x)<<16) +#define DRAW_XORG(x) (x) + + +#define _3DSTATE_ENABLES_1_CMD (CMD_3D|(0x3<<24)) +#define ENABLE_LOGIC_OP_MASK ((1<<23)|(1<<22)) +#define ENABLE_LOGIC_OP ((1<<23)|(1<<22)) +#define DISABLE_LOGIC_OP (1<<23) +#define ENABLE_STENCIL_TEST ((1<<21)|(1<<20)) +#define DISABLE_STENCIL_TEST (1<<21) +#define ENABLE_DEPTH_BIAS ((1<<11)|(1<<10)) +#define DISABLE_DEPTH_BIAS (1<<11) +#define ENABLE_SPEC_ADD_MASK ((1<<9)|(1<<8)) +#define ENABLE_SPEC_ADD ((1<<9)|(1<<8)) +#define DISABLE_SPEC_ADD (1<<9) +#define ENABLE_DIS_FOG_MASK ((1<<7)|(1<<6)) +#define ENABLE_FOG ((1<<7)|(1<<6)) +#define DISABLE_FOG (1<<7) +#define ENABLE_DIS_ALPHA_TEST_MASK ((1<<5)|(1<<4)) +#define ENABLE_ALPHA_TEST ((1<<5)|(1<<4)) +#define DISABLE_ALPHA_TEST (1<<5) +#define ENABLE_DIS_CBLEND_MASK ((1<<3)|(1<<2)) +#define ENABLE_COLOR_BLEND ((1<<3)|(1<<2)) +#define DISABLE_COLOR_BLEND (1<<3) +#define ENABLE_DIS_DEPTH_TEST_MASK ((1<<1)|1) +#define ENABLE_DEPTH_TEST ((1<<1)|1) +#define DISABLE_DEPTH_TEST (1<<1) + +/* _3DSTATE_ENABLES_2, p138 */ +#define _3DSTATE_ENABLES_2_CMD (CMD_3D|(0x4<<24)) +#define ENABLE_STENCIL_WRITE ((1<<21)|(1<<20)) +#define DISABLE_STENCIL_WRITE (1<<21) +#define ENABLE_TEX_CACHE ((1<<17)|(1<<16)) +#define DISABLE_TEX_CACHE (1<<17) +#define ENABLE_DITHER ((1<<9)|(1<<8)) +#define DISABLE_DITHER (1<<9) +#define ENABLE_COLOR_MASK (1<<10) +#define WRITEMASK_ALPHA (1<<7) +#define WRITEMASK_ALPHA_SHIFT 7 +#define WRITEMASK_RED (1<<6) +#define WRITEMASK_RED_SHIFT 6 +#define WRITEMASK_GREEN (1<<5) +#define WRITEMASK_GREEN_SHIFT 5 +#define WRITEMASK_BLUE (1<<4) +#define WRITEMASK_BLUE_SHIFT 4 +#define WRITEMASK_MASK ((1<<4)|(1<<5)|(1<<6)|(1<<7)) +#define ENABLE_COLOR_WRITE ((1<<3)|(1<<2)) +#define DISABLE_COLOR_WRITE (1<<3) +#define ENABLE_DIS_DEPTH_WRITE_MASK 0x3 +#define ENABLE_DEPTH_WRITE ((1<<1)|1) +#define DISABLE_DEPTH_WRITE (1<<1) + +/* _3DSTATE_FOG_COLOR, p139 */ +#define _3DSTATE_FOG_COLOR_CMD (CMD_3D|(0x15<<24)) +#define FOG_COLOR_RED(x) ((x)<<16) +#define FOG_COLOR_GREEN(x) ((x)<<8) +#define FOG_COLOR_BLUE(x) (x) + +/* _3DSTATE_FOG_MODE, p140 */ +#define _3DSTATE_FOG_MODE_CMD (CMD_3D|(0x1d<<24)|(0x89<<16)|2) +/* Dword 1 */ +#define FOGFUNC_ENABLE (1<<31) +#define FOGFUNC_VERTEX 0 +#define FOGFUNC_PIXEL_EXP (1<<28) +#define FOGFUNC_PIXEL_EXP2 (2<<28) +#define FOGFUNC_PIXEL_LINEAR (3<<28) +#define FOGSRC_INDEX_Z (1<<27) +#define FOGSRC_INDEX_W ((1<<27)|(1<<25)) +#define FOG_LINEAR_CONST (1<<24) +#define FOG_CONST_1(x) ((x)<<4) +#define ENABLE_FOG_DENSITY (1<<23) +/* Dword 2 */ +#define FOG_CONST_2(x) (x) +/* Dword 3 */ +#define FOG_DENSITY(x) (x) + +/* _3DSTATE_INDEPENDENT_ALPHA_BLEND, p142 */ +#define _3DSTATE_INDPT_ALPHA_BLEND_CMD (CMD_3D|(0x0b<<24)) +#define ENABLE_INDPT_ALPHA_BLEND ((1<<23)|(1<<22)) +#define DISABLE_INDPT_ALPHA_BLEND (1<<23) +#define ALPHA_BLENDFUNC_MASK 0x3f0000 +#define ENABLE_ALPHA_BLENDFUNC (1<<21) +#define ABLENDFUNC_ADD 0 +#define ABLENDFUNC_SUB (1<<16) +#define ABLENDFUNC_RVSE_SUB (2<<16) +#define ABLENDFUNC_MIN (3<<16) +#define ABLENDFUNC_MAX (4<<16) +#define SRC_DST_ABLEND_MASK 0xfff +#define ENABLE_SRC_ABLEND_FACTOR (1<<11) +#define SRC_ABLEND_FACT(x) ((x)<<6) +#define ENABLE_DST_ABLEND_FACTOR (1<<5) +#define DST_ABLEND_FACT(x) (x) + + +/* _3DSTATE_MAP_BLEND_ARG, p152 */ +#define _3DSTATE_MAP_BLEND_ARG_CMD(stage) (CMD_3D|(0x0e<<24)|((stage)<<20)) + +#define TEXPIPE_COLOR 0 +#define TEXPIPE_ALPHA (1<<18) +#define TEXPIPE_KILL (2<<18) +#define TEXBLEND_ARG0 0 +#define TEXBLEND_ARG1 (1<<15) +#define TEXBLEND_ARG2 (2<<15) +#define TEXBLEND_ARG3 (3<<15) +#define TEXBLENDARG_MODIFY_PARMS (1<<6) +#define TEXBLENDARG_REPLICATE_ALPHA (1<<5) +#define TEXBLENDARG_INV_ARG (1<<4) +#define TEXBLENDARG_ONE 0 +#define TEXBLENDARG_FACTOR 0x01 +#define TEXBLENDARG_ACCUM 0x02 +#define TEXBLENDARG_DIFFUSE 0x03 +#define TEXBLENDARG_SPEC 0x04 +#define TEXBLENDARG_CURRENT 0x05 +#define TEXBLENDARG_TEXEL0 0x06 +#define TEXBLENDARG_TEXEL1 0x07 +#define TEXBLENDARG_TEXEL2 0x08 +#define TEXBLENDARG_TEXEL3 0x09 +#define TEXBLENDARG_FACTOR_N 0x0e + +/* _3DSTATE_MAP_BLEND_OP, p155 */ +#define _3DSTATE_MAP_BLEND_OP_CMD(stage) (CMD_3D|(0x0d<<24)|((stage)<<20)) +#if 0 +# define TEXPIPE_COLOR 0 +# define TEXPIPE_ALPHA (1<<18) +# define TEXPIPE_KILL (2<<18) +#endif +#define ENABLE_TEXOUTPUT_WRT_SEL (1<<17) +#define TEXOP_OUTPUT_CURRENT 0 +#define TEXOP_OUTPUT_ACCUM (1<<15) +#define ENABLE_TEX_CNTRL_STAGE ((1<<12)|(1<<11)) +#define DISABLE_TEX_CNTRL_STAGE (1<<12) +#define TEXOP_SCALE_SHIFT 9 +#define TEXOP_SCALE_1X (0 << TEXOP_SCALE_SHIFT) +#define TEXOP_SCALE_2X (1 << TEXOP_SCALE_SHIFT) +#define TEXOP_SCALE_4X (2 << TEXOP_SCALE_SHIFT) +#define TEXOP_MODIFY_PARMS (1<<8) +#define TEXOP_LAST_STAGE (1<<7) +#define TEXBLENDOP_KILLPIXEL 0x02 +#define TEXBLENDOP_ARG1 0x01 +#define TEXBLENDOP_ARG2 0x02 +#define TEXBLENDOP_MODULATE 0x03 +#define TEXBLENDOP_ADD 0x06 +#define TEXBLENDOP_ADDSIGNED 0x07 +#define TEXBLENDOP_BLEND 0x08 +#define TEXBLENDOP_BLEND_AND_ADD 0x09 +#define TEXBLENDOP_SUBTRACT 0x0a +#define TEXBLENDOP_DOT3 0x0b +#define TEXBLENDOP_DOT4 0x0c +#define TEXBLENDOP_MODULATE_AND_ADD 0x0d +#define TEXBLENDOP_MODULATE_2X_AND_ADD 0x0e +#define TEXBLENDOP_MODULATE_4X_AND_ADD 0x0f + +/* _3DSTATE_MAP_BUMP_TABLE, p160 TODO */ +/* _3DSTATE_MAP_COLOR_CHROMA_KEY, p161 TODO */ + +#define _3DSTATE_MAP_COORD_TRANSFORM ((3<<29)|(0x1d<<24)|(0x8c<<16)) +#define DISABLE_TEX_TRANSFORM (1<<28) +#define TEXTURE_SET(x) (x<<29) + +#define _3DSTATE_VERTEX_TRANSFORM ((3<<29)|(0x1d<<24)|(0x8b<<16)) +#define DISABLE_VIEWPORT_TRANSFORM (1<<31) +#define DISABLE_PERSPECTIVE_DIVIDE (1<<29) + + +/* _3DSTATE_MAP_COORD_SET_BINDINGS, p162 */ +#define _3DSTATE_MAP_COORD_SETBIND_CMD (CMD_3D|(0x1d<<24)|(0x02<<16)) +#define TEXBIND_MASK3 ((1<<15)|(1<<14)|(1<<13)|(1<<12)) +#define TEXBIND_MASK2 ((1<<11)|(1<<10)|(1<<9)|(1<<8)) +#define TEXBIND_MASK1 ((1<<7)|(1<<6)|(1<<5)|(1<<4)) +#define TEXBIND_MASK0 ((1<<3)|(1<<2)|(1<<1)|1) + +#define TEXBIND_SET3(x) ((x)<<12) +#define TEXBIND_SET2(x) ((x)<<8) +#define TEXBIND_SET1(x) ((x)<<4) +#define TEXBIND_SET0(x) (x) + +#define TEXCOORDSRC_KEEP 0 +#define TEXCOORDSRC_DEFAULT 0x01 +#define TEXCOORDSRC_VTXSET_0 0x08 +#define TEXCOORDSRC_VTXSET_1 0x09 +#define TEXCOORDSRC_VTXSET_2 0x0a +#define TEXCOORDSRC_VTXSET_3 0x0b +#define TEXCOORDSRC_VTXSET_4 0x0c +#define TEXCOORDSRC_VTXSET_5 0x0d +#define TEXCOORDSRC_VTXSET_6 0x0e +#define TEXCOORDSRC_VTXSET_7 0x0f + +#define MAP_UNIT(unit) ((unit)<<16) +#define MAP_UNIT_MASK (0x7<<16) + +/* _3DSTATE_MAP_COORD_SETS, p164 */ +#define _3DSTATE_MAP_COORD_SET_CMD (CMD_3D|(0x1c<<24)|(0x01<<19)) +#define ENABLE_TEXCOORD_PARAMS (1<<15) +#define TEXCOORDS_ARE_NORMAL (1<<14) +#define TEXCOORDS_ARE_IN_TEXELUNITS 0 +#define TEXCOORDTYPE_CARTESIAN 0 +#define TEXCOORDTYPE_HOMOGENEOUS (1<<11) +#define TEXCOORDTYPE_VECTOR (2<<11) +#define TEXCOORDTYPE_MASK (0x7<<11) +#define ENABLE_ADDR_V_CNTL (1<<7) +#define ENABLE_ADDR_U_CNTL (1<<3) +#define TEXCOORD_ADDR_V_MODE(x) ((x)<<4) +#define TEXCOORD_ADDR_U_MODE(x) (x) +#define TEXCOORDMODE_WRAP 0 +#define TEXCOORDMODE_MIRROR 1 +#define TEXCOORDMODE_CLAMP 2 +#define TEXCOORDMODE_WRAP_SHORTEST 3 +#define TEXCOORDMODE_CLAMP_BORDER 4 +#define TEXCOORD_ADDR_V_MASK 0x70 +#define TEXCOORD_ADDR_U_MASK 0x7 + +/* _3DSTATE_MAP_CUBE, p168 TODO */ +#define _3DSTATE_MAP_CUBE (CMD_3D|(0x1c<<24)|(0x0a<<19)) +#define CUBE_NEGX_ENABLE (1<<5) +#define CUBE_POSX_ENABLE (1<<4) +#define CUBE_NEGY_ENABLE (1<<3) +#define CUBE_POSY_ENABLE (1<<2) +#define CUBE_NEGZ_ENABLE (1<<1) +#define CUBE_POSZ_ENABLE (1<<0) + + +/* _3DSTATE_MODES_1, p190 */ +#define _3DSTATE_MODES_1_CMD (CMD_3D|(0x08<<24)) +#define BLENDFUNC_MASK 0x3f0000 +#define ENABLE_COLR_BLND_FUNC (1<<21) +#define BLENDFUNC_ADD 0 +#define BLENDFUNC_SUB (1<<16) +#define BLENDFUNC_RVRSE_SUB (2<<16) +#define BLENDFUNC_MIN (3<<16) +#define BLENDFUNC_MAX (4<<16) +#define SRC_DST_BLND_MASK 0xfff +#define ENABLE_SRC_BLND_FACTOR (1<<11) +#define ENABLE_DST_BLND_FACTOR (1<<5) +#define SRC_BLND_FACT(x) ((x)<<6) +#define DST_BLND_FACT(x) (x) + + +/* _3DSTATE_MODES_2, p192 */ +#define _3DSTATE_MODES_2_CMD (CMD_3D|(0x0f<<24)) +#define ENABLE_GLOBAL_DEPTH_BIAS (1<<22) +#define GLOBAL_DEPTH_BIAS(x) ((x)<<14) +#define ENABLE_ALPHA_TEST_FUNC (1<<13) +#define ENABLE_ALPHA_REF_VALUE (1<<8) +#define ALPHA_TEST_FUNC(x) ((x)<<9) +#define ALPHA_REF_VALUE(x) (x) + +#define ALPHA_TEST_REF_MASK 0x3fff + +/* _3DSTATE_MODES_3, p193 */ +#define _3DSTATE_MODES_3_CMD (CMD_3D|(0x02<<24)) +#define DEPTH_TEST_FUNC_MASK 0x1f0000 +#define ENABLE_DEPTH_TEST_FUNC (1<<20) +/* Uses COMPAREFUNC */ +#define DEPTH_TEST_FUNC(x) ((x)<<16) +#define ENABLE_ALPHA_SHADE_MODE (1<<11) +#define ENABLE_FOG_SHADE_MODE (1<<9) +#define ENABLE_SPEC_SHADE_MODE (1<<7) +#define ENABLE_COLOR_SHADE_MODE (1<<5) +#define ALPHA_SHADE_MODE(x) ((x)<<10) +#define FOG_SHADE_MODE(x) ((x)<<8) +#define SPEC_SHADE_MODE(x) ((x)<<6) +#define COLOR_SHADE_MODE(x) ((x)<<4) +#define CULLMODE_MASK 0xf +#define ENABLE_CULL_MODE (1<<3) +#define CULLMODE_BOTH 0 +#define CULLMODE_NONE 1 +#define CULLMODE_CW 2 +#define CULLMODE_CCW 3 + +#define SHADE_MODE_LINEAR 0 +#define SHADE_MODE_FLAT 0x1 + +/* _3DSTATE_MODES_4, p195 */ +#define _3DSTATE_MODES_4_CMD (CMD_3D|(0x16<<24)) +#define ENABLE_LOGIC_OP_FUNC (1<<23) +#define LOGIC_OP_FUNC(x) ((x)<<18) +#define LOGICOP_MASK ((1<<18)|(1<<19)|(1<<20)|(1<<21)) +#define LOGICOP_CLEAR 0 +#define LOGICOP_NOR 0x1 +#define LOGICOP_AND_INV 0x2 +#define LOGICOP_COPY_INV 0x3 +#define LOGICOP_AND_RVRSE 0x4 +#define LOGICOP_INV 0x5 +#define LOGICOP_XOR 0x6 +#define LOGICOP_NAND 0x7 +#define LOGICOP_AND 0x8 +#define LOGICOP_EQUIV 0x9 +#define LOGICOP_NOOP 0xa +#define LOGICOP_OR_INV 0xb +#define LOGICOP_COPY 0xc +#define LOGICOP_OR_RVRSE 0xd +#define LOGICOP_OR 0xe +#define LOGICOP_SET 0xf +#define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00)) +#define ENABLE_STENCIL_TEST_MASK (1<<17) +#define STENCIL_TEST_MASK(x) (((x)&0xff)<<8) +#define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff)) +#define ENABLE_STENCIL_WRITE_MASK (1<<16) +#define STENCIL_WRITE_MASK(x) ((x)&0xff) + +/* _3DSTATE_MODES_5, p196 */ +#define _3DSTATE_MODES_5_CMD (CMD_3D|(0x0c<<24)) +#define ENABLE_SPRITE_POINT_TEX (1<<23) +#define SPRITE_POINT_TEX_ON (1<<22) +#define SPRITE_POINT_TEX_OFF 0 +#define FLUSH_RENDER_CACHE (1<<18) +#define FLUSH_TEXTURE_CACHE (1<<16) +#define FIXED_LINE_WIDTH_MASK 0xfc00 +#define ENABLE_FIXED_LINE_WIDTH (1<<15) +#define FIXED_LINE_WIDTH(x) ((x)<<10) +#define FIXED_POINT_WIDTH_MASK 0x3ff +#define ENABLE_FIXED_POINT_WIDTH (1<<9) +#define FIXED_POINT_WIDTH(x) (x) + +/* _3DSTATE_RASTERIZATION_RULES, p198 */ +#define _3DSTATE_RASTER_RULES_CMD (CMD_3D|(0x07<<24)) +#define ENABLE_POINT_RASTER_RULE (1<<15) +#define OGL_POINT_RASTER_RULE (1<<13) +#define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8) +#define ENABLE_TRI_FAN_PROVOKE_VRTX (1<<5) +#define ENABLE_TRI_STRIP_PROVOKE_VRTX (1<<2) +#define LINE_STRIP_PROVOKE_VRTX(x) ((x)<<6) +#define TRI_FAN_PROVOKE_VRTX(x) ((x)<<3) +#define TRI_STRIP_PROVOKE_VRTX(x) (x) + +/* _3DSTATE_SCISSOR_ENABLE, p200 */ +#define _3DSTATE_SCISSOR_ENABLE_CMD (CMD_3D|(0x1c<<24)|(0x10<<19)) +#define ENABLE_SCISSOR_RECT ((1<<1) | 1) +#define DISABLE_SCISSOR_RECT (1<<1) + +/* _3DSTATE_SCISSOR_RECTANGLE_0, p201 */ +#define _3DSTATE_SCISSOR_RECT_0_CMD (CMD_3D|(0x1d<<24)|(0x81<<16)|1) +/* Dword 1 */ +#define SCISSOR_RECT_0_YMIN(x) ((x)<<16) +#define SCISSOR_RECT_0_XMIN(x) (x) +/* Dword 2 */ +#define SCISSOR_RECT_0_YMAX(x) ((x)<<16) +#define SCISSOR_RECT_0_XMAX(x) (x) + +/* _3DSTATE_STENCIL_TEST, p202 */ +#define _3DSTATE_STENCIL_TEST_CMD (CMD_3D|(0x09<<24)) +#define ENABLE_STENCIL_PARMS (1<<23) +#define STENCIL_OPS_MASK (0xffc000) +#define STENCIL_FAIL_OP(x) ((x)<<20) +#define STENCIL_PASS_DEPTH_FAIL_OP(x) ((x)<<17) +#define STENCIL_PASS_DEPTH_PASS_OP(x) ((x)<<14) + +#define ENABLE_STENCIL_TEST_FUNC_MASK ((1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)) +#define ENABLE_STENCIL_TEST_FUNC (1<<13) +/* Uses COMPAREFUNC */ +#define STENCIL_TEST_FUNC(x) ((x)<<9) +#define STENCIL_REF_VALUE_MASK ((1<<8)|0xff) +#define ENABLE_STENCIL_REF_VALUE (1<<8) +#define STENCIL_REF_VALUE(x) (x) + +/* _3DSTATE_VERTEX_FORMAT, p204 */ +#define _3DSTATE_VFT0_CMD (CMD_3D|(0x05<<24)) +#define VFT0_POINT_WIDTH (1<<12) +#define VFT0_TEX_COUNT_MASK (7<<8) +#define VFT0_TEX_COUNT_SHIFT 8 +#define VFT0_TEX_COUNT(x) ((x)<<8) +#define VFT0_SPEC (1<<7) +#define VFT0_DIFFUSE (1<<6) +#define VFT0_DEPTH_OFFSET (1<<5) +#define VFT0_XYZ (1<<1) +#define VFT0_XYZW (2<<1) +#define VFT0_XY (3<<1) +#define VFT0_XYW (4<<1) +#define VFT0_XYZW_MASK (7<<1) + +/* _3DSTATE_VERTEX_FORMAT_2, p206 */ +#define _3DSTATE_VFT1_CMD (CMD_3D|(0x0a<<24)) +#define VFT1_TEX7_FMT(x) ((x)<<14) +#define VFT1_TEX6_FMT(x) ((x)<<12) +#define VFT1_TEX5_FMT(x) ((x)<<10) +#define VFT1_TEX4_FMT(x) ((x)<<8) +#define VFT1_TEX3_FMT(x) ((x)<<6) +#define VFT1_TEX2_FMT(x) ((x)<<4) +#define VFT1_TEX1_FMT(x) ((x)<<2) +#define VFT1_TEX0_FMT(x) (x) +#define VFT1_TEX0_MASK 3 +#define VFT1_TEX1_SHIFT 2 +#define TEXCOORDFMT_2D 0 +#define TEXCOORDFMT_3D 1 +#define TEXCOORDFMT_4D 2 +#define TEXCOORDFMT_1D 3 + +/*New stuff picked up along the way */ + +#define MLC_LOD_BIAS_MASK ((1<<7)-1) + + +/* _3DSTATE_VERTEX_TRANSFORM, p207 */ +#define _3DSTATE_VERTEX_TRANS_CMD (CMD_3D|(0x1d<<24)|(0x8b<<16)|0) +#define _3DSTATE_VERTEX_TRANS_MTX_CMD (CMD_3D|(0x1d<<24)|(0x8b<<16)|6) +/* Dword 1 */ +#define ENABLE_VIEWPORT_TRANSFORM ((1<<31)|(1<<30)) +#define DISABLE_VIEWPORT_TRANSFORM (1<<31) +#define ENABLE_PERSP_DIVIDE ((1<<29)|(1<<28)) +#define DISABLE_PERSP_DIVIDE (1<<29) +#define VRTX_TRANS_LOAD_MATRICES 0x7421 +#define VRTX_TRANS_NO_LOAD_MATRICES 0x0000 +/* Dword 2 -> 7 are matrix elements */ + +/* _3DSTATE_W_STATE, p209 */ +#define _3DSTATE_W_STATE_CMD (CMD_3D|(0x1d<<24)|(0x8d<<16)|1) +/* Dword 1 */ +#define MAGIC_W_STATE_DWORD1 0x00000008 +/* Dword 2 */ +#define WFAR_VALUE(x) (x) + + +/* Stipple command, carried over from the i810, apparently: + */ +#define _3DSTATE_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) +#define ST1_ENABLE (1<<16) +#define ST1_MASK (0xffff) + + + +#define _3DSTATE_LOAD_STATE_IMMEDIATE_2 ((0x3<<29)|(0x1d<<24)|(0x03<<16)) +#define LOAD_TEXTURE_MAP0 (1<<11) +#define LOAD_GLOBAL_COLOR_FACTOR (1<<6) + +#define TM0S0_ADDRESS_MASK 0xfffffffc +#define TM0S0_USE_FENCE (1<<1) + +#define TM0S1_HEIGHT_SHIFT 21 +#define TM0S1_WIDTH_SHIFT 10 +#define TM0S1_PALETTE_SELECT (1<<9) +#define TM0S1_MAPSURF_FORMAT_MASK (0x7 << 6) +#define TM0S1_MAPSURF_FORMAT_SHIFT 6 +#define MAPSURF_8BIT_INDEXED (0<<6) +#define MAPSURF_8BIT (1<<6) +#define MAPSURF_16BIT (2<<6) +#define MAPSURF_32BIT (3<<6) +#define MAPSURF_411 (4<<6) +#define MAPSURF_422 (5<<6) +#define MAPSURF_COMPRESSED (6<<6) +#define MAPSURF_4BIT_INDEXED (7<<6) +#define TM0S1_MT_FORMAT_MASK (0x7 << 3) +#define TM0S1_MT_FORMAT_SHIFT 3 +#define MT_4BIT_IDX_ARGB8888 (7<<3) /* SURFACE_4BIT_INDEXED */ +#define MT_8BIT_IDX_RGB565 (0<<3) /* SURFACE_8BIT_INDEXED */ +#define MT_8BIT_IDX_ARGB1555 (1<<3) +#define MT_8BIT_IDX_ARGB4444 (2<<3) +#define MT_8BIT_IDX_AY88 (3<<3) +#define MT_8BIT_IDX_ABGR8888 (4<<3) +#define MT_8BIT_IDX_BUMP_88DVDU (5<<3) +#define MT_8BIT_IDX_BUMP_655LDVDU (6<<3) +#define MT_8BIT_IDX_ARGB8888 (7<<3) +#define MT_8BIT_I8 (0<<3) /* SURFACE_8BIT */ +#define MT_8BIT_L8 (1<<3) +#define MT_16BIT_RGB565 (0<<3) /* SURFACE_16BIT */ +#define MT_16BIT_ARGB1555 (1<<3) +#define MT_16BIT_ARGB4444 (2<<3) +#define MT_16BIT_AY88 (3<<3) +#define MT_16BIT_DIB_ARGB1555_8888 (4<<3) +#define MT_16BIT_BUMP_88DVDU (5<<3) +#define MT_16BIT_BUMP_655LDVDU (6<<3) +#define MT_16BIT_DIB_RGB565_8888 (7<<3) +#define MT_32BIT_ARGB8888 (0<<3) /* SURFACE_32BIT */ +#define MT_32BIT_ABGR8888 (1<<3) +#define MT_32BIT_BUMP_XLDVDU_8888 (6<<3) +#define MT_32BIT_DIB_8888 (7<<3) +#define MT_411_YUV411 (0<<3) /* SURFACE_411 */ +#define MT_422_YCRCB_SWAPY (0<<3) /* SURFACE_422 */ +#define MT_422_YCRCB_NORMAL (1<<3) +#define MT_422_YCRCB_SWAPUV (2<<3) +#define MT_422_YCRCB_SWAPUVY (3<<3) +#define MT_COMPRESS_DXT1 (0<<3) /* SURFACE_COMPRESSED */ +#define MT_COMPRESS_DXT2_3 (1<<3) +#define MT_COMPRESS_DXT4_5 (2<<3) +#define MT_COMPRESS_FXT1 (3<<3) +#define TM0S1_COLORSPACE_CONVERSION (1 << 2) +#define TM0S1_TILED_SURFACE (1 << 1) +#define TM0S1_TILE_WALK (1 << 0) + +#define TM0S2_PITCH_SHIFT 21 +#define TM0S2_CUBE_FACE_ENA_SHIFT 15 +#define TM0S2_CUBE_FACE_ENA_MASK (1<<15) +#define TM0S2_MAP_FORMAT (1<<14) +#define TM0S2_VERTICAL_LINE_STRIDE (1<<13) +#define TM0S2_VERITCAL_LINE_STRIDE_OFF (1<<12) +#define TM0S2_OUTPUT_CHAN_SHIFT 10 +#define TM0S2_OUTPUT_CHAN_MASK (3<<10) + +#define TM0S3_MIP_FILTER_MASK (0x3<<30) +#define TM0S3_MIP_FILTER_SHIFT 30 +#define MIPFILTER_NONE 0 +#define MIPFILTER_NEAREST 1 +#define MIPFILTER_LINEAR 3 +#define TM0S3_MAG_FILTER_MASK (0x3<<28) +#define TM0S3_MAG_FILTER_SHIFT 28 +#define TM0S3_MIN_FILTER_MASK (0x3<<26) +#define TM0S3_MIN_FILTER_SHIFT 26 +#define FILTER_NEAREST 0 +#define FILTER_LINEAR 1 +#define FILTER_ANISOTROPIC 2 + +#define TM0S3_LOD_BIAS_SHIFT 17 +#define TM0S3_LOD_BIAS_MASK (0x1ff<<17) +#define TM0S3_MAX_MIP_SHIFT 9 +#define TM0S3_MAX_MIP_MASK (0xff<<9) +#define TM0S3_MIN_MIP_SHIFT 3 +#define TM0S3_MIN_MIP_MASK (0x3f<<3) +#define TM0S3_KILL_PIXEL (1<<2) +#define TM0S3_KEYED_FILTER (1<<1) +#define TM0S3_CHROMA_KEY (1<<0) + + +/* _3DSTATE_MAP_TEXEL_STREAM, p188 */ +#define _3DSTATE_MAP_TEX_STREAM_CMD (CMD_3D|(0x1c<<24)|(0x05<<19)) +#define DISABLE_TEX_STREAM_BUMP (1<<12) +#define ENABLE_TEX_STREAM_BUMP ((1<<12)|(1<<11)) +#define TEX_MODIFY_UNIT_0 0 +#define TEX_MODIFY_UNIT_1 (1<<8) +#define ENABLE_TEX_STREAM_COORD_SET (1<<7) +#define TEX_STREAM_COORD_SET(x) ((x)<<4) +#define ENABLE_TEX_STREAM_MAP_IDX (1<<3) +#define TEX_STREAM_MAP_IDX(x) (x) + + +#define MI_FLUSH ((0<<29)|(4<<23)) +#define FLUSH_MAP_CACHE (1<<0) + +#endif diff --git a/src/mesa/drivers/dri/i915tex/i830_state.c b/src/mesa/drivers/dri/i915tex/i830_state.c new file mode 100644 index 0000000000..83d82882a6 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i830_state.c @@ -0,0 +1,1113 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "glheader.h" +#include "context.h" +#include "macros.h" +#include "enums.h" +#include "dd.h" + +#include "texmem.h" + +#include "intel_screen.h" +#include "intel_batchbuffer.h" +#include "intel_fbo.h" + +#include "i830_context.h" +#include "i830_reg.h" + +#define FILE_DEBUG_FLAG DEBUG_STATE + +static void +i830StencilFuncSeparate(GLcontext * ctx, GLenum face, GLenum func, GLint ref, + GLuint mask) +{ + struct i830_context *i830 = i830_context(ctx); + int test = intel_translate_compare_func(func); + + mask = mask & 0xff; + + DBG("%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(func), ref, mask); + + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; + i830->state.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | + STENCIL_TEST_MASK(mask)); + i830->state.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_REF_VALUE_MASK | + ENABLE_STENCIL_TEST_FUNC_MASK); + i830->state.Ctx[I830_CTXREG_STENCILTST] |= (ENABLE_STENCIL_REF_VALUE | + ENABLE_STENCIL_TEST_FUNC | + STENCIL_REF_VALUE(ref) | + STENCIL_TEST_FUNC(test)); +} + +static void +i830StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask) +{ + struct i830_context *i830 = i830_context(ctx); + + DBG("%s : mask 0x%x\n", __FUNCTION__, mask); + + mask = mask & 0xff; + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; + i830->state.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | + STENCIL_WRITE_MASK(mask)); +} + +static void +i830StencilOpSeparate(GLcontext * ctx, GLenum face, GLenum fail, GLenum zfail, + GLenum zpass) +{ + struct i830_context *i830 = i830_context(ctx); + int fop, dfop, dpop; + + DBG("%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(fail), + _mesa_lookup_enum_by_nr(zfail), + _mesa_lookup_enum_by_nr(zpass)); + + fop = 0; + dfop = 0; + dpop = 0; + + switch (fail) { + case GL_KEEP: + fop = STENCILOP_KEEP; + break; + case GL_ZERO: + fop = STENCILOP_ZERO; + break; + case GL_REPLACE: + fop = STENCILOP_REPLACE; + break; + case GL_INCR: + fop = STENCILOP_INCRSAT; + break; + case GL_DECR: + fop = STENCILOP_DECRSAT; + break; + case GL_INCR_WRAP: + fop = STENCILOP_INCR; + break; + case GL_DECR_WRAP: + fop = STENCILOP_DECR; + break; + case GL_INVERT: + fop = STENCILOP_INVERT; + break; + default: + break; + } + switch (zfail) { + case GL_KEEP: + dfop = STENCILOP_KEEP; + break; + case GL_ZERO: + dfop = STENCILOP_ZERO; + break; + case GL_REPLACE: + dfop = STENCILOP_REPLACE; + break; + case GL_INCR: + dfop = STENCILOP_INCRSAT; + break; + case GL_DECR: + dfop = STENCILOP_DECRSAT; + break; + case GL_INCR_WRAP: + dfop = STENCILOP_INCR; + break; + case GL_DECR_WRAP: + dfop = STENCILOP_DECR; + break; + case GL_INVERT: + dfop = STENCILOP_INVERT; + break; + default: + break; + } + switch (zpass) { + case GL_KEEP: + dpop = STENCILOP_KEEP; + break; + case GL_ZERO: + dpop = STENCILOP_ZERO; + break; + case GL_REPLACE: + dpop = STENCILOP_REPLACE; + break; + case GL_INCR: + dpop = STENCILOP_INCRSAT; + break; + case GL_DECR: + dpop = STENCILOP_DECRSAT; + break; + case GL_INCR_WRAP: + dpop = STENCILOP_INCR; + break; + case GL_DECR_WRAP: + dpop = STENCILOP_DECR; + break; + case GL_INVERT: + dpop = STENCILOP_INVERT; + break; + default: + break; + } + + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_OPS_MASK); + i830->state.Ctx[I830_CTXREG_STENCILTST] |= (ENABLE_STENCIL_PARMS | + STENCIL_FAIL_OP(fop) | + STENCIL_PASS_DEPTH_FAIL_OP + (dfop) | + STENCIL_PASS_DEPTH_PASS_OP + (dpop)); +} + +static void +i830AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref) +{ + struct i830_context *i830 = i830_context(ctx); + int test = intel_translate_compare_func(func); + GLubyte refByte; + GLuint refInt; + + UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref); + refInt = (GLuint) refByte; + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_STATE2] &= ~ALPHA_TEST_REF_MASK; + i830->state.Ctx[I830_CTXREG_STATE2] |= (ENABLE_ALPHA_TEST_FUNC | + ENABLE_ALPHA_REF_VALUE | + ALPHA_TEST_FUNC(test) | + ALPHA_REF_VALUE(refInt)); +} + +/** + * Makes sure that the proper enables are set for LogicOp, Independant Alpha + * Blend, and Blending. It needs to be called from numerous places where we + * could change the LogicOp or Independant Alpha Blend without subsequent + * calls to glEnable. + * + * \todo + * This function is substantially different from the old i830-specific driver. + * I'm not sure which is correct. + */ +static void +i830EvalLogicOpBlendState(GLcontext * ctx) +{ + struct i830_context *i830 = i830_context(ctx); + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + + if (ctx->Color._LogicOpEnabled) { + i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND | + ENABLE_LOGIC_OP_MASK); + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= (DISABLE_COLOR_BLEND | + ENABLE_LOGIC_OP); + } + else if (ctx->Color.BlendEnabled) { + i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND | + ENABLE_LOGIC_OP_MASK); + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= (ENABLE_COLOR_BLEND | + DISABLE_LOGIC_OP); + } + else { + i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND | + ENABLE_LOGIC_OP_MASK); + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= (DISABLE_COLOR_BLEND | + DISABLE_LOGIC_OP); + } +} + +static void +i830BlendColor(GLcontext * ctx, const GLfloat color[4]) +{ + struct i830_context *i830 = i830_context(ctx); + GLubyte r, g, b, a; + + DBG("%s\n", __FUNCTION__); + + UNCLAMPED_FLOAT_TO_UBYTE(r, color[RCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(g, color[GCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]); + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_BLENDCOLOR1] = + (a << 24) | (r << 16) | (g << 8) | b; +} + +/** + * Sets both the blend equation (called "function" in i830 docs) and the + * blend function (called "factor" in i830 docs). This is done in a single + * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX) + * change the interpretation of the blend function. + */ +static void +i830_set_blend_state(GLcontext * ctx) +{ + struct i830_context *i830 = i830_context(ctx); + int funcA; + int funcRGB; + int eqnA; + int eqnRGB; + int iab; + int s1; + + + funcRGB = + SRC_BLND_FACT(intel_translate_blend_factor(ctx->Color.BlendSrcRGB)) + | DST_BLND_FACT(intel_translate_blend_factor(ctx->Color.BlendDstRGB)); + + switch (ctx->Color.BlendEquationRGB) { + case GL_FUNC_ADD: + eqnRGB = BLENDFUNC_ADD; + break; + case GL_MIN: + eqnRGB = BLENDFUNC_MIN; + funcRGB = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); + break; + case GL_MAX: + eqnRGB = BLENDFUNC_MAX; + funcRGB = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); + break; + case GL_FUNC_SUBTRACT: + eqnRGB = BLENDFUNC_SUB; + break; + case GL_FUNC_REVERSE_SUBTRACT: + eqnRGB = BLENDFUNC_RVRSE_SUB; + break; + default: + fprintf(stderr, "[%s:%u] Invalid RGB blend equation (0x%04x).\n", + __FUNCTION__, __LINE__, ctx->Color.BlendEquationRGB); + return; + } + + + funcA = SRC_ABLEND_FACT(intel_translate_blend_factor(ctx->Color.BlendSrcA)) + | DST_ABLEND_FACT(intel_translate_blend_factor(ctx->Color.BlendDstA)); + + switch (ctx->Color.BlendEquationA) { + case GL_FUNC_ADD: + eqnA = BLENDFUNC_ADD; + break; + case GL_MIN: + eqnA = BLENDFUNC_MIN; + funcA = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); + break; + case GL_MAX: + eqnA = BLENDFUNC_MAX; + funcA = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); + break; + case GL_FUNC_SUBTRACT: + eqnA = BLENDFUNC_SUB; + break; + case GL_FUNC_REVERSE_SUBTRACT: + eqnA = BLENDFUNC_RVRSE_SUB; + break; + default: + fprintf(stderr, "[%s:%u] Invalid alpha blend equation (0x%04x).\n", + __FUNCTION__, __LINE__, ctx->Color.BlendEquationA); + return; + } + + iab = eqnA | funcA + | _3DSTATE_INDPT_ALPHA_BLEND_CMD + | ENABLE_SRC_ABLEND_FACTOR | ENABLE_DST_ABLEND_FACTOR + | ENABLE_ALPHA_BLENDFUNC; + s1 = eqnRGB | funcRGB + | _3DSTATE_MODES_1_CMD + | ENABLE_SRC_BLND_FACTOR | ENABLE_DST_BLND_FACTOR + | ENABLE_COLR_BLND_FUNC; + + if ((eqnA | funcA) != (eqnRGB | funcRGB)) + iab |= ENABLE_INDPT_ALPHA_BLEND; + else + iab |= DISABLE_INDPT_ALPHA_BLEND; + + if (iab != i830->state.Ctx[I830_CTXREG_IALPHAB] || + s1 != i830->state.Ctx[I830_CTXREG_STATE1]) { + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_IALPHAB] = iab; + i830->state.Ctx[I830_CTXREG_STATE1] = s1; + } + + /* This will catch a logicop blend equation. It will also ensure + * independant alpha blend is really in the correct state (either enabled + * or disabled) if blending is already enabled. + */ + + i830EvalLogicOpBlendState(ctx); + + if (0) { + fprintf(stderr, + "[%s:%u] STATE1: 0x%08x IALPHAB: 0x%08x blend is %sabled\n", + __FUNCTION__, __LINE__, i830->state.Ctx[I830_CTXREG_STATE1], + i830->state.Ctx[I830_CTXREG_IALPHAB], + (ctx->Color.BlendEnabled) ? "en" : "dis"); + } +} + + +static void +i830BlendEquationSeparate(GLcontext * ctx, GLenum modeRGB, GLenum modeA) +{ + DBG("%s -> %s, %s\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(modeRGB), + _mesa_lookup_enum_by_nr(modeA)); + + (void) modeRGB; + (void) modeA; + i830_set_blend_state(ctx); +} + + +static void +i830BlendFuncSeparate(GLcontext * ctx, GLenum sfactorRGB, + GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA) +{ + DBG("%s -> RGB(%s, %s) A(%s, %s)\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(sfactorRGB), + _mesa_lookup_enum_by_nr(dfactorRGB), + _mesa_lookup_enum_by_nr(sfactorA), + _mesa_lookup_enum_by_nr(dfactorA)); + + (void) sfactorRGB; + (void) dfactorRGB; + (void) sfactorA; + (void) dfactorA; + i830_set_blend_state(ctx); +} + + + +static void +i830DepthFunc(GLcontext * ctx, GLenum func) +{ + struct i830_context *i830 = i830_context(ctx); + int test = intel_translate_compare_func(func); + + DBG("%s\n", __FUNCTION__); + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_STATE3] &= ~DEPTH_TEST_FUNC_MASK; + i830->state.Ctx[I830_CTXREG_STATE3] |= (ENABLE_DEPTH_TEST_FUNC | + DEPTH_TEST_FUNC(test)); +} + +static void +i830DepthMask(GLcontext * ctx, GLboolean flag) +{ + struct i830_context *i830 = i830_context(ctx); + + DBG("%s flag (%d)\n", __FUNCTION__, flag); + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + + i830->state.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; + + if (flag && ctx->Depth.Test) + i830->state.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_DEPTH_WRITE; + else + i830->state.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE; +} + +/* ============================================================= + * Polygon stipple + * + * The i830 supports a 4x4 stipple natively, GL wants 32x32. + * Fortunately stipple is usually a repeating pattern. + */ +static void +i830PolygonStipple(GLcontext * ctx, const GLubyte * mask) +{ + struct i830_context *i830 = i830_context(ctx); + const GLubyte *m = mask; + GLubyte p[4]; + int i, j, k; + int active = (ctx->Polygon.StippleFlag && + i830->intel.reduced_primitive == GL_TRIANGLES); + GLuint newMask; + + if (active) { + I830_STATECHANGE(i830, I830_UPLOAD_STIPPLE); + i830->state.Stipple[I830_STPREG_ST1] &= ~ST1_ENABLE; + } + + p[0] = mask[12] & 0xf; + p[0] |= p[0] << 4; + p[1] = mask[8] & 0xf; + p[1] |= p[1] << 4; + p[2] = mask[4] & 0xf; + p[2] |= p[2] << 4; + p[3] = mask[0] & 0xf; + p[3] |= p[3] << 4; + + for (k = 0; k < 8; k++) + for (j = 3; j >= 0; j--) + for (i = 0; i < 4; i++, m++) + if (*m != p[j]) { + i830->intel.hw_stipple = 0; + return; + } + + newMask = (((p[0] & 0xf) << 0) | + ((p[1] & 0xf) << 4) | + ((p[2] & 0xf) << 8) | ((p[3] & 0xf) << 12)); + + + if (newMask == 0xffff || newMask == 0x0) { + /* this is needed to make conform pass */ + i830->intel.hw_stipple = 0; + return; + } + + i830->state.Stipple[I830_STPREG_ST1] &= ~0xffff; + i830->state.Stipple[I830_STPREG_ST1] |= newMask; + i830->intel.hw_stipple = 1; + + if (active) + i830->state.Stipple[I830_STPREG_ST1] |= ST1_ENABLE; +} + + +/* ============================================================= + * Hardware clipping + */ +static void +i830Scissor(GLcontext * ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + struct i830_context *i830 = i830_context(ctx); + int x1, y1, x2, y2; + + if (!ctx->DrawBuffer) + return; + + DBG("%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); + + if (ctx->DrawBuffer->Name == 0) { + x1 = x; + y1 = ctx->DrawBuffer->Height - (y + h); + x2 = x + w - 1; + y2 = y1 + h - 1; + DBG("%s %d..%d,%d..%d (inverted)\n", __FUNCTION__, x1, x2, y1, y2); + } + else { + /* FBO - not inverted + */ + x1 = x; + y1 = y; + x2 = x + w - 1; + y2 = y + h - 1; + DBG("%s %d..%d,%d..%d (not inverted)\n", __FUNCTION__, x1, x2, y1, y2); + } + + x1 = CLAMP(x1, 0, ctx->DrawBuffer->Width - 1); + y1 = CLAMP(y1, 0, ctx->DrawBuffer->Height - 1); + x2 = CLAMP(x2, 0, ctx->DrawBuffer->Width - 1); + y2 = CLAMP(y2, 0, ctx->DrawBuffer->Height - 1); + + DBG("%s %d..%d,%d..%d (clamped)\n", __FUNCTION__, x1, x2, y1, y2); + + I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS); + i830->state.Buffer[I830_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff); + i830->state.Buffer[I830_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff); +} + +static void +i830LogicOp(GLcontext * ctx, GLenum opcode) +{ + struct i830_context *i830 = i830_context(ctx); + int tmp = intel_translate_logic_op(opcode); + + DBG("%s\n", __FUNCTION__); + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_STATE4] &= ~LOGICOP_MASK; + i830->state.Ctx[I830_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp); +} + + + +static void +i830CullFaceFrontFace(GLcontext * ctx, GLenum unused) +{ + struct i830_context *i830 = i830_context(ctx); + GLuint mode; + + DBG("%s\n", __FUNCTION__); + + if (!ctx->Polygon.CullFlag) { + mode = CULLMODE_NONE; + } + else if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) { + mode = CULLMODE_CW; + + if (ctx->Polygon.CullFaceMode == GL_FRONT) + mode ^= (CULLMODE_CW ^ CULLMODE_CCW); + if (ctx->Polygon.FrontFace != GL_CCW) + mode ^= (CULLMODE_CW ^ CULLMODE_CCW); + } + else { + mode = CULLMODE_BOTH; + } + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_STATE3] &= ~CULLMODE_MASK; + i830->state.Ctx[I830_CTXREG_STATE3] |= ENABLE_CULL_MODE | mode; +} + +static void +i830LineWidth(GLcontext * ctx, GLfloat widthf) +{ + struct i830_context *i830 = i830_context(ctx); + int width; + int state5; + + DBG("%s\n", __FUNCTION__); + + width = (int) (widthf * 2); + CLAMP_SELF(width, 1, 15); + + state5 = i830->state.Ctx[I830_CTXREG_STATE5] & ~FIXED_LINE_WIDTH_MASK; + state5 |= (ENABLE_FIXED_LINE_WIDTH | FIXED_LINE_WIDTH(width)); + + if (state5 != i830->state.Ctx[I830_CTXREG_STATE5]) { + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_STATE5] = state5; + } +} + +static void +i830PointSize(GLcontext * ctx, GLfloat size) +{ + struct i830_context *i830 = i830_context(ctx); + GLint point_size = (int) size; + + DBG("%s\n", __FUNCTION__); + + CLAMP_SELF(point_size, 1, 256); + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_STATE5] &= ~FIXED_POINT_WIDTH_MASK; + i830->state.Ctx[I830_CTXREG_STATE5] |= (ENABLE_FIXED_POINT_WIDTH | + FIXED_POINT_WIDTH(point_size)); +} + + +/* ============================================================= + * Color masks + */ + +static void +i830ColorMask(GLcontext * ctx, + GLboolean r, GLboolean g, GLboolean b, GLboolean a) +{ + struct i830_context *i830 = i830_context(ctx); + GLuint tmp = 0; + + DBG("%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, r, g, b, a); + + tmp = ((i830->state.Ctx[I830_CTXREG_ENABLES_2] & ~WRITEMASK_MASK) | + ENABLE_COLOR_MASK | + ENABLE_COLOR_WRITE | + ((!r) << WRITEMASK_RED_SHIFT) | + ((!g) << WRITEMASK_GREEN_SHIFT) | + ((!b) << WRITEMASK_BLUE_SHIFT) | ((!a) << WRITEMASK_ALPHA_SHIFT)); + + if (tmp != i830->state.Ctx[I830_CTXREG_ENABLES_2]) { + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_ENABLES_2] = tmp; + } +} + +static void +update_specular(GLcontext * ctx) +{ + struct i830_context *i830 = i830_context(ctx); + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK; + + if (NEED_SECONDARY_COLOR(ctx)) + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_SPEC_ADD; + else + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_SPEC_ADD; +} + +static void +i830LightModelfv(GLcontext * ctx, GLenum pname, const GLfloat * param) +{ + DBG("%s\n", __FUNCTION__); + + if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { + update_specular(ctx); + } +} + +/* In Mesa 3.5 we can reliably do native flatshading. + */ +static void +i830ShadeModel(GLcontext * ctx, GLenum mode) +{ + struct i830_context *i830 = i830_context(ctx); + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + + +#define SHADE_MODE_MASK ((1<<10)|(1<<8)|(1<<6)|(1<<4)) + + i830->state.Ctx[I830_CTXREG_STATE3] &= ~SHADE_MODE_MASK; + + if (mode == GL_FLAT) { + i830->state.Ctx[I830_CTXREG_STATE3] |= + (ALPHA_SHADE_MODE(SHADE_MODE_FLAT) | FOG_SHADE_MODE(SHADE_MODE_FLAT) + | SPEC_SHADE_MODE(SHADE_MODE_FLAT) | + COLOR_SHADE_MODE(SHADE_MODE_FLAT)); + } + else { + i830->state.Ctx[I830_CTXREG_STATE3] |= + (ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) | + FOG_SHADE_MODE(SHADE_MODE_LINEAR) | + SPEC_SHADE_MODE(SHADE_MODE_LINEAR) | + COLOR_SHADE_MODE(SHADE_MODE_LINEAR)); + } +} + +/* ============================================================= + * Fog + */ +static void +i830Fogfv(GLcontext * ctx, GLenum pname, const GLfloat * param) +{ + struct i830_context *i830 = i830_context(ctx); + + DBG("%s\n", __FUNCTION__); + + if (pname == GL_FOG_COLOR) { + GLuint color = (((GLubyte) (ctx->Fog.Color[0] * 255.0F) << 16) | + ((GLubyte) (ctx->Fog.Color[1] * 255.0F) << 8) | + ((GLubyte) (ctx->Fog.Color[2] * 255.0F) << 0)); + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_FOGCOLOR] = + (_3DSTATE_FOG_COLOR_CMD | color); + } +} + +/* ============================================================= + */ + +static void +i830Enable(GLcontext * ctx, GLenum cap, GLboolean state) +{ + struct i830_context *i830 = i830_context(ctx); + + switch (cap) { + case GL_LIGHTING: + case GL_COLOR_SUM: + update_specular(ctx); + break; + + case GL_ALPHA_TEST: + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_ALPHA_TEST_MASK; + if (state) + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_ALPHA_TEST; + else + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_ALPHA_TEST; + + break; + + case GL_BLEND: + i830EvalLogicOpBlendState(ctx); + break; + + case GL_COLOR_LOGIC_OP: + i830EvalLogicOpBlendState(ctx); + + /* Logicop doesn't seem to work at 16bpp: + */ + if (i830->intel.intelScreen->cpp == 2) + FALLBACK(&i830->intel, I830_FALLBACK_LOGICOP, state); + break; + + case GL_DITHER: + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DITHER; + + if (state) + i830->state.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_DITHER; + else + i830->state.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DITHER; + break; + + case GL_DEPTH_TEST: + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; + + if (state) + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_DEPTH_TEST; + else + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST; + + /* Also turn off depth writes when GL_DEPTH_TEST is disabled: + */ + i830DepthMask(ctx, ctx->Depth.Mask); + break; + + case GL_SCISSOR_TEST: + I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS); + + if (state) + i830->state.Buffer[I830_DESTREG_SENABLE] = + (_3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT); + else + i830->state.Buffer[I830_DESTREG_SENABLE] = + (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); + + break; + + case GL_LINE_SMOOTH: + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + + i830->state.Ctx[I830_CTXREG_AA] &= ~AA_LINE_ENABLE; + if (state) + i830->state.Ctx[I830_CTXREG_AA] |= AA_LINE_ENABLE; + else + i830->state.Ctx[I830_CTXREG_AA] |= AA_LINE_DISABLE; + break; + + case GL_FOG: + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_FOG_MASK; + if (state) + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_FOG; + else + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_FOG; + break; + + case GL_CULL_FACE: + i830CullFaceFrontFace(ctx, 0); + break; + + case GL_TEXTURE_2D: + break; + + case GL_STENCIL_TEST: + { + GLboolean hw_stencil = GL_FALSE; + if (ctx->DrawBuffer) { + struct intel_renderbuffer *irbStencil + = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL); + hw_stencil = (irbStencil && irbStencil->region); + } + if (hw_stencil) { + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + + if (state) { + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST; + i830->state.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_STENCIL_WRITE; + } + else { + i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST; + i830->state.Ctx[I830_CTXREG_ENABLES_2] &= + ~ENABLE_STENCIL_WRITE; + i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_STENCIL_TEST; + i830->state.Ctx[I830_CTXREG_ENABLES_2] |= + DISABLE_STENCIL_WRITE; + } + } + else { + FALLBACK(&i830->intel, I830_FALLBACK_STENCIL, state); + } + } + break; + + case GL_POLYGON_STIPPLE: + /* The stipple command worked on my 855GM box, but not my 845G. + * I'll do more testing later to find out exactly which hardware + * supports it. Disabled for now. + */ + if (i830->intel.hw_stipple && + i830->intel.reduced_primitive == GL_TRIANGLES) { + I830_STATECHANGE(i830, I830_UPLOAD_STIPPLE); + i830->state.Stipple[I830_STPREG_ST1] &= ~ST1_ENABLE; + if (state) + i830->state.Stipple[I830_STPREG_ST1] |= ST1_ENABLE; + } + break; + + default: + ; + } +} + + +static void +i830_init_packets(struct i830_context *i830) +{ + intelScreenPrivate *screen = i830->intel.intelScreen; + + /* Zero all state */ + memset(&i830->state, 0, sizeof(i830->state)); + + /* Set default blend state */ + i830->state.TexBlend[0][0] = (_3DSTATE_MAP_BLEND_OP_CMD(0) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXOP_LAST_STAGE | TEXBLENDOP_ARG1); + i830->state.TexBlend[0][1] = (_3DSTATE_MAP_BLEND_OP_CMD(0) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | TEXBLENDOP_ARG1); + i830->state.TexBlend[0][2] = (_3DSTATE_MAP_BLEND_ARG_CMD(0) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_DIFFUSE); + i830->state.TexBlend[0][3] = (_3DSTATE_MAP_BLEND_ARG_CMD(0) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_DIFFUSE); + + i830->state.TexBlendWordsUsed[0] = 4; + + + i830->state.Ctx[I830_CTXREG_VF] = 0; + i830->state.Ctx[I830_CTXREG_VF2] = 0; + + i830->state.Ctx[I830_CTXREG_AA] = (_3DSTATE_AA_CMD | + AA_LINE_ECAAR_WIDTH_ENABLE | + AA_LINE_ECAAR_WIDTH_1_0 | + AA_LINE_REGION_WIDTH_ENABLE | + AA_LINE_REGION_WIDTH_1_0 | + AA_LINE_DISABLE); + + i830->state.Ctx[I830_CTXREG_ENABLES_1] = (_3DSTATE_ENABLES_1_CMD | + DISABLE_LOGIC_OP | + DISABLE_STENCIL_TEST | + DISABLE_DEPTH_BIAS | + DISABLE_SPEC_ADD | + DISABLE_FOG | + DISABLE_ALPHA_TEST | + DISABLE_COLOR_BLEND | + DISABLE_DEPTH_TEST); + +#if 000 /* XXX all the stencil enable state is set in i830Enable(), right? */ + if (i830->intel.hw_stencil) { + i830->state.Ctx[I830_CTXREG_ENABLES_2] = (_3DSTATE_ENABLES_2_CMD | + ENABLE_STENCIL_WRITE | + ENABLE_TEX_CACHE | + ENABLE_DITHER | + ENABLE_COLOR_MASK | + /* set no color comps disabled */ + ENABLE_COLOR_WRITE | + ENABLE_DEPTH_WRITE); + } + else +#endif + { + i830->state.Ctx[I830_CTXREG_ENABLES_2] = (_3DSTATE_ENABLES_2_CMD | + DISABLE_STENCIL_WRITE | + ENABLE_TEX_CACHE | + ENABLE_DITHER | + ENABLE_COLOR_MASK | + /* set no color comps disabled */ + ENABLE_COLOR_WRITE | + ENABLE_DEPTH_WRITE); + } + + i830->state.Ctx[I830_CTXREG_STATE1] = (_3DSTATE_MODES_1_CMD | + ENABLE_COLR_BLND_FUNC | + BLENDFUNC_ADD | + ENABLE_SRC_BLND_FACTOR | + SRC_BLND_FACT(BLENDFACT_ONE) | + ENABLE_DST_BLND_FACTOR | + DST_BLND_FACT(BLENDFACT_ZERO)); + + i830->state.Ctx[I830_CTXREG_STATE2] = (_3DSTATE_MODES_2_CMD | + ENABLE_GLOBAL_DEPTH_BIAS | + GLOBAL_DEPTH_BIAS(0) | + ENABLE_ALPHA_TEST_FUNC | + ALPHA_TEST_FUNC(COMPAREFUNC_ALWAYS) + | ALPHA_REF_VALUE(0)); + + i830->state.Ctx[I830_CTXREG_STATE3] = (_3DSTATE_MODES_3_CMD | + ENABLE_DEPTH_TEST_FUNC | + DEPTH_TEST_FUNC(COMPAREFUNC_LESS) | + ENABLE_ALPHA_SHADE_MODE | + ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) + | ENABLE_FOG_SHADE_MODE | + FOG_SHADE_MODE(SHADE_MODE_LINEAR) | + ENABLE_SPEC_SHADE_MODE | + SPEC_SHADE_MODE(SHADE_MODE_LINEAR) | + ENABLE_COLOR_SHADE_MODE | + COLOR_SHADE_MODE(SHADE_MODE_LINEAR) + | ENABLE_CULL_MODE | CULLMODE_NONE); + + i830->state.Ctx[I830_CTXREG_STATE4] = (_3DSTATE_MODES_4_CMD | + ENABLE_LOGIC_OP_FUNC | + LOGIC_OP_FUNC(LOGICOP_COPY) | + ENABLE_STENCIL_TEST_MASK | + STENCIL_TEST_MASK(0xff) | + ENABLE_STENCIL_WRITE_MASK | + STENCIL_WRITE_MASK(0xff)); + + i830->state.Ctx[I830_CTXREG_STENCILTST] = (_3DSTATE_STENCIL_TEST_CMD | + ENABLE_STENCIL_PARMS | + STENCIL_FAIL_OP(STENCILOP_KEEP) + | + STENCIL_PASS_DEPTH_FAIL_OP + (STENCILOP_KEEP) | + STENCIL_PASS_DEPTH_PASS_OP + (STENCILOP_KEEP) | + ENABLE_STENCIL_TEST_FUNC | + STENCIL_TEST_FUNC + (COMPAREFUNC_ALWAYS) | + ENABLE_STENCIL_REF_VALUE | + STENCIL_REF_VALUE(0)); + + i830->state.Ctx[I830_CTXREG_STATE5] = (_3DSTATE_MODES_5_CMD | FLUSH_TEXTURE_CACHE | ENABLE_SPRITE_POINT_TEX | SPRITE_POINT_TEX_OFF | ENABLE_FIXED_LINE_WIDTH | FIXED_LINE_WIDTH(0x2) | /* 1.0 */ + ENABLE_FIXED_POINT_WIDTH | + FIXED_POINT_WIDTH(1)); + + i830->state.Ctx[I830_CTXREG_IALPHAB] = (_3DSTATE_INDPT_ALPHA_BLEND_CMD | + DISABLE_INDPT_ALPHA_BLEND | + ENABLE_ALPHA_BLENDFUNC | + ABLENDFUNC_ADD); + + i830->state.Ctx[I830_CTXREG_FOGCOLOR] = (_3DSTATE_FOG_COLOR_CMD | + FOG_COLOR_RED(0) | + FOG_COLOR_GREEN(0) | + FOG_COLOR_BLUE(0)); + + i830->state.Ctx[I830_CTXREG_BLENDCOLOR0] = _3DSTATE_CONST_BLEND_COLOR_CMD; + i830->state.Ctx[I830_CTXREG_BLENDCOLOR1] = 0; + + i830->state.Ctx[I830_CTXREG_MCSB0] = _3DSTATE_MAP_COORD_SETBIND_CMD; + i830->state.Ctx[I830_CTXREG_MCSB1] = (TEXBIND_SET3(TEXCOORDSRC_VTXSET_3) | + TEXBIND_SET2(TEXCOORDSRC_VTXSET_2) | + TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) | + TEXBIND_SET0(TEXCOORDSRC_VTXSET_0)); + + + i830->state.Stipple[I830_STPREG_ST0] = _3DSTATE_STIPPLE; + + i830->state.Buffer[I830_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD; + i830->state.Buffer[I830_DESTREG_CBUFADDR1] = (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(screen->front.pitch) | /* pitch in bytes */ + BUF_3D_USE_FENCE); + + + i830->state.Buffer[I830_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD; + i830->state.Buffer[I830_DESTREG_DBUFADDR1] = (BUF_3D_ID_DEPTH | BUF_3D_PITCH(screen->depth.pitch) | /* pitch in bytes */ + BUF_3D_USE_FENCE); + + i830->state.Buffer[I830_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD; + + switch (screen->fbFormat) { + case DV_PF_565: + i830->state.Buffer[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | /* .5 */ + screen->fbFormat | + DEPTH_IS_Z | + DEPTH_FRMT_16_FIXED); + break; + case DV_PF_8888: + i830->state.Buffer[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | /* .5 */ + screen->fbFormat | + DEPTH_IS_Z | + DEPTH_FRMT_24_FIXED_8_OTHER); + break; + } + + i830->state.Buffer[I830_DESTREG_SENABLE] = (_3DSTATE_SCISSOR_ENABLE_CMD | + DISABLE_SCISSOR_RECT); + i830->state.Buffer[I830_DESTREG_SR0] = _3DSTATE_SCISSOR_RECT_0_CMD; + i830->state.Buffer[I830_DESTREG_SR1] = 0; + i830->state.Buffer[I830_DESTREG_SR2] = 0; +} + + +void +i830InitStateFuncs(struct dd_function_table *functions) +{ + functions->AlphaFunc = i830AlphaFunc; + functions->BlendColor = i830BlendColor; + functions->BlendEquationSeparate = i830BlendEquationSeparate; + functions->BlendFuncSeparate = i830BlendFuncSeparate; + functions->ColorMask = i830ColorMask; + functions->CullFace = i830CullFaceFrontFace; + functions->DepthFunc = i830DepthFunc; + functions->DepthMask = i830DepthMask; + functions->Enable = i830Enable; + functions->Fogfv = i830Fogfv; + functions->FrontFace = i830CullFaceFrontFace; + functions->LightModelfv = i830LightModelfv; + functions->LineWidth = i830LineWidth; + functions->LogicOpcode = i830LogicOp; + functions->PointSize = i830PointSize; + functions->PolygonStipple = i830PolygonStipple; + functions->Scissor = i830Scissor; + functions->ShadeModel = i830ShadeModel; + functions->StencilFuncSeparate = i830StencilFuncSeparate; + functions->StencilMaskSeparate = i830StencilMaskSeparate; + functions->StencilOpSeparate = i830StencilOpSeparate; +} + +void +i830InitState(struct i830_context *i830) +{ + GLcontext *ctx = &i830->intel.ctx; + + i830_init_packets(i830); + + intelInitState(ctx); + + memcpy(&i830->initial, &i830->state, sizeof(i830->state)); + + i830->current = &i830->state; + i830->state.emitted = 0; + i830->state.active = (I830_UPLOAD_INVARIENT | + I830_UPLOAD_TEXBLEND(0) | + I830_UPLOAD_STIPPLE | + I830_UPLOAD_CTX | I830_UPLOAD_BUFFERS); +} diff --git a/src/mesa/drivers/dri/i915tex/i830_tex.c b/src/mesa/drivers/dri/i915tex/i830_tex.c new file mode 100644 index 0000000000..fed464d1aa --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i830_tex.c @@ -0,0 +1,100 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "glheader.h" +#include "mtypes.h" +#include "imports.h" +#include "simple_list.h" +#include "enums.h" +#include "image.h" +#include "texstore.h" +#include "texformat.h" +#include "texmem.h" +#include "swrast/swrast.h" + +#include "mm.h" + +#include "intel_ioctl.h" + +#include "i830_context.h" +#include "i830_reg.h" + + + +static void +i830TexEnv(GLcontext * ctx, GLenum target, + GLenum pname, const GLfloat * param) +{ + + switch (pname) { + case GL_TEXTURE_ENV_COLOR: + case GL_TEXTURE_ENV_MODE: + case GL_COMBINE_RGB: + case GL_COMBINE_ALPHA: + case GL_SOURCE0_RGB: + case GL_SOURCE1_RGB: + case GL_SOURCE2_RGB: + case GL_SOURCE0_ALPHA: + case GL_SOURCE1_ALPHA: + case GL_SOURCE2_ALPHA: + case GL_OPERAND0_RGB: + case GL_OPERAND1_RGB: + case GL_OPERAND2_RGB: + case GL_OPERAND0_ALPHA: + case GL_OPERAND1_ALPHA: + case GL_OPERAND2_ALPHA: + case GL_RGB_SCALE: + case GL_ALPHA_SCALE: + break; + + case GL_TEXTURE_LOD_BIAS:{ + struct i830_context *i830 = i830_context(ctx); + GLuint unit = ctx->Texture.CurrentUnit; + int b = (int) ((*param) * 16.0); + if (b > 63) + b = 63; + if (b < -64) + b = -64; + I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit)); + i830->lodbias_tm0s3[unit] = + ((b << TM0S3_LOD_BIAS_SHIFT) & TM0S3_LOD_BIAS_MASK); + break; + } + + default: + break; + } +} + + + + +void +i830InitTextureFuncs(struct dd_function_table *functions) +{ + functions->TexEnv = i830TexEnv; +} diff --git a/src/mesa/drivers/dri/i915tex/i830_texblend.c b/src/mesa/drivers/dri/i915tex/i830_texblend.c new file mode 100644 index 0000000000..58f220eb7c --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i830_texblend.c @@ -0,0 +1,463 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "glheader.h" +#include "macros.h" +#include "mtypes.h" +#include "simple_list.h" +#include "enums.h" +#include "texformat.h" +#include "texstore.h" + +#include "mm.h" + +#include "intel_screen.h" +#include "intel_ioctl.h" +#include "intel_tex.h" + +#include "i830_context.h" +#include "i830_reg.h" + + +/* ================================================================ + * Texture combine functions + */ +static GLuint +pass_through(GLuint * state, GLuint blendUnit) +{ + state[0] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | TEXOP_MODIFY_PARMS | TEXBLENDOP_ARG1); + state[1] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | TEXOP_MODIFY_PARMS | TEXBLENDOP_ARG1); + state[2] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | TEXBLENDARG_CURRENT); + state[3] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | TEXBLENDARG_CURRENT); + + return 4; +} + +static GLuint +emit_factor(GLuint blendUnit, GLuint * state, GLuint count, + const GLfloat * factor) +{ + GLubyte r, g, b, a; + GLuint col; + + if (0) + fprintf(stderr, "emit constant %d: %.2f %.2f %.2f %.2f\n", + blendUnit, factor[0], factor[1], factor[2], factor[3]); + + UNCLAMPED_FLOAT_TO_UBYTE(r, factor[0]); + UNCLAMPED_FLOAT_TO_UBYTE(g, factor[1]); + UNCLAMPED_FLOAT_TO_UBYTE(b, factor[2]); + UNCLAMPED_FLOAT_TO_UBYTE(a, factor[3]); + + col = ((a << 24) | (r << 16) | (g << 8) | b); + + state[count++] = _3DSTATE_COLOR_FACTOR_N_CMD(blendUnit); + state[count++] = col; + + return count; +} + + +static INLINE GLuint +GetTexelOp(GLint unit) +{ + switch (unit) { + case 0: + return TEXBLENDARG_TEXEL0; + case 1: + return TEXBLENDARG_TEXEL1; + case 2: + return TEXBLENDARG_TEXEL2; + case 3: + return TEXBLENDARG_TEXEL3; + default: + return TEXBLENDARG_TEXEL0; + } +} + + +/** + * Calculate the hardware instuctions to setup the current texture enviromnemt + * settings. Since \c gl_texture_unit::_CurrentCombine is used, both + * "classic" texture enviroments and GL_ARB_texture_env_combine type texture + * environments are treated identically. + * + * \todo + * This function should return \c GLboolean. When \c GL_FALSE is returned, + * it means that an environment is selected that the hardware cannot do. This + * is the way the Radeon and R200 drivers work. + * + * \todo + * Looking at i830_3d_regs.h, it seems the i830 can do part of + * GL_ATI_texture_env_combine3. It can handle using \c GL_ONE and + * \c GL_ZERO as combine inputs (which the code already supports). It can + * also handle the \c GL_MODULATE_ADD_ATI mode. Is it worth investigating + * partial support for the extension? + */ +GLuint +i830SetTexEnvCombine(struct i830_context * i830, + const struct gl_tex_env_combine_state * combine, + GLint blendUnit, + GLuint texel_op, GLuint * state, const GLfloat * factor) +{ + const GLuint numColorArgs = combine->_NumArgsRGB; + const GLuint numAlphaArgs = combine->_NumArgsA; + + GLuint blendop; + GLuint ablendop; + GLuint args_RGB[3]; + GLuint args_A[3]; + GLuint rgb_shift; + GLuint alpha_shift; + GLboolean need_factor = 0; + int i; + unsigned used; + static const GLuint tex_blend_rgb[3] = { + TEXPIPE_COLOR | TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS, + TEXPIPE_COLOR | TEXBLEND_ARG2 | TEXBLENDARG_MODIFY_PARMS, + TEXPIPE_COLOR | TEXBLEND_ARG0 | TEXBLENDARG_MODIFY_PARMS, + }; + static const GLuint tex_blend_a[3] = { + TEXPIPE_ALPHA | TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS, + TEXPIPE_ALPHA | TEXBLEND_ARG2 | TEXBLENDARG_MODIFY_PARMS, + TEXPIPE_ALPHA | TEXBLEND_ARG0 | TEXBLENDARG_MODIFY_PARMS, + }; + + if (INTEL_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, "%s\n", __FUNCTION__); + + + /* The EXT version of the DOT3 extension does not support the + * scale factor, but the ARB version (and the version in OpenGL + * 1.3) does. + */ + switch (combine->ModeRGB) { + case GL_DOT3_RGB_EXT: + alpha_shift = combine->ScaleShiftA; + rgb_shift = 0; + break; + + case GL_DOT3_RGBA_EXT: + alpha_shift = 0; + rgb_shift = 0; + break; + + default: + rgb_shift = combine->ScaleShiftRGB; + alpha_shift = combine->ScaleShiftA; + break; + } + + + switch (combine->ModeRGB) { + case GL_REPLACE: + blendop = TEXBLENDOP_ARG1; + break; + case GL_MODULATE: + blendop = TEXBLENDOP_MODULATE; + break; + case GL_ADD: + blendop = TEXBLENDOP_ADD; + break; + case GL_ADD_SIGNED: + blendop = TEXBLENDOP_ADDSIGNED; + break; + case GL_INTERPOLATE: + blendop = TEXBLENDOP_BLEND; + break; + case GL_SUBTRACT: + blendop = TEXBLENDOP_SUBTRACT; + break; + case GL_DOT3_RGB_EXT: + case GL_DOT3_RGB: + blendop = TEXBLENDOP_DOT3; + break; + case GL_DOT3_RGBA_EXT: + case GL_DOT3_RGBA: + blendop = TEXBLENDOP_DOT3; + break; + default: + return pass_through(state, blendUnit); + } + + blendop |= (rgb_shift << TEXOP_SCALE_SHIFT); + + + /* Handle RGB args */ + for (i = 0; i < 3; i++) { + switch (combine->SourceRGB[i]) { + case GL_TEXTURE: + args_RGB[i] = texel_op; + break; + case GL_TEXTURE0: + case GL_TEXTURE1: + case GL_TEXTURE2: + case GL_TEXTURE3: + args_RGB[i] = GetTexelOp(combine->SourceRGB[i] - GL_TEXTURE0); + break; + case GL_CONSTANT: + args_RGB[i] = TEXBLENDARG_FACTOR_N; + need_factor = 1; + break; + case GL_PRIMARY_COLOR: + args_RGB[i] = TEXBLENDARG_DIFFUSE; + break; + case GL_PREVIOUS: + args_RGB[i] = TEXBLENDARG_CURRENT; + break; + default: + return pass_through(state, blendUnit); + } + + switch (combine->OperandRGB[i]) { + case GL_SRC_COLOR: + args_RGB[i] |= 0; + break; + case GL_ONE_MINUS_SRC_COLOR: + args_RGB[i] |= TEXBLENDARG_INV_ARG; + break; + case GL_SRC_ALPHA: + args_RGB[i] |= TEXBLENDARG_REPLICATE_ALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + args_RGB[i] |= (TEXBLENDARG_REPLICATE_ALPHA | TEXBLENDARG_INV_ARG); + break; + default: + return pass_through(state, blendUnit); + } + } + + + /* Need to knobble the alpha calculations of TEXBLENDOP_DOT4 to + * match the spec. Can't use DOT3 as it won't propogate values + * into alpha as required: + * + * Note - the global factor is set up with alpha == .5, so + * the alpha part of the DOT4 calculation should be zero. + */ + if (combine->ModeRGB == GL_DOT3_RGBA_EXT || + combine->ModeRGB == GL_DOT3_RGBA) { + ablendop = TEXBLENDOP_DOT4; + args_A[0] = TEXBLENDARG_FACTOR; /* the global factor */ + args_A[1] = TEXBLENDARG_FACTOR; + args_A[2] = TEXBLENDARG_FACTOR; + } + else { + switch (combine->ModeA) { + case GL_REPLACE: + ablendop = TEXBLENDOP_ARG1; + break; + case GL_MODULATE: + ablendop = TEXBLENDOP_MODULATE; + break; + case GL_ADD: + ablendop = TEXBLENDOP_ADD; + break; + case GL_ADD_SIGNED: + ablendop = TEXBLENDOP_ADDSIGNED; + break; + case GL_INTERPOLATE: + ablendop = TEXBLENDOP_BLEND; + break; + case GL_SUBTRACT: + ablendop = TEXBLENDOP_SUBTRACT; + break; + default: + return pass_through(state, blendUnit); + } + + + ablendop |= (alpha_shift << TEXOP_SCALE_SHIFT); + + /* Handle A args */ + for (i = 0; i < 3; i++) { + switch (combine->SourceA[i]) { + case GL_TEXTURE: + args_A[i] = texel_op; + break; + case GL_TEXTURE0: + case GL_TEXTURE1: + case GL_TEXTURE2: + case GL_TEXTURE3: + args_A[i] = GetTexelOp(combine->SourceA[i] - GL_TEXTURE0); + break; + case GL_CONSTANT: + args_A[i] = TEXBLENDARG_FACTOR_N; + need_factor = 1; + break; + case GL_PRIMARY_COLOR: + args_A[i] = TEXBLENDARG_DIFFUSE; + break; + case GL_PREVIOUS: + args_A[i] = TEXBLENDARG_CURRENT; + break; + default: + return pass_through(state, blendUnit); + } + + switch (combine->OperandA[i]) { + case GL_SRC_ALPHA: + args_A[i] |= 0; + break; + case GL_ONE_MINUS_SRC_ALPHA: + args_A[i] |= TEXBLENDARG_INV_ARG; + break; + default: + return pass_through(state, blendUnit); + } + } + } + + + + /* Native Arg1 == Arg0 in GL_EXT_texture_env_combine spec */ + /* Native Arg2 == Arg1 in GL_EXT_texture_env_combine spec */ + /* Native Arg0 == Arg2 in GL_EXT_texture_env_combine spec */ + + /* When we render we need to figure out which is the last really enabled + * tex unit, and put last stage on it + */ + + + /* Build color & alpha pipelines */ + + used = 0; + state[used++] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | TEXOP_MODIFY_PARMS | blendop); + state[used++] = (_3DSTATE_MAP_BLEND_OP_CMD(blendUnit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | TEXOP_MODIFY_PARMS | ablendop); + + for (i = 0; i < numColorArgs; i++) { + state[used++] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + tex_blend_rgb[i] | args_RGB[i]); + } + + for (i = 0; i < numAlphaArgs; i++) { + state[used++] = (_3DSTATE_MAP_BLEND_ARG_CMD(blendUnit) | + tex_blend_a[i] | args_A[i]); + } + + + if (need_factor) + return emit_factor(blendUnit, state, used, factor); + else + return used; +} + + +static void +emit_texblend(struct i830_context *i830, GLuint unit, GLuint blendUnit, + GLboolean last_stage) +{ + struct gl_texture_unit *texUnit = &i830->intel.ctx.Texture.Unit[unit]; + GLuint tmp[I830_TEXBLEND_SIZE], tmp_sz; + + + if (0) + fprintf(stderr, "%s unit %d\n", __FUNCTION__, unit); + + /* Update i830->state.TexBlend + */ + tmp_sz = i830SetTexEnvCombine(i830, texUnit->_CurrentCombine, blendUnit, + GetTexelOp(unit), tmp, texUnit->EnvColor); + + if (last_stage) + tmp[0] |= TEXOP_LAST_STAGE; + + if (tmp_sz != i830->state.TexBlendWordsUsed[blendUnit] || + memcmp(tmp, i830->state.TexBlend[blendUnit], + tmp_sz * sizeof(GLuint))) { + + I830_STATECHANGE(i830, I830_UPLOAD_TEXBLEND(blendUnit)); + memcpy(i830->state.TexBlend[blendUnit], tmp, tmp_sz * sizeof(GLuint)); + i830->state.TexBlendWordsUsed[blendUnit] = tmp_sz; + } + + I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND(blendUnit), GL_TRUE); +} + +static void +emit_passthrough(struct i830_context *i830) +{ + GLuint tmp[I830_TEXBLEND_SIZE], tmp_sz; + GLuint unit = 0; + + tmp_sz = pass_through(tmp, unit); + tmp[0] |= TEXOP_LAST_STAGE; + + if (tmp_sz != i830->state.TexBlendWordsUsed[unit] || + memcmp(tmp, i830->state.TexBlend[unit], tmp_sz * sizeof(GLuint))) { + + I830_STATECHANGE(i830, I830_UPLOAD_TEXBLEND(unit)); + memcpy(i830->state.TexBlend[unit], tmp, tmp_sz * sizeof(GLuint)); + i830->state.TexBlendWordsUsed[unit] = tmp_sz; + } + + I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND(unit), GL_TRUE); +} + +void +i830EmitTextureBlend(struct i830_context *i830) +{ + GLcontext *ctx = &i830->intel.ctx; + GLuint unit, last_stage = 0, blendunit = 0; + + I830_ACTIVESTATE(i830, I830_UPLOAD_TEXBLEND_ALL, GL_FALSE); + + if (ctx->Texture._EnabledUnits) { + for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) + if (ctx->Texture.Unit[unit]._ReallyEnabled) + last_stage = unit; + + for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) + if (ctx->Texture.Unit[unit]._ReallyEnabled) + emit_texblend(i830, unit, blendunit++, last_stage == unit); + } + else { + emit_passthrough(i830); + } +} diff --git a/src/mesa/drivers/dri/i915tex/i830_texstate.c b/src/mesa/drivers/dri/i915tex/i830_texstate.c new file mode 100644 index 0000000000..ba79cf9459 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i830_texstate.c @@ -0,0 +1,316 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "glheader.h" +#include "macros.h" +#include "mtypes.h" +#include "simple_list.h" +#include "enums.h" +#include "texformat.h" +#include "texstore.h" + +#include "mm.h" + +#include "intel_screen.h" +#include "intel_ioctl.h" +#include "intel_tex.h" +#include "intel_mipmap_tree.h" +#include "intel_regions.h" + +#include "i830_context.h" +#include "i830_reg.h" + + + +static GLuint +translate_texture_format(GLuint mesa_format) +{ + switch (mesa_format) { + case MESA_FORMAT_L8: + return MAPSURF_8BIT | MT_8BIT_L8; + case MESA_FORMAT_I8: + return MAPSURF_8BIT | MT_8BIT_I8; + case MESA_FORMAT_A8: + return MAPSURF_8BIT | MT_8BIT_I8; /* Kludge! */ + case MESA_FORMAT_AL88: + return MAPSURF_16BIT | MT_16BIT_AY88; + case MESA_FORMAT_RGB565: + return MAPSURF_16BIT | MT_16BIT_RGB565; + case MESA_FORMAT_ARGB1555: + return MAPSURF_16BIT | MT_16BIT_ARGB1555; + case MESA_FORMAT_ARGB4444: + return MAPSURF_16BIT | MT_16BIT_ARGB4444; + case MESA_FORMAT_ARGB8888: + return MAPSURF_32BIT | MT_32BIT_ARGB8888; + case MESA_FORMAT_YCBCR_REV: + return (MAPSURF_422 | MT_422_YCRCB_NORMAL); + case MESA_FORMAT_YCBCR: + return (MAPSURF_422 | MT_422_YCRCB_SWAPY); + case MESA_FORMAT_RGB_FXT1: + case MESA_FORMAT_RGBA_FXT1: + return (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1); + case MESA_FORMAT_RGBA_DXT1: + case MESA_FORMAT_RGB_DXT1: + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); + case MESA_FORMAT_RGBA_DXT3: + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3); + case MESA_FORMAT_RGBA_DXT5: + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); + default: + fprintf(stderr, "%s: bad image format %x\n", __FUNCTION__, mesa_format); + abort(); + return 0; + } +} + + + + +/* The i915 (and related graphics cores) do not support GL_CLAMP. The + * Intel drivers for "other operating systems" implement GL_CLAMP as + * GL_CLAMP_TO_EDGE, so the same is done here. + */ +static GLuint +translate_wrap_mode(GLenum wrap) +{ + switch (wrap) { + case GL_REPEAT: + return TEXCOORDMODE_WRAP; + case GL_CLAMP: + case GL_CLAMP_TO_EDGE: + return TEXCOORDMODE_CLAMP; /* not really correct */ + case GL_CLAMP_TO_BORDER: + return TEXCOORDMODE_CLAMP_BORDER; + case GL_MIRRORED_REPEAT: + return TEXCOORDMODE_MIRROR; + default: + return TEXCOORDMODE_WRAP; + } +} + + +/* Recalculate all state from scratch. Perhaps not the most + * efficient, but this has gotten complex enough that we need + * something which is understandable and reliable. + */ +static GLboolean +i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) +{ + GLcontext *ctx = &intel->ctx; + struct i830_context *i830 = i830_context(ctx); + struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current; + struct intel_texture_object *intelObj = intel_texture_object(tObj); + struct gl_texture_image *firstImage; + GLuint *state = i830->state.Tex[unit]; + + memset(state, 0, sizeof(state)); + + if (!intel_finalize_mipmap_tree(intel, unit)) + return GL_FALSE; + + /* Get first image here, since intelObj->firstLevel will get set in + * the intel_finalize_mipmap_tree() call above. + */ + firstImage = tObj->Image[0][intelObj->firstLevel]; + + i830->state.tex_buffer[unit] = intelObj->mt->region->buffer; + i830->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, 0, + intelObj-> + firstLevel); + + + state[I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 | + (LOAD_TEXTURE_MAP0 << unit) | 4); + +/* state[I830_TEXREG_TM0S0] = (TM0S0_USE_FENCE | */ +/* t->intel.TextureOffset); */ + + + state[I830_TEXREG_TM0S1] = + (((firstImage->Height - 1) << TM0S1_HEIGHT_SHIFT) | + ((firstImage->Width - 1) << TM0S1_WIDTH_SHIFT) | + translate_texture_format(firstImage->TexFormat->MesaFormat)); + + state[I830_TEXREG_TM0S2] = + (((((intelObj->mt->pitch * intelObj->mt->cpp) / 4) - + 1) << TM0S2_PITCH_SHIFT) | TM0S2_CUBE_FACE_ENA_MASK); + + { + if (tObj->Target == GL_TEXTURE_CUBE_MAP) + state[I830_TEXREG_CUBE] = (_3DSTATE_MAP_CUBE | MAP_UNIT(unit) | + CUBE_NEGX_ENABLE | + CUBE_POSX_ENABLE | + CUBE_NEGY_ENABLE | + CUBE_POSY_ENABLE | + CUBE_NEGZ_ENABLE | CUBE_POSZ_ENABLE); + else + state[I830_TEXREG_CUBE] = (_3DSTATE_MAP_CUBE | MAP_UNIT(unit)); + } + + + + + { + GLuint minFilt, mipFilt, magFilt; + + switch (tObj->MinFilter) { + case GL_NEAREST: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_NONE; + break; + case GL_LINEAR: + minFilt = FILTER_LINEAR; + mipFilt = MIPFILTER_NONE; + break; + case GL_NEAREST_MIPMAP_NEAREST: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_NEAREST; + break; + case GL_LINEAR_MIPMAP_NEAREST: + minFilt = FILTER_LINEAR; + mipFilt = MIPFILTER_NEAREST; + break; + case GL_NEAREST_MIPMAP_LINEAR: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_LINEAR; + break; + case GL_LINEAR_MIPMAP_LINEAR: + minFilt = FILTER_LINEAR; + mipFilt = MIPFILTER_LINEAR; + break; + default: + return GL_FALSE; + } + + if (tObj->MaxAnisotropy > 1.0) { + minFilt = FILTER_ANISOTROPIC; + magFilt = FILTER_ANISOTROPIC; + } + else { + switch (tObj->MagFilter) { + case GL_NEAREST: + magFilt = FILTER_NEAREST; + break; + case GL_LINEAR: + magFilt = FILTER_LINEAR; + break; + default: + return GL_FALSE; + } + } + + state[I830_TEXREG_TM0S3] = i830->lodbias_tm0s3[unit]; + +#if 0 + /* YUV conversion: + */ + if (firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR || + firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV) + state[I830_TEXREG_TM0S3] |= SS2_COLORSPACE_CONVERSION; +#endif + + state[I830_TEXREG_TM0S3] |= ((intelObj->lastLevel - + intelObj->firstLevel) * + 4) << TM0S3_MIN_MIP_SHIFT; + + state[I830_TEXREG_TM0S3] |= ((minFilt << TM0S3_MIN_FILTER_SHIFT) | + (mipFilt << TM0S3_MIP_FILTER_SHIFT) | + (magFilt << TM0S3_MAG_FILTER_SHIFT)); + } + + { + GLenum ws = tObj->WrapS; + GLenum wt = tObj->WrapT; + + + /* 3D textures not available on i830 + */ + if (tObj->Target == GL_TEXTURE_3D) + return GL_FALSE; + + state[I830_TEXREG_MCS] = (_3DSTATE_MAP_COORD_SET_CMD | + MAP_UNIT(unit) | + ENABLE_TEXCOORD_PARAMS | + ss3 | + ENABLE_ADDR_V_CNTL | + TEXCOORD_ADDR_V_MODE(translate_wrap_mode(wt)) + | ENABLE_ADDR_U_CNTL | + TEXCOORD_ADDR_U_MODE(translate_wrap_mode + (ws))); + } + + + state[I830_TEXREG_TM0S4] = INTEL_PACKCOLOR8888(tObj->_BorderChan[0], + tObj->_BorderChan[1], + tObj->_BorderChan[2], + tObj->_BorderChan[3]); + + + I830_ACTIVESTATE(i830, I830_UPLOAD_TEX(unit), GL_TRUE); + /* memcmp was already disabled, but definitely won't work as the + * region might now change and that wouldn't be detected: + */ + I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit)); + return GL_TRUE; +} + + + + +void +i830UpdateTextureState(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + GLboolean ok = GL_TRUE; + GLuint i; + + for (i = 0; i < I830_TEX_UNITS && ok; i++) { + switch (intel->ctx.Texture.Unit[i]._ReallyEnabled) { + case TEXTURE_1D_BIT: + case TEXTURE_2D_BIT: + case TEXTURE_CUBE_BIT: + ok = i830_update_tex_unit(intel, i, TEXCOORDS_ARE_NORMAL); + break; + case TEXTURE_RECT_BIT: + ok = i830_update_tex_unit(intel, i, TEXCOORDS_ARE_IN_TEXELUNITS); + break; + case 0: + if (i830->state.active & I830_UPLOAD_TEX(i)) + I830_ACTIVESTATE(i830, I830_UPLOAD_TEX(i), GL_FALSE); + break; + case TEXTURE_3D_BIT: + default: + ok = GL_FALSE; + break; + } + } + + FALLBACK(intel, I830_FALLBACK_TEXTURE, !ok); + + if (ok) + i830EmitTextureBlend(i830); +} diff --git a/src/mesa/drivers/dri/i915tex/i830_vtbl.c b/src/mesa/drivers/dri/i915tex/i830_vtbl.c new file mode 100644 index 0000000000..45502da290 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i830_vtbl.c @@ -0,0 +1,606 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "i830_context.h" +#include "i830_reg.h" +#include "intel_batchbuffer.h" +#include "intel_regions.h" +#include "tnl/t_context.h" +#include "tnl/t_vertex.h" + +#define FILE_DEBUG_FLAG DEBUG_STATE + +static GLboolean i830_check_vertex_size(struct intel_context *intel, + GLuint expected); + +#define SZ_TO_HW(sz) ((sz-2)&0x3) +#define EMIT_SZ(sz) (EMIT_1F + (sz) - 1) +#define EMIT_ATTR( ATTR, STYLE, V0 ) \ +do { \ + intel->vertex_attrs[intel->vertex_attr_count].attrib = (ATTR); \ + intel->vertex_attrs[intel->vertex_attr_count].format = (STYLE); \ + intel->vertex_attr_count++; \ + v0 |= V0; \ +} while (0) + +#define EMIT_PAD( N ) \ +do { \ + intel->vertex_attrs[intel->vertex_attr_count].attrib = 0; \ + intel->vertex_attrs[intel->vertex_attr_count].format = EMIT_PAD; \ + intel->vertex_attrs[intel->vertex_attr_count].offset = (N); \ + intel->vertex_attr_count++; \ +} while (0) + + +#define VRTX_TEX_SET_FMT(n, x) ((x)<<((n)*2)) +#define TEXBIND_SET(n, x) ((x)<<((n)*4)) + +static void +i830_render_start(struct intel_context *intel) +{ + GLcontext *ctx = &intel->ctx; + struct i830_context *i830 = i830_context(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + DECLARE_RENDERINPUTS(index_bitset); + GLuint v0 = _3DSTATE_VFT0_CMD; + GLuint v2 = _3DSTATE_VFT1_CMD; + GLuint mcsb1 = 0; + + RENDERINPUTS_COPY(index_bitset, tnl->render_inputs_bitset); + + /* Important: + */ + VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr; + intel->vertex_attr_count = 0; + + /* EMIT_ATTR's must be in order as they tell t_vertex.c how to + * build up a hardware vertex. + */ + if (RENDERINPUTS_TEST_RANGE(index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX)) { + EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, VFT0_XYZW); + intel->coloroffset = 4; + } + else { + EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, VFT0_XYZ); + intel->coloroffset = 3; + } + + if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_POINTSIZE)) { + EMIT_ATTR(_TNL_ATTRIB_POINTSIZE, EMIT_1F, VFT0_POINT_WIDTH); + } + + EMIT_ATTR(_TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, VFT0_DIFFUSE); + + intel->specoffset = 0; + if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_COLOR1) || + RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_FOG)) { + if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_COLOR1)) { + intel->specoffset = intel->coloroffset + 1; + EMIT_ATTR(_TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, VFT0_SPEC); + } + else + EMIT_PAD(3); + + if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_FOG)) + EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1UB_1F, VFT0_SPEC); + else + EMIT_PAD(1); + } + + if (RENDERINPUTS_TEST_RANGE(index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX)) { + int i, count = 0; + + for (i = 0; i < I830_TEX_UNITS; i++) { + if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_TEX(i))) { + GLuint sz = VB->TexCoordPtr[i]->size; + GLuint emit; + GLuint mcs = (i830->state.Tex[i][I830_TEXREG_MCS] & + ~TEXCOORDTYPE_MASK); + + switch (sz) { + case 1: + case 2: + emit = EMIT_2F; + sz = 2; + mcs |= TEXCOORDTYPE_CARTESIAN; + break; + case 3: + emit = EMIT_3F; + sz = 3; + mcs |= TEXCOORDTYPE_VECTOR; + break; + case 4: + emit = EMIT_3F_XYW; + sz = 3; + mcs |= TEXCOORDTYPE_HOMOGENEOUS; + break; + default: + continue; + }; + + + EMIT_ATTR(_TNL_ATTRIB_TEX0 + i, emit, 0); + v2 |= VRTX_TEX_SET_FMT(count, SZ_TO_HW(sz)); + mcsb1 |= (count + 8) << (i * 4); + + if (mcs != i830->state.Tex[i][I830_TEXREG_MCS]) { + I830_STATECHANGE(i830, I830_UPLOAD_TEX(i)); + i830->state.Tex[i][I830_TEXREG_MCS] = mcs; + } + + count++; + } + } + + v0 |= VFT0_TEX_COUNT(count); + } + + /* Only need to change the vertex emit code if there has been a + * statechange to a new hardware vertex format: + */ + if (v0 != i830->state.Ctx[I830_CTXREG_VF] || + v2 != i830->state.Ctx[I830_CTXREG_VF2] || + mcsb1 != i830->state.Ctx[I830_CTXREG_MCSB1] || + !RENDERINPUTS_EQUAL(index_bitset, i830->last_index_bitset)) { + int k; + + I830_STATECHANGE(i830, I830_UPLOAD_CTX); + + /* Must do this *after* statechange, so as not to affect + * buffered vertices reliant on the old state: + */ + intel->vertex_size = + _tnl_install_attrs(ctx, + intel->vertex_attrs, + intel->vertex_attr_count, + intel->ViewportMatrix.m, 0); + + intel->vertex_size >>= 2; + + i830->state.Ctx[I830_CTXREG_VF] = v0; + i830->state.Ctx[I830_CTXREG_VF2] = v2; + i830->state.Ctx[I830_CTXREG_MCSB1] = mcsb1; + RENDERINPUTS_COPY(i830->last_index_bitset, index_bitset); + + k = i830_check_vertex_size(intel, intel->vertex_size); + assert(k); + } +} + +static void +i830_reduced_primitive_state(struct intel_context *intel, GLenum rprim) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + GLuint st1 = i830->state.Stipple[I830_STPREG_ST1]; + + st1 &= ~ST1_ENABLE; + + switch (rprim) { + case GL_TRIANGLES: + if (intel->ctx.Polygon.StippleFlag && intel->hw_stipple) + st1 |= ST1_ENABLE; + break; + case GL_LINES: + case GL_POINTS: + default: + break; + } + + i830->intel.reduced_primitive = rprim; + + if (st1 != i830->state.Stipple[I830_STPREG_ST1]) { + INTEL_FIREVERTICES(intel); + + I830_STATECHANGE(i830, I830_UPLOAD_STIPPLE); + i830->state.Stipple[I830_STPREG_ST1] = st1; + } +} + +/* Pull apart the vertex format registers and figure out how large a + * vertex is supposed to be. + */ +static GLboolean +i830_check_vertex_size(struct intel_context *intel, GLuint expected) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + int vft0 = i830->current->Ctx[I830_CTXREG_VF]; + int vft1 = i830->current->Ctx[I830_CTXREG_VF2]; + int nrtex = (vft0 & VFT0_TEX_COUNT_MASK) >> VFT0_TEX_COUNT_SHIFT; + int i, sz = 0; + + switch (vft0 & VFT0_XYZW_MASK) { + case VFT0_XY: + sz = 2; + break; + case VFT0_XYZ: + sz = 3; + break; + case VFT0_XYW: + sz = 3; + break; + case VFT0_XYZW: + sz = 4; + break; + default: + fprintf(stderr, "no xyzw specified\n"); + return 0; + } + + if (vft0 & VFT0_SPEC) + sz++; + if (vft0 & VFT0_DIFFUSE) + sz++; + if (vft0 & VFT0_DEPTH_OFFSET) + sz++; + if (vft0 & VFT0_POINT_WIDTH) + sz++; + + for (i = 0; i < nrtex; i++) { + switch (vft1 & VFT1_TEX0_MASK) { + case TEXCOORDFMT_2D: + sz += 2; + break; + case TEXCOORDFMT_3D: + sz += 3; + break; + case TEXCOORDFMT_4D: + sz += 4; + break; + case TEXCOORDFMT_1D: + sz += 1; + break; + } + vft1 >>= VFT1_TEX1_SHIFT; + } + + if (sz != expected) + fprintf(stderr, "vertex size mismatch %d/%d\n", sz, expected); + + return sz == expected; +} + +static void +i830_emit_invarient_state(struct intel_context *intel) +{ + BATCH_LOCALS; + + BEGIN_BATCH(40, 0); + + OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_DFLT_Z_CMD); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_FOG_MODE_CMD); + OUT_BATCH(FOGFUNC_ENABLE | + FOG_LINEAR_CONST | FOGSRC_INDEX_Z | ENABLE_FOG_DENSITY); + OUT_BATCH(0); + OUT_BATCH(0); + + + OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | + MAP_UNIT(0) | + DISABLE_TEX_STREAM_BUMP | + ENABLE_TEX_STREAM_COORD_SET | + TEX_STREAM_COORD_SET(0) | + ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(0)); + OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | + MAP_UNIT(1) | + DISABLE_TEX_STREAM_BUMP | + ENABLE_TEX_STREAM_COORD_SET | + TEX_STREAM_COORD_SET(1) | + ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(1)); + OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | + MAP_UNIT(2) | + DISABLE_TEX_STREAM_BUMP | + ENABLE_TEX_STREAM_COORD_SET | + TEX_STREAM_COORD_SET(2) | + ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(2)); + OUT_BATCH(_3DSTATE_MAP_TEX_STREAM_CMD | + MAP_UNIT(3) | + DISABLE_TEX_STREAM_BUMP | + ENABLE_TEX_STREAM_COORD_SET | + TEX_STREAM_COORD_SET(3) | + ENABLE_TEX_STREAM_MAP_IDX | TEX_STREAM_MAP_IDX(3)); + + OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM); + OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(0)); + OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM); + OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(1)); + OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM); + OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(2)); + OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM); + OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(3)); + + OUT_BATCH(_3DSTATE_RASTER_RULES_CMD | + ENABLE_POINT_RASTER_RULE | + OGL_POINT_RASTER_RULE | + ENABLE_LINE_STRIP_PROVOKE_VRTX | + ENABLE_TRI_FAN_PROVOKE_VRTX | + ENABLE_TRI_STRIP_PROVOKE_VRTX | + LINE_STRIP_PROVOKE_VRTX(1) | + TRI_FAN_PROVOKE_VRTX(2) | TRI_STRIP_PROVOKE_VRTX(2)); + + OUT_BATCH(_3DSTATE_VERTEX_TRANSFORM); + OUT_BATCH(DISABLE_VIEWPORT_TRANSFORM | DISABLE_PERSPECTIVE_DIVIDE); + + OUT_BATCH(_3DSTATE_W_STATE_CMD); + OUT_BATCH(MAGIC_W_STATE_DWORD1); + OUT_BATCH(0x3f800000 /* 1.0 in IEEE float */ ); + + + OUT_BATCH(_3DSTATE_COLOR_FACTOR_CMD); + OUT_BATCH(0x80808080); /* .5 required in alpha for GL_DOT3_RGBA_EXT */ + + ADVANCE_BATCH(); +} + + +#define emit( intel, state, size ) \ +do { \ + int k; \ + BEGIN_BATCH(size / sizeof(GLuint), 0); \ + for (k = 0 ; k < size / sizeof(GLuint) ; k++) { \ + if (0) _mesa_printf(" 0x%08x\n", state[k]); \ + OUT_BATCH(state[k]); \ + } \ + ADVANCE_BATCH(); \ +} while (0) + +static GLuint +get_state_size(struct i830_hw_state *state) +{ + GLuint dirty = state->active & ~state->emitted; + GLuint sz = 0; + GLuint i; + + if (dirty & I830_UPLOAD_INVARIENT) + sz += 40 * sizeof(int); + + if (dirty & I830_UPLOAD_CTX) + sz += sizeof(state->Ctx); + + if (dirty & I830_UPLOAD_BUFFERS) + sz += sizeof(state->Buffer); + + if (dirty & I830_UPLOAD_STIPPLE) + sz += sizeof(state->Stipple); + + for (i = 0; i < I830_TEX_UNITS; i++) { + if ((dirty & I830_UPLOAD_TEX(i))) + sz += sizeof(state->Tex[i]); + + if (dirty & I830_UPLOAD_TEXBLEND(i)) + sz += state->TexBlendWordsUsed[i] * 4; + } + + return sz; +} + + +/* Push the state into the sarea and/or texture memory. + */ +static void +i830_emit_state(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + struct i830_hw_state *state = i830->current; + int i; + GLuint dirty; + BATCH_LOCALS; + + /* We don't hold the lock at this point, so want to make sure that + * there won't be a buffer wrap. + * + * It might be better to talk about explicit places where + * scheduling is allowed, rather than assume that it is whenever a + * batchbuffer fills up. + */ + intel_batchbuffer_require_space(intel->batch, get_state_size(state), 0); + + /* Do this here as we may have flushed the batchbuffer above, + * causing more state to be dirty! + */ + dirty = state->active & ~state->emitted; + + if (dirty & I830_UPLOAD_INVARIENT) { + DBG("I830_UPLOAD_INVARIENT:\n"); + i830_emit_invarient_state(intel); + } + + if (dirty & I830_UPLOAD_CTX) { + DBG("I830_UPLOAD_CTX:\n"); + emit(i830, state->Ctx, sizeof(state->Ctx)); + + } + + if (dirty & I830_UPLOAD_BUFFERS) { + DBG("I830_UPLOAD_BUFFERS:\n"); + BEGIN_BATCH(I830_DEST_SETUP_SIZE + 2, 0); + OUT_BATCH(state->Buffer[I830_DESTREG_CBUFADDR0]); + OUT_BATCH(state->Buffer[I830_DESTREG_CBUFADDR1]); + OUT_RELOC(state->draw_region->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); + + if (state->depth_region) { + OUT_BATCH(state->Buffer[I830_DESTREG_DBUFADDR0]); + OUT_BATCH(state->Buffer[I830_DESTREG_DBUFADDR1]); + OUT_RELOC(state->depth_region->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); + } + + OUT_BATCH(state->Buffer[I830_DESTREG_DV0]); + OUT_BATCH(state->Buffer[I830_DESTREG_DV1]); + OUT_BATCH(state->Buffer[I830_DESTREG_SENABLE]); + OUT_BATCH(state->Buffer[I830_DESTREG_SR0]); + OUT_BATCH(state->Buffer[I830_DESTREG_SR1]); + OUT_BATCH(state->Buffer[I830_DESTREG_SR2]); + ADVANCE_BATCH(); + } + + if (dirty & I830_UPLOAD_STIPPLE) { + DBG("I830_UPLOAD_STIPPLE:\n"); + emit(i830, state->Stipple, sizeof(state->Stipple)); + } + + for (i = 0; i < I830_TEX_UNITS; i++) { + if ((dirty & I830_UPLOAD_TEX(i))) { + DBG("I830_UPLOAD_TEX(%d):\n", i); + + BEGIN_BATCH(I830_TEX_SETUP_SIZE + 1, 0); + OUT_BATCH(state->Tex[i][I830_TEXREG_TM0LI]); + + if (state->tex_buffer[i]) { + OUT_RELOC(state->tex_buffer[i], + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, + state->tex_offset[i] | TM0S0_USE_FENCE); + } + else { + assert(i == 0); + assert(state == &i830->meta); + OUT_BATCH(0); + } + + OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S1]); + OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S2]); + OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S3]); + OUT_BATCH(state->Tex[i][I830_TEXREG_TM0S4]); + OUT_BATCH(state->Tex[i][I830_TEXREG_MCS]); + OUT_BATCH(state->Tex[i][I830_TEXREG_CUBE]); + } + + if (dirty & I830_UPLOAD_TEXBLEND(i)) { + DBG("I830_UPLOAD_TEXBLEND(%d): %d words\n", i, + state->TexBlendWordsUsed[i]); + emit(i830, state->TexBlend[i], state->TexBlendWordsUsed[i] * 4); + } + } + + state->emitted |= dirty; +} + +static void +i830_destroy_context(struct intel_context *intel) +{ + _tnl_free_vertices(&intel->ctx); +} + +static void +i830_set_draw_region(struct intel_context *intel, + struct intel_region *draw_region, + struct intel_region *depth_region) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + + intel_region_release(&i830->state.draw_region); + intel_region_release(&i830->state.depth_region); + intel_region_reference(&i830->state.draw_region, draw_region); + intel_region_reference(&i830->state.depth_region, depth_region); + + /* XXX FBO: Need code from i915_set_draw_region() */ + + I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS); + I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS); + i830->state.Buffer[I830_DESTREG_CBUFADDR1] = + (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(draw_region->pitch) | + BUF_3D_USE_FENCE); + i830->state.Buffer[I830_DESTREG_DBUFADDR1] = + (BUF_3D_ID_DEPTH | BUF_3D_PITCH(depth_region->pitch) | + BUF_3D_USE_FENCE); +} + +#if 0 +static void +i830_update_color_z_regions(intelContextPtr intel, + const intelRegion * colorRegion, + const intelRegion * depthRegion) +{ + i830ContextPtr i830 = I830_CONTEXT(intel); + + i830->state.Buffer[I830_DESTREG_CBUFADDR1] = + (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(colorRegion->pitch) | + BUF_3D_USE_FENCE); + i830->state.Buffer[I830_DESTREG_CBUFADDR2] = colorRegion->offset; + + i830->state.Buffer[I830_DESTREG_DBUFADDR1] = + (BUF_3D_ID_DEPTH | BUF_3D_PITCH(depthRegion->pitch) | BUF_3D_USE_FENCE); + i830->state.Buffer[I830_DESTREG_DBUFADDR2] = depthRegion->offset; +} +#endif + + +/* This isn't really handled at the moment. + */ +static void +i830_lost_hardware(struct intel_context *intel) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + i830->state.emitted = 0; +} + + + +static GLuint +i830_flush_cmd(void) +{ + return MI_FLUSH | FLUSH_MAP_CACHE; +} + + +static void +i830_assert_not_dirty( struct intel_context *intel ) +{ + struct i830_context *i830 = i830_context(&intel->ctx); + struct i830_hw_state *state = i830->current; + GLuint dirty = state->active & ~state->emitted; + assert(!dirty); +} + + +void +i830InitVtbl(struct i830_context *i830) +{ + i830->intel.vtbl.check_vertex_size = i830_check_vertex_size; + i830->intel.vtbl.destroy = i830_destroy_context; + i830->intel.vtbl.emit_state = i830_emit_state; + i830->intel.vtbl.lost_hardware = i830_lost_hardware; + i830->intel.vtbl.reduced_primitive_state = i830_reduced_primitive_state; + i830->intel.vtbl.set_draw_region = i830_set_draw_region; + i830->intel.vtbl.update_texture_state = i830UpdateTextureState; + i830->intel.vtbl.flush_cmd = i830_flush_cmd; + i830->intel.vtbl.render_start = i830_render_start; + i830->intel.vtbl.assert_not_dirty = i830_assert_not_dirty; +} diff --git a/src/mesa/drivers/dri/i915tex/i915_context.c b/src/mesa/drivers/dri/i915tex/i915_context.c new file mode 100644 index 0000000000..4cbe29d79d --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_context.c @@ -0,0 +1,175 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "i915_context.h" +#include "imports.h" +#include "intel_tex.h" +#include "intel_tris.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" +#include "tnl/t_vertex.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/tnl.h" +#include "array_cache/acache.h" + +#include "utils.h" +#include "i915_reg.h" + +#include "intel_regions.h" +#include "intel_batchbuffer.h" + +/*************************************** + * Mesa's Driver Functions + ***************************************/ + +static const struct dri_extension i915_extensions[] = { + {"GL_ARB_depth_texture", NULL}, + {"GL_ARB_fragment_program", NULL}, + {"GL_ARB_shadow", NULL}, + {"GL_ARB_texture_env_crossbar", NULL}, + {"GL_ARB_texture_non_power_of_two", NULL}, + {"GL_EXT_shadow_funcs", NULL}, + /* ARB extn won't work if not enabled */ + {"GL_SGIX_depth_texture", NULL}, + {NULL, NULL} +}; + +/* Override intel default. + */ +static void +i915InvalidateState(GLcontext * ctx, GLuint new_state) +{ + _swrast_InvalidateState(ctx, new_state); + _swsetup_InvalidateState(ctx, new_state); + _ac_InvalidateState(ctx, new_state); + _tnl_InvalidateState(ctx, new_state); + _tnl_invalidate_vertex_state(ctx, new_state); + intel_context(ctx)->NewGLState |= new_state; + + /* Todo: gather state values under which tracked parameters become + * invalidated, add callbacks for things like + * ProgramLocalParameters, etc. + */ + { + struct i915_fragment_program *p = + (struct i915_fragment_program *) ctx->FragmentProgram._Current; + if (p && p->nr_params) + p->params_uptodate = 0; + } + + if (new_state & (_NEW_FOG | _NEW_HINT | _NEW_PROGRAM)) + i915_update_fog(ctx); +} + + +static void +i915InitDriverFunctions(struct dd_function_table *functions) +{ + intelInitDriverFunctions(functions); + i915InitStateFunctions(functions); + i915InitTextureFuncs(functions); + i915InitFragProgFuncs(functions); + functions->UpdateState = i915InvalidateState; +} + + + +GLboolean +i915CreateContext(const __GLcontextModes * mesaVis, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate) +{ + struct dd_function_table functions; + struct i915_context *i915 = + (struct i915_context *) CALLOC_STRUCT(i915_context); + struct intel_context *intel = &i915->intel; + GLcontext *ctx = &intel->ctx; + + if (!i915) + return GL_FALSE; + + if (0) + _mesa_printf("\ntexmem-0-3 branch\n\n"); + + i915InitVtbl(i915); + i915InitMetaFuncs(i915); + + i915InitDriverFunctions(&functions); + + if (!intelInitContext(intel, mesaVis, driContextPriv, + sharedContextPrivate, &functions)) { + FREE(i915); + return GL_FALSE; + } + + ctx->Const.MaxTextureUnits = I915_TEX_UNITS; + ctx->Const.MaxTextureImageUnits = I915_TEX_UNITS; + ctx->Const.MaxTextureCoordUnits = I915_TEX_UNITS; + + + /* Advertise the full hardware capabilities. The new memory + * manager should cope much better with overload situations: + */ + ctx->Const.MaxTextureLevels = 12; + ctx->Const.Max3DTextureLevels = 9; + ctx->Const.MaxCubeTextureLevels = 12; + ctx->Const.MaxTextureRectSize = (1 << 11); + ctx->Const.MaxTextureUnits = I915_TEX_UNITS; + + /* GL_ARB_fragment_program limits - don't think Mesa actually + * validates programs against these, and in any case one ARB + * instruction can translate to more than one HW instruction, so + * we'll still have to check and fallback each time. + */ + ctx->Const.FragmentProgram.MaxNativeTemps = I915_MAX_TEMPORARY; + ctx->Const.FragmentProgram.MaxNativeAttribs = 11; /* 8 tex, 2 color, fog */ + ctx->Const.FragmentProgram.MaxNativeParameters = I915_MAX_CONSTANT; + ctx->Const.FragmentProgram.MaxNativeAluInstructions = I915_MAX_ALU_INSN; + ctx->Const.FragmentProgram.MaxNativeTexInstructions = I915_MAX_TEX_INSN; + ctx->Const.FragmentProgram.MaxNativeInstructions = (I915_MAX_ALU_INSN + + I915_MAX_TEX_INSN); + ctx->Const.FragmentProgram.MaxNativeTexIndirections = + I915_MAX_TEX_INDIRECT; + ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; /* I don't think we have one */ + + ctx->_MaintainTexEnvProgram = 1; + ctx->_UseTexEnvProgram = 1; + + driInitExtensions(ctx, i915_extensions, GL_FALSE); + + + _tnl_init_vertices(ctx, ctx->Const.MaxArrayLockSize + 12, + 36 * sizeof(GLfloat)); + + intel->verts = TNL_CONTEXT(ctx)->clipspace.vertex_buf; + + i915InitState(i915); + + return GL_TRUE; +} diff --git a/src/mesa/drivers/dri/i915tex/i915_context.h b/src/mesa/drivers/dri/i915tex/i915_context.h new file mode 100644 index 0000000000..5ae76fcd18 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_context.h @@ -0,0 +1,367 @@ + /************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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. + * + **************************************************************************/ + +#ifndef I915CONTEXT_INC +#define I915CONTEXT_INC + +#include "intel_context.h" + +#define I915_FALLBACK_TEXTURE 0x1000 +#define I915_FALLBACK_COLORMASK 0x2000 +#define I915_FALLBACK_STENCIL 0x4000 +#define I915_FALLBACK_STIPPLE 0x8000 +#define I915_FALLBACK_PROGRAM 0x10000 +#define I915_FALLBACK_LOGICOP 0x20000 +#define I915_FALLBACK_POLYGON_SMOOTH 0x40000 +#define I915_FALLBACK_POINT_SMOOTH 0x80000 + +#define I915_UPLOAD_CTX 0x1 +#define I915_UPLOAD_BUFFERS 0x2 +#define I915_UPLOAD_STIPPLE 0x4 +#define I915_UPLOAD_PROGRAM 0x8 +#define I915_UPLOAD_CONSTANTS 0x10 +#define I915_UPLOAD_FOG 0x20 +#define I915_UPLOAD_INVARIENT 0x40 +#define I915_UPLOAD_DEFAULTS 0x80 +#define I915_UPLOAD_TEX(i) (0x00010000<<(i)) +#define I915_UPLOAD_TEX_ALL (0x00ff0000) +#define I915_UPLOAD_TEX_0_SHIFT 16 + + +/* State structure offsets - these will probably disappear. + */ +#define I915_DESTREG_CBUFADDR0 0 +#define I915_DESTREG_CBUFADDR1 1 +#define I915_DESTREG_DBUFADDR0 3 +#define I915_DESTREG_DBUFADDR1 4 +#define I915_DESTREG_DV0 6 +#define I915_DESTREG_DV1 7 +#define I915_DESTREG_SENABLE 8 +#define I915_DESTREG_SR0 9 +#define I915_DESTREG_SR1 10 +#define I915_DESTREG_SR2 11 +#define I915_DEST_SETUP_SIZE 12 + +#define I915_CTXREG_STATE4 0 +#define I915_CTXREG_LI 1 +#define I915_CTXREG_LIS2 2 +#define I915_CTXREG_LIS4 3 +#define I915_CTXREG_LIS5 4 +#define I915_CTXREG_LIS6 5 +#define I915_CTXREG_IAB 6 +#define I915_CTXREG_BLENDCOLOR0 7 +#define I915_CTXREG_BLENDCOLOR1 8 +#define I915_CTX_SETUP_SIZE 9 + +#define I915_FOGREG_COLOR 0 +#define I915_FOGREG_MODE0 1 +#define I915_FOGREG_MODE1 2 +#define I915_FOGREG_MODE2 3 +#define I915_FOGREG_MODE3 4 +#define I915_FOG_SETUP_SIZE 5 + +#define I915_STPREG_ST0 0 +#define I915_STPREG_ST1 1 +#define I915_STP_SETUP_SIZE 2 + +#define I915_TEXREG_MS3 1 +#define I915_TEXREG_MS4 2 +#define I915_TEXREG_SS2 3 +#define I915_TEXREG_SS3 4 +#define I915_TEXREG_SS4 5 +#define I915_TEX_SETUP_SIZE 6 + +#define I915_DEFREG_C0 0 +#define I915_DEFREG_C1 1 +#define I915_DEFREG_S0 2 +#define I915_DEFREG_S1 3 +#define I915_DEFREG_Z0 4 +#define I915_DEFREG_Z1 5 +#define I915_DEF_SETUP_SIZE 6 + + +#define I915_MAX_CONSTANT 32 +#define I915_CONSTANT_SIZE (2+(4*I915_MAX_CONSTANT)) + + +#define I915_PROGRAM_SIZE 192 + + +/* Hardware version of a parsed fragment program. "Derived" from the + * mesa fragment_program struct. + */ +struct i915_fragment_program +{ + struct gl_fragment_program FragProg; + + GLboolean translated; + GLboolean params_uptodate; + GLboolean on_hardware; + GLboolean error; /* If program is malformed for any reason. */ + + GLuint nr_tex_indirect; + GLuint nr_tex_insn; + GLuint nr_alu_insn; + GLuint nr_decl_insn; + + + + + /* TODO: split between the stored representation of a program and + * the state used to build that representation. + */ + GLcontext *ctx; + + GLuint declarations[I915_PROGRAM_SIZE]; + GLuint program[I915_PROGRAM_SIZE]; + + GLfloat constant[I915_MAX_CONSTANT][4]; + GLuint constant_flags[I915_MAX_CONSTANT]; + GLuint nr_constants; + + GLuint *csr; /* Cursor, points into program. + */ + + GLuint *decl; /* Cursor, points into declarations. + */ + + GLuint decl_s; /* flags for which s regs need to be decl'd */ + GLuint decl_t; /* flags for which t regs need to be decl'd */ + + GLuint temp_flag; /* Tracks temporary regs which are in + * use. + */ + + GLuint utemp_flag; /* Tracks TYPE_U temporary regs which are in + * use. + */ + + + + /* Helpers for i915_fragprog.c: + */ + GLuint wpos_tex; + GLboolean depth_written; + + struct + { + GLuint reg; /* Hardware constant idx */ + const GLfloat *values; /* Pointer to tracked values */ + } param[I915_MAX_CONSTANT]; + GLuint nr_params; + + + /* Helpers for i915_texprog.c: + */ + GLuint src_texture; /* Reg containing sampled texture color, + * else UREG_BAD. + */ + + GLuint src_previous; /* Reg containing color from previous + * stage. May need to be decl'd. + */ + + GLuint last_tex_stage; /* Number of last enabled texture unit */ + + struct vertex_buffer *VB; +}; + + + + + + + +#define I915_TEX_UNITS 8 + + +struct i915_hw_state +{ + GLuint Ctx[I915_CTX_SETUP_SIZE]; + GLuint Buffer[I915_DEST_SETUP_SIZE]; + GLuint Stipple[I915_STP_SETUP_SIZE]; + GLuint Fog[I915_FOG_SETUP_SIZE]; + GLuint Defaults[I915_DEF_SETUP_SIZE]; + GLuint Tex[I915_TEX_UNITS][I915_TEX_SETUP_SIZE]; + GLuint Constant[I915_CONSTANT_SIZE]; + GLuint ConstantSize; + GLuint Program[I915_PROGRAM_SIZE]; + GLuint ProgramSize; + + /* Region pointers for relocation: + */ + struct intel_region *draw_region; + struct intel_region *depth_region; +/* struct intel_region *tex_region[I915_TEX_UNITS]; */ + + /* Regions aren't actually that appropriate here as the memory may + * be from a PBO or FBO. Just use the buffer id. Will have to do + * this for draw and depth for FBO's... + */ + struct _DriBufferObject *tex_buffer[I915_TEX_UNITS]; + GLuint tex_offset[I915_TEX_UNITS]; + + + GLuint active; /* I915_UPLOAD_* */ + GLuint emitted; /* I915_UPLOAD_* */ +}; + +#define I915_FOG_PIXEL 2 +#define I915_FOG_VERTEX 1 +#define I915_FOG_NONE 0 + +struct i915_context +{ + struct intel_context intel; + + GLuint last_ReallyEnabled; + GLuint vertex_fog; + GLuint lodbias_ss2[MAX_TEXTURE_UNITS]; + + + struct i915_fragment_program tex_program; + struct i915_fragment_program *current_program; + + struct i915_hw_state meta, initial, state, *current; +}; + + +#define I915_STATECHANGE(i915, flag) \ +do { \ + INTEL_FIREVERTICES( &(i915)->intel ); \ + (i915)->state.emitted &= ~(flag); \ +} while (0) + +#define I915_ACTIVESTATE(i915, flag, mode) \ +do { \ + INTEL_FIREVERTICES( &(i915)->intel ); \ + if (mode) \ + (i915)->state.active |= (flag); \ + else \ + (i915)->state.active &= ~(flag); \ +} while (0) + + +/*====================================================================== + * i915_vtbl.c + */ +extern void i915InitVtbl(struct i915_context *i915); + +extern void +i915_state_draw_region(struct intel_context *intel, + struct i915_hw_state *state, + struct intel_region *color_region, + struct intel_region *depth_region); + + + +#define SZ_TO_HW(sz) ((sz-2)&0x3) +#define EMIT_SZ(sz) (EMIT_1F + (sz) - 1) +#define EMIT_ATTR( ATTR, STYLE, S4, SZ ) \ +do { \ + intel->vertex_attrs[intel->vertex_attr_count].attrib = (ATTR); \ + intel->vertex_attrs[intel->vertex_attr_count].format = (STYLE); \ + s4 |= S4; \ + intel->vertex_attr_count++; \ + offset += (SZ); \ +} while (0) + +#define EMIT_PAD( N ) \ +do { \ + intel->vertex_attrs[intel->vertex_attr_count].attrib = 0; \ + intel->vertex_attrs[intel->vertex_attr_count].format = EMIT_PAD; \ + intel->vertex_attrs[intel->vertex_attr_count].offset = (N); \ + intel->vertex_attr_count++; \ + offset += (N); \ +} while (0) + + + +/*====================================================================== + * i915_context.c + */ +extern GLboolean i915CreateContext(const __GLcontextModes * mesaVis, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate); + + +/*====================================================================== + * i915_texprog.c + */ +extern void i915ValidateTextureProgram(struct i915_context *i915); + + +/*====================================================================== + * i915_debug.c + */ +extern void i915_disassemble_program(const GLuint * program, GLuint sz); +extern void i915_print_ureg(const char *msg, GLuint ureg); + + +/*====================================================================== + * i915_state.c + */ +extern void i915InitStateFunctions(struct dd_function_table *functions); +extern void i915InitState(struct i915_context *i915); +extern void i915_update_fog(GLcontext * ctx); + + +/*====================================================================== + * i915_tex.c + */ +extern void i915UpdateTextureState(struct intel_context *intel); +extern void i915InitTextureFuncs(struct dd_function_table *functions); + +/*====================================================================== + * i915_metaops.c + */ +void i915InitMetaFuncs(struct i915_context *i915); + + +/*====================================================================== + * i915_fragprog.c + */ +extern void i915ValidateFragmentProgram(struct i915_context *i915); +extern void i915InitFragProgFuncs(struct dd_function_table *functions); + +/*====================================================================== + * Inline conversion functions. These are better-typed than the + * macros used previously: + */ +static INLINE struct i915_context * +i915_context(GLcontext * ctx) +{ + return (struct i915_context *) ctx; +} + + + +#define I915_CONTEXT(ctx) i915_context(ctx) + + + +#endif diff --git a/src/mesa/drivers/dri/i915tex/i915_debug.c b/src/mesa/drivers/dri/i915tex/i915_debug.c new file mode 100644 index 0000000000..974527e14c --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_debug.c @@ -0,0 +1,334 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "i915_reg.h" +#include "i915_context.h" +#include + + +static const char *opcodes[0x20] = { + "NOP", + "ADD", + "MOV", + "MUL", + "MAD", + "DP2ADD", + "DP3", + "DP4", + "FRC", + "RCP", + "RSQ", + "EXP", + "LOG", + "CMP", + "MIN", + "MAX", + "FLR", + "MOD", + "TRC", + "SGE", + "SLT", + "TEXLD", + "TEXLDP", + "TEXLDB", + "TEXKILL", + "DCL", + "0x1a", + "0x1b", + "0x1c", + "0x1d", + "0x1e", + "0x1f", +}; + + +static const int args[0x20] = { + 0, /* 0 nop */ + 2, /* 1 add */ + 1, /* 2 mov */ + 2, /* 3 m ul */ + 3, /* 4 mad */ + 3, /* 5 dp2add */ + 2, /* 6 dp3 */ + 2, /* 7 dp4 */ + 1, /* 8 frc */ + 1, /* 9 rcp */ + 1, /* a rsq */ + 1, /* b exp */ + 1, /* c log */ + 3, /* d cmp */ + 2, /* e min */ + 2, /* f max */ + 1, /* 10 flr */ + 1, /* 11 mod */ + 1, /* 12 trc */ + 2, /* 13 sge */ + 2, /* 14 slt */ + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + + +static const char *regname[0x8] = { + "R", + "T", + "CONST", + "S", + "OC", + "OD", + "U", + "UNKNOWN", +}; + +static void +print_reg_type_nr(GLuint type, GLuint nr) +{ + switch (type) { + case REG_TYPE_T: + switch (nr) { + case T_DIFFUSE: + fprintf(stderr, "T_DIFFUSE"); + return; + case T_SPECULAR: + fprintf(stderr, "T_SPECULAR"); + return; + case T_FOG_W: + fprintf(stderr, "T_FOG_W"); + return; + default: + fprintf(stderr, "T_TEX%d", nr); + return; + } + case REG_TYPE_OC: + if (nr == 0) { + fprintf(stderr, "oC"); + return; + } + break; + case REG_TYPE_OD: + if (nr == 0) { + fprintf(stderr, "oD"); + return; + } + break; + default: + break; + } + + fprintf(stderr, "%s[%d]", regname[type], nr); +} + +#define REG_SWIZZLE_MASK 0x7777 +#define REG_NEGATE_MASK 0x8888 + +#define REG_SWIZZLE_XYZW ((SRC_X << A2_SRC2_CHANNEL_X_SHIFT) | \ + (SRC_Y << A2_SRC2_CHANNEL_Y_SHIFT) | \ + (SRC_Z << A2_SRC2_CHANNEL_Z_SHIFT) | \ + (SRC_W << A2_SRC2_CHANNEL_W_SHIFT)) + + +static void +print_reg_neg_swizzle(GLuint reg) +{ + int i; + + if ((reg & REG_SWIZZLE_MASK) == REG_SWIZZLE_XYZW && + (reg & REG_NEGATE_MASK) == 0) + return; + + fprintf(stderr, "."); + + for (i = 3; i >= 0; i--) { + if (reg & (1 << ((i * 4) + 3))) + fprintf(stderr, "-"); + + switch ((reg >> (i * 4)) & 0x7) { + case 0: + fprintf(stderr, "x"); + break; + case 1: + fprintf(stderr, "y"); + break; + case 2: + fprintf(stderr, "z"); + break; + case 3: + fprintf(stderr, "w"); + break; + case 4: + fprintf(stderr, "0"); + break; + case 5: + fprintf(stderr, "1"); + break; + default: + fprintf(stderr, "?"); + break; + } + } +} + + +static void +print_src_reg(GLuint dword) +{ + GLuint nr = (dword >> A2_SRC2_NR_SHIFT) & REG_NR_MASK; + GLuint type = (dword >> A2_SRC2_TYPE_SHIFT) & REG_TYPE_MASK; + print_reg_type_nr(type, nr); + print_reg_neg_swizzle(dword); +} + +void +i915_print_ureg(const char *msg, GLuint ureg) +{ + fprintf(stderr, "%s: ", msg); + print_src_reg(ureg >> 8); + fprintf(stderr, "\n"); +} + +static void +print_dest_reg(GLuint dword) +{ + GLuint nr = (dword >> A0_DEST_NR_SHIFT) & REG_NR_MASK; + GLuint type = (dword >> A0_DEST_TYPE_SHIFT) & REG_TYPE_MASK; + print_reg_type_nr(type, nr); + if ((dword & A0_DEST_CHANNEL_ALL) == A0_DEST_CHANNEL_ALL) + return; + fprintf(stderr, "."); + if (dword & A0_DEST_CHANNEL_X) + fprintf(stderr, "x"); + if (dword & A0_DEST_CHANNEL_Y) + fprintf(stderr, "y"); + if (dword & A0_DEST_CHANNEL_Z) + fprintf(stderr, "z"); + if (dword & A0_DEST_CHANNEL_W) + fprintf(stderr, "w"); +} + + +#define GET_SRC0_REG(r0, r1) ((r0<<14)|(r1>>A1_SRC0_CHANNEL_W_SHIFT)) +#define GET_SRC1_REG(r0, r1) ((r0<<8)|(r1>>A2_SRC1_CHANNEL_W_SHIFT)) +#define GET_SRC2_REG(r) (r) + + +static void +print_arith_op(GLuint opcode, const GLuint * program) +{ + if (opcode != A0_NOP) { + print_dest_reg(program[0]); + if (program[0] & A0_DEST_SATURATE) + fprintf(stderr, " = SATURATE "); + else + fprintf(stderr, " = "); + } + + fprintf(stderr, "%s ", opcodes[opcode]); + + print_src_reg(GET_SRC0_REG(program[0], program[1])); + if (args[opcode] == 1) { + fprintf(stderr, "\n"); + return; + } + + fprintf(stderr, ", "); + print_src_reg(GET_SRC1_REG(program[1], program[2])); + if (args[opcode] == 2) { + fprintf(stderr, "\n"); + return; + } + + fprintf(stderr, ", "); + print_src_reg(GET_SRC2_REG(program[2])); + fprintf(stderr, "\n"); + return; +} + + +static void +print_tex_op(GLuint opcode, const GLuint * program) +{ + print_dest_reg(program[0] | A0_DEST_CHANNEL_ALL); + fprintf(stderr, " = "); + + fprintf(stderr, "%s ", opcodes[opcode]); + + fprintf(stderr, "S[%d],", program[0] & T0_SAMPLER_NR_MASK); + + print_reg_type_nr((program[1] >> T1_ADDRESS_REG_TYPE_SHIFT) & + REG_TYPE_MASK, + (program[1] >> T1_ADDRESS_REG_NR_SHIFT) & REG_NR_MASK); + fprintf(stderr, "\n"); +} + +static void +print_dcl_op(GLuint opcode, const GLuint * program) +{ + fprintf(stderr, "%s ", opcodes[opcode]); + print_dest_reg(program[0] | A0_DEST_CHANNEL_ALL); + fprintf(stderr, "\n"); +} + + +void +i915_disassemble_program(const GLuint * program, GLuint sz) +{ + GLuint size = program[0] & 0x1ff; + GLint i; + + fprintf(stderr, "BEGIN\n"); + + if (size + 2 != sz) { + fprintf(stderr, "%s: program size mismatch %d/%d\n", __FUNCTION__, + size + 2, sz); + exit(1); + } + + program++; + for (i = 1; i < sz; i += 3, program += 3) { + GLuint opcode = program[0] & (0x1f << 24); + + if ((GLint) opcode >= A0_NOP && opcode <= A0_SLT) + print_arith_op(opcode >> 24, program); + else if (opcode >= T0_TEXLD && opcode <= T0_TEXKILL) + print_tex_op(opcode >> 24, program); + else if (opcode == D0_DCL) + print_dcl_op(opcode >> 24, program); + else + fprintf(stderr, "Unknown opcode 0x%x\n", opcode); + } + + fprintf(stderr, "END\n\n"); +} diff --git a/src/mesa/drivers/dri/i915tex/i915_fragprog.c b/src/mesa/drivers/dri/i915tex/i915_fragprog.c new file mode 100644 index 0000000000..2ddcbc4325 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_fragprog.c @@ -0,0 +1,1072 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "glheader.h" +#include "macros.h" +#include "enums.h" + +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "intel_batchbuffer.h" + +#include "i915_reg.h" +#include "i915_context.h" +#include "i915_program.h" + +#include "program_instruction.h" +#include "program.h" + + + +/* 1, -1/3!, 1/5!, -1/7! */ +static const GLfloat sin_constants[4] = { 1.0, + -1.0 / (3 * 2 * 1), + 1.0 / (5 * 4 * 3 * 2 * 1), + -1.0 / (7 * 6 * 5 * 4 * 3 * 2 * 1) +}; + +/* 1, -1/2!, 1/4!, -1/6! */ +static const GLfloat cos_constants[4] = { 1.0, + -1.0 / (2 * 1), + 1.0 / (4 * 3 * 2 * 1), + -1.0 / (6 * 5 * 4 * 3 * 2 * 1) +}; + +/** + * Retrieve a ureg for the given source register. Will emit + * constants, apply swizzling and negation as needed. + */ +static GLuint +src_vector(struct i915_fragment_program *p, + const struct prog_src_register *source, + const struct gl_fragment_program *program) +{ + GLuint src; + + switch (source->File) { + + /* Registers: + */ + case PROGRAM_TEMPORARY: + if (source->Index >= I915_MAX_TEMPORARY) { + i915_program_error(p, "Exceeded max temporary reg"); + return 0; + } + src = UREG(REG_TYPE_R, source->Index); + break; + case PROGRAM_INPUT: + switch (source->Index) { + case FRAG_ATTRIB_WPOS: + src = i915_emit_decl(p, REG_TYPE_T, p->wpos_tex, D0_CHANNEL_ALL); + break; + case FRAG_ATTRIB_COL0: + src = i915_emit_decl(p, REG_TYPE_T, T_DIFFUSE, D0_CHANNEL_ALL); + break; + case FRAG_ATTRIB_COL1: + src = i915_emit_decl(p, REG_TYPE_T, T_SPECULAR, D0_CHANNEL_XYZ); + src = swizzle(src, X, Y, Z, ONE); + break; + case FRAG_ATTRIB_FOGC: + src = i915_emit_decl(p, REG_TYPE_T, T_FOG_W, D0_CHANNEL_W); + src = swizzle(src, W, W, W, W); + break; + case FRAG_ATTRIB_TEX0: + case FRAG_ATTRIB_TEX1: + case FRAG_ATTRIB_TEX2: + case FRAG_ATTRIB_TEX3: + case FRAG_ATTRIB_TEX4: + case FRAG_ATTRIB_TEX5: + case FRAG_ATTRIB_TEX6: + case FRAG_ATTRIB_TEX7: + src = i915_emit_decl(p, REG_TYPE_T, + T_TEX0 + (source->Index - FRAG_ATTRIB_TEX0), + D0_CHANNEL_ALL); + break; + + default: + i915_program_error(p, "Bad source->Index"); + return 0; + } + break; + + /* Various paramters and env values. All emitted to + * hardware as program constants. + */ + case PROGRAM_LOCAL_PARAM: + src = i915_emit_param4fv(p, program->Base.LocalParams[source->Index]); + break; + + case PROGRAM_ENV_PARAM: + src = + i915_emit_param4fv(p, + p->ctx->FragmentProgram.Parameters[source-> + Index]); + break; + + case PROGRAM_STATE_VAR: + case PROGRAM_NAMED_PARAM: + src = + i915_emit_param4fv(p, + program->Base.Parameters->ParameterValues[source-> + Index]); + break; + + default: + i915_program_error(p, "Bad source->File"); + return 0; + } + + src = swizzle(src, + GET_SWZ(source->Swizzle, 0), + GET_SWZ(source->Swizzle, 1), + GET_SWZ(source->Swizzle, 2), GET_SWZ(source->Swizzle, 3)); + + if (source->NegateBase) + src = negate(src, + GET_BIT(source->NegateBase, 0), + GET_BIT(source->NegateBase, 1), + GET_BIT(source->NegateBase, 2), + GET_BIT(source->NegateBase, 3)); + + return src; +} + + +static GLuint +get_result_vector(struct i915_fragment_program *p, + const struct prog_instruction *inst) +{ + switch (inst->DstReg.File) { + case PROGRAM_OUTPUT: + switch (inst->DstReg.Index) { + case FRAG_RESULT_COLR: + return UREG(REG_TYPE_OC, 0); + case FRAG_RESULT_DEPR: + p->depth_written = 1; + return UREG(REG_TYPE_OD, 0); + default: + i915_program_error(p, "Bad inst->DstReg.Index"); + return 0; + } + case PROGRAM_TEMPORARY: + return UREG(REG_TYPE_R, inst->DstReg.Index); + default: + i915_program_error(p, "Bad inst->DstReg.File"); + return 0; + } +} + +static GLuint +get_result_flags(const struct prog_instruction *inst) +{ + GLuint flags = 0; + + if (inst->SaturateMode == SATURATE_ZERO_ONE) + flags |= A0_DEST_SATURATE; + if (inst->DstReg.WriteMask & WRITEMASK_X) + flags |= A0_DEST_CHANNEL_X; + if (inst->DstReg.WriteMask & WRITEMASK_Y) + flags |= A0_DEST_CHANNEL_Y; + if (inst->DstReg.WriteMask & WRITEMASK_Z) + flags |= A0_DEST_CHANNEL_Z; + if (inst->DstReg.WriteMask & WRITEMASK_W) + flags |= A0_DEST_CHANNEL_W; + + return flags; +} + +static GLuint +translate_tex_src_target(struct i915_fragment_program *p, GLubyte bit) +{ + switch (bit) { + case TEXTURE_1D_INDEX: + return D0_SAMPLE_TYPE_2D; + case TEXTURE_2D_INDEX: + return D0_SAMPLE_TYPE_2D; + case TEXTURE_RECT_INDEX: + return D0_SAMPLE_TYPE_2D; + case TEXTURE_3D_INDEX: + return D0_SAMPLE_TYPE_VOLUME; + case TEXTURE_CUBE_INDEX: + return D0_SAMPLE_TYPE_CUBE; + default: + i915_program_error(p, "TexSrcBit"); + return 0; + } +} + +#define EMIT_TEX( OP ) \ +do { \ + GLuint dim = translate_tex_src_target( p, inst->TexSrcTarget ); \ + GLuint sampler = i915_emit_decl(p, REG_TYPE_S, \ + inst->TexSrcUnit, dim); \ + GLuint coord = src_vector( p, &inst->SrcReg[0], program); \ + /* Texel lookup */ \ + \ + i915_emit_texld( p, \ + get_result_vector( p, inst ), \ + get_result_flags( inst ), \ + sampler, \ + coord, \ + OP); \ +} while (0) + +#define EMIT_ARITH( OP, N ) \ +do { \ + i915_emit_arith( p, \ + OP, \ + get_result_vector( p, inst ), \ + get_result_flags( inst ), 0, \ + (N<1)?0:src_vector( p, &inst->SrcReg[0], program), \ + (N<2)?0:src_vector( p, &inst->SrcReg[1], program), \ + (N<3)?0:src_vector( p, &inst->SrcReg[2], program)); \ +} while (0) + +#define EMIT_1ARG_ARITH( OP ) EMIT_ARITH( OP, 1 ) +#define EMIT_2ARG_ARITH( OP ) EMIT_ARITH( OP, 2 ) +#define EMIT_3ARG_ARITH( OP ) EMIT_ARITH( OP, 3 ) + + +/* Possible concerns: + * + * SIN, COS -- could use another taylor step? + * LIT -- results seem a little different to sw mesa + * LOG -- different to mesa on negative numbers, but this is conformant. + * + * Parse failures -- Mesa doesn't currently give a good indication + * internally whether a particular program string parsed or not. This + * can lead to confusion -- hopefully we cope with it ok now. + * + */ +static void +upload_program(struct i915_fragment_program *p) +{ + const struct gl_fragment_program *program = + p->ctx->FragmentProgram._Current; + const struct prog_instruction *inst = program->Base.Instructions; + +/* _mesa_debug_fp_inst(program->Base.NumInstructions, inst); */ + + /* Is this a parse-failed program? Ensure a valid program is + * loaded, as the flagging of an error isn't sufficient to stop + * this being uploaded to hardware. + */ + if (inst[0].Opcode == OPCODE_END) { + GLuint tmp = i915_get_utemp(p); + i915_emit_arith(p, + A0_MOV, + UREG(REG_TYPE_OC, 0), + A0_DEST_CHANNEL_ALL, 0, + swizzle(tmp, ONE, ZERO, ONE, ONE), 0, 0); + return; + } + + while (1) { + GLuint src0, src1, src2, flags; + GLuint tmp = 0; + + switch (inst->Opcode) { + case OPCODE_ABS: + src0 = src_vector(p, &inst->SrcReg[0], program); + i915_emit_arith(p, + A0_MAX, + get_result_vector(p, inst), + get_result_flags(inst), 0, + src0, negate(src0, 1, 1, 1, 1), 0); + break; + + case OPCODE_ADD: + EMIT_2ARG_ARITH(A0_ADD); + break; + + case OPCODE_CMP: + src0 = src_vector(p, &inst->SrcReg[0], program); + src1 = src_vector(p, &inst->SrcReg[1], program); + src2 = src_vector(p, &inst->SrcReg[2], program); + i915_emit_arith(p, A0_CMP, get_result_vector(p, inst), get_result_flags(inst), 0, src0, src2, src1); /* NOTE: order of src2, src1 */ + break; + + case OPCODE_COS: + src0 = src_vector(p, &inst->SrcReg[0], program); + tmp = i915_get_utemp(p); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_X, 0, + src0, i915_emit_const1f(p, 1.0 / (M_PI * 2)), 0); + + i915_emit_arith(p, A0_MOD, tmp, A0_DEST_CHANNEL_X, 0, tmp, 0, 0); + + /* By choosing different taylor constants, could get rid of this mul: + */ + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_X, 0, + tmp, i915_emit_const1f(p, (M_PI * 2)), 0); + + /* + * t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1 + * t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, 1 + * t0 = MUL t0.xxz1 t0.z111 ; x^6 x^4 x^2 1 + * result = DP4 t0, cos_constants + */ + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_XY, 0, + swizzle(tmp, X, X, ONE, ONE), + swizzle(tmp, X, ONE, ONE, ONE), 0); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_XYZ, 0, + swizzle(tmp, X, Y, X, ONE), + swizzle(tmp, X, X, ONE, ONE), 0); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_XYZ, 0, + swizzle(tmp, X, X, Z, ONE), + swizzle(tmp, Z, ONE, ONE, ONE), 0); + + i915_emit_arith(p, + A0_DP4, + get_result_vector(p, inst), + get_result_flags(inst), 0, + swizzle(tmp, ONE, Z, Y, X), + i915_emit_const4fv(p, cos_constants), 0); + + break; + + case OPCODE_DP3: + EMIT_2ARG_ARITH(A0_DP3); + break; + + case OPCODE_DP4: + EMIT_2ARG_ARITH(A0_DP4); + break; + + case OPCODE_DPH: + src0 = src_vector(p, &inst->SrcReg[0], program); + src1 = src_vector(p, &inst->SrcReg[1], program); + + i915_emit_arith(p, + A0_DP4, + get_result_vector(p, inst), + get_result_flags(inst), 0, + swizzle(src0, X, Y, Z, ONE), src1, 0); + break; + + case OPCODE_DST: + src0 = src_vector(p, &inst->SrcReg[0], program); + src1 = src_vector(p, &inst->SrcReg[1], program); + + /* result[0] = 1 * 1; + * result[1] = a[1] * b[1]; + * result[2] = a[2] * 1; + * result[3] = 1 * b[3]; + */ + i915_emit_arith(p, + A0_MUL, + get_result_vector(p, inst), + get_result_flags(inst), 0, + swizzle(src0, ONE, Y, Z, ONE), + swizzle(src1, ONE, Y, ONE, W), 0); + break; + + case OPCODE_EX2: + src0 = src_vector(p, &inst->SrcReg[0], program); + + i915_emit_arith(p, + A0_EXP, + get_result_vector(p, inst), + get_result_flags(inst), 0, + swizzle(src0, X, X, X, X), 0, 0); + break; + + case OPCODE_FLR: + EMIT_1ARG_ARITH(A0_FLR); + break; + + case OPCODE_FRC: + EMIT_1ARG_ARITH(A0_FRC); + break; + + case OPCODE_KIL: + src0 = src_vector(p, &inst->SrcReg[0], program); + tmp = i915_get_utemp(p); + + i915_emit_texld(p, tmp, A0_DEST_CHANNEL_ALL, /* use a dummy dest reg */ + 0, src0, T0_TEXKILL); + break; + + case OPCODE_LG2: + src0 = src_vector(p, &inst->SrcReg[0], program); + + i915_emit_arith(p, + A0_LOG, + get_result_vector(p, inst), + get_result_flags(inst), 0, + swizzle(src0, X, X, X, X), 0, 0); + break; + + case OPCODE_LIT: + src0 = src_vector(p, &inst->SrcReg[0], program); + tmp = i915_get_utemp(p); + + /* tmp = max( a.xyzw, a.00zw ) + * XXX: Clamp tmp.w to -128..128 + * tmp.y = log(tmp.y) + * tmp.y = tmp.w * tmp.y + * tmp.y = exp(tmp.y) + * result = cmp (a.11-x1, a.1x01, a.1xy1 ) + */ + i915_emit_arith(p, A0_MAX, tmp, A0_DEST_CHANNEL_ALL, 0, + src0, swizzle(src0, ZERO, ZERO, Z, W), 0); + + i915_emit_arith(p, A0_LOG, tmp, A0_DEST_CHANNEL_Y, 0, + swizzle(tmp, Y, Y, Y, Y), 0, 0); + + i915_emit_arith(p, A0_MUL, tmp, A0_DEST_CHANNEL_Y, 0, + swizzle(tmp, ZERO, Y, ZERO, ZERO), + swizzle(tmp, ZERO, W, ZERO, ZERO), 0); + + i915_emit_arith(p, A0_EXP, tmp, A0_DEST_CHANNEL_Y, 0, + swizzle(tmp, Y, Y, Y, Y), 0, 0); + + i915_emit_arith(p, A0_CMP, + get_result_vector(p, inst), + get_result_flags(inst), 0, + negate(swizzle(tmp, ONE, ONE, X, ONE), 0, 0, 1, 0), + swizzle(tmp, ONE, X, ZERO, ONE), + swizzle(tmp, ONE, X, Y, ONE)); + + break; + + case OPCODE_LRP: + src0 = src_vector(p, &inst->SrcReg[0], program); + src1 = src_vector(p, &inst->SrcReg[1], program); + src2 = src_vector(p, &inst->SrcReg[2], program); + flags = get_result_flags(inst); + tmp = i915_get_utemp(p); + + /* b*a + c*(1-a) + * + * b*a + c - ca + * + * tmp = b*a + c, + * result = (-c)*a + tmp + */ + i915_emit_arith(p, A0_MAD, tmp, + flags & A0_DEST_CHANNEL_ALL, 0, src1, src0, src2); + + i915_emit_arith(p, A0_MAD, + get_result_vector(p, inst), + flags, 0, negate(src2, 1, 1, 1, 1), src0, tmp); + break; + + case OPCODE_MAD: + EMIT_3ARG_ARITH(A0_MAD); + break; + + case OPCODE_MAX: + EMIT_2ARG_ARITH(A0_MAX); + break; + + case OPCODE_MIN: + src0 = src_vector(p, &inst->SrcReg[0], program); + src1 = src_vector(p, &inst->SrcReg[1], program); + tmp = i915_get_utemp(p); + flags = get_result_flags(inst); + + i915_emit_arith(p, + A0_MAX, + tmp, flags & A0_DEST_CHANNEL_ALL, 0, + negate(src0, 1, 1, 1, 1), + negate(src1, 1, 1, 1, 1), 0); + + i915_emit_arith(p, + A0_MOV, + get_result_vector(p, inst), + flags, 0, negate(tmp, 1, 1, 1, 1), 0, 0); + break; + + case OPCODE_MOV: + EMIT_1ARG_ARITH(A0_MOV); + break; + + case OPCODE_MUL: + EMIT_2ARG_ARITH(A0_MUL); + break; + + case OPCODE_POW: + src0 = src_vector(p, &inst->SrcReg[0], program); + src1 = src_vector(p, &inst->SrcReg[1], program); + tmp = i915_get_utemp(p); + flags = get_result_flags(inst); + + /* XXX: masking on intermediate values, here and elsewhere. + */ + i915_emit_arith(p, + A0_LOG, + tmp, A0_DEST_CHANNEL_X, 0, + swizzle(src0, X, X, X, X), 0, 0); + + i915_emit_arith(p, A0_MUL, tmp, A0_DEST_CHANNEL_X, 0, tmp, src1, 0); + + + i915_emit_arith(p, + A0_EXP, + get_result_vector(p, inst), + flags, 0, swizzle(tmp, X, X, X, X), 0, 0); + + break; + + case OPCODE_RCP: + src0 = src_vector(p, &inst->SrcReg[0], program); + + i915_emit_arith(p, + A0_RCP, + get_result_vector(p, inst), + get_result_flags(inst), 0, + swizzle(src0, X, X, X, X), 0, 0); + break; + + case OPCODE_RSQ: + + src0 = src_vector(p, &inst->SrcReg[0], program); + + i915_emit_arith(p, + A0_RSQ, + get_result_vector(p, inst), + get_result_flags(inst), 0, + swizzle(src0, X, X, X, X), 0, 0); + break; + + case OPCODE_SCS: + src0 = src_vector(p, &inst->SrcReg[0], program); + tmp = i915_get_utemp(p); + + /* + * t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1 + * t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, x + * t1 = MUL t0.xyyw t0.yz11 ; x^7 x^5 x^3 x + * scs.x = DP4 t1, sin_constants + * t1 = MUL t0.xxz1 t0.z111 ; x^6 x^4 x^2 1 + * scs.y = DP4 t1, cos_constants + */ + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_XY, 0, + swizzle(src0, X, X, ONE, ONE), + swizzle(src0, X, ONE, ONE, ONE), 0); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_ALL, 0, + swizzle(tmp, X, Y, X, Y), + swizzle(tmp, X, X, ONE, ONE), 0); + + if (inst->DstReg.WriteMask & WRITEMASK_Y) { + GLuint tmp1; + + if (inst->DstReg.WriteMask & WRITEMASK_X) + tmp1 = i915_get_utemp(p); + else + tmp1 = tmp; + + i915_emit_arith(p, + A0_MUL, + tmp1, A0_DEST_CHANNEL_ALL, 0, + swizzle(tmp, X, Y, Y, W), + swizzle(tmp, X, Z, ONE, ONE), 0); + + i915_emit_arith(p, + A0_DP4, + get_result_vector(p, inst), + A0_DEST_CHANNEL_Y, 0, + swizzle(tmp1, W, Z, Y, X), + i915_emit_const4fv(p, sin_constants), 0); + } + + if (inst->DstReg.WriteMask & WRITEMASK_X) { + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_XYZ, 0, + swizzle(tmp, X, X, Z, ONE), + swizzle(tmp, Z, ONE, ONE, ONE), 0); + + i915_emit_arith(p, + A0_DP4, + get_result_vector(p, inst), + A0_DEST_CHANNEL_X, 0, + swizzle(tmp, ONE, Z, Y, X), + i915_emit_const4fv(p, cos_constants), 0); + } + break; + + case OPCODE_SGE: + EMIT_2ARG_ARITH(A0_SGE); + break; + + case OPCODE_SIN: + src0 = src_vector(p, &inst->SrcReg[0], program); + tmp = i915_get_utemp(p); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_X, 0, + src0, i915_emit_const1f(p, 1.0 / (M_PI * 2)), 0); + + i915_emit_arith(p, A0_MOD, tmp, A0_DEST_CHANNEL_X, 0, tmp, 0, 0); + + /* By choosing different taylor constants, could get rid of this mul: + */ + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_X, 0, + tmp, i915_emit_const1f(p, (M_PI * 2)), 0); + + /* + * t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1 + * t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, x + * t1 = MUL t0.xyyw t0.yz11 ; x^7 x^5 x^3 x + * result = DP4 t1.wzyx, sin_constants + */ + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_XY, 0, + swizzle(tmp, X, X, ONE, ONE), + swizzle(tmp, X, ONE, ONE, ONE), 0); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_ALL, 0, + swizzle(tmp, X, Y, X, Y), + swizzle(tmp, X, X, ONE, ONE), 0); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_ALL, 0, + swizzle(tmp, X, Y, Y, W), + swizzle(tmp, X, Z, ONE, ONE), 0); + + i915_emit_arith(p, + A0_DP4, + get_result_vector(p, inst), + get_result_flags(inst), 0, + swizzle(tmp, W, Z, Y, X), + i915_emit_const4fv(p, sin_constants), 0); + break; + + case OPCODE_SLT: + EMIT_2ARG_ARITH(A0_SLT); + break; + + case OPCODE_SUB: + src0 = src_vector(p, &inst->SrcReg[0], program); + src1 = src_vector(p, &inst->SrcReg[1], program); + + i915_emit_arith(p, + A0_ADD, + get_result_vector(p, inst), + get_result_flags(inst), 0, + src0, negate(src1, 1, 1, 1, 1), 0); + break; + + case OPCODE_SWZ: + EMIT_1ARG_ARITH(A0_MOV); /* extended swizzle handled natively */ + break; + + case OPCODE_TEX: + EMIT_TEX(T0_TEXLD); + break; + + case OPCODE_TXB: + EMIT_TEX(T0_TEXLDB); + break; + + case OPCODE_TXP: + EMIT_TEX(T0_TEXLDP); + break; + + case OPCODE_XPD: + /* Cross product: + * result.x = src0.y * src1.z - src0.z * src1.y; + * result.y = src0.z * src1.x - src0.x * src1.z; + * result.z = src0.x * src1.y - src0.y * src1.x; + * result.w = undef; + */ + src0 = src_vector(p, &inst->SrcReg[0], program); + src1 = src_vector(p, &inst->SrcReg[1], program); + tmp = i915_get_utemp(p); + + i915_emit_arith(p, + A0_MUL, + tmp, A0_DEST_CHANNEL_ALL, 0, + swizzle(src0, Z, X, Y, ONE), + swizzle(src1, Y, Z, X, ONE), 0); + + i915_emit_arith(p, + A0_MAD, + get_result_vector(p, inst), + get_result_flags(inst), 0, + swizzle(src0, Y, Z, X, ONE), + swizzle(src1, Z, X, Y, ONE), + negate(tmp, 1, 1, 1, 0)); + break; + + case OPCODE_END: + return; + + default: + i915_program_error(p, "bad opcode"); + return; + } + + inst++; + i915_release_utemps(p); + } +} + +/* Rather than trying to intercept and jiggle depth writes during + * emit, just move the value into its correct position at the end of + * the program: + */ +static void +fixup_depth_write(struct i915_fragment_program *p) +{ + if (p->depth_written) { + GLuint depth = UREG(REG_TYPE_OD, 0); + + i915_emit_arith(p, + A0_MOV, + depth, A0_DEST_CHANNEL_W, 0, + swizzle(depth, X, Y, Z, Z), 0, 0); + } +} + + +#define FRAG_BIT_TEX(n) (FRAG_BIT_TEX0 << (n)) + + +static void +check_wpos(struct i915_fragment_program *p) +{ + GLuint inputs = p->FragProg.Base.InputsRead; + GLint i; + + p->wpos_tex = -1; + + for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) { + if (inputs & FRAG_BIT_TEX(i)) + continue; + else if (inputs & FRAG_BIT_WPOS) { + p->wpos_tex = i; + inputs &= ~FRAG_BIT_WPOS; + } + } + + if (inputs & FRAG_BIT_WPOS) { + i915_program_error(p, "No free texcoord for wpos value"); + } +} + + +static void +translate_program(struct i915_fragment_program *p) +{ + struct i915_context *i915 = I915_CONTEXT(p->ctx); + + i915_init_program(i915, p); + check_wpos(p); + upload_program(p); + fixup_depth_write(p); + i915_fini_program(p); + + p->translated = 1; +} + + +static void +track_params(struct i915_fragment_program *p) +{ + GLint i; + + if (p->nr_params) + _mesa_load_state_parameters(p->ctx, p->FragProg.Base.Parameters); + + for (i = 0; i < p->nr_params; i++) { + GLint reg = p->param[i].reg; + COPY_4V(p->constant[reg], p->param[i].values); + } + + p->params_uptodate = 1; + p->on_hardware = 0; /* overkill */ +} + + +static void +i915BindProgram(GLcontext * ctx, GLenum target, struct gl_program *prog) +{ + if (target == GL_FRAGMENT_PROGRAM_ARB) { + struct i915_context *i915 = I915_CONTEXT(ctx); + struct i915_fragment_program *p = (struct i915_fragment_program *) prog; + + if (i915->current_program == p) + return; + + if (i915->current_program) { + i915->current_program->on_hardware = 0; + i915->current_program->params_uptodate = 0; + } + + i915->current_program = p; + + assert(p->on_hardware == 0); + assert(p->params_uptodate == 0); + + /* Hack: make sure fog is correctly enabled according to this + * fragment program's fog options. + */ + ctx->Driver.Enable(ctx, GL_FRAGMENT_PROGRAM_ARB, + ctx->FragmentProgram.Enabled); + } +} + +static struct gl_program * +i915NewProgram(GLcontext * ctx, GLenum target, GLuint id) +{ + switch (target) { + case GL_VERTEX_PROGRAM_ARB: + return _mesa_init_vertex_program(ctx, CALLOC_STRUCT(gl_vertex_program), + target, id); + + case GL_FRAGMENT_PROGRAM_ARB:{ + struct i915_fragment_program *prog = + CALLOC_STRUCT(i915_fragment_program); + if (prog) { + i915_init_program(I915_CONTEXT(ctx), prog); + + return _mesa_init_fragment_program(ctx, &prog->FragProg, + target, id); + } + else + return NULL; + } + + default: + /* Just fallback: + */ + return _mesa_new_program(ctx, target, id); + } +} + +static void +i915DeleteProgram(GLcontext * ctx, struct gl_program *prog) +{ + if (prog->Target == GL_FRAGMENT_PROGRAM_ARB) { + struct i915_context *i915 = I915_CONTEXT(ctx); + struct i915_fragment_program *p = (struct i915_fragment_program *) prog; + + if (i915->current_program == p) + i915->current_program = 0; + } + + _mesa_delete_program(ctx, prog); +} + + +static GLboolean +i915IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog) +{ + if (target == GL_FRAGMENT_PROGRAM_ARB) { + struct i915_fragment_program *p = (struct i915_fragment_program *) prog; + + if (!p->translated) + translate_program(p); + + return !p->error; + } + else + return GL_TRUE; +} + +static void +i915ProgramStringNotify(GLcontext * ctx, + GLenum target, struct gl_program *prog) +{ + if (target == GL_FRAGMENT_PROGRAM_ARB) { + struct i915_fragment_program *p = (struct i915_fragment_program *) prog; + p->translated = 0; + + /* Hack: make sure fog is correctly enabled according to this + * fragment program's fog options. + */ + ctx->Driver.Enable(ctx, GL_FRAGMENT_PROGRAM_ARB, + ctx->FragmentProgram.Enabled); + } + + _tnl_program_string(ctx, target, prog); +} + + +void +i915ValidateFragmentProgram(struct i915_context *i915) +{ + GLcontext *ctx = &i915->intel.ctx; + struct intel_context *intel = intel_context(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + + struct i915_fragment_program *p = + (struct i915_fragment_program *) ctx->FragmentProgram._Current; + + const GLuint inputsRead = p->FragProg.Base.InputsRead; + GLuint s4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_VFMT_MASK; + GLuint s2 = S2_TEXCOORD_NONE; + int i, offset = 0; + + if (i915->current_program != p) { + if (i915->current_program) { + i915->current_program->on_hardware = 0; + i915->current_program->params_uptodate = 0; + } + + i915->current_program = p; + } + + + /* Important: + */ + VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr; + + if (!p->translated) + translate_program(p); + + intel->vertex_attr_count = 0; + intel->wpos_offset = 0; + intel->wpos_size = 0; + intel->coloroffset = 0; + intel->specoffset = 0; + + if (inputsRead & FRAG_BITS_TEX_ANY) { + EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, S4_VFMT_XYZW, 16); + } + else { + EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, S4_VFMT_XYZ, 12); + } + + if (inputsRead & FRAG_BIT_COL0) { + intel->coloroffset = offset / 4; + EMIT_ATTR(_TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, S4_VFMT_COLOR, 4); + } + + if ((inputsRead & (FRAG_BIT_COL1 | FRAG_BIT_FOGC)) || + i915->vertex_fog != I915_FOG_NONE) { + + if (inputsRead & FRAG_BIT_COL1) { + intel->specoffset = offset / 4; + EMIT_ATTR(_TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, S4_VFMT_SPEC_FOG, 3); + } + else + EMIT_PAD(3); + + if ((inputsRead & FRAG_BIT_FOGC) || i915->vertex_fog != I915_FOG_NONE) + EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1UB_1F, S4_VFMT_SPEC_FOG, 1); + else + EMIT_PAD(1); + } + +#if 0 + if ((inputsRead & FRAG_BIT_FOGC) || i915->vertex_fog != I915_FOG_NONE) { + EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1F, S4_VFMT_FOG_PARAM, 4); + } +#endif + + for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) { + if (inputsRead & FRAG_BIT_TEX(i)) { + int sz = VB->TexCoordPtr[i]->size; + + s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK); + s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(sz)); + + EMIT_ATTR(_TNL_ATTRIB_TEX0 + i, EMIT_SZ(sz), 0, sz * 4); + } + else if (i == p->wpos_tex) { + + /* If WPOS is required, duplicate the XYZ position data in an + * unused texture coordinate: + */ + s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK); + s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(3)); + + intel->wpos_offset = offset; + intel->wpos_size = 3 * sizeof(GLuint); + + EMIT_PAD(intel->wpos_size); + } + } + + if (s2 != i915->state.Ctx[I915_CTXREG_LIS2] || + s4 != i915->state.Ctx[I915_CTXREG_LIS4]) { + int k; + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + + /* Must do this *after* statechange, so as not to affect + * buffered vertices reliant on the old state: + */ + intel->vertex_size = _tnl_install_attrs(&intel->ctx, + intel->vertex_attrs, + intel->vertex_attr_count, + intel->ViewportMatrix.m, 0); + + intel->vertex_size >>= 2; + + i915->state.Ctx[I915_CTXREG_LIS2] = s2; + i915->state.Ctx[I915_CTXREG_LIS4] = s4; + + k = intel->vtbl.check_vertex_size(intel, intel->vertex_size); + assert(k); + } + + if (!p->params_uptodate) + track_params(p); + + if (!p->on_hardware) + i915_upload_program(i915, p); +} + +void +i915InitFragProgFuncs(struct dd_function_table *functions) +{ + functions->BindProgram = i915BindProgram; + functions->NewProgram = i915NewProgram; + functions->DeleteProgram = i915DeleteProgram; + functions->IsProgramNative = i915IsProgramNative; + functions->ProgramStringNotify = i915ProgramStringNotify; +} diff --git a/src/mesa/drivers/dri/i915tex/i915_metaops.c b/src/mesa/drivers/dri/i915tex/i915_metaops.c new file mode 100644 index 0000000000..3ab62bc806 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_metaops.c @@ -0,0 +1,509 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "glheader.h" +#include "enums.h" +#include "mtypes.h" +#include "macros.h" +#include "utils.h" + +#include "intel_screen.h" +#include "intel_batchbuffer.h" +#include "intel_ioctl.h" +#include "intel_regions.h" +#include "intel_rotate.h" + +#include "i915_context.h" +#include "i915_reg.h" + +/* We touch almost everything: + */ +#define ACTIVE (I915_UPLOAD_INVARIENT | \ + I915_UPLOAD_CTX | \ + I915_UPLOAD_BUFFERS | \ + I915_UPLOAD_STIPPLE | \ + I915_UPLOAD_PROGRAM | \ + I915_UPLOAD_FOG | \ + I915_UPLOAD_TEX(0)) + +#define SET_STATE( i915, STATE ) \ +do { \ + i915->current->emitted &= ~ACTIVE; \ + i915->current = &i915->STATE; \ + i915->current->emitted &= ~ACTIVE; \ +} while (0) + + +static void +meta_no_stencil_write(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + + /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE ) + */ + i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_TEST_ENABLE | + S5_STENCIL_WRITE_ENABLE); + + i915->meta.emitted &= ~I915_UPLOAD_CTX; +} + +static void +meta_no_depth_write(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + + /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_FALSE ) + */ + i915->meta.Ctx[I915_CTXREG_LIS6] &= ~(S6_DEPTH_TEST_ENABLE | + S6_DEPTH_WRITE_ENABLE); + + i915->meta.emitted &= ~I915_UPLOAD_CTX; +} + +static void +meta_depth_replace(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + + /* ctx->Driver.Enable( ctx, GL_DEPTH_TEST, GL_TRUE ) + * ctx->Driver.DepthMask( ctx, GL_TRUE ) + */ + i915->meta.Ctx[I915_CTXREG_LIS6] |= (S6_DEPTH_TEST_ENABLE | + S6_DEPTH_WRITE_ENABLE); + + /* ctx->Driver.DepthFunc( ctx, GL_REPLACE ) + */ + i915->meta.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_FUNC_MASK; + i915->meta.Ctx[I915_CTXREG_LIS6] |= + COMPAREFUNC_ALWAYS << S6_DEPTH_TEST_FUNC_SHIFT; + + i915->meta.emitted &= ~I915_UPLOAD_CTX; +} + + +/* Set stencil unit to replace always with the reference value. + */ +static void +meta_stencil_replace(struct intel_context *intel, + GLuint s_mask, GLuint s_clear) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + GLuint op = STENCILOP_REPLACE; + GLuint func = COMPAREFUNC_ALWAYS; + + /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_TRUE ) + */ + i915->meta.Ctx[I915_CTXREG_LIS5] |= (S5_STENCIL_TEST_ENABLE | + S5_STENCIL_WRITE_ENABLE); + + /* ctx->Driver.StencilMask( ctx, s_mask ) + */ + i915->meta.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; + + i915->meta.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | + STENCIL_WRITE_MASK(s_mask)); + + /* ctx->Driver.StencilOp( ctx, GL_REPLACE, GL_REPLACE, GL_REPLACE ) + */ + i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK | + S5_STENCIL_PASS_Z_FAIL_MASK | + S5_STENCIL_PASS_Z_PASS_MASK); + + i915->meta.Ctx[I915_CTXREG_LIS5] |= ((op << S5_STENCIL_FAIL_SHIFT) | + (op << S5_STENCIL_PASS_Z_FAIL_SHIFT) | + (op << S5_STENCIL_PASS_Z_PASS_SHIFT)); + + + /* ctx->Driver.StencilFunc( ctx, GL_ALWAYS, s_ref, ~0 ) + */ + i915->meta.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; + i915->meta.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | + STENCIL_TEST_MASK(0xff)); + + i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_REF_MASK | + S5_STENCIL_TEST_FUNC_MASK); + + i915->meta.Ctx[I915_CTXREG_LIS5] |= ((s_clear << S5_STENCIL_REF_SHIFT) | + (func << S5_STENCIL_TEST_FUNC_SHIFT)); + + + i915->meta.emitted &= ~I915_UPLOAD_CTX; +} + + +static void +meta_color_mask(struct intel_context *intel, GLboolean state) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + const GLuint mask = (S5_WRITEDISABLE_RED | + S5_WRITEDISABLE_GREEN | + S5_WRITEDISABLE_BLUE | S5_WRITEDISABLE_ALPHA); + + /* Copy colormask state from "regular" hw context. + */ + if (state) { + i915->meta.Ctx[I915_CTXREG_LIS5] &= ~mask; + i915->meta.Ctx[I915_CTXREG_LIS5] |= + (i915->state.Ctx[I915_CTXREG_LIS5] & mask); + } + else + i915->meta.Ctx[I915_CTXREG_LIS5] |= mask; + + i915->meta.emitted &= ~I915_UPLOAD_CTX; +} + + + +static void +meta_import_pixel_state(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + memcpy(i915->meta.Fog, i915->state.Fog, I915_FOG_SETUP_SIZE * 4); + + i915->meta.Ctx[I915_CTXREG_LIS5] = i915->state.Ctx[I915_CTXREG_LIS5]; + i915->meta.Ctx[I915_CTXREG_LIS6] = i915->state.Ctx[I915_CTXREG_LIS6]; + i915->meta.Ctx[I915_CTXREG_STATE4] = i915->state.Ctx[I915_CTXREG_STATE4]; + i915->meta.Ctx[I915_CTXREG_BLENDCOLOR1] = + i915->state.Ctx[I915_CTXREG_BLENDCOLOR1]; + i915->meta.Ctx[I915_CTXREG_IAB] = i915->state.Ctx[I915_CTXREG_IAB]; + + i915->meta.Buffer[I915_DESTREG_SENABLE] = + i915->state.Buffer[I915_DESTREG_SENABLE]; + i915->meta.Buffer[I915_DESTREG_SR1] = i915->state.Buffer[I915_DESTREG_SR1]; + i915->meta.Buffer[I915_DESTREG_SR2] = i915->state.Buffer[I915_DESTREG_SR2]; + + i915->meta.emitted &= ~I915_UPLOAD_FOG; + i915->meta.emitted &= ~I915_UPLOAD_BUFFERS; + i915->meta.emitted &= ~I915_UPLOAD_CTX; +} + + + + +#define REG( type, nr ) (((type)<<5)|(nr)) + +#define REG_R(x) REG(REG_TYPE_R, x) +#define REG_T(x) REG(REG_TYPE_T, x) +#define REG_CONST(x) REG(REG_TYPE_CONST, x) +#define REG_S(x) REG(REG_TYPE_S, x) +#define REG_OC REG(REG_TYPE_OC, 0) +#define REG_OD REG(REG_TYPE_OD, 0) +#define REG_U(x) REG(REG_TYPE_U, x) + +#define REG_T_DIFFUSE REG(REG_TYPE_T, T_DIFFUSE) +#define REG_T_SPECULAR REG(REG_TYPE_T, T_SPECULAR) +#define REG_T_FOG_W REG(REG_TYPE_T, T_FOG_W) +#define REG_T_TEX(x) REG(REG_TYPE_T, x) + + +#define A0_DEST_REG( reg ) ( (reg) << A0_DEST_NR_SHIFT ) +#define A0_SRC0_REG( reg ) ( (reg) << A0_SRC0_NR_SHIFT ) +#define A1_SRC1_REG( reg ) ( (reg) << A1_SRC1_NR_SHIFT ) +#define A1_SRC2_REG( reg ) ( (reg) << A1_SRC2_NR_SHIFT ) +#define A2_SRC2_REG( reg ) ( (reg) << A2_SRC2_NR_SHIFT ) +#define D0_DECL_REG( reg ) ( (reg) << D0_NR_SHIFT ) +#define T0_DEST_REG( reg ) ( (reg) << T0_DEST_NR_SHIFT ) + +#define T0_SAMPLER( unit ) ((unit)<ctx); + + static const GLuint prog[] = { + _3DSTATE_PIXEL_SHADER_PROGRAM, + + /* Declare incoming diffuse color: + */ + (D0_DCL | D0_DECL_REG(REG_T_DIFFUSE) | D0_CHANNEL_ALL), + D1_MBZ, + D2_MBZ, + + /* output-color = mov(t_diffuse) + */ + (A0_MOV | + A0_DEST_REG(REG_OC) | + A0_DEST_CHANNEL_ALL | A0_SRC0_REG(REG_T_DIFFUSE)), + (A1_SRC0_XYZW), + 0, + }; + + + memcpy(i915->meta.Program, prog, sizeof(prog)); + i915->meta.ProgramSize = sizeof(prog) / sizeof(*prog); + i915->meta.Program[0] |= i915->meta.ProgramSize - 2; + i915->meta.emitted &= ~I915_UPLOAD_PROGRAM; +} + +static void +meta_texture_blend_replace(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + + static const GLuint prog[] = { + _3DSTATE_PIXEL_SHADER_PROGRAM, + + /* Declare the sampler: + */ + (D0_DCL | D0_DECL_REG(REG_S(0)) | D0_SAMPLE_TYPE_2D | D0_CHANNEL_NONE), + D1_MBZ, + D2_MBZ, + + /* Declare the interpolated texture coordinate: + */ + (D0_DCL | D0_DECL_REG(REG_T_TEX(0)) | D0_CHANNEL_ALL), + D1_MBZ, + D2_MBZ, + + /* output-color = texld(sample0, texcoord0) + */ + (T0_TEXLD | T0_DEST_REG(REG_OC) | T0_SAMPLER(0)), + T1_ADDRESS_REG(REG_TYPE_T, 0), + T2_MBZ + }; + + memcpy(i915->meta.Program, prog, sizeof(prog)); + i915->meta.ProgramSize = sizeof(prog) / sizeof(*prog); + i915->meta.Program[0] |= i915->meta.ProgramSize - 2; + i915->meta.emitted &= ~I915_UPLOAD_PROGRAM; +} + + + + + +/* Set up an arbitary piece of memory as a rectangular texture + * (including the front or back buffer). + */ +static GLboolean +meta_tex_rect_source(struct intel_context *intel, + struct _DriBufferObject *buffer, + GLuint offset, + GLuint pitch, GLuint height, GLenum format, GLenum type) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + GLuint unit = 0; + GLint numLevels = 1; + GLuint *state = i915->meta.Tex[0]; + GLuint textureFormat; + GLuint cpp; + + /* A full implementation of this would do the upload through + * glTexImage2d, and get all the conversion operations at that + * point. We are restricted, but still at least have access to the + * fragment program swizzle. + */ + switch (format) { + case GL_BGRA: + switch (type) { + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_BYTE: + textureFormat = (MAPSURF_32BIT | MT_32BIT_ARGB8888); + cpp = 4; + break; + default: + return GL_FALSE; + } + break; + case GL_RGBA: + switch (type) { + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_BYTE: + textureFormat = (MAPSURF_32BIT | MT_32BIT_ABGR8888); + cpp = 4; + break; + default: + return GL_FALSE; + } + break; + case GL_BGR: + switch (type) { + case GL_UNSIGNED_SHORT_5_6_5_REV: + textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); + cpp = 2; + break; + default: + return GL_FALSE; + } + break; + case GL_RGB: + switch (type) { + case GL_UNSIGNED_SHORT_5_6_5: + textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); + cpp = 2; + break; + default: + return GL_FALSE; + } + break; + + default: + return GL_FALSE; + } + + + if ((pitch * cpp) & 3) { + _mesa_printf("%s: texture is not dword pitch\n", __FUNCTION__); + return GL_FALSE; + } + +/* intel_region_release(&i915->meta.tex_region[0]); */ +/* intel_region_reference(&i915->meta.tex_region[0], region); */ + i915->meta.tex_buffer[0] = buffer; + i915->meta.tex_offset[0] = offset; + + state[I915_TEXREG_MS3] = (((height - 1) << MS3_HEIGHT_SHIFT) | + ((pitch - 1) << MS3_WIDTH_SHIFT) | + textureFormat | MS3_USE_FENCE_REGS); + + state[I915_TEXREG_MS4] = (((((pitch * cpp) / 4) - 1) << MS4_PITCH_SHIFT) | + MS4_CUBE_FACE_ENA_MASK | + ((((numLevels - 1) * 4)) << MS4_MAX_LOD_SHIFT)); + + state[I915_TEXREG_SS2] = ((FILTER_NEAREST << SS2_MIN_FILTER_SHIFT) | + (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT) | + (FILTER_NEAREST << SS2_MAG_FILTER_SHIFT)); + + state[I915_TEXREG_SS3] = ((TEXCOORDMODE_WRAP << SS3_TCX_ADDR_MODE_SHIFT) | + (TEXCOORDMODE_WRAP << SS3_TCY_ADDR_MODE_SHIFT) | + (TEXCOORDMODE_WRAP << SS3_TCZ_ADDR_MODE_SHIFT) | + (unit << SS3_TEXTUREMAP_INDEX_SHIFT)); + + state[I915_TEXREG_SS4] = 0; + + i915->meta.emitted &= ~I915_UPLOAD_TEX(0); + return GL_TRUE; +} + + +/** + * Set the color and depth drawing region for meta ops. + */ +static void +meta_draw_region(struct intel_context *intel, + struct intel_region *color_region, + struct intel_region *depth_region) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + i915_state_draw_region(intel, &i915->meta, color_region, depth_region); +} + + +static void +set_vertex_format(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + + i915->meta.Ctx[I915_CTXREG_LIS2] = + (S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) | + S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) | + S2_TEXCOORD_FMT(2, TEXCOORDFMT_NOT_PRESENT) | + S2_TEXCOORD_FMT(3, TEXCOORDFMT_NOT_PRESENT) | + S2_TEXCOORD_FMT(4, TEXCOORDFMT_NOT_PRESENT) | + S2_TEXCOORD_FMT(5, TEXCOORDFMT_NOT_PRESENT) | + S2_TEXCOORD_FMT(6, TEXCOORDFMT_NOT_PRESENT) | + S2_TEXCOORD_FMT(7, TEXCOORDFMT_NOT_PRESENT)); + + i915->meta.Ctx[I915_CTXREG_LIS4] &= ~S4_VFMT_MASK; + + i915->meta.Ctx[I915_CTXREG_LIS4] |= (S4_VFMT_COLOR | S4_VFMT_XYZ); + + i915->meta.emitted &= ~I915_UPLOAD_CTX; +} + + + +/* Operations where the 3D engine is decoupled temporarily from the + * current GL state and used for other purposes than simply rendering + * incoming triangles. + */ +static void +install_meta_state(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + memcpy(&i915->meta, &i915->initial, sizeof(i915->meta)); + i915->meta.active = ACTIVE; + i915->meta.emitted = 0; + + SET_STATE(i915, meta); + set_vertex_format(intel); + meta_no_texture(intel); +} + +static void +leave_meta_state(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + intel_region_release(&i915->meta.draw_region); + intel_region_release(&i915->meta.depth_region); +/* intel_region_release(&i915->meta.tex_region[0]); */ + SET_STATE(i915, state); +} + + + +void +i915InitMetaFuncs(struct i915_context *i915) +{ + i915->intel.vtbl.install_meta_state = install_meta_state; + i915->intel.vtbl.leave_meta_state = leave_meta_state; + i915->intel.vtbl.meta_no_depth_write = meta_no_depth_write; + i915->intel.vtbl.meta_no_stencil_write = meta_no_stencil_write; + i915->intel.vtbl.meta_stencil_replace = meta_stencil_replace; + i915->intel.vtbl.meta_depth_replace = meta_depth_replace; + i915->intel.vtbl.meta_color_mask = meta_color_mask; + i915->intel.vtbl.meta_no_texture = meta_no_texture; + i915->intel.vtbl.meta_texture_blend_replace = meta_texture_blend_replace; + i915->intel.vtbl.meta_tex_rect_source = meta_tex_rect_source; + i915->intel.vtbl.meta_draw_region = meta_draw_region; + i915->intel.vtbl.meta_import_pixel_state = meta_import_pixel_state; +} diff --git a/src/mesa/drivers/dri/i915tex/i915_program.c b/src/mesa/drivers/dri/i915tex/i915_program.c new file mode 100644 index 0000000000..4fb56222c6 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_program.c @@ -0,0 +1,518 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 + +#include "glheader.h" +#include "macros.h" +#include "enums.h" + +#include "tnl/t_context.h" +#include "intel_batchbuffer.h" + +#include "i915_reg.h" +#include "i915_context.h" +#include "i915_program.h" + + +#define A0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) +#define D0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) +#define T0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) +#define A0_SRC0( reg ) (((reg)&UREG_MASK)>>UREG_A0_SRC0_SHIFT_LEFT) +#define A1_SRC0( reg ) (((reg)&UREG_MASK)<>UREG_A1_SRC1_SHIFT_LEFT) +#define A2_SRC1( reg ) (((reg)&UREG_MASK)<>UREG_A2_SRC2_SHIFT_LEFT) + +/* These are special, and don't have swizzle/negate bits. + */ +#define T0_SAMPLER( reg ) (GET_UREG_NR(reg)<temp_flag); + if (!bit) { + fprintf(stderr, "%s: out of temporaries\n", __FILE__); + exit(1); + } + + p->temp_flag |= 1 << (bit - 1); + return UREG(REG_TYPE_R, (bit - 1)); +} + + +GLuint +i915_get_utemp(struct i915_fragment_program * p) +{ + int bit = ffs(~p->utemp_flag); + if (!bit) { + fprintf(stderr, "%s: out of temporaries\n", __FILE__); + exit(1); + } + + p->utemp_flag |= 1 << (bit - 1); + return UREG(REG_TYPE_U, (bit - 1)); +} + +void +i915_release_utemps(struct i915_fragment_program *p) +{ + p->utemp_flag = ~0x7; +} + + +GLuint +i915_emit_decl(struct i915_fragment_program *p, + GLuint type, GLuint nr, GLuint d0_flags) +{ + GLuint reg = UREG(type, nr); + + if (type == REG_TYPE_T) { + if (p->decl_t & (1 << nr)) + return reg; + + p->decl_t |= (1 << nr); + } + else if (type == REG_TYPE_S) { + if (p->decl_s & (1 << nr)) + return reg; + + p->decl_s |= (1 << nr); + } + else + return reg; + + *(p->decl++) = (D0_DCL | D0_DEST(reg) | d0_flags); + *(p->decl++) = D1_MBZ; + *(p->decl++) = D2_MBZ; + + p->nr_decl_insn++; + return reg; +} + +GLuint +i915_emit_arith(struct i915_fragment_program * p, + GLuint op, + GLuint dest, + GLuint mask, + GLuint saturate, GLuint src0, GLuint src1, GLuint src2) +{ + GLuint c[3]; + GLuint nr_const = 0; + + assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST); + dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)); + assert(dest); + + if (GET_UREG_TYPE(src0) == REG_TYPE_CONST) + c[nr_const++] = 0; + if (GET_UREG_TYPE(src1) == REG_TYPE_CONST) + c[nr_const++] = 1; + if (GET_UREG_TYPE(src2) == REG_TYPE_CONST) + c[nr_const++] = 2; + + /* Recursively call this function to MOV additional const values + * into temporary registers. Use utemp registers for this - + * currently shouldn't be possible to run out, but keep an eye on + * this. + */ + if (nr_const > 1) { + GLuint s[3], first, i, old_utemp_flag; + + s[0] = src0; + s[1] = src1; + s[2] = src2; + old_utemp_flag = p->utemp_flag; + + first = GET_UREG_NR(s[c[0]]); + for (i = 1; i < nr_const; i++) { + if (GET_UREG_NR(s[c[i]]) != first) { + GLuint tmp = i915_get_utemp(p); + + i915_emit_arith(p, A0_MOV, tmp, A0_DEST_CHANNEL_ALL, 0, + s[c[i]], 0, 0); + s[c[i]] = tmp; + } + } + + src0 = s[0]; + src1 = s[1]; + src2 = s[2]; + p->utemp_flag = old_utemp_flag; /* restore */ + } + + *(p->csr++) = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0)); + *(p->csr++) = (A1_SRC0(src0) | A1_SRC1(src1)); + *(p->csr++) = (A2_SRC1(src1) | A2_SRC2(src2)); + + p->nr_alu_insn++; + return dest; +} + +GLuint i915_emit_texld( struct i915_fragment_program *p, + GLuint dest, + GLuint destmask, + GLuint sampler, + GLuint coord, + GLuint op ) +{ + if (coord != UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord))) { + /* No real way to work around this in the general case - need to + * allocate and declare a new temporary register (a utemp won't + * do). Will fallback for now. + */ + i915_program_error(p, "Can't (yet) swizzle TEX arguments"); + return 0; + } + + /* Don't worry about saturate as we only support + */ + if (destmask != A0_DEST_CHANNEL_ALL) { + GLuint tmp = i915_get_utemp(p); + i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, op ); + i915_emit_arith( p, A0_MOV, dest, destmask, 0, tmp, 0, 0 ); + return dest; + } + else { + assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST); + assert(dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest))); + + if (GET_UREG_TYPE(coord) != REG_TYPE_T) { + p->nr_tex_indirect++; + } + + *(p->csr++) = (op | + T0_DEST( dest ) | + T0_SAMPLER( sampler )); + + *(p->csr++) = T1_ADDRESS_REG( coord ); + *(p->csr++) = T2_MBZ; + + p->nr_tex_insn++; + return dest; + } +} + + +GLuint +i915_emit_const1f(struct i915_fragment_program * p, GLfloat c0) +{ + GLint reg, idx; + + if (c0 == 0.0) + return swizzle(UREG(REG_TYPE_R, 0), ZERO, ZERO, ZERO, ZERO); + if (c0 == 1.0) + return swizzle(UREG(REG_TYPE_R, 0), ONE, ONE, ONE, ONE); + + for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { + if (p->constant_flags[reg] == I915_CONSTFLAG_PARAM) + continue; + for (idx = 0; idx < 4; idx++) { + if (!(p->constant_flags[reg] & (1 << idx)) || + p->constant[reg][idx] == c0) { + p->constant[reg][idx] = c0; + p->constant_flags[reg] |= 1 << idx; + if (reg + 1 > p->nr_constants) + p->nr_constants = reg + 1; + return swizzle(UREG(REG_TYPE_CONST, reg), idx, ZERO, ZERO, ONE); + } + } + } + + fprintf(stderr, "%s: out of constants\n", __FUNCTION__); + p->error = 1; + return 0; +} + +GLuint +i915_emit_const2f(struct i915_fragment_program * p, GLfloat c0, GLfloat c1) +{ + GLint reg, idx; + + if (c0 == 0.0) + return swizzle(i915_emit_const1f(p, c1), ZERO, X, Z, W); + if (c0 == 1.0) + return swizzle(i915_emit_const1f(p, c1), ONE, X, Z, W); + + if (c1 == 0.0) + return swizzle(i915_emit_const1f(p, c0), X, ZERO, Z, W); + if (c1 == 1.0) + return swizzle(i915_emit_const1f(p, c0), X, ONE, Z, W); + + for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { + if (p->constant_flags[reg] == 0xf || + p->constant_flags[reg] == I915_CONSTFLAG_PARAM) + continue; + for (idx = 0; idx < 3; idx++) { + if (!(p->constant_flags[reg] & (3 << idx))) { + p->constant[reg][idx] = c0; + p->constant[reg][idx + 1] = c1; + p->constant_flags[reg] |= 3 << idx; + if (reg + 1 > p->nr_constants) + p->nr_constants = reg + 1; + return swizzle(UREG(REG_TYPE_CONST, reg), idx, idx + 1, ZERO, + ONE); + } + } + } + + fprintf(stderr, "%s: out of constants\n", __FUNCTION__); + p->error = 1; + return 0; +} + + + +GLuint +i915_emit_const4f(struct i915_fragment_program * p, + GLfloat c0, GLfloat c1, GLfloat c2, GLfloat c3) +{ + GLint reg; + + for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { + if (p->constant_flags[reg] == 0xf && + p->constant[reg][0] == c0 && + p->constant[reg][1] == c1 && + p->constant[reg][2] == c2 && p->constant[reg][3] == c3) { + return UREG(REG_TYPE_CONST, reg); + } + else if (p->constant_flags[reg] == 0) { + p->constant[reg][0] = c0; + p->constant[reg][1] = c1; + p->constant[reg][2] = c2; + p->constant[reg][3] = c3; + p->constant_flags[reg] = 0xf; + if (reg + 1 > p->nr_constants) + p->nr_constants = reg + 1; + return UREG(REG_TYPE_CONST, reg); + } + } + + fprintf(stderr, "%s: out of constants\n", __FUNCTION__); + p->error = 1; + return 0; +} + + +GLuint +i915_emit_const4fv(struct i915_fragment_program * p, const GLfloat * c) +{ + return i915_emit_const4f(p, c[0], c[1], c[2], c[3]); +} + + +GLuint +i915_emit_param4fv(struct i915_fragment_program * p, const GLfloat * values) +{ + GLint reg, i; + + for (i = 0; i < p->nr_params; i++) { + if (p->param[i].values == values) + return UREG(REG_TYPE_CONST, p->param[i].reg); + } + + + for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { + if (p->constant_flags[reg] == 0) { + p->constant_flags[reg] = I915_CONSTFLAG_PARAM; + i = p->nr_params++; + + p->param[i].values = values; + p->param[i].reg = reg; + p->params_uptodate = 0; + + if (reg + 1 > p->nr_constants) + p->nr_constants = reg + 1; + return UREG(REG_TYPE_CONST, reg); + } + } + + fprintf(stderr, "%s: out of constants\n", __FUNCTION__); + p->error = 1; + return 0; +} + + + + +void +i915_program_error(struct i915_fragment_program *p, const char *msg) +{ + /* XXX we shouldn't print anything to stdout, record GL error or + * call _mesa_problem() + */ + fprintf(stderr, "%s\n", msg); + p->error = 1; +} + +void +i915_init_program(struct i915_context *i915, struct i915_fragment_program *p) +{ + GLcontext *ctx = &i915->intel.ctx; + TNLcontext *tnl = TNL_CONTEXT(ctx); + + p->translated = 0; + p->params_uptodate = 0; + p->on_hardware = 0; + p->error = 0; + + p->nr_tex_indirect = 1; /* correct? */ + p->nr_tex_insn = 0; + p->nr_alu_insn = 0; + p->nr_decl_insn = 0; + + p->ctx = ctx; + memset(p->constant_flags, 0, sizeof(p->constant_flags)); + + p->nr_constants = 0; + p->csr = p->program; + p->decl = p->declarations; + p->decl_s = 0; + p->decl_t = 0; + p->temp_flag = 0xffff000; + p->utemp_flag = ~0x7; + p->wpos_tex = -1; + p->depth_written = 0; + p->nr_params = 0; + + p->src_texture = UREG_BAD; + p->src_previous = UREG(REG_TYPE_T, T_DIFFUSE); + p->last_tex_stage = 0; + p->VB = &tnl->vb; + + *(p->decl++) = _3DSTATE_PIXEL_SHADER_PROGRAM; +} + + +void +i915_fini_program(struct i915_fragment_program *p) +{ + GLuint program_size = p->csr - p->program; + GLuint decl_size = p->decl - p->declarations; + + if (p->nr_tex_indirect > I915_MAX_TEX_INDIRECT) + i915_program_error(p, "Exceeded max nr indirect texture lookups"); + + if (p->nr_tex_insn > I915_MAX_TEX_INSN) + i915_program_error(p, "Exceeded max TEX instructions"); + + if (p->nr_alu_insn > I915_MAX_ALU_INSN) + i915_program_error(p, "Exceeded max ALU instructions"); + + if (p->nr_decl_insn > I915_MAX_DECL_INSN) + i915_program_error(p, "Exceeded max DECL instructions"); + + if (p->error) { + p->FragProg.Base.NumNativeInstructions = 0; + p->FragProg.NumNativeAluInstructions = 0; + p->FragProg.NumNativeTexInstructions = 0; + p->FragProg.NumNativeTexIndirections = 0; + } + else { + p->FragProg.Base.NumNativeInstructions = (p->nr_alu_insn + + p->nr_tex_insn + + p->nr_decl_insn); + p->FragProg.NumNativeAluInstructions = p->nr_alu_insn; + p->FragProg.NumNativeTexInstructions = p->nr_tex_insn; + p->FragProg.NumNativeTexIndirections = p->nr_tex_indirect; + } + + p->declarations[0] |= program_size + decl_size - 2; +} + +void +i915_upload_program(struct i915_context *i915, + struct i915_fragment_program *p) +{ + GLuint program_size = p->csr - p->program; + GLuint decl_size = p->decl - p->declarations; + + FALLBACK(&i915->intel, I915_FALLBACK_PROGRAM, p->error); + + /* Could just go straight to the batchbuffer from here: + */ + if (i915->state.ProgramSize != (program_size + decl_size) || + memcmp(i915->state.Program + decl_size, p->program, + program_size * sizeof(int)) != 0) { + I915_STATECHANGE(i915, I915_UPLOAD_PROGRAM); + memcpy(i915->state.Program, p->declarations, decl_size * sizeof(int)); + memcpy(i915->state.Program + decl_size, p->program, + program_size * sizeof(int)); + i915->state.ProgramSize = decl_size + program_size; + } + + /* Always seemed to get a failure if I used memcmp() to + * shortcircuit this state upload. Needs further investigation? + */ + if (p->nr_constants) { + GLuint nr = p->nr_constants; + + I915_ACTIVESTATE(i915, I915_UPLOAD_CONSTANTS, 1); + I915_STATECHANGE(i915, I915_UPLOAD_CONSTANTS); + + i915->state.Constant[0] = _3DSTATE_PIXEL_SHADER_CONSTANTS | ((nr) * 4); + i915->state.Constant[1] = (1 << (nr - 1)) | ((1 << (nr - 1)) - 1); + + memcpy(&i915->state.Constant[2], p->constant, 4 * sizeof(int) * (nr)); + i915->state.ConstantSize = 2 + (nr) * 4; + + if (0) { + GLuint i; + for (i = 0; i < nr; i++) { + fprintf(stderr, "const[%d]: %f %f %f %f\n", i, + p->constant[i][0], + p->constant[i][1], p->constant[i][2], p->constant[i][3]); + } + } + } + else { + I915_ACTIVESTATE(i915, I915_UPLOAD_CONSTANTS, 0); + } + + p->on_hardware = 1; +} diff --git a/src/mesa/drivers/dri/i915tex/i915_program.h b/src/mesa/drivers/dri/i915tex/i915_program.h new file mode 100644 index 0000000000..3c12b34f16 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_program.h @@ -0,0 +1,160 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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. + * + **************************************************************************/ + + +#ifndef I915_PROGRAM_H +#define I915_PROGRAM_H + +#include "i915_context.h" +#include "i915_reg.h" + + + +/* Having zero and one in here makes the definition of swizzle a lot + * easier. + */ +#define UREG_TYPE_SHIFT 29 +#define UREG_NR_SHIFT 24 +#define UREG_CHANNEL_X_NEGATE_SHIFT 23 +#define UREG_CHANNEL_X_SHIFT 20 +#define UREG_CHANNEL_Y_NEGATE_SHIFT 19 +#define UREG_CHANNEL_Y_SHIFT 16 +#define UREG_CHANNEL_Z_NEGATE_SHIFT 15 +#define UREG_CHANNEL_Z_SHIFT 12 +#define UREG_CHANNEL_W_NEGATE_SHIFT 11 +#define UREG_CHANNEL_W_SHIFT 8 +#define UREG_CHANNEL_ZERO_NEGATE_MBZ 5 +#define UREG_CHANNEL_ZERO_SHIFT 4 +#define UREG_CHANNEL_ONE_NEGATE_MBZ 1 +#define UREG_CHANNEL_ONE_SHIFT 0 + +#define UREG_BAD 0xffffffff /* not a valid ureg */ + +#define X SRC_X +#define Y SRC_Y +#define Z SRC_Z +#define W SRC_W +#define ZERO SRC_ZERO +#define ONE SRC_ONE + +/* Construct a ureg: + */ +#define UREG( type, nr ) (((type)<< UREG_TYPE_SHIFT) | \ + ((nr) << UREG_NR_SHIFT) | \ + (X << UREG_CHANNEL_X_SHIFT) | \ + (Y << UREG_CHANNEL_Y_SHIFT) | \ + (Z << UREG_CHANNEL_Z_SHIFT) | \ + (W << UREG_CHANNEL_W_SHIFT) | \ + (ZERO << UREG_CHANNEL_ZERO_SHIFT) | \ + (ONE << UREG_CHANNEL_ONE_SHIFT)) + +#define GET_CHANNEL_SRC( reg, channel ) ((reg<<(channel*4)) & (0xf<<20)) +#define CHANNEL_SRC( src, channel ) (src>>(channel*4)) + +#define GET_UREG_TYPE(reg) (((reg)>>UREG_TYPE_SHIFT)®_TYPE_MASK) +#define GET_UREG_NR(reg) (((reg)>>UREG_NR_SHIFT)®_NR_MASK) + + + +#define UREG_XYZW_CHANNEL_MASK 0x00ffff00 + +/* One neat thing about the UREG representation: + */ +static INLINE int +swizzle(int reg, int x, int y, int z, int w) +{ + return ((reg & ~UREG_XYZW_CHANNEL_MASK) | + CHANNEL_SRC(GET_CHANNEL_SRC(reg, x), 0) | + CHANNEL_SRC(GET_CHANNEL_SRC(reg, y), 1) | + CHANNEL_SRC(GET_CHANNEL_SRC(reg, z), 2) | + CHANNEL_SRC(GET_CHANNEL_SRC(reg, w), 3)); +} + +/* Another neat thing about the UREG representation: + */ +static INLINE int +negate(int reg, int x, int y, int z, int w) +{ + return reg ^ (((x & 1) << UREG_CHANNEL_X_NEGATE_SHIFT) | + ((y & 1) << UREG_CHANNEL_Y_NEGATE_SHIFT) | + ((z & 1) << UREG_CHANNEL_Z_NEGATE_SHIFT) | + ((w & 1) << UREG_CHANNEL_W_NEGATE_SHIFT)); +} + + +extern GLuint i915_get_temp(struct i915_fragment_program *p); +extern GLuint i915_get_utemp(struct i915_fragment_program *p); +extern void i915_release_utemps(struct i915_fragment_program *p); + + +extern GLuint i915_emit_texld(struct i915_fragment_program *p, + GLuint dest, + GLuint destmask, + GLuint sampler, GLuint coord, GLuint op); + +extern GLuint i915_emit_arith(struct i915_fragment_program *p, + GLuint op, + GLuint dest, + GLuint mask, + GLuint saturate, + GLuint src0, GLuint src1, GLuint src2); + +extern GLuint i915_emit_decl(struct i915_fragment_program *p, + GLuint type, GLuint nr, GLuint d0_flags); + + +extern GLuint i915_emit_const1f(struct i915_fragment_program *p, GLfloat c0); + +extern GLuint i915_emit_const2f(struct i915_fragment_program *p, + GLfloat c0, GLfloat c1); + +extern GLuint i915_emit_const4fv(struct i915_fragment_program *p, + const GLfloat * c); + +extern GLuint i915_emit_const4f(struct i915_fragment_program *p, + GLfloat c0, GLfloat c1, + GLfloat c2, GLfloat c3); + + +extern GLuint i915_emit_param4fv(struct i915_fragment_program *p, + const GLfloat * values); + +extern void i915_program_error(struct i915_fragment_program *p, + const char *msg); + +extern void i915_init_program(struct i915_context *i915, + struct i915_fragment_program *p); + +extern void i915_upload_program(struct i915_context *i915, + struct i915_fragment_program *p); + +extern void i915_fini_program(struct i915_fragment_program *p); + + + + +#endif diff --git a/src/mesa/drivers/dri/i915tex/i915_reg.h b/src/mesa/drivers/dri/i915tex/i915_reg.h new file mode 100644 index 0000000000..04b199905c --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_reg.h @@ -0,0 +1,841 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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. + * + **************************************************************************/ + + +#ifndef _I915_REG_H_ +#define _I915_REG_H_ + + +#include "intel_reg.h" + +#define I915_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value) + +#define CMD_3D (0x3<<29) + +#define PRIM3D_INLINE (CMD_3D | (0x1f<<24)) +#define PRIM3D_TRILIST (0x0<<18) +#define PRIM3D_TRISTRIP (0x1<<18) +#define PRIM3D_TRISTRIP_RVRSE (0x2<<18) +#define PRIM3D_TRIFAN (0x3<<18) +#define PRIM3D_POLY (0x4<<18) +#define PRIM3D_LINELIST (0x5<<18) +#define PRIM3D_LINESTRIP (0x6<<18) +#define PRIM3D_RECTLIST (0x7<<18) +#define PRIM3D_POINTLIST (0x8<<18) +#define PRIM3D_DIB (0x9<<18) +#define PRIM3D_CLEAR_RECT (0xa<<18) +#define PRIM3D_ZONE_INIT (0xd<<18) +#define PRIM3D_MASK (0x1f<<18) + +/* p137 */ +#define _3DSTATE_AA_CMD (CMD_3D | (0x06<<24)) +#define AA_LINE_ECAAR_WIDTH_ENABLE (1<<16) +#define AA_LINE_ECAAR_WIDTH_0_5 0 +#define AA_LINE_ECAAR_WIDTH_1_0 (1<<14) +#define AA_LINE_ECAAR_WIDTH_2_0 (2<<14) +#define AA_LINE_ECAAR_WIDTH_4_0 (3<<14) +#define AA_LINE_REGION_WIDTH_ENABLE (1<<8) +#define AA_LINE_REGION_WIDTH_0_5 0 +#define AA_LINE_REGION_WIDTH_1_0 (1<<6) +#define AA_LINE_REGION_WIDTH_2_0 (2<<6) +#define AA_LINE_REGION_WIDTH_4_0 (3<<6) + +/* 3DSTATE_BACKFACE_STENCIL_OPS, p138*/ +#define _3DSTATE_BACKFACE_STENCIL_OPS (CMD_3D | (0x8<<24)) +#define BFO_ENABLE_STENCIL_REF (1<<23) +#define BFO_STENCIL_REF_SHIFT 15 +#define BFO_STENCIL_REF_MASK (0xff<<15) +#define BFO_ENABLE_STENCIL_FUNCS (1<<14) +#define BFO_STENCIL_TEST_SHIFT 11 +#define BFO_STENCIL_TEST_MASK (0x7<<11) +#define BFO_STENCIL_FAIL_SHIFT 8 +#define BFO_STENCIL_FAIL_MASK (0x7<<8) +#define BFO_STENCIL_PASS_Z_FAIL_SHIFT 5 +#define BFO_STENCIL_PASS_Z_FAIL_MASK (0x7<<5) +#define BFO_STENCIL_PASS_Z_PASS_SHIFT 2 +#define BFO_STENCIL_PASS_Z_PASS_MASK (0x7<<2) +#define BFO_ENABLE_STENCIL_TWO_SIDE (1<<1) +#define BFO_STENCIL_TWO_SIDE (1<<0) + + +/* 3DSTATE_BACKFACE_STENCIL_MASKS, p140 */ +#define _3DSTATE_BACKFACE_STENCIL_MASKS (CMD_3D | (0x9<<24)) +#define BFM_ENABLE_STENCIL_TEST_MASK (1<<17) +#define BFM_ENABLE_STENCIL_WRITE_MASK (1<<16) +#define BFM_STENCIL_TEST_MASK_SHIFT 8 +#define BFM_STENCIL_TEST_MASK_MASK (0xff<<8) +#define BFM_STENCIL_WRITE_MASK_SHIFT 0 +#define BFM_STENCIL_WRITE_MASK_MASK (0xff<<0) + + + +/* 3DSTATE_BIN_CONTROL p141 */ + +/* p143 */ +#define _3DSTATE_BUF_INFO_CMD (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1) +/* Dword 1 */ +#define BUF_3D_ID_COLOR_BACK (0x3<<24) +#define BUF_3D_ID_DEPTH (0x7<<24) +#define BUF_3D_USE_FENCE (1<<23) +#define BUF_3D_TILED_SURFACE (1<<22) +#define BUF_3D_TILE_WALK_X 0 +#define BUF_3D_TILE_WALK_Y (1<<21) +#define BUF_3D_PITCH(x) (((x)/4)<<2) +/* Dword 2 */ +#define BUF_3D_ADDR(x) ((x) & ~0x3) + + +/* 3DSTATE_CHROMA_KEY */ + +/* 3DSTATE_CLEAR_PARAMETERS, p150 */ + +/* 3DSTATE_CONSTANT_BLEND_COLOR, p153 */ +#define _3DSTATE_CONST_BLEND_COLOR_CMD (CMD_3D | (0x1d<<24) | (0x88<<16)) + + + +/* 3DSTATE_COORD_SET_BINDINGS, p154 */ +#define _3DSTATE_COORD_SET_BINDINGS (CMD_3D | (0x16<<24)) +#define CSB_TCB(iunit, eunit) ((eunit)<<(iunit*3)) + +/* p156 */ +#define _3DSTATE_DFLT_DIFFUSE_CMD (CMD_3D | (0x1d<<24) | (0x99<<16)) + +/* p157 */ +#define _3DSTATE_DFLT_SPEC_CMD (CMD_3D | (0x1d<<24) | (0x9a<<16)) + +/* p158 */ +#define _3DSTATE_DFLT_Z_CMD (CMD_3D | (0x1d<<24) | (0x98<<16)) + + +/* 3DSTATE_DEPTH_OFFSET_SCALE, p159 */ +#define _3DSTATE_DEPTH_OFFSET_SCALE (CMD_3D | (0x1d<<24) | (0x97<<16)) +/* scale in dword 1 */ + + +/* 3DSTATE_DEPTH_SUBRECT_DISABLE, p160 */ +#define _3DSTATE_DEPTH_SUBRECT_DISABLE (CMD_3D | (0x1c<<24) | (0x11<19) | 0x2) + +/* p161 */ +#define _3DSTATE_DST_BUF_VARS_CMD (CMD_3D | (0x1d<<24) | (0x85<<16)) +/* Dword 1 */ +#define TEX_DEFAULT_COLOR_OGL (0<<30) +#define TEX_DEFAULT_COLOR_D3D (1<<30) +#define ZR_EARLY_DEPTH (1<<29) +#define LOD_PRECLAMP_OGL (1<<28) +#define LOD_PRECLAMP_D3D (0<<28) +#define DITHER_FULL_ALWAYS (0<<26) +#define DITHER_FULL_ON_FB_BLEND (1<<26) +#define DITHER_CLAMPED_ALWAYS (2<<26) +#define LINEAR_GAMMA_BLEND_32BPP (1<<25) +#define DEBUG_DISABLE_ENH_DITHER (1<<24) +#define DSTORG_HORT_BIAS(x) ((x)<<20) +#define DSTORG_VERT_BIAS(x) ((x)<<16) +#define COLOR_4_2_2_CHNL_WRT_ALL 0 +#define COLOR_4_2_2_CHNL_WRT_Y (1<<12) +#define COLOR_4_2_2_CHNL_WRT_CR (2<<12) +#define COLOR_4_2_2_CHNL_WRT_CB (3<<12) +#define COLOR_4_2_2_CHNL_WRT_CRCB (4<<12) +#define COLR_BUF_8BIT 0 +#define COLR_BUF_RGB555 (1<<8) +#define COLR_BUF_RGB565 (2<<8) +#define COLR_BUF_ARGB8888 (3<<8) +#define DEPTH_FRMT_16_FIXED 0 +#define DEPTH_FRMT_16_FLOAT (1<<2) +#define DEPTH_FRMT_24_FIXED_8_OTHER (2<<2) +#define VERT_LINE_STRIDE_1 (1<<1) +#define VERT_LINE_STRIDE_0 (0<<1) +#define VERT_LINE_STRIDE_OFS_1 1 +#define VERT_LINE_STRIDE_OFS_0 0 + +/* p166 */ +#define _3DSTATE_DRAW_RECT_CMD (CMD_3D|(0x1d<<24)|(0x80<<16)|3) +/* Dword 1 */ +#define DRAW_RECT_DIS_DEPTH_OFS (1<<30) +#define DRAW_DITHER_OFS_X(x) ((x)<<26) +#define DRAW_DITHER_OFS_Y(x) ((x)<<24) +/* Dword 2 */ +#define DRAW_YMIN(x) ((x)<<16) +#define DRAW_XMIN(x) (x) +/* Dword 3 */ +#define DRAW_YMAX(x) ((x)<<16) +#define DRAW_XMAX(x) (x) +/* Dword 4 */ +#define DRAW_YORG(x) ((x)<<16) +#define DRAW_XORG(x) (x) + + +/* 3DSTATE_FILTER_COEFFICIENTS_4X4, p170 */ + +/* 3DSTATE_FILTER_COEFFICIENTS_6X5, p172 */ + + +/* _3DSTATE_FOG_COLOR, p173 */ +#define _3DSTATE_FOG_COLOR_CMD (CMD_3D|(0x15<<24)) +#define FOG_COLOR_RED(x) ((x)<<16) +#define FOG_COLOR_GREEN(x) ((x)<<8) +#define FOG_COLOR_BLUE(x) (x) + +/* _3DSTATE_FOG_MODE, p174 */ +#define _3DSTATE_FOG_MODE_CMD (CMD_3D|(0x1d<<24)|(0x89<<16)|2) +/* Dword 1 */ +#define FMC1_FOGFUNC_MODIFY_ENABLE (1<<31) +#define FMC1_FOGFUNC_VERTEX (0<<28) +#define FMC1_FOGFUNC_PIXEL_EXP (1<<28) +#define FMC1_FOGFUNC_PIXEL_EXP2 (2<<28) +#define FMC1_FOGFUNC_PIXEL_LINEAR (3<<28) +#define FMC1_FOGFUNC_MASK (3<<28) +#define FMC1_FOGINDEX_MODIFY_ENABLE (1<<27) +#define FMC1_FOGINDEX_Z (0<<25) +#define FMC1_FOGINDEX_W (1<<25) +#define FMC1_C1_C2_MODIFY_ENABLE (1<<24) +#define FMC1_DENSITY_MODIFY_ENABLE (1<<23) +#define FMC1_C1_ONE (1<<13) +#define FMC1_C1_MASK (0xffff<<4) +/* Dword 2 */ +#define FMC2_C2_ONE (1<<16) +/* Dword 3 */ +#define FMC3_D_ONE (1<<16) + + + +/* _3DSTATE_INDEPENDENT_ALPHA_BLEND, p177 */ +#define _3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD (CMD_3D|(0x0b<<24)) +#define IAB_MODIFY_ENABLE (1<<23) +#define IAB_ENABLE (1<<22) +#define IAB_MODIFY_FUNC (1<<21) +#define IAB_FUNC_SHIFT 16 +#define IAB_MODIFY_SRC_FACTOR (1<<11) +#define IAB_SRC_FACTOR_SHIFT 6 +#define IAB_SRC_FACTOR_MASK (BLENDFACT_MASK<<6) +#define IAB_MODIFY_DST_FACTOR (1<<5) +#define IAB_DST_FACTOR_SHIFT 0 +#define IAB_DST_FACTOR_MASK (BLENDFACT_MASK<<0) + + +#define BLENDFUNC_ADD 0x0 +#define BLENDFUNC_SUBTRACT 0x1 +#define BLENDFUNC_REVERSE_SUBTRACT 0x2 +#define BLENDFUNC_MIN 0x3 +#define BLENDFUNC_MAX 0x4 +#define BLENDFUNC_MASK 0x7 + +/* 3DSTATE_LOAD_INDIRECT, p180 */ + +#define _3DSTATE_LOAD_INDIRECT (CMD_3D|(0x1d<<24)|(0x7<<16)) +#define LI0_STATE_STATIC_INDIRECT (0x01<<8) +#define LI0_STATE_DYNAMIC_INDIRECT (0x02<<8) +#define LI0_STATE_SAMPLER (0x04<<8) +#define LI0_STATE_MAP (0x08<<8) +#define LI0_STATE_PROGRAM (0x10<<8) +#define LI0_STATE_CONSTANTS (0x20<<8) + +#define SIS0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define SIS0_FORCE_LOAD (1<<1) +#define SIS0_BUFFER_VALID (1<<0) +#define SIS1_BUFFER_LENGTH(x) ((x)&0xff) + +#define DIS0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define DIS0_BUFFER_RESET (1<<1) +#define DIS0_BUFFER_VALID (1<<0) + +#define SSB0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define SSB0_FORCE_LOAD (1<<1) +#define SSB0_BUFFER_VALID (1<<0) +#define SSB1_BUFFER_LENGTH(x) ((x)&0xff) + +#define MSB0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define MSB0_FORCE_LOAD (1<<1) +#define MSB0_BUFFER_VALID (1<<0) +#define MSB1_BUFFER_LENGTH(x) ((x)&0xff) + +#define PSP0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define PSP0_FORCE_LOAD (1<<1) +#define PSP0_BUFFER_VALID (1<<0) +#define PSP1_BUFFER_LENGTH(x) ((x)&0xff) + +#define PSC0_BUFFER_ADDRESS(x) ((x)&~0x3) +#define PSC0_FORCE_LOAD (1<<1) +#define PSC0_BUFFER_VALID (1<<0) +#define PSC1_BUFFER_LENGTH(x) ((x)&0xff) + + + + + +/* _3DSTATE_RASTERIZATION_RULES */ +#define _3DSTATE_RASTER_RULES_CMD (CMD_3D|(0x07<<24)) +#define ENABLE_POINT_RASTER_RULE (1<<15) +#define OGL_POINT_RASTER_RULE (1<<13) +#define ENABLE_TEXKILL_3D_4D (1<<10) +#define TEXKILL_3D (0<<9) +#define TEXKILL_4D (1<<9) +#define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8) +#define ENABLE_TRI_FAN_PROVOKE_VRTX (1<<5) +#define LINE_STRIP_PROVOKE_VRTX(x) ((x)<<6) +#define TRI_FAN_PROVOKE_VRTX(x) ((x)<<3) + +/* _3DSTATE_SCISSOR_ENABLE, p256 */ +#define _3DSTATE_SCISSOR_ENABLE_CMD (CMD_3D|(0x1c<<24)|(0x10<<19)) +#define ENABLE_SCISSOR_RECT ((1<<1) | 1) +#define DISABLE_SCISSOR_RECT (1<<1) + +/* _3DSTATE_SCISSOR_RECTANGLE_0, p257 */ +#define _3DSTATE_SCISSOR_RECT_0_CMD (CMD_3D|(0x1d<<24)|(0x81<<16)|1) +/* Dword 1 */ +#define SCISSOR_RECT_0_YMIN(x) ((x)<<16) +#define SCISSOR_RECT_0_XMIN(x) (x) +/* Dword 2 */ +#define SCISSOR_RECT_0_YMAX(x) ((x)<<16) +#define SCISSOR_RECT_0_XMAX(x) (x) + +/* p189 */ +#define _3DSTATE_LOAD_STATE_IMMEDIATE_1 ((0x3<<29)|(0x1d<<24)|(0x04<<16)) +#define I1_LOAD_S(n) (1<<(4+n)) + +#define S0_VB_OFFSET_MASK 0xffffffc +#define S0_AUTO_CACHE_INV_DISABLE (1<<0) + +#define S1_VERTEX_WIDTH_SHIFT 24 +#define S1_VERTEX_WIDTH_MASK (0x3f<<24) +#define S1_VERTEX_PITCH_SHIFT 16 +#define S1_VERTEX_PITCH_MASK (0x3f<<16) + +#define TEXCOORDFMT_2D 0x0 +#define TEXCOORDFMT_3D 0x1 +#define TEXCOORDFMT_4D 0x2 +#define TEXCOORDFMT_1D 0x3 +#define TEXCOORDFMT_2D_16 0x4 +#define TEXCOORDFMT_4D_16 0x5 +#define TEXCOORDFMT_NOT_PRESENT 0xf +#define S2_TEXCOORD_FMT0_MASK 0xf +#define S2_TEXCOORD_FMT1_SHIFT 4 +#define S2_TEXCOORD_FMT(unit, type) ((type)<<(unit*4)) +#define S2_TEXCOORD_NONE (~0) + +/* S3 not interesting */ + +#define S4_POINT_WIDTH_SHIFT 23 +#define S4_POINT_WIDTH_MASK (0x1ff<<23) +#define S4_LINE_WIDTH_SHIFT 19 +#define S4_LINE_WIDTH_ONE (0x2<<19) +#define S4_LINE_WIDTH_MASK (0xf<<19) +#define S4_FLATSHADE_ALPHA (1<<18) +#define S4_FLATSHADE_FOG (1<<17) +#define S4_FLATSHADE_SPECULAR (1<<16) +#define S4_FLATSHADE_COLOR (1<<15) +#define S4_CULLMODE_BOTH (0<<13) +#define S4_CULLMODE_NONE (1<<13) +#define S4_CULLMODE_CW (2<<13) +#define S4_CULLMODE_CCW (3<<13) +#define S4_CULLMODE_MASK (3<<13) +#define S4_VFMT_POINT_WIDTH (1<<12) +#define S4_VFMT_SPEC_FOG (1<<11) +#define S4_VFMT_COLOR (1<<10) +#define S4_VFMT_DEPTH_OFFSET (1<<9) +#define S4_VFMT_XYZ (1<<6) +#define S4_VFMT_XYZW (2<<6) +#define S4_VFMT_XY (3<<6) +#define S4_VFMT_XYW (4<<6) +#define S4_VFMT_XYZW_MASK (7<<6) +#define S4_FORCE_DEFAULT_DIFFUSE (1<<5) +#define S4_FORCE_DEFAULT_SPECULAR (1<<4) +#define S4_LOCAL_DEPTH_OFFSET_ENABLE (1<<3) +#define S4_VFMT_FOG_PARAM (1<<2) +#define S4_SPRITE_POINT_ENABLE (1<<1) +#define S4_LINE_ANTIALIAS_ENABLE (1<<0) + +#define S4_VFMT_MASK (S4_VFMT_POINT_WIDTH | \ + S4_VFMT_SPEC_FOG | \ + S4_VFMT_COLOR | \ + S4_VFMT_DEPTH_OFFSET | \ + S4_VFMT_XYZW_MASK | \ + S4_VFMT_FOG_PARAM) + + +#define S5_WRITEDISABLE_ALPHA (1<<31) +#define S5_WRITEDISABLE_RED (1<<30) +#define S5_WRITEDISABLE_GREEN (1<<29) +#define S5_WRITEDISABLE_BLUE (1<<28) +#define S5_WRITEDISABLE_MASK (0xf<<28) +#define S5_FORCE_DEFAULT_POINT_SIZE (1<<27) +#define S5_LAST_PIXEL_ENABLE (1<<26) +#define S5_GLOBAL_DEPTH_OFFSET_ENABLE (1<<25) +#define S5_FOG_ENABLE (1<<24) +#define S5_STENCIL_REF_SHIFT 16 +#define S5_STENCIL_REF_MASK (0xff<<16) +#define S5_STENCIL_TEST_FUNC_SHIFT 13 +#define S5_STENCIL_TEST_FUNC_MASK (0x7<<13) +#define S5_STENCIL_FAIL_SHIFT 10 +#define S5_STENCIL_FAIL_MASK (0x7<<10) +#define S5_STENCIL_PASS_Z_FAIL_SHIFT 7 +#define S5_STENCIL_PASS_Z_FAIL_MASK (0x7<<7) +#define S5_STENCIL_PASS_Z_PASS_SHIFT 4 +#define S5_STENCIL_PASS_Z_PASS_MASK (0x7<<4) +#define S5_STENCIL_WRITE_ENABLE (1<<3) +#define S5_STENCIL_TEST_ENABLE (1<<2) +#define S5_COLOR_DITHER_ENABLE (1<<1) +#define S5_LOGICOP_ENABLE (1<<0) + + +#define S6_ALPHA_TEST_ENABLE (1<<31) +#define S6_ALPHA_TEST_FUNC_SHIFT 28 +#define S6_ALPHA_TEST_FUNC_MASK (0x7<<28) +#define S6_ALPHA_REF_SHIFT 20 +#define S6_ALPHA_REF_MASK (0xff<<20) +#define S6_DEPTH_TEST_ENABLE (1<<19) +#define S6_DEPTH_TEST_FUNC_SHIFT 16 +#define S6_DEPTH_TEST_FUNC_MASK (0x7<<16) +#define S6_CBUF_BLEND_ENABLE (1<<15) +#define S6_CBUF_BLEND_FUNC_SHIFT 12 +#define S6_CBUF_BLEND_FUNC_MASK (0x7<<12) +#define S6_CBUF_SRC_BLEND_FACT_SHIFT 8 +#define S6_CBUF_SRC_BLEND_FACT_MASK (0xf<<8) +#define S6_CBUF_DST_BLEND_FACT_SHIFT 4 +#define S6_CBUF_DST_BLEND_FACT_MASK (0xf<<4) +#define S6_DEPTH_WRITE_ENABLE (1<<3) +#define S6_COLOR_WRITE_ENABLE (1<<2) +#define S6_TRISTRIP_PV_SHIFT 0 +#define S6_TRISTRIP_PV_MASK (0x3<<0) + +#define S7_DEPTH_OFFSET_CONST_MASK ~0 + +/* 3DSTATE_MAP_DEINTERLACER_PARAMETERS */ + +/* 3DSTATE_MAP_PALETTE_LOAD_32, p206 */ +#define _3DSTATE_MAP_PALETTE_LOAD_32 (CMD_3D|(0x1d<<24)|(0x8f<<16)) +/* subsequent dwords up to length (max 16) are ARGB8888 color values */ + +/* _3DSTATE_MODES_4, p218 */ +#define _3DSTATE_MODES_4_CMD (CMD_3D|(0x0d<<24)) +#define ENABLE_LOGIC_OP_FUNC (1<<23) +#define LOGIC_OP_FUNC(x) ((x)<<18) +#define LOGICOP_MASK (0xf<<18) +#define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00)) +#define ENABLE_STENCIL_TEST_MASK (1<<17) +#define STENCIL_TEST_MASK(x) (((x)&0xff)<<8) +#define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff)) +#define ENABLE_STENCIL_WRITE_MASK (1<<16) +#define STENCIL_WRITE_MASK(x) ((x)&0xff) + +/* _3DSTATE_MODES_5, p220 */ +#define _3DSTATE_MODES_5_CMD (CMD_3D|(0x0c<<24)) +#define PIPELINE_FLUSH_RENDER_CACHE (1<<18) +#define PIPELINE_FLUSH_TEXTURE_CACHE (1<<16) + + +/* p221 */ +#define _3DSTATE_PIXEL_SHADER_CONSTANTS (CMD_3D|(0x1d<<24)|(0x6<<16)) +#define PS1_REG(n) (1<<(n)) +#define PS2_CONST_X(n) (n) +#define PS3_CONST_Y(n) (n) +#define PS4_CONST_Z(n) (n) +#define PS5_CONST_W(n) (n) + +/* p222 */ + + +#define I915_MAX_TEX_INDIRECT 4 +#define I915_MAX_TEX_INSN 32 +#define I915_MAX_ALU_INSN 64 +#define I915_MAX_DECL_INSN 27 +#define I915_MAX_TEMPORARY 16 + + +/* Each instruction is 3 dwords long, though most don't require all + * this space. Maximum of 123 instructions. Smaller maxes per insn + * type. + */ +#define _3DSTATE_PIXEL_SHADER_PROGRAM (CMD_3D|(0x1d<<24)|(0x5<<16)) + +#define REG_TYPE_R 0 /* temporary regs, no need to + * dcl, must be written before + * read -- Preserved between + * phases. + */ +#define REG_TYPE_T 1 /* Interpolated values, must be + * dcl'ed before use. + * + * 0..7: texture coord, + * 8: diffuse spec, + * 9: specular color, + * 10: fog parameter in w. + */ +#define REG_TYPE_CONST 2 /* Restriction: only one const + * can be referenced per + * instruction, though it may be + * selected for multiple inputs. + * Constants not initialized + * default to zero. + */ +#define REG_TYPE_S 3 /* sampler */ +#define REG_TYPE_OC 4 /* output color (rgba) */ +#define REG_TYPE_OD 5 /* output depth (w), xyz are + * temporaries. If not written, + * interpolated depth is used? + */ +#define REG_TYPE_U 6 /* unpreserved temporaries */ +#define REG_TYPE_MASK 0x7 +#define REG_NR_MASK 0xf + + +/* REG_TYPE_T: + */ +#define T_TEX0 0 +#define T_TEX1 1 +#define T_TEX2 2 +#define T_TEX3 3 +#define T_TEX4 4 +#define T_TEX5 5 +#define T_TEX6 6 +#define T_TEX7 7 +#define T_DIFFUSE 8 +#define T_SPECULAR 9 +#define T_FOG_W 10 /* interpolated fog is in W coord */ + +/* Arithmetic instructions */ + +/* .replicate_swizzle == selection and replication of a particular + * scalar channel, ie., .xxxx, .yyyy, .zzzz or .wwww + */ +#define A0_NOP (0x0<<24) /* no operation */ +#define A0_ADD (0x1<<24) /* dst = src0 + src1 */ +#define A0_MOV (0x2<<24) /* dst = src0 */ +#define A0_MUL (0x3<<24) /* dst = src0 * src1 */ +#define A0_MAD (0x4<<24) /* dst = src0 * src1 + src2 */ +#define A0_DP2ADD (0x5<<24) /* dst.xyzw = src0.xy dot src1.xy + src2.replicate_swizzle */ +#define A0_DP3 (0x6<<24) /* dst.xyzw = src0.xyz dot src1.xyz */ +#define A0_DP4 (0x7<<24) /* dst.xyzw = src0.xyzw dot src1.xyzw */ +#define A0_FRC (0x8<<24) /* dst = src0 - floor(src0) */ +#define A0_RCP (0x9<<24) /* dst.xyzw = 1/(src0.replicate_swizzle) */ +#define A0_RSQ (0xa<<24) /* dst.xyzw = 1/(sqrt(abs(src0.replicate_swizzle))) */ +#define A0_EXP (0xb<<24) /* dst.xyzw = exp2(src0.replicate_swizzle) */ +#define A0_LOG (0xc<<24) /* dst.xyzw = log2(abs(src0.replicate_swizzle)) */ +#define A0_CMP (0xd<<24) /* dst = (src0 >= 0.0) ? src1 : src2 */ +#define A0_MIN (0xe<<24) /* dst = (src0 < src1) ? src0 : src1 */ +#define A0_MAX (0xf<<24) /* dst = (src0 >= src1) ? src0 : src1 */ +#define A0_FLR (0x10<<24) /* dst = floor(src0) */ +#define A0_MOD (0x11<<24) /* dst = src0 fmod 1.0 */ +#define A0_TRC (0x12<<24) /* dst = int(src0) */ +#define A0_SGE (0x13<<24) /* dst = src0 >= src1 ? 1.0 : 0.0 */ +#define A0_SLT (0x14<<24) /* dst = src0 < src1 ? 1.0 : 0.0 */ +#define A0_DEST_SATURATE (1<<22) +#define A0_DEST_TYPE_SHIFT 19 +/* Allow: R, OC, OD, U */ +#define A0_DEST_NR_SHIFT 14 +/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ +#define A0_DEST_CHANNEL_X (1<<10) +#define A0_DEST_CHANNEL_Y (2<<10) +#define A0_DEST_CHANNEL_Z (4<<10) +#define A0_DEST_CHANNEL_W (8<<10) +#define A0_DEST_CHANNEL_ALL (0xf<<10) +#define A0_DEST_CHANNEL_SHIFT 10 +#define A0_SRC0_TYPE_SHIFT 7 +#define A0_SRC0_NR_SHIFT 2 + +#define A0_DEST_CHANNEL_XY (A0_DEST_CHANNEL_X|A0_DEST_CHANNEL_Y) +#define A0_DEST_CHANNEL_XYZ (A0_DEST_CHANNEL_XY|A0_DEST_CHANNEL_Z) + + +#define SRC_X 0 +#define SRC_Y 1 +#define SRC_Z 2 +#define SRC_W 3 +#define SRC_ZERO 4 +#define SRC_ONE 5 + +#define A1_SRC0_CHANNEL_X_NEGATE (1<<31) +#define A1_SRC0_CHANNEL_X_SHIFT 28 +#define A1_SRC0_CHANNEL_Y_NEGATE (1<<27) +#define A1_SRC0_CHANNEL_Y_SHIFT 24 +#define A1_SRC0_CHANNEL_Z_NEGATE (1<<23) +#define A1_SRC0_CHANNEL_Z_SHIFT 20 +#define A1_SRC0_CHANNEL_W_NEGATE (1<<19) +#define A1_SRC0_CHANNEL_W_SHIFT 16 +#define A1_SRC1_TYPE_SHIFT 13 +#define A1_SRC1_NR_SHIFT 8 +#define A1_SRC1_CHANNEL_X_NEGATE (1<<7) +#define A1_SRC1_CHANNEL_X_SHIFT 4 +#define A1_SRC1_CHANNEL_Y_NEGATE (1<<3) +#define A1_SRC1_CHANNEL_Y_SHIFT 0 + +#define A2_SRC1_CHANNEL_Z_NEGATE (1<<31) +#define A2_SRC1_CHANNEL_Z_SHIFT 28 +#define A2_SRC1_CHANNEL_W_NEGATE (1<<27) +#define A2_SRC1_CHANNEL_W_SHIFT 24 +#define A2_SRC2_TYPE_SHIFT 21 +#define A2_SRC2_NR_SHIFT 16 +#define A2_SRC2_CHANNEL_X_NEGATE (1<<15) +#define A2_SRC2_CHANNEL_X_SHIFT 12 +#define A2_SRC2_CHANNEL_Y_NEGATE (1<<11) +#define A2_SRC2_CHANNEL_Y_SHIFT 8 +#define A2_SRC2_CHANNEL_Z_NEGATE (1<<7) +#define A2_SRC2_CHANNEL_Z_SHIFT 4 +#define A2_SRC2_CHANNEL_W_NEGATE (1<<3) +#define A2_SRC2_CHANNEL_W_SHIFT 0 + + + +/* Texture instructions */ +#define T0_TEXLD (0x15<<24) /* Sample texture using predeclared + * sampler and address, and output + * filtered texel data to destination + * register */ +#define T0_TEXLDP (0x16<<24) /* Same as texld but performs a + * perspective divide of the texture + * coordinate .xyz values by .w before + * sampling. */ +#define T0_TEXLDB (0x17<<24) /* Same as texld but biases the + * computed LOD by w. Only S4.6 two's + * comp is used. This implies that a + * float to fixed conversion is + * done. */ +#define T0_TEXKILL (0x18<<24) /* Does not perform a sampling + * operation. Simply kills the pixel + * if any channel of the address + * register is < 0.0. */ +#define T0_DEST_TYPE_SHIFT 19 +/* Allow: R, OC, OD, U */ +/* Note: U (unpreserved) regs do not retain their values between + * phases (cannot be used for feedback) + * + * Note: oC and OD registers can only be used as the destination of a + * texture instruction once per phase (this is an implementation + * restriction). + */ +#define T0_DEST_NR_SHIFT 14 +/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ +#define T0_SAMPLER_NR_SHIFT 0 /* This field ignored for TEXKILL */ +#define T0_SAMPLER_NR_MASK (0xf<<0) + +#define T1_ADDRESS_REG_TYPE_SHIFT 24 /* Reg to use as texture coord */ +/* Allow R, T, OC, OD -- R, OC, OD are 'dependent' reads, new program phase */ +#define T1_ADDRESS_REG_NR_SHIFT 17 +#define T2_MBZ 0 + +/* Declaration instructions */ +#define D0_DCL (0x19<<24) /* Declare a t (interpolated attrib) + * register or an s (sampler) + * register. */ +#define D0_SAMPLE_TYPE_SHIFT 22 +#define D0_SAMPLE_TYPE_2D (0x0<<22) +#define D0_SAMPLE_TYPE_CUBE (0x1<<22) +#define D0_SAMPLE_TYPE_VOLUME (0x2<<22) +#define D0_SAMPLE_TYPE_MASK (0x3<<22) + +#define D0_TYPE_SHIFT 19 +/* Allow: T, S */ +#define D0_NR_SHIFT 14 +/* Allow T: 0..10, S: 0..15 */ +#define D0_CHANNEL_X (1<<10) +#define D0_CHANNEL_Y (2<<10) +#define D0_CHANNEL_Z (4<<10) +#define D0_CHANNEL_W (8<<10) +#define D0_CHANNEL_ALL (0xf<<10) +#define D0_CHANNEL_NONE (0<<10) + +#define D0_CHANNEL_XY (D0_CHANNEL_X|D0_CHANNEL_Y) +#define D0_CHANNEL_XYZ (D0_CHANNEL_XY|D0_CHANNEL_Z) + +/* I915 Errata: Do not allow (xz), (xw), (xzw) combinations for diffuse + * or specular declarations. + * + * For T dcls, only allow: (x), (xy), (xyz), (w), (xyzw) + * + * Must be zero for S (sampler) dcls + */ +#define D1_MBZ 0 +#define D2_MBZ 0 + + + +/* p207 */ +#define _3DSTATE_MAP_STATE (CMD_3D|(0x1d<<24)|(0x0<<16)) + +#define MS1_MAPMASK_SHIFT 0 +#define MS1_MAPMASK_MASK (0x8fff<<0) + +#define MS2_UNTRUSTED_SURFACE (1<<31) +#define MS2_ADDRESS_MASK 0xfffffffc +#define MS2_VERTICAL_LINE_STRIDE (1<<1) +#define MS2_VERTICAL_OFFSET (1<<1) + +#define MS3_HEIGHT_SHIFT 21 +#define MS3_WIDTH_SHIFT 10 +#define MS3_PALETTE_SELECT (1<<9) +#define MS3_MAPSURF_FORMAT_SHIFT 7 +#define MS3_MAPSURF_FORMAT_MASK (0x7<<7) +#define MAPSURF_8BIT (1<<7) +#define MAPSURF_16BIT (2<<7) +#define MAPSURF_32BIT (3<<7) +#define MAPSURF_422 (5<<7) +#define MAPSURF_COMPRESSED (6<<7) +#define MAPSURF_4BIT_INDEXED (7<<7) +#define MS3_MT_FORMAT_MASK (0x7 << 3) +#define MS3_MT_FORMAT_SHIFT 3 +#define MT_4BIT_IDX_ARGB8888 (7<<3) /* SURFACE_4BIT_INDEXED */ +#define MT_8BIT_I8 (0<<3) /* SURFACE_8BIT */ +#define MT_8BIT_L8 (1<<3) +#define MT_8BIT_A8 (4<<3) +#define MT_8BIT_MONO8 (5<<3) +#define MT_16BIT_RGB565 (0<<3) /* SURFACE_16BIT */ +#define MT_16BIT_ARGB1555 (1<<3) +#define MT_16BIT_ARGB4444 (2<<3) +#define MT_16BIT_AY88 (3<<3) +#define MT_16BIT_88DVDU (5<<3) +#define MT_16BIT_BUMP_655LDVDU (6<<3) +#define MT_16BIT_I16 (7<<3) +#define MT_16BIT_L16 (8<<3) +#define MT_16BIT_A16 (9<<3) +#define MT_32BIT_ARGB8888 (0<<3) /* SURFACE_32BIT */ +#define MT_32BIT_ABGR8888 (1<<3) +#define MT_32BIT_XRGB8888 (2<<3) +#define MT_32BIT_XBGR8888 (3<<3) +#define MT_32BIT_QWVU8888 (4<<3) +#define MT_32BIT_AXVU8888 (5<<3) +#define MT_32BIT_LXVU8888 (6<<3) +#define MT_32BIT_XLVU8888 (7<<3) +#define MT_32BIT_ARGB2101010 (8<<3) +#define MT_32BIT_ABGR2101010 (9<<3) +#define MT_32BIT_AWVU2101010 (0xA<<3) +#define MT_32BIT_GR1616 (0xB<<3) +#define MT_32BIT_VU1616 (0xC<<3) +#define MT_32BIT_xI824 (0xD<<3) +#define MT_32BIT_xA824 (0xE<<3) +#define MT_32BIT_xL824 (0xF<<3) +#define MT_422_YCRCB_SWAPY (0<<3) /* SURFACE_422 */ +#define MT_422_YCRCB_NORMAL (1<<3) +#define MT_422_YCRCB_SWAPUV (2<<3) +#define MT_422_YCRCB_SWAPUVY (3<<3) +#define MT_COMPRESS_DXT1 (0<<3) /* SURFACE_COMPRESSED */ +#define MT_COMPRESS_DXT2_3 (1<<3) +#define MT_COMPRESS_DXT4_5 (2<<3) +#define MT_COMPRESS_FXT1 (3<<3) +#define MT_COMPRESS_DXT1_RGB (4<<3) +#define MS3_USE_FENCE_REGS (1<<2) +#define MS3_TILED_SURFACE (1<<1) +#define MS3_TILE_WALK (1<<0) + +#define MS4_PITCH_SHIFT 21 +#define MS4_CUBE_FACE_ENA_NEGX (1<<20) +#define MS4_CUBE_FACE_ENA_POSX (1<<19) +#define MS4_CUBE_FACE_ENA_NEGY (1<<18) +#define MS4_CUBE_FACE_ENA_POSY (1<<17) +#define MS4_CUBE_FACE_ENA_NEGZ (1<<16) +#define MS4_CUBE_FACE_ENA_POSZ (1<<15) +#define MS4_CUBE_FACE_ENA_MASK (0x3f<<15) +#define MS4_MAX_LOD_SHIFT 9 +#define MS4_MAX_LOD_MASK (0x3f<<9) +#define MS4_MIP_LAYOUT_LEGACY (0<<8) +#define MS4_MIP_LAYOUT_BELOW_LPT (0<<8) +#define MS4_MIP_LAYOUT_RIGHT_LPT (1<<8) +#define MS4_VOLUME_DEPTH_SHIFT 0 +#define MS4_VOLUME_DEPTH_MASK (0xff<<0) + +/* p244 */ +#define _3DSTATE_SAMPLER_STATE (CMD_3D|(0x1d<<24)|(0x1<<16)) + +#define SS1_MAPMASK_SHIFT 0 +#define SS1_MAPMASK_MASK (0x8fff<<0) + +#define SS2_REVERSE_GAMMA_ENABLE (1<<31) +#define SS2_PACKED_TO_PLANAR_ENABLE (1<<30) +#define SS2_COLORSPACE_CONVERSION (1<<29) +#define SS2_CHROMAKEY_SHIFT 27 +#define SS2_BASE_MIP_LEVEL_SHIFT 22 +#define SS2_BASE_MIP_LEVEL_MASK (0x1f<<22) +#define SS2_MIP_FILTER_SHIFT 20 +#define SS2_MIP_FILTER_MASK (0x3<<20) +#define MIPFILTER_NONE 0 +#define MIPFILTER_NEAREST 1 +#define MIPFILTER_LINEAR 3 +#define SS2_MAG_FILTER_SHIFT 17 +#define SS2_MAG_FILTER_MASK (0x7<<17) +#define FILTER_NEAREST 0 +#define FILTER_LINEAR 1 +#define FILTER_ANISOTROPIC 2 +#define FILTER_4X4_1 3 +#define FILTER_4X4_2 4 +#define FILTER_4X4_FLAT 5 +#define FILTER_6X5_MONO 6 /* XXX - check */ +#define SS2_MIN_FILTER_SHIFT 14 +#define SS2_MIN_FILTER_MASK (0x7<<14) +#define SS2_LOD_BIAS_SHIFT 5 +#define SS2_LOD_BIAS_ONE (0x10<<5) +#define SS2_LOD_BIAS_MASK (0x1ff<<5) +/* Shadow requires: + * MT_X8{I,L,A}24 or MT_{I,L,A}16 texture format + * FILTER_4X4_x MIN and MAG filters + */ +#define SS2_SHADOW_ENABLE (1<<4) +#define SS2_MAX_ANISO_MASK (1<<3) +#define SS2_MAX_ANISO_2 (0<<3) +#define SS2_MAX_ANISO_4 (1<<3) +#define SS2_SHADOW_FUNC_SHIFT 0 +#define SS2_SHADOW_FUNC_MASK (0x7<<0) +/* SS2_SHADOW_FUNC values: see COMPAREFUNC_* */ + +#define SS3_MIN_LOD_SHIFT 24 +#define SS3_MIN_LOD_ONE (0x10<<24) +#define SS3_MIN_LOD_MASK (0xff<<24) +#define SS3_KILL_PIXEL_ENABLE (1<<17) +#define SS3_TCX_ADDR_MODE_SHIFT 12 +#define SS3_TCX_ADDR_MODE_MASK (0x7<<12) +#define TEXCOORDMODE_WRAP 0 +#define TEXCOORDMODE_MIRROR 1 +#define TEXCOORDMODE_CLAMP_EDGE 2 +#define TEXCOORDMODE_CUBE 3 +#define TEXCOORDMODE_CLAMP_BORDER 4 +#define TEXCOORDMODE_MIRROR_ONCE 5 +#define SS3_TCY_ADDR_MODE_SHIFT 9 +#define SS3_TCY_ADDR_MODE_MASK (0x7<<9) +#define SS3_TCZ_ADDR_MODE_SHIFT 6 +#define SS3_TCZ_ADDR_MODE_MASK (0x7<<6) +#define SS3_NORMALIZED_COORDS (1<<5) +#define SS3_TEXTUREMAP_INDEX_SHIFT 1 +#define SS3_TEXTUREMAP_INDEX_MASK (0xf<<1) +#define SS3_DEINTERLACER_ENABLE (1<<0) + +#define SS4_BORDER_COLOR_MASK (~0) + +/* 3DSTATE_SPAN_STIPPLE, p258 + */ +#define _3DSTATE_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) +#define ST1_ENABLE (1<<16) +#define ST1_MASK (0xffff) + +#define _3DSTATE_DEFAULT_Z ((0x3<<29)|(0x1d<<24)|(0x98<<16)) +#define _3DSTATE_DEFAULT_DIFFUSE ((0x3<<29)|(0x1d<<24)|(0x99<<16)) +#define _3DSTATE_DEFAULT_SPECULAR ((0x3<<29)|(0x1d<<24)|(0x9a<<16)) + + +#define MI_FLUSH ((0<<29)|(4<<23)) +#define FLUSH_MAP_CACHE (1<<0) +#define INHIBIT_FLUSH_RENDER_CACHE (1<<2) + + +#endif diff --git a/src/mesa/drivers/dri/i915tex/i915_state.c b/src/mesa/drivers/dri/i915tex/i915_state.c new file mode 100644 index 0000000000..d68801d3f9 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_state.c @@ -0,0 +1,1019 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "glheader.h" +#include "context.h" +#include "macros.h" +#include "enums.h" +#include "dd.h" +#include "tnl/tnl.h" +#include "tnl/t_context.h" + +#include "texmem.h" + +#include "intel_fbo.h" +#include "intel_screen.h" +#include "intel_batchbuffer.h" + +#include "i915_context.h" +#include "i915_reg.h" + +#define FILE_DEBUG_FLAG DEBUG_STATE + +static void +i915StencilFuncSeparate(GLcontext * ctx, GLenum face, GLenum func, GLint ref, + GLuint mask) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + int test = intel_translate_compare_func(func); + + mask = mask & 0xff; + + DBG("%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(func), ref, mask); + + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; + i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | + STENCIL_TEST_MASK(mask)); + + i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_REF_MASK | + S5_STENCIL_TEST_FUNC_MASK); + + i915->state.Ctx[I915_CTXREG_LIS5] |= ((ref << S5_STENCIL_REF_SHIFT) | + (test << + S5_STENCIL_TEST_FUNC_SHIFT)); +} + +static void +i915StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + + DBG("%s : mask 0x%x\n", __FUNCTION__, mask); + + mask = mask & 0xff; + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; + i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | + STENCIL_WRITE_MASK(mask)); +} + + +static void +i915StencilOpSeparate(GLcontext * ctx, GLenum face, GLenum fail, GLenum zfail, + GLenum zpass) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + int fop = intel_translate_stencil_op(fail); + int dfop = intel_translate_stencil_op(zfail); + int dpop = intel_translate_stencil_op(zpass); + + + DBG("%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(fail), + _mesa_lookup_enum_by_nr(zfail), _mesa_lookup_enum_by_nr(zpass)); + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + + i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK | + S5_STENCIL_PASS_Z_FAIL_MASK | + S5_STENCIL_PASS_Z_PASS_MASK); + + i915->state.Ctx[I915_CTXREG_LIS5] |= ((fop << S5_STENCIL_FAIL_SHIFT) | + (dfop << + S5_STENCIL_PASS_Z_FAIL_SHIFT) | + (dpop << + S5_STENCIL_PASS_Z_PASS_SHIFT)); +} + +static void +i915AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + int test = intel_translate_compare_func(func); + GLubyte refByte; + + UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref); + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_LIS6] &= ~(S6_ALPHA_TEST_FUNC_MASK | + S6_ALPHA_REF_MASK); + i915->state.Ctx[I915_CTXREG_LIS6] |= ((test << S6_ALPHA_TEST_FUNC_SHIFT) | + (((GLuint) refByte) << + S6_ALPHA_REF_SHIFT)); +} + +/* This function makes sure that the proper enables are + * set for LogicOp, Independant Alpha Blend, and Blending. + * It needs to be called from numerous places where we + * could change the LogicOp or Independant Alpha Blend without subsequent + * calls to glEnable. + */ +static void +i915EvalLogicOpBlendState(GLcontext * ctx) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + + if (ctx->Color._LogicOpEnabled) { + i915->state.Ctx[I915_CTXREG_LIS5] |= S5_LOGICOP_ENABLE; + i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE; + } + else { + i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_LOGICOP_ENABLE; + + if (ctx->Color.BlendEnabled) { + i915->state.Ctx[I915_CTXREG_LIS6] |= S6_CBUF_BLEND_ENABLE; + } + else { + i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE; + } + } +} + +static void +i915BlendColor(GLcontext * ctx, const GLfloat color[4]) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + GLubyte r, g, b, a; + + DBG("%s\n", __FUNCTION__); + + UNCLAMPED_FLOAT_TO_UBYTE(r, color[RCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(g, color[GCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]); + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = + (a << 24) | (r << 16) | (g << 8) | b; +} + + +#define DST_BLND_FACT(f) ((f)<state.Ctx[I915_CTXREG_IAB] & + ~(IAB_SRC_FACTOR_MASK | + IAB_DST_FACTOR_MASK | + (BLENDFUNC_MASK << IAB_FUNC_SHIFT) | IAB_ENABLE)); + + GLuint lis6 = (i915->state.Ctx[I915_CTXREG_LIS6] & + ~(S6_CBUF_SRC_BLEND_FACT_MASK | + S6_CBUF_DST_BLEND_FACT_MASK | S6_CBUF_BLEND_FUNC_MASK)); + + GLuint eqRGB = ctx->Color.BlendEquationRGB; + GLuint eqA = ctx->Color.BlendEquationA; + GLuint srcRGB = ctx->Color.BlendSrcRGB; + GLuint dstRGB = ctx->Color.BlendDstRGB; + GLuint srcA = ctx->Color.BlendSrcA; + GLuint dstA = ctx->Color.BlendDstA; + + if (eqRGB == GL_MIN || eqRGB == GL_MAX) { + srcRGB = dstRGB = GL_ONE; + } + + if (eqA == GL_MIN || eqA == GL_MAX) { + srcA = dstA = GL_ONE; + } + + lis6 |= SRC_BLND_FACT(intel_translate_blend_factor(srcRGB)); + lis6 |= DST_BLND_FACT(intel_translate_blend_factor(dstRGB)); + lis6 |= translate_blend_equation(eqRGB) << S6_CBUF_BLEND_FUNC_SHIFT; + + iab |= SRC_ABLND_FACT(intel_translate_blend_factor(srcA)); + iab |= DST_ABLND_FACT(intel_translate_blend_factor(dstA)); + iab |= translate_blend_equation(eqA) << IAB_FUNC_SHIFT; + + if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) + iab |= IAB_ENABLE; + + if (iab != i915->state.Ctx[I915_CTXREG_IAB] || + lis6 != i915->state.Ctx[I915_CTXREG_LIS6]) { + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_IAB] = iab; + i915->state.Ctx[I915_CTXREG_LIS6] = lis6; + } + + /* This will catch a logicop blend equation */ + i915EvalLogicOpBlendState(ctx); +} + + +static void +i915BlendFuncSeparate(GLcontext * ctx, GLenum srcRGB, + GLenum dstRGB, GLenum srcA, GLenum dstA) +{ + i915UpdateBlendState(ctx); +} + + +static void +i915BlendEquationSeparate(GLcontext * ctx, GLenum eqRGB, GLenum eqA) +{ + i915UpdateBlendState(ctx); +} + + +static void +i915DepthFunc(GLcontext * ctx, GLenum func) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + int test = intel_translate_compare_func(func); + + DBG("%s\n", __FUNCTION__); + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_FUNC_MASK; + i915->state.Ctx[I915_CTXREG_LIS6] |= test << S6_DEPTH_TEST_FUNC_SHIFT; +} + +static void +i915DepthMask(GLcontext * ctx, GLboolean flag) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + + DBG("%s flag (%d)\n", __FUNCTION__, flag); + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + + if (flag && ctx->Depth.Test) + i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_WRITE_ENABLE; + else + i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_WRITE_ENABLE; +} + +/* ============================================================= + * Polygon stipple + * + * The i915 supports a 4x4 stipple natively, GL wants 32x32. + * Fortunately stipple is usually a repeating pattern. + */ +static void +i915PolygonStipple(GLcontext * ctx, const GLubyte * mask) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + const GLubyte *m = mask; + GLubyte p[4]; + int i, j, k; + int active = (ctx->Polygon.StippleFlag && + i915->intel.reduced_primitive == GL_TRIANGLES); + GLuint newMask; + + if (active) { + I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); + i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE; + } + + p[0] = mask[12] & 0xf; + p[0] |= p[0] << 4; + p[1] = mask[8] & 0xf; + p[1] |= p[1] << 4; + p[2] = mask[4] & 0xf; + p[2] |= p[2] << 4; + p[3] = mask[0] & 0xf; + p[3] |= p[3] << 4; + + for (k = 0; k < 8; k++) + for (j = 3; j >= 0; j--) + for (i = 0; i < 4; i++, m++) + if (*m != p[j]) { + i915->intel.hw_stipple = 0; + return; + } + + newMask = (((p[0] & 0xf) << 0) | + ((p[1] & 0xf) << 4) | + ((p[2] & 0xf) << 8) | ((p[3] & 0xf) << 12)); + + + if (newMask == 0xffff || newMask == 0x0) { + /* this is needed to make conform pass */ + i915->intel.hw_stipple = 0; + return; + } + + i915->state.Stipple[I915_STPREG_ST1] &= ~0xffff; + i915->state.Stipple[I915_STPREG_ST1] |= newMask; + i915->intel.hw_stipple = 1; + + if (active) + i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE; +} + + +/* ============================================================= + * Hardware clipping + */ +static void +i915Scissor(GLcontext * ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + int x1, y1, x2, y2; + + if (!ctx->DrawBuffer) + return; + + DBG("%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); + + if (ctx->DrawBuffer->Name == 0) { + x1 = x; + y1 = ctx->DrawBuffer->Height - (y + h); + x2 = x + w - 1; + y2 = y1 + h - 1; + DBG("%s %d..%d,%d..%d (inverted)\n", __FUNCTION__, x1, x2, y1, y2); + } + else { + /* FBO - not inverted + */ + x1 = x; + y1 = y; + x2 = x + w - 1; + y2 = y + h - 1; + DBG("%s %d..%d,%d..%d (not inverted)\n", __FUNCTION__, x1, x2, y1, y2); + } + + x1 = CLAMP(x1, 0, ctx->DrawBuffer->Width - 1); + y1 = CLAMP(y1, 0, ctx->DrawBuffer->Height - 1); + x2 = CLAMP(x2, 0, ctx->DrawBuffer->Width - 1); + y2 = CLAMP(y2, 0, ctx->DrawBuffer->Height - 1); + + DBG("%s %d..%d,%d..%d (clamped)\n", __FUNCTION__, x1, x2, y1, y2); + + I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); + i915->state.Buffer[I915_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff); + i915->state.Buffer[I915_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff); +} + +static void +i915LogicOp(GLcontext * ctx, GLenum opcode) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + int tmp = intel_translate_logic_op(opcode); + + DBG("%s\n", __FUNCTION__); + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_STATE4] &= ~LOGICOP_MASK; + i915->state.Ctx[I915_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp); +} + + + +static void +i915CullFaceFrontFace(GLcontext * ctx, GLenum unused) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + GLuint mode; + + DBG("%s %d\n", __FUNCTION__, + ctx->DrawBuffer ? ctx->DrawBuffer->Name : 0); + + if (!ctx->Polygon.CullFlag) { + mode = S4_CULLMODE_NONE; + } + else if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) { + mode = S4_CULLMODE_CW; + + if (ctx->DrawBuffer && ctx->DrawBuffer->Name != 0) + mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); + if (ctx->Polygon.CullFaceMode == GL_FRONT) + mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); + if (ctx->Polygon.FrontFace != GL_CCW) + mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); + } + else { + mode = S4_CULLMODE_BOTH; + } + + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_CULLMODE_MASK; + i915->state.Ctx[I915_CTXREG_LIS4] |= mode; +} + +static void +i915LineWidth(GLcontext * ctx, GLfloat widthf) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_LINE_WIDTH_MASK; + int width; + + DBG("%s\n", __FUNCTION__); + + width = (int) (widthf * 2); + CLAMP_SELF(width, 1, 0xf); + lis4 |= width << S4_LINE_WIDTH_SHIFT; + + if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) { + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_LIS4] = lis4; + } +} + +static void +i915PointSize(GLcontext * ctx, GLfloat size) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_POINT_WIDTH_MASK; + GLint point_size = (int) size; + + DBG("%s\n", __FUNCTION__); + + CLAMP_SELF(point_size, 1, 255); + lis4 |= point_size << S4_POINT_WIDTH_SHIFT; + + if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) { + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_LIS4] = lis4; + } +} + + +/* ============================================================= + * Color masks + */ + +static void +i915ColorMask(GLcontext * ctx, + GLboolean r, GLboolean g, GLboolean b, GLboolean a) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + GLuint tmp = i915->state.Ctx[I915_CTXREG_LIS5] & ~S5_WRITEDISABLE_MASK; + + DBG("%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, r, g, b, + a); + + if (!r) + tmp |= S5_WRITEDISABLE_RED; + if (!g) + tmp |= S5_WRITEDISABLE_GREEN; + if (!b) + tmp |= S5_WRITEDISABLE_BLUE; + if (!a) + tmp |= S5_WRITEDISABLE_ALPHA; + + if (tmp != i915->state.Ctx[I915_CTXREG_LIS5]) { + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + i915->state.Ctx[I915_CTXREG_LIS5] = tmp; + } +} + +static void +update_specular(GLcontext * ctx) +{ + /* A hack to trigger the rebuild of the fragment program. + */ + intel_context(ctx)->NewGLState |= _NEW_TEXTURE; + I915_CONTEXT(ctx)->tex_program.translated = 0; +} + +static void +i915LightModelfv(GLcontext * ctx, GLenum pname, const GLfloat * param) +{ + DBG("%s\n", __FUNCTION__); + + if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { + update_specular(ctx); + } +} + +static void +i915ShadeModel(GLcontext * ctx, GLenum mode) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + + if (mode == GL_SMOOTH) { + i915->state.Ctx[I915_CTXREG_LIS4] &= ~(S4_FLATSHADE_ALPHA | + S4_FLATSHADE_COLOR | + S4_FLATSHADE_SPECULAR); + } + else { + i915->state.Ctx[I915_CTXREG_LIS4] |= (S4_FLATSHADE_ALPHA | + S4_FLATSHADE_COLOR | + S4_FLATSHADE_SPECULAR); + } +} + +/* ============================================================= + * Fog + */ +void +i915_update_fog(GLcontext * ctx) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + GLenum mode; + GLboolean enabled; + GLboolean try_pixel_fog; + + if (ctx->FragmentProgram._Active) { + /* Pull in static fog state from program */ + + mode = ctx->FragmentProgram._Current->FogOption; + enabled = (mode != GL_NONE); + try_pixel_fog = 0; + } + else { + enabled = ctx->Fog.Enabled; + mode = ctx->Fog.Mode; + + try_pixel_fog = (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT && ctx->Hint.Fog == GL_NICEST && 0); /* XXX - DISABLE -- Need ortho fallback */ + } + + if (!enabled) { + i915->vertex_fog = I915_FOG_NONE; + } + else if (try_pixel_fog) { + + I915_STATECHANGE(i915, I915_UPLOAD_FOG); + i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_FOGFUNC_MASK; + i915->vertex_fog = I915_FOG_PIXEL; + + switch (mode) { + case GL_LINEAR: + if (ctx->Fog.End <= ctx->Fog.Start) { + /* XXX - this won't work with fragment programs. Need to + * either fallback or append fog instructions to end of + * program in the case of linear fog. + */ + i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_VERTEX; + i915->vertex_fog = I915_FOG_VERTEX; + } + else { + GLfloat c1 = ctx->Fog.End / (ctx->Fog.End - ctx->Fog.Start); + GLfloat c2 = 1.0 / (ctx->Fog.End - ctx->Fog.Start); + + i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_C1_MASK; + i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_LINEAR; + i915->state.Fog[I915_FOGREG_MODE1] |= + ((GLuint) (c1 * FMC1_C1_ONE)) & FMC1_C1_MASK; + + if (i915->state.Fog[I915_FOGREG_MODE1] & FMC1_FOGINDEX_Z) { + i915->state.Fog[I915_FOGREG_MODE2] = + (GLuint) (c2 * FMC2_C2_ONE); + } + else { + union + { + float f; + int i; + } fi; + fi.f = c2; + i915->state.Fog[I915_FOGREG_MODE2] = fi.i; + } + } + break; + case GL_EXP: + i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_EXP; + break; + case GL_EXP2: + i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_EXP2; + break; + default: + break; + } + } + else { /* if (i915->vertex_fog != I915_FOG_VERTEX) */ + + I915_STATECHANGE(i915, I915_UPLOAD_FOG); + i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_FOGFUNC_MASK; + i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_VERTEX; + i915->vertex_fog = I915_FOG_VERTEX; + } + + { + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + I915_ACTIVESTATE(i915, I915_UPLOAD_FOG, enabled); + if (enabled) + i915->state.Ctx[I915_CTXREG_LIS5] |= S5_FOG_ENABLE; + else + i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_FOG_ENABLE; + } + + if (enabled) { + _tnl_allow_vertex_fog(ctx, (i915->vertex_fog == I915_FOG_VERTEX)); + _tnl_allow_pixel_fog(ctx, (i915->vertex_fog != I915_FOG_VERTEX)); + } +} + +static void +i915Fogfv(GLcontext * ctx, GLenum pname, const GLfloat * param) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + + switch (pname) { + case GL_FOG_COORDINATE_SOURCE_EXT: + case GL_FOG_MODE: + case GL_FOG_START: + case GL_FOG_END: + break; + + case GL_FOG_DENSITY: + I915_STATECHANGE(i915, I915_UPLOAD_FOG); + + if (i915->state.Fog[I915_FOGREG_MODE1] & FMC1_FOGINDEX_Z) { + i915->state.Fog[I915_FOGREG_MODE3] = (GLuint) (ctx->Fog.Density * + FMC3_D_ONE); + } + else { + union + { + float f; + int i; + } fi; + fi.f = ctx->Fog.Density; + i915->state.Fog[I915_FOGREG_MODE3] = fi.i; + } + break; + + case GL_FOG_COLOR: + I915_STATECHANGE(i915, I915_UPLOAD_FOG); + i915->state.Fog[I915_FOGREG_COLOR] = + (_3DSTATE_FOG_COLOR_CMD | + ((GLubyte) (ctx->Fog.Color[0] * 255.0F) << 16) | + ((GLubyte) (ctx->Fog.Color[1] * 255.0F) << 8) | + ((GLubyte) (ctx->Fog.Color[2] * 255.0F) << 0)); + break; + + default: + break; + } +} + +static void +i915Hint(GLcontext * ctx, GLenum target, GLenum state) +{ + switch (target) { + case GL_FOG_HINT: + break; + default: + break; + } +} + +/* ============================================================= + */ + +static void +i915Enable(GLcontext * ctx, GLenum cap, GLboolean state) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + + switch (cap) { + case GL_TEXTURE_2D: + break; + + case GL_LIGHTING: + case GL_COLOR_SUM: + update_specular(ctx); + break; + + case GL_ALPHA_TEST: + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + if (state) + i915->state.Ctx[I915_CTXREG_LIS6] |= S6_ALPHA_TEST_ENABLE; + else + i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_ALPHA_TEST_ENABLE; + break; + + case GL_BLEND: + i915EvalLogicOpBlendState(ctx); + break; + + case GL_COLOR_LOGIC_OP: + i915EvalLogicOpBlendState(ctx); + + /* Logicop doesn't seem to work at 16bpp: + */ + if (i915->intel.intelScreen->cpp == 2) /* XXX FBO fix */ + FALLBACK(&i915->intel, I915_FALLBACK_LOGICOP, state); + break; + + case GL_FRAGMENT_PROGRAM_ARB: + break; + + case GL_DITHER: + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + if (state) + i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE; + else + i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_COLOR_DITHER_ENABLE; + break; + + case GL_DEPTH_TEST: + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + if (state) + i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_TEST_ENABLE; + else + i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_ENABLE; + + i915DepthMask(ctx, ctx->Depth.Mask); + break; + + case GL_SCISSOR_TEST: + I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); + if (state) + i915->state.Buffer[I915_DESTREG_SENABLE] = + (_3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT); + else + i915->state.Buffer[I915_DESTREG_SENABLE] = + (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); + break; + + case GL_LINE_SMOOTH: + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + if (state) + i915->state.Ctx[I915_CTXREG_LIS4] |= S4_LINE_ANTIALIAS_ENABLE; + else + i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_LINE_ANTIALIAS_ENABLE; + break; + + case GL_FOG: + break; + + case GL_CULL_FACE: + i915CullFaceFrontFace(ctx, 0); + break; + + case GL_STENCIL_TEST: + { + GLboolean hw_stencil = GL_FALSE; + if (ctx->DrawBuffer) { + struct intel_renderbuffer *irbStencil + = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL); + hw_stencil = (irbStencil && irbStencil->region); + } + if (hw_stencil) { + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + if (state) + i915->state.Ctx[I915_CTXREG_LIS5] |= (S5_STENCIL_TEST_ENABLE | + S5_STENCIL_WRITE_ENABLE); + else + i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_TEST_ENABLE | + S5_STENCIL_WRITE_ENABLE); + } + else { + FALLBACK(&i915->intel, I915_FALLBACK_STENCIL, state); + } + } + break; + + case GL_POLYGON_STIPPLE: + /* The stipple command worked on my 855GM box, but not my 845G. + * I'll do more testing later to find out exactly which hardware + * supports it. Disabled for now. + */ + if (i915->intel.hw_stipple && + i915->intel.reduced_primitive == GL_TRIANGLES) { + I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); + if (state) + i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE; + else + i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE; + } + break; + + case GL_POLYGON_SMOOTH: + break; + + case GL_POINT_SMOOTH: + break; + + default: + ; + } +} + + +static void +i915_init_packets(struct i915_context *i915) +{ + intelScreenPrivate *screen = i915->intel.intelScreen; + + /* Zero all state */ + memset(&i915->state, 0, sizeof(i915->state)); + + + { + I915_STATECHANGE(i915, I915_UPLOAD_CTX); + /* Probably don't want to upload all this stuff every time one + * piece changes. + */ + i915->state.Ctx[I915_CTXREG_LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_1 | + I1_LOAD_S(2) | + I1_LOAD_S(4) | + I1_LOAD_S(5) | I1_LOAD_S(6) | (4)); + i915->state.Ctx[I915_CTXREG_LIS2] = 0; + i915->state.Ctx[I915_CTXREG_LIS4] = 0; + i915->state.Ctx[I915_CTXREG_LIS5] = 0; + + if (screen->cpp == 2) /* XXX FBO fix */ + i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE; + + + i915->state.Ctx[I915_CTXREG_LIS6] = (S6_COLOR_WRITE_ENABLE | + (2 << S6_TRISTRIP_PV_SHIFT)); + + i915->state.Ctx[I915_CTXREG_STATE4] = (_3DSTATE_MODES_4_CMD | + ENABLE_LOGIC_OP_FUNC | + LOGIC_OP_FUNC(LOGICOP_COPY) | + ENABLE_STENCIL_TEST_MASK | + STENCIL_TEST_MASK(0xff) | + ENABLE_STENCIL_WRITE_MASK | + STENCIL_WRITE_MASK(0xff)); + + i915->state.Ctx[I915_CTXREG_IAB] = + (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | IAB_MODIFY_ENABLE | + IAB_MODIFY_FUNC | IAB_MODIFY_SRC_FACTOR | IAB_MODIFY_DST_FACTOR); + + i915->state.Ctx[I915_CTXREG_BLENDCOLOR0] = + _3DSTATE_CONST_BLEND_COLOR_CMD; + i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = 0; + + } + + { + I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); + i915->state.Stipple[I915_STPREG_ST0] = _3DSTATE_STIPPLE; + } + + + { + I915_STATECHANGE(i915, I915_UPLOAD_FOG); + i915->state.Fog[I915_FOGREG_MODE0] = _3DSTATE_FOG_MODE_CMD; + i915->state.Fog[I915_FOGREG_MODE1] = (FMC1_FOGFUNC_MODIFY_ENABLE | + FMC1_FOGFUNC_VERTEX | + FMC1_FOGINDEX_MODIFY_ENABLE | + FMC1_FOGINDEX_W | + FMC1_C1_C2_MODIFY_ENABLE | + FMC1_DENSITY_MODIFY_ENABLE); + i915->state.Fog[I915_FOGREG_COLOR] = _3DSTATE_FOG_COLOR_CMD; + } + + + { + I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); + /* color buffer offset/stride */ + i915->state.Buffer[I915_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD; + /* XXX FBO: remove this? Also get set in i915_set_draw_region() */ + i915->state.Buffer[I915_DESTREG_CBUFADDR1] = (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(screen->front.pitch) | /* pitch in bytes */ + BUF_3D_USE_FENCE); + + i915->state.Buffer[I915_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD; + /* XXX FBO: remove this? Also get set in i915_set_draw_region() */ + i915->state.Buffer[I915_DESTREG_DBUFADDR1] = (BUF_3D_ID_DEPTH | BUF_3D_PITCH(screen->depth.pitch) | /* pitch in bytes */ + BUF_3D_USE_FENCE); + + i915->state.Buffer[I915_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD; + + /* XXX FBO: remove this? Also get set in i915_set_draw_region() */ +#if 0 /* seems we don't need this */ + switch (screen->fbFormat) { + case DV_PF_565: + i915->state.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | /* .5 */ + LOD_PRECLAMP_OGL | + TEX_DEFAULT_COLOR_OGL | + DITHER_FULL_ALWAYS | + screen->fbFormat | + DEPTH_FRMT_16_FIXED); + break; + case DV_PF_8888: + i915->state.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | /* .5 */ + LOD_PRECLAMP_OGL | + TEX_DEFAULT_COLOR_OGL | + screen->fbFormat | + DEPTH_FRMT_24_FIXED_8_OTHER); + break; + } +#endif + + + /* scissor */ + i915->state.Buffer[I915_DESTREG_SENABLE] = + (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); + i915->state.Buffer[I915_DESTREG_SR0] = _3DSTATE_SCISSOR_RECT_0_CMD; + i915->state.Buffer[I915_DESTREG_SR1] = 0; + i915->state.Buffer[I915_DESTREG_SR2] = 0; + } + + +#if 0 + { + I915_STATECHANGE(i915, I915_UPLOAD_DEFAULTS); + i915->state.Default[I915_DEFREG_C0] = _3DSTATE_DEFAULT_DIFFUSE; + i915->state.Default[I915_DEFREG_C1] = 0; + i915->state.Default[I915_DEFREG_S0] = _3DSTATE_DEFAULT_SPECULAR; + i915->state.Default[I915_DEFREG_S1] = 0; + i915->state.Default[I915_DEFREG_Z0] = _3DSTATE_DEFAULT_Z; + i915->state.Default[I915_DEFREG_Z1] = 0; + } +#endif + + + /* These will be emitted every at the head of every buffer, unless + * we get hardware contexts working. + */ + i915->state.active = (I915_UPLOAD_PROGRAM | + I915_UPLOAD_STIPPLE | + I915_UPLOAD_CTX | + I915_UPLOAD_BUFFERS | I915_UPLOAD_INVARIENT); +} + +void +i915InitStateFunctions(struct dd_function_table *functions) +{ + functions->AlphaFunc = i915AlphaFunc; + functions->BlendColor = i915BlendColor; + functions->BlendEquationSeparate = i915BlendEquationSeparate; + functions->BlendFuncSeparate = i915BlendFuncSeparate; + functions->ColorMask = i915ColorMask; + functions->CullFace = i915CullFaceFrontFace; + functions->DepthFunc = i915DepthFunc; + functions->DepthMask = i915DepthMask; + functions->Enable = i915Enable; + functions->Fogfv = i915Fogfv; + functions->FrontFace = i915CullFaceFrontFace; + functions->Hint = i915Hint; + functions->LightModelfv = i915LightModelfv; + functions->LineWidth = i915LineWidth; + functions->LogicOpcode = i915LogicOp; + functions->PointSize = i915PointSize; + functions->PolygonStipple = i915PolygonStipple; + functions->Scissor = i915Scissor; + functions->ShadeModel = i915ShadeModel; + functions->StencilFuncSeparate = i915StencilFuncSeparate; + functions->StencilMaskSeparate = i915StencilMaskSeparate; + functions->StencilOpSeparate = i915StencilOpSeparate; +} + + +void +i915InitState(struct i915_context *i915) +{ + GLcontext *ctx = &i915->intel.ctx; + + i915_init_packets(i915); + + intelInitState(ctx); + + memcpy(&i915->initial, &i915->state, sizeof(i915->state)); + i915->current = &i915->state; +} diff --git a/src/mesa/drivers/dri/i915tex/i915_tex.c b/src/mesa/drivers/dri/i915tex/i915_tex.c new file mode 100644 index 0000000000..a53abe9a92 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_tex.c @@ -0,0 +1,113 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "glheader.h" +#include "mtypes.h" +#include "imports.h" +#include "simple_list.h" +#include "enums.h" +#include "image.h" +#include "texstore.h" +#include "texformat.h" +#include "texmem.h" +#include "swrast/swrast.h" + +#include "mm.h" + +#include "intel_ioctl.h" + +#include "i915_context.h" +#include "i915_reg.h" + + + +static void +i915TexEnv(GLcontext * ctx, GLenum target, + GLenum pname, const GLfloat * param) +{ + struct i915_context *i915 = I915_CONTEXT(ctx); + + switch (pname) { + case GL_TEXTURE_ENV_COLOR: /* Should be a tracked param */ + case GL_TEXTURE_ENV_MODE: + case GL_COMBINE_RGB: + case GL_COMBINE_ALPHA: + case GL_SOURCE0_RGB: + case GL_SOURCE1_RGB: + case GL_SOURCE2_RGB: + case GL_SOURCE0_ALPHA: + case GL_SOURCE1_ALPHA: + case GL_SOURCE2_ALPHA: + case GL_OPERAND0_RGB: + case GL_OPERAND1_RGB: + case GL_OPERAND2_RGB: + case GL_OPERAND0_ALPHA: + case GL_OPERAND1_ALPHA: + case GL_OPERAND2_ALPHA: + case GL_RGB_SCALE: + case GL_ALPHA_SCALE: + i915->tex_program.translated = 0; + break; + + case GL_TEXTURE_LOD_BIAS:{ + GLuint unit = ctx->Texture.CurrentUnit; + GLint b = (int) ((*param) * 16.0); + if (b > 255) + b = 255; + if (b < -256) + b = -256; + I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit)); + i915->lodbias_ss2[unit] = + ((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK); + break; + } + + default: + break; + } +} + + +static void +i915BindTexture(GLcontext * ctx, GLenum target, + struct gl_texture_object *texobj) +{ + /* Need this if image format changes between bound textures. + * Could try and shortcircuit by checking for differences in + * state between incoming and outgoing textures: + */ + I915_CONTEXT(ctx)->tex_program.translated = 0; +} + + + +void +i915InitTextureFuncs(struct dd_function_table *functions) +{ + functions->BindTexture = i915BindTexture; + functions->TexEnv = i915TexEnv; +} diff --git a/src/mesa/drivers/dri/i915tex/i915_tex_layout.c b/src/mesa/drivers/dri/i915tex/i915_tex_layout.c new file mode 100644 index 0000000000..e9360ecea8 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_tex_layout.c @@ -0,0 +1,380 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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. + * + **************************************************************************/ + +/* Code to layout images in a mipmap tree for i915 and i945 + * respectively. + */ + +#include "intel_mipmap_tree.h" +#include "macros.h" +#include "intel_context.h" + +#define FILE_DEBUG_FLAG DEBUG_TEXTURE + +static GLint initial_offsets[6][2] = { {0, 0}, +{0, 2}, +{1, 0}, +{1, 2}, +{1, 1}, +{1, 3} +}; + + +static GLint step_offsets[6][2] = { {0, 2}, +{0, 2}, +{-1, 2}, +{-1, 2}, +{-1, 1}, +{-1, 1} +}; + +static GLuint +minify(GLuint d) +{ + return MAX2(1, d >> 1); +} + +GLboolean +i915_miptree_layout(struct intel_mipmap_tree * mt) +{ + GLint level; + + switch (mt->target) { + case GL_TEXTURE_CUBE_MAP:{ + const GLuint dim = mt->width0; + GLuint face; + + /* double pitch for cube layouts */ + mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp; + mt->total_height = dim * 4; + + for (level = mt->first_level; level <= mt->last_level; level++) + intel_miptree_set_level_info(mt, level, 6, + 0, 0, + mt->pitch, mt->total_height, 1); + + for (face = 0; face < 6; face++) { + GLuint x = initial_offsets[face][0] * dim; + GLuint y = initial_offsets[face][1] * dim; + GLuint d = dim; + + for (level = mt->first_level; level <= mt->last_level; level++) { + intel_miptree_set_image_offset(mt, level, face, x, y); + + if (d == 0) + _mesa_printf("cube mipmap %d/%d (%d..%d) is 0x0\n", + face, level, mt->first_level, mt->last_level); + + d >>= 1; + x += step_offsets[face][0] * d; + y += step_offsets[face][1] * d; + } + } + break; + } + case GL_TEXTURE_3D:{ + GLuint width = mt->width0; + GLuint height = mt->height0; + GLuint depth = mt->depth0; + GLuint stack_height = 0; + + /* Calculate the size of a single slice. + */ + mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; + + /* XXX: hardware expects/requires 9 levels at minimum. + */ + for (level = mt->first_level; level <= MAX2(8, mt->last_level); + level++) { + intel_miptree_set_level_info(mt, level, 1, 0, mt->total_height, + width, height, depth); + + + stack_height += MAX2(2, height); + + width = minify(width); + height = minify(height); + depth = minify(depth); + } + + /* Fixup depth image_offsets: + */ + depth = mt->depth0; + for (level = mt->first_level; level <= mt->last_level; level++) { + GLuint i; + for (i = 0; i < depth; i++) + intel_miptree_set_image_offset(mt, level, i, + 0, i * stack_height); + + depth = minify(depth); + } + + + /* Multiply slice size by texture depth for total size. It's + * remarkable how wasteful of memory the i915 texture layouts + * are. They are largely fixed in the i945. + */ + mt->total_height = stack_height * mt->depth0; + break; + } + + default:{ + GLuint width = mt->width0; + GLuint height = mt->height0; + GLuint img_height; + + mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; + mt->total_height = 0; + + for (level = mt->first_level; level <= mt->last_level; level++) { + intel_miptree_set_level_info(mt, level, 1, + 0, mt->total_height, + width, height, 1); + + if (mt->compressed) + img_height = MAX2(1, height / 4); + else + img_height = MAX2(2, height); + + mt->total_height += img_height; + mt->total_height += 1; + mt->total_height &= ~1; + + width = minify(width); + height = minify(height); + } + break; + } + } + DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__, + mt->pitch, + mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp); + + return GL_TRUE; +} + + +GLboolean +i945_miptree_layout(struct intel_mipmap_tree * mt) +{ + GLint level; + + switch (mt->target) { + case GL_TEXTURE_CUBE_MAP:{ + const GLuint dim = mt->width0; + GLuint face; + + /* Depending on the size of the largest images, pitch can be + * determined either by the old-style packing of cubemap faces, + * or the final row of 4x4, 2x2 and 1x1 faces below this. + */ + if (dim > 32) + mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp; + else + mt->pitch = 14 * 8; + + mt->total_height = dim * 4 + 4; + + /* Set all the levels to effectively occupy the whole rectangular region. + */ + for (level = mt->first_level; level <= mt->last_level; level++) + intel_miptree_set_level_info(mt, level, 6, + 0, 0, + mt->pitch, mt->total_height, 1); + + + + for (face = 0; face < 6; face++) { + GLuint x = initial_offsets[face][0] * dim; + GLuint y = initial_offsets[face][1] * dim; + GLuint d = dim; + + if (dim == 4 && face >= 4) { + y = mt->total_height - 4; + x = (face - 4) * 8; + } + else if (dim < 4) { + y = mt->total_height - 4; + x = face * 8; + } + + for (level = mt->first_level; level <= mt->last_level; level++) { + intel_miptree_set_image_offset(mt, level, face, x, y); + + d >>= 1; + + switch (d) { + case 4: + switch (face) { + case FACE_POS_X: + case FACE_NEG_X: + x += step_offsets[face][0] * d; + y += step_offsets[face][1] * d; + break; + case FACE_POS_Y: + case FACE_NEG_Y: + y += 12; + x -= 8; + break; + case FACE_POS_Z: + case FACE_NEG_Z: + y = mt->total_height - 4; + x = (face - 4) * 8; + break; + } + + case 2: + y = mt->total_height - 4; + x = 16 + face * 8; + break; + + case 1: + x += 48; + break; + + default: + x += step_offsets[face][0] * d; + y += step_offsets[face][1] * d; + break; + } + } + } + break; + } + case GL_TEXTURE_3D:{ + GLuint width = mt->width0; + GLuint height = mt->height0; + GLuint depth = mt->depth0; + GLuint pack_x_pitch, pack_x_nr; + GLuint pack_y_pitch; + GLuint level; + + mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; + mt->total_height = 0; + + pack_y_pitch = MAX2(mt->height0, 2); + pack_x_pitch = mt->pitch; + pack_x_nr = 1; + + for (level = mt->first_level; level <= mt->last_level; level++) { + GLuint nr_images = mt->target == GL_TEXTURE_3D ? depth : 6; + GLint x = 0; + GLint y = 0; + GLint q, j; + + intel_miptree_set_level_info(mt, level, nr_images, + 0, mt->total_height, + width, height, depth); + + for (q = 0; q < nr_images;) { + for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) { + intel_miptree_set_image_offset(mt, level, q, x, y); + x += pack_x_pitch; + } + + x = 0; + y += pack_y_pitch; + } + + + mt->total_height += y; + + if (pack_x_pitch > 4) { + pack_x_pitch >>= 1; + pack_x_nr <<= 1; + assert(pack_x_pitch * pack_x_nr <= mt->pitch); + } + + if (pack_y_pitch > 2) { + pack_y_pitch >>= 1; + } + + width = minify(width); + height = minify(height); + depth = minify(depth); + } + break; + } + + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_RECTANGLE_ARB:{ + GLuint x = 0; + GLuint y = 0; + GLuint width = mt->width0; + GLuint height = mt->height0; + GLint align_h = 2; + + mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; + mt->total_height = 0; + + for (level = mt->first_level; level <= mt->last_level; level++) { + GLuint img_height; + + intel_miptree_set_level_info(mt, level, 1, + x, y, + width, + mt->compressed ? height/4 : height, 1); + + + if (mt->compressed) + img_height = MAX2(1, height / 4); + else + img_height = MAX2(align_h, height); + + /* LPT change: step right after second mipmap. + */ + if (level == mt->first_level + 1) { + x += mt->pitch / 2; + x = (x + 3) & ~3; + } + else { + y += img_height; + y += align_h - 1; + y &= ~(align_h - 1); + } + + /* Because the images are packed better, the final offset + * might not be the maximal one: + */ + mt->total_height = MAX2(mt->total_height, y); + + width = minify(width); + height = minify(height); + } + break; + } + default: + _mesa_problem(NULL, "Unexpected tex target in i945_miptree_layout()"); + } + + DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__, + mt->pitch, + mt->total_height, mt->cpp, mt->pitch * mt->total_height * mt->cpp); + + return GL_TRUE; +} diff --git a/src/mesa/drivers/dri/i915tex/i915_texstate.c b/src/mesa/drivers/dri/i915tex/i915_texstate.c new file mode 100644 index 0000000000..e0ecdfde24 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_texstate.c @@ -0,0 +1,338 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "mtypes.h" +#include "enums.h" +#include "texformat.h" +#include "dri_bufmgr.h" + +#include "intel_mipmap_tree.h" +#include "intel_tex.h" + +#include "i915_context.h" +#include "i915_reg.h" + + +static GLuint +translate_texture_format(GLuint mesa_format) +{ + switch (mesa_format) { + case MESA_FORMAT_L8: + return MAPSURF_8BIT | MT_8BIT_L8; + case MESA_FORMAT_I8: + return MAPSURF_8BIT | MT_8BIT_I8; + case MESA_FORMAT_A8: + return MAPSURF_8BIT | MT_8BIT_A8; + case MESA_FORMAT_AL88: + return MAPSURF_16BIT | MT_16BIT_AY88; + case MESA_FORMAT_RGB565: + return MAPSURF_16BIT | MT_16BIT_RGB565; + case MESA_FORMAT_ARGB1555: + return MAPSURF_16BIT | MT_16BIT_ARGB1555; + case MESA_FORMAT_ARGB4444: + return MAPSURF_16BIT | MT_16BIT_ARGB4444; + case MESA_FORMAT_ARGB8888: + return MAPSURF_32BIT | MT_32BIT_ARGB8888; + case MESA_FORMAT_YCBCR_REV: + return (MAPSURF_422 | MT_422_YCRCB_NORMAL); + case MESA_FORMAT_YCBCR: + return (MAPSURF_422 | MT_422_YCRCB_SWAPY); + case MESA_FORMAT_RGB_FXT1: + case MESA_FORMAT_RGBA_FXT1: + return (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1); + case MESA_FORMAT_Z16: + return (MAPSURF_16BIT | MT_16BIT_L16); + case MESA_FORMAT_RGBA_DXT1: + case MESA_FORMAT_RGB_DXT1: + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); + case MESA_FORMAT_RGBA_DXT3: + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3); + case MESA_FORMAT_RGBA_DXT5: + return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); + case MESA_FORMAT_Z24_S8: + return (MAPSURF_32BIT | MT_32BIT_xL824); + default: + fprintf(stderr, "%s: bad image format %x\n", __FUNCTION__, mesa_format); + abort(); + return 0; + } +} + + + + +/* The i915 (and related graphics cores) do not support GL_CLAMP. The + * Intel drivers for "other operating systems" implement GL_CLAMP as + * GL_CLAMP_TO_EDGE, so the same is done here. + */ +static GLuint +translate_wrap_mode(GLenum wrap) +{ + switch (wrap) { + case GL_REPEAT: + return TEXCOORDMODE_WRAP; + case GL_CLAMP: + return TEXCOORDMODE_CLAMP_EDGE; /* not quite correct */ + case GL_CLAMP_TO_EDGE: + return TEXCOORDMODE_CLAMP_EDGE; + case GL_CLAMP_TO_BORDER: + return TEXCOORDMODE_CLAMP_BORDER; + case GL_MIRRORED_REPEAT: + return TEXCOORDMODE_MIRROR; + default: + return TEXCOORDMODE_WRAP; + } +} + + + +/* Recalculate all state from scratch. Perhaps not the most + * efficient, but this has gotten complex enough that we need + * something which is understandable and reliable. + */ +static GLboolean +i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) +{ + GLcontext *ctx = &intel->ctx; + struct i915_context *i915 = i915_context(ctx); + struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current; + struct intel_texture_object *intelObj = intel_texture_object(tObj); + struct gl_texture_image *firstImage; + GLuint *state = i915->state.Tex[unit]; + + memset(state, 0, sizeof(state)); + + /*We need to refcount these. */ + + if (i915->state.tex_buffer[unit] != NULL) { + driBOUnReference(i915->state.tex_buffer[unit]); + i915->state.tex_buffer[unit] = NULL; + } + + if (!intel_finalize_mipmap_tree(intel, unit)) + return GL_FALSE; + + /* Get first image here, since intelObj->firstLevel will get set in + * the intel_finalize_mipmap_tree() call above. + */ + firstImage = tObj->Image[0][intelObj->firstLevel]; + + i915->state.tex_buffer[unit] = driBOReference(intelObj->mt->region->buffer); + i915->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, 0, + intelObj-> + firstLevel); + + state[I915_TEXREG_MS3] = + (((firstImage->Height - 1) << MS3_HEIGHT_SHIFT) | + ((firstImage->Width - 1) << MS3_WIDTH_SHIFT) | + translate_texture_format(firstImage->TexFormat->MesaFormat) | + MS3_USE_FENCE_REGS); + + state[I915_TEXREG_MS4] = + (((((intelObj->mt->pitch * intelObj->mt->cpp) / 4) - + 1) << MS4_PITCH_SHIFT) | MS4_CUBE_FACE_ENA_MASK | + ((((intelObj->lastLevel - + intelObj->firstLevel) * + 4)) << MS4_MAX_LOD_SHIFT) | ((firstImage->Depth - + 1) << MS4_VOLUME_DEPTH_SHIFT)); + + + { + GLuint minFilt, mipFilt, magFilt; + + switch (tObj->MinFilter) { + case GL_NEAREST: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_NONE; + break; + case GL_LINEAR: + minFilt = FILTER_LINEAR; + mipFilt = MIPFILTER_NONE; + break; + case GL_NEAREST_MIPMAP_NEAREST: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_NEAREST; + break; + case GL_LINEAR_MIPMAP_NEAREST: + minFilt = FILTER_LINEAR; + mipFilt = MIPFILTER_NEAREST; + break; + case GL_NEAREST_MIPMAP_LINEAR: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_LINEAR; + break; + case GL_LINEAR_MIPMAP_LINEAR: + minFilt = FILTER_LINEAR; + mipFilt = MIPFILTER_LINEAR; + break; + default: + return GL_FALSE; + } + + if (tObj->MaxAnisotropy > 1.0) { + minFilt = FILTER_ANISOTROPIC; + magFilt = FILTER_ANISOTROPIC; + } + else { + switch (tObj->MagFilter) { + case GL_NEAREST: + magFilt = FILTER_NEAREST; + break; + case GL_LINEAR: + magFilt = FILTER_LINEAR; + break; + default: + return GL_FALSE; + } + } + + state[I915_TEXREG_SS2] = i915->lodbias_ss2[unit]; + + /* YUV conversion: + */ + if (firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR || + firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV) + state[I915_TEXREG_SS2] |= SS2_COLORSPACE_CONVERSION; + + /* Shadow: + */ + if (tObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB && + tObj->Target != GL_TEXTURE_3D) { + + state[I915_TEXREG_SS2] |= + (SS2_SHADOW_ENABLE | + intel_translate_compare_func(tObj->CompareFunc)); + + minFilt = FILTER_4X4_FLAT; + magFilt = FILTER_4X4_FLAT; + } + + state[I915_TEXREG_SS2] |= ((minFilt << SS2_MIN_FILTER_SHIFT) | + (mipFilt << SS2_MIP_FILTER_SHIFT) | + (magFilt << SS2_MAG_FILTER_SHIFT)); + } + + { + GLenum ws = tObj->WrapS; + GLenum wt = tObj->WrapT; + GLenum wr = tObj->WrapR; + + + /* 3D textures don't seem to respect the border color. + * Fallback if there's ever a danger that they might refer to + * it. + * + * Effectively this means fallback on 3D clamp or + * clamp_to_border. + */ + if (tObj->Target == GL_TEXTURE_3D && + (tObj->MinFilter != GL_NEAREST || + tObj->MagFilter != GL_NEAREST) && + (ws == GL_CLAMP || + wt == GL_CLAMP || + wr == GL_CLAMP || + ws == GL_CLAMP_TO_BORDER || + wt == GL_CLAMP_TO_BORDER || wr == GL_CLAMP_TO_BORDER)) + return GL_FALSE; + + + state[I915_TEXREG_SS3] = ss3; /* SS3_NORMALIZED_COORDS */ + + state[I915_TEXREG_SS3] |= + ((translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT) | + (translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT) | + (translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT)); + + state[I915_TEXREG_SS3] |= (unit << SS3_TEXTUREMAP_INDEX_SHIFT); + } + + + state[I915_TEXREG_SS4] = INTEL_PACKCOLOR8888(tObj->_BorderChan[0], + tObj->_BorderChan[1], + tObj->_BorderChan[2], + tObj->_BorderChan[3]); + + + I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(unit), GL_TRUE); + /* memcmp was already disabled, but definitely won't work as the + * region might now change and that wouldn't be detected: + */ + I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit)); + + +#if 0 + DBG(TEXTURE, "state[I915_TEXREG_SS2] = 0x%x\n", state[I915_TEXREG_SS2]); + DBG(TEXTURE, "state[I915_TEXREG_SS3] = 0x%x\n", state[I915_TEXREG_SS3]); + DBG(TEXTURE, "state[I915_TEXREG_SS4] = 0x%x\n", state[I915_TEXREG_SS4]); + DBG(TEXTURE, "state[I915_TEXREG_MS2] = 0x%x\n", state[I915_TEXREG_MS2]); + DBG(TEXTURE, "state[I915_TEXREG_MS3] = 0x%x\n", state[I915_TEXREG_MS3]); + DBG(TEXTURE, "state[I915_TEXREG_MS4] = 0x%x\n", state[I915_TEXREG_MS4]); +#endif + + return GL_TRUE; +} + + + + +void +i915UpdateTextureState(struct intel_context *intel) +{ + GLboolean ok = GL_TRUE; + GLuint i; + + for (i = 0; i < I915_TEX_UNITS && ok; i++) { + switch (intel->ctx.Texture.Unit[i]._ReallyEnabled) { + case TEXTURE_1D_BIT: + case TEXTURE_2D_BIT: + case TEXTURE_CUBE_BIT: + case TEXTURE_3D_BIT: + ok = i915_update_tex_unit(intel, i, SS3_NORMALIZED_COORDS); + break; + case TEXTURE_RECT_BIT: + ok = i915_update_tex_unit(intel, i, 0); + break; + case 0:{ + struct i915_context *i915 = i915_context(&intel->ctx); + if (i915->state.active & I915_UPLOAD_TEX(i)) + I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(i), GL_FALSE); + + if (i915->state.tex_buffer[i] != NULL) { + driBOUnReference(i915->state.tex_buffer[i]); + i915->state.tex_buffer[i] = NULL; + } + + break; + } + default: + ok = GL_FALSE; + break; + } + } + + FALLBACK(intel, I915_FALLBACK_TEXTURE, !ok); +} diff --git a/src/mesa/drivers/dri/i915tex/i915_vtbl.c b/src/mesa/drivers/dri/i915tex/i915_vtbl.c new file mode 100644 index 0000000000..827990d2cf --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/i915_vtbl.c @@ -0,0 +1,549 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "glheader.h" +#include "mtypes.h" +#include "imports.h" +#include "macros.h" +#include "colormac.h" + +#include "tnl/t_context.h" +#include "tnl/t_vertex.h" + +#include "intel_batchbuffer.h" +#include "intel_tex.h" +#include "intel_regions.h" + +#include "i915_reg.h" +#include "i915_context.h" + +static void +i915_render_start(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + + i915ValidateFragmentProgram(i915); +} + + +static void +i915_reduced_primitive_state(struct intel_context *intel, GLenum rprim) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + GLuint st1 = i915->state.Stipple[I915_STPREG_ST1]; + + st1 &= ~ST1_ENABLE; + + switch (rprim) { + case GL_TRIANGLES: + if (intel->ctx.Polygon.StippleFlag && intel->hw_stipple) + st1 |= ST1_ENABLE; + break; + case GL_LINES: + case GL_POINTS: + default: + break; + } + + i915->intel.reduced_primitive = rprim; + + if (st1 != i915->state.Stipple[I915_STPREG_ST1]) { + INTEL_FIREVERTICES(intel); + + I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); + i915->state.Stipple[I915_STPREG_ST1] = st1; + } +} + + +/* Pull apart the vertex format registers and figure out how large a + * vertex is supposed to be. + */ +static GLboolean +i915_check_vertex_size(struct intel_context *intel, GLuint expected) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + int lis2 = i915->current->Ctx[I915_CTXREG_LIS2]; + int lis4 = i915->current->Ctx[I915_CTXREG_LIS4]; + int i, sz = 0; + + switch (lis4 & S4_VFMT_XYZW_MASK) { + case S4_VFMT_XY: + sz = 2; + break; + case S4_VFMT_XYZ: + sz = 3; + break; + case S4_VFMT_XYW: + sz = 3; + break; + case S4_VFMT_XYZW: + sz = 4; + break; + default: + fprintf(stderr, "no xyzw specified\n"); + return 0; + } + + if (lis4 & S4_VFMT_SPEC_FOG) + sz++; + if (lis4 & S4_VFMT_COLOR) + sz++; + if (lis4 & S4_VFMT_DEPTH_OFFSET) + sz++; + if (lis4 & S4_VFMT_POINT_WIDTH) + sz++; + if (lis4 & S4_VFMT_FOG_PARAM) + sz++; + + for (i = 0; i < 8; i++) { + switch (lis2 & S2_TEXCOORD_FMT0_MASK) { + case TEXCOORDFMT_2D: + sz += 2; + break; + case TEXCOORDFMT_3D: + sz += 3; + break; + case TEXCOORDFMT_4D: + sz += 4; + break; + case TEXCOORDFMT_1D: + sz += 1; + break; + case TEXCOORDFMT_2D_16: + sz += 1; + break; + case TEXCOORDFMT_4D_16: + sz += 2; + break; + case TEXCOORDFMT_NOT_PRESENT: + break; + default: + fprintf(stderr, "bad texcoord fmt %d\n", i); + return GL_FALSE; + } + lis2 >>= S2_TEXCOORD_FMT1_SHIFT; + } + + if (sz != expected) + fprintf(stderr, "vertex size mismatch %d/%d\n", sz, expected); + + return sz == expected; +} + + +static void +i915_emit_invarient_state(struct intel_context *intel) +{ + BATCH_LOCALS; + + BEGIN_BATCH(200, 0); + + OUT_BATCH(_3DSTATE_AA_CMD | + AA_LINE_ECAAR_WIDTH_ENABLE | + AA_LINE_ECAAR_WIDTH_1_0 | + AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0); + + OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_DFLT_Z_CMD); + OUT_BATCH(0); + + /* Don't support texture crossbar yet */ + OUT_BATCH(_3DSTATE_COORD_SET_BINDINGS | + CSB_TCB(0, 0) | + CSB_TCB(1, 1) | + CSB_TCB(2, 2) | + CSB_TCB(3, 3) | + CSB_TCB(4, 4) | CSB_TCB(5, 5) | CSB_TCB(6, 6) | CSB_TCB(7, 7)); + + OUT_BATCH(_3DSTATE_RASTER_RULES_CMD | + ENABLE_POINT_RASTER_RULE | + OGL_POINT_RASTER_RULE | + ENABLE_LINE_STRIP_PROVOKE_VRTX | + ENABLE_TRI_FAN_PROVOKE_VRTX | + LINE_STRIP_PROVOKE_VRTX(1) | + TRI_FAN_PROVOKE_VRTX(2) | ENABLE_TEXKILL_3D_4D | TEXKILL_4D); + + /* Need to initialize this to zero. + */ + OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | (1)); + OUT_BATCH(0); + + /* XXX: Use this */ + OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); + + OUT_BATCH(_3DSTATE_SCISSOR_RECT_0_CMD); + OUT_BATCH(0); + OUT_BATCH(0); + + OUT_BATCH(_3DSTATE_DEPTH_SUBRECT_DISABLE); + + OUT_BATCH(_3DSTATE_LOAD_INDIRECT | 0); /* disable indirect state */ + OUT_BATCH(0); + + + /* Don't support twosided stencil yet */ + OUT_BATCH(_3DSTATE_BACKFACE_STENCIL_OPS | BFO_ENABLE_STENCIL_TWO_SIDE | 0); + + ADVANCE_BATCH(); +} + + +#define emit(intel, state, size ) \ + intel_batchbuffer_data(intel->batch, state, size, 0 ) + +static GLuint +get_dirty(struct i915_hw_state *state) +{ + GLuint dirty; + + /* Workaround the multitex hang - if one texture unit state is + * modified, emit all texture units. + */ + dirty = state->active & ~state->emitted; + if (dirty & I915_UPLOAD_TEX_ALL) + state->emitted &= ~I915_UPLOAD_TEX_ALL; + dirty = state->active & ~state->emitted; + return dirty; +} + + +static GLuint +get_state_size(struct i915_hw_state *state) +{ + GLuint dirty = get_dirty(state); + GLuint i; + GLuint sz = 0; + + if (dirty & I915_UPLOAD_CTX) + sz += sizeof(state->Ctx); + + if (dirty & I915_UPLOAD_BUFFERS) + sz += sizeof(state->Buffer); + + if (dirty & I915_UPLOAD_STIPPLE) + sz += sizeof(state->Stipple); + + if (dirty & I915_UPLOAD_FOG) + sz += sizeof(state->Fog); + + if (dirty & I915_UPLOAD_TEX_ALL) { + int nr = 0; + for (i = 0; i < I915_TEX_UNITS; i++) + if (dirty & I915_UPLOAD_TEX(i)) + nr++; + + sz += (2 + nr * 3) * sizeof(GLuint) * 2; + } + + if (dirty & I915_UPLOAD_CONSTANTS) + sz += state->ConstantSize * sizeof(GLuint); + + if (dirty & I915_UPLOAD_PROGRAM) + sz += state->ProgramSize * sizeof(GLuint); + + return sz; +} + + +/* Push the state into the sarea and/or texture memory. + */ +static void +i915_emit_state(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + struct i915_hw_state *state = i915->current; + int i; + GLuint dirty; + BATCH_LOCALS; + + /* We don't hold the lock at this point, so want to make sure that + * there won't be a buffer wrap. + * + * It might be better to talk about explicit places where + * scheduling is allowed, rather than assume that it is whenever a + * batchbuffer fills up. + */ + intel_batchbuffer_require_space(intel->batch, get_state_size(state), 0); + + /* Do this here as we may have flushed the batchbuffer above, + * causing more state to be dirty! + */ + dirty = get_dirty(state); + + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "%s dirty: %x\n", __FUNCTION__, dirty); + + if (dirty & I915_UPLOAD_INVARIENT) { + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I915_UPLOAD_INVARIENT:\n"); + i915_emit_invarient_state(intel); + } + + if (dirty & I915_UPLOAD_CTX) { + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I915_UPLOAD_CTX:\n"); + emit(intel, state->Ctx, sizeof(state->Ctx)); + } + + if (dirty & I915_UPLOAD_BUFFERS) { + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I915_UPLOAD_BUFFERS:\n"); + BEGIN_BATCH(I915_DEST_SETUP_SIZE + 2, 0); + OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR0]); + OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR1]); + OUT_RELOC(state->draw_region->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, + state->draw_region->draw_offset); + + if (state->depth_region) { + OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR0]); + OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR1]); + OUT_RELOC(state->depth_region->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, + state->depth_region->draw_offset); + } + + OUT_BATCH(state->Buffer[I915_DESTREG_DV0]); + OUT_BATCH(state->Buffer[I915_DESTREG_DV1]); + OUT_BATCH(state->Buffer[I915_DESTREG_SENABLE]); + OUT_BATCH(state->Buffer[I915_DESTREG_SR0]); + OUT_BATCH(state->Buffer[I915_DESTREG_SR1]); + OUT_BATCH(state->Buffer[I915_DESTREG_SR2]); + ADVANCE_BATCH(); + } + + if (dirty & I915_UPLOAD_STIPPLE) { + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I915_UPLOAD_STIPPLE:\n"); + emit(intel, state->Stipple, sizeof(state->Stipple)); + } + + if (dirty & I915_UPLOAD_FOG) { + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I915_UPLOAD_FOG:\n"); + emit(intel, state->Fog, sizeof(state->Fog)); + } + + /* Combine all the dirty texture state into a single command to + * avoid lockups on I915 hardware. + */ + if (dirty & I915_UPLOAD_TEX_ALL) { + int nr = 0; + + for (i = 0; i < I915_TEX_UNITS; i++) + if (dirty & I915_UPLOAD_TEX(i)) + nr++; + + BEGIN_BATCH(2 + nr * 3, 0); + OUT_BATCH(_3DSTATE_MAP_STATE | (3 * nr)); + OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT); + for (i = 0; i < I915_TEX_UNITS; i++) + if (dirty & I915_UPLOAD_TEX(i)) { + + if (state->tex_buffer[i]) { + OUT_RELOC(state->tex_buffer[i], + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, + state->tex_offset[i]); + } + else { + assert(i == 0); + assert(state == &i915->meta); + OUT_BATCH(0); + } + + OUT_BATCH(state->Tex[i][I915_TEXREG_MS3]); + OUT_BATCH(state->Tex[i][I915_TEXREG_MS4]); + } + ADVANCE_BATCH(); + + BEGIN_BATCH(2 + nr * 3, 0); + OUT_BATCH(_3DSTATE_SAMPLER_STATE | (3 * nr)); + OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT); + for (i = 0; i < I915_TEX_UNITS; i++) + if (dirty & I915_UPLOAD_TEX(i)) { + OUT_BATCH(state->Tex[i][I915_TEXREG_SS2]); + OUT_BATCH(state->Tex[i][I915_TEXREG_SS3]); + OUT_BATCH(state->Tex[i][I915_TEXREG_SS4]); + } + ADVANCE_BATCH(); + } + + if (dirty & I915_UPLOAD_CONSTANTS) { + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I915_UPLOAD_CONSTANTS:\n"); + emit(intel, state->Constant, state->ConstantSize * sizeof(GLuint)); + } + + if (dirty & I915_UPLOAD_PROGRAM) { + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "I915_UPLOAD_PROGRAM:\n"); + + assert((state->Program[0] & 0x1ff) + 2 == state->ProgramSize); + + emit(intel, state->Program, state->ProgramSize * sizeof(GLuint)); + if (INTEL_DEBUG & DEBUG_STATE) + i915_disassemble_program(state->Program, state->ProgramSize); + } + + state->emitted |= dirty; +} + +static void +i915_destroy_context(struct intel_context *intel) +{ + _tnl_free_vertices(&intel->ctx); +} + + +/** + * Set the drawing regions for the color and depth/stencil buffers. + * This involves setting the pitch, cpp and buffer ID/location. + * Also set pixel format for color and Z rendering + * Used for setting both regular and meta state. + */ +void +i915_state_draw_region(struct intel_context *intel, + struct i915_hw_state *state, + struct intel_region *color_region, + struct intel_region *depth_region) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + GLuint value; + + ASSERT(state == &i915->state || state == &i915->meta); + + if (state->draw_region != color_region) { + intel_region_release(&state->draw_region); + intel_region_reference(&state->draw_region, color_region); + } + if (state->depth_region != depth_region) { + intel_region_release(&state->depth_region); + intel_region_reference(&state->depth_region, depth_region); + } + + /* + * Set stride/cpp values + */ + if (color_region) { + state->Buffer[I915_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD; + state->Buffer[I915_DESTREG_CBUFADDR1] = + (BUF_3D_ID_COLOR_BACK | + BUF_3D_PITCH(color_region->pitch * color_region->cpp) | + BUF_3D_USE_FENCE); + } + + if (depth_region) { + state->Buffer[I915_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD; + state->Buffer[I915_DESTREG_DBUFADDR1] = + (BUF_3D_ID_DEPTH | + BUF_3D_PITCH(depth_region->pitch * depth_region->cpp) | + BUF_3D_USE_FENCE); + } + + /* + * Compute/set I915_DESTREG_DV1 value + */ + value = (DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | /* .5 */ + LOD_PRECLAMP_OGL | TEX_DEFAULT_COLOR_OGL); + if (color_region && color_region->cpp == 4) { + value |= DV_PF_8888; + } + else { + value |= (DITHER_FULL_ALWAYS | DV_PF_565); + } + if (depth_region && depth_region->cpp == 4) { + value |= DEPTH_FRMT_24_FIXED_8_OTHER; + } + else { + value |= DEPTH_FRMT_16_FIXED; + } + state->Buffer[I915_DESTREG_DV1] = value; + + I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); +} + + +static void +i915_set_draw_region(struct intel_context *intel, + struct intel_region *color_region, + struct intel_region *depth_region) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + i915_state_draw_region(intel, &i915->state, color_region, depth_region); +} + + + +static void +i915_lost_hardware(struct intel_context *intel) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + i915->state.emitted = 0; +} + +static GLuint +i915_flush_cmd(void) +{ + return MI_FLUSH | FLUSH_MAP_CACHE; +} + +static void +i915_assert_not_dirty( struct intel_context *intel ) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + struct i915_hw_state *state = i915->current; + GLuint dirty = get_dirty(state); + assert(!dirty); +} + + +void +i915InitVtbl(struct i915_context *i915) +{ + i915->intel.vtbl.check_vertex_size = i915_check_vertex_size; + i915->intel.vtbl.destroy = i915_destroy_context; + i915->intel.vtbl.emit_state = i915_emit_state; + i915->intel.vtbl.lost_hardware = i915_lost_hardware; + i915->intel.vtbl.reduced_primitive_state = i915_reduced_primitive_state; + i915->intel.vtbl.render_start = i915_render_start; + i915->intel.vtbl.set_draw_region = i915_set_draw_region; + i915->intel.vtbl.update_texture_state = i915UpdateTextureState; + i915->intel.vtbl.flush_cmd = i915_flush_cmd; + i915->intel.vtbl.assert_not_dirty = i915_assert_not_dirty; +} diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c new file mode 100644 index 0000000000..b4e0b74f16 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c @@ -0,0 +1,342 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "intel_batchbuffer.h" +#include "intel_ioctl.h" + +/* Relocations in kernel space: + * - pass dma buffer seperately + * - memory manager knows how to patch + * - pass list of dependent buffers + * - pass relocation list + * + * Either: + * - get back an offset for buffer to fire + * - memory manager knows how to fire buffer + * + * Really want the buffer to be AGP and pinned. + * + */ + +/* Cliprect fence: The highest fence protecting a dma buffer + * containing explicit cliprect information. Like the old drawable + * lock but irq-driven. X server must wait for this fence to expire + * before changing cliprects [and then doing sw rendering?]. For + * other dma buffers, the scheduler will grab current cliprect info + * and mix into buffer. X server must hold the lock while changing + * cliprects??? Make per-drawable. Need cliprects in shared memory + * -- beats storing them with every cmd buffer in the queue. + * + * ==> X server must wait for this fence to expire before touching the + * framebuffer with new cliprects. + * + * ==> Cliprect-dependent buffers associated with a + * cliprect-timestamp. All of the buffers associated with a timestamp + * must go to hardware before any buffer with a newer timestamp. + * + * ==> Dma should be queued per-drawable for correct X/GL + * synchronization. Or can fences be used for this? + * + * Applies to: Blit operations, metaops, X server operations -- X + * server automatically waits on its own dma to complete before + * modifying cliprects ??? + */ + +static void +intel_dump_batchbuffer(GLuint offset, GLuint * ptr, GLuint count) +{ + int i; + fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", count / 4); + for (i = 0; i < count / 4; i += 4) + fprintf(stderr, "0x%x:\t0x%08x 0x%08x 0x%08x 0x%08x\n", + offset + i * 4, ptr[i], ptr[i + 1], ptr[i + 2], ptr[i + 3]); + fprintf(stderr, "END BATCH\n\n\n"); +} + +void +intel_batchbuffer_reset(struct intel_batchbuffer *batch) +{ + + int i; + + /* + * Get a new, free batchbuffer. + */ + + batch->size = batch->intel->intelScreen->maxBatchSize; + driBOData(batch->buffer, batch->size, NULL, 0); + + driBOResetList(&batch->list); + + /* + * Unreference buffers previously on the relocation list. + */ + + for (i = 0; i < batch->nr_relocs; i++) { + struct buffer_reloc *r = &batch->reloc[i]; + driBOUnReference(r->buf); + } + + batch->list_count = 0; + batch->nr_relocs = 0; + batch->flags = 0; + + /* + * We don't refcount the batchbuffer itself since we can't destroy it + * while it's on the list. + */ + + + driBOAddListItem(&batch->list, batch->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_EXE); + + + batch->map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0); + batch->ptr = batch->map; +} + +/*====================================================================== + * Public functions + */ +struct intel_batchbuffer * +intel_batchbuffer_alloc(struct intel_context *intel) +{ + struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); + + batch->intel = intel; + + driGenBuffers(intel->intelScreen->batchPool, "batchbuffer", 1, + &batch->buffer, 4096, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, 0); + batch->last_fence = NULL; + driBOCreateList(20, &batch->list); + intel_batchbuffer_reset(batch); + return batch; +} + +void +intel_batchbuffer_free(struct intel_batchbuffer *batch) +{ + if (batch->last_fence) { + driFenceFinish(batch->last_fence, + DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW, GL_FALSE); + driFenceUnReference(batch->last_fence); + batch->last_fence = NULL; + } + if (batch->map) { + driBOUnmap(batch->buffer); + batch->map = NULL; + } + driBOUnReference(batch->buffer); + batch->buffer = NULL; + free(batch); +} + +/* TODO: Push this whole function into bufmgr. + */ +static void +do_flush_locked(struct intel_batchbuffer *batch, + GLuint used, + GLboolean ignore_cliprects, GLboolean allow_unlock) +{ + GLuint *ptr; + GLuint i; + struct intel_context *intel = batch->intel; + unsigned fenceFlags; + struct _DriFenceObject *fo; + + driBOValidateList(batch->intel->driFd, &batch->list); + + /* Apply the relocations. This nasty map indicates to me that the + * whole task should be done internally by the memory manager, and + * that dma buffers probably need to be pinned within agp space. + */ + ptr = (GLuint *) driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, + DRM_BO_HINT_ALLOW_UNFENCED_MAP); + + + for (i = 0; i < batch->nr_relocs; i++) { + struct buffer_reloc *r = &batch->reloc[i]; + + ptr[r->offset / 4] = driBOOffset(r->buf) + r->delta; + } + + if (INTEL_DEBUG & DEBUG_BATCH) + intel_dump_batchbuffer(0, ptr, used); + + driBOUnmap(batch->buffer); + batch->map = NULL; + + /* Throw away non-effective packets. Won't work once we have + * hardware contexts which would preserve statechanges beyond a + * single buffer. + */ + + if (!(intel->numClipRects == 0 && !ignore_cliprects)) { + intel_batch_ioctl(batch->intel, + driBOOffset(batch->buffer), + used, ignore_cliprects, allow_unlock); + } + + + /* + * Kernel fencing. The flags tells the kernel that we've + * programmed an MI_FLUSH. + */ + + fenceFlags = DRM_I915_FENCE_FLAG_FLUSHED; + fo = driFenceBuffers(batch->intel->driFd, + "Batch fence", fenceFlags); + + /* + * User space fencing. + */ + + driBOFence(batch->buffer, fo); + + if (driFenceType(fo) == DRM_FENCE_TYPE_EXE) { + + /* + * Oops. We only validated a batch buffer. This means we + * didn't do any proper rendering. Discard this fence object. + */ + + driFenceUnReference(fo); + } else { + driFenceUnReference(batch->last_fence); + batch->last_fence = fo; + for (i = 0; i < batch->nr_relocs; i++) { + struct buffer_reloc *r = &batch->reloc[i]; + driBOFence(r->buf, fo); + } + } + + if (intel->numClipRects == 0 && !ignore_cliprects) { + if (allow_unlock) { + UNLOCK_HARDWARE(intel); + sched_yield(); + LOCK_HARDWARE(intel); + } + intel->vtbl.lost_hardware(intel); + } +} + + +struct _DriFenceObject * +intel_batchbuffer_flush(struct intel_batchbuffer *batch) +{ + struct intel_context *intel = batch->intel; + GLuint used = batch->ptr - batch->map; + + if (used == 0) + return batch->last_fence; + + /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a + * performance drain that we would like to avoid. + */ + if (used & 4) { + ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->ptr)[1] = 0; + ((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END; + used += 12; + } + else { + ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd(); + ((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END; + used += 8; + } + + driBOUnmap(batch->buffer); + batch->ptr = NULL; + batch->map = NULL; + + /* TODO: Just pass the relocation list and dma buffer up to the + * kernel. + */ + if (!intel->locked) { + assert(!(batch->flags & INTEL_BATCH_NO_CLIPRECTS)); + + LOCK_HARDWARE(intel); + do_flush_locked(batch, used, GL_FALSE, GL_TRUE); + UNLOCK_HARDWARE(intel); + } + else { + GLboolean ignore_cliprects = !(batch->flags & INTEL_BATCH_CLIPRECTS); + do_flush_locked(batch, used, ignore_cliprects, GL_FALSE); + } + + /* Reset the buffer: + */ + intel_batchbuffer_reset(batch); + return batch->last_fence; +} + +void +intel_batchbuffer_finish(struct intel_batchbuffer *batch) +{ + struct _DriFenceObject *fence = intel_batchbuffer_flush(batch); + driFenceReference(fence); + driFenceFinish(fence, 3, GL_FALSE); + driFenceUnReference(fence); +} + + +/* This is the only way buffers get added to the validate list. + */ +GLboolean +intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, + struct _DriBufferObject *buffer, + GLuint flags, GLuint mask, GLuint delta) +{ + assert(batch->nr_relocs <= MAX_RELOCS); + + driBOAddListItem(&batch->list, buffer, flags, mask); + + { + struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++]; + driBOReference(buffer); + r->buf = buffer; + r->offset = batch->ptr - batch->map; + r->delta = delta; + } + + batch->ptr += 4; + return GL_TRUE; +} + + + +void +intel_batchbuffer_data(struct intel_batchbuffer *batch, + const void *data, GLuint bytes, GLuint flags) +{ + assert((bytes & 3) == 0); + intel_batchbuffer_require_space(batch, bytes, flags); + __memcpy(batch->ptr, data, bytes); + batch->ptr += bytes; +} diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h new file mode 100644 index 0000000000..a83dbf423d --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h @@ -0,0 +1,124 @@ +#ifndef INTEL_BATCHBUFFER_H +#define INTEL_BATCHBUFFER_H + +#include "mtypes.h" +#include "dri_bufmgr.h" + +struct intel_context; + +#define BATCH_SZ 16384 +#define BATCH_RESERVED 16 + +#define MAX_RELOCS 100 + +#define INTEL_BATCH_NO_CLIPRECTS 0x1 +#define INTEL_BATCH_CLIPRECTS 0x2 + +struct buffer_reloc +{ + struct _DriBufferObject *buf; + GLuint offset; + GLuint delta; /* not needed? */ +}; + +struct intel_batchbuffer +{ + struct bufmgr *bm; + struct intel_context *intel; + + struct _DriBufferObject *buffer; + struct _DriFenceObject *last_fence; + GLuint flags; + + drmBOList list; + GLuint list_count; + GLubyte *map; + GLubyte *ptr; + + struct buffer_reloc reloc[MAX_RELOCS]; + GLuint nr_relocs; + GLuint size; +}; + +struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context + *intel); + +void intel_batchbuffer_free(struct intel_batchbuffer *batch); + + +void intel_batchbuffer_finish(struct intel_batchbuffer *batch); + +struct _DriFenceObject *intel_batchbuffer_flush(struct intel_batchbuffer + *batch); + +void intel_batchbuffer_reset(struct intel_batchbuffer *batch); + + +/* Unlike bmBufferData, this currently requires the buffer be mapped. + * Consider it a convenience function wrapping multple + * intel_buffer_dword() calls. + */ +void intel_batchbuffer_data(struct intel_batchbuffer *batch, + const void *data, GLuint bytes, GLuint flags); + +void intel_batchbuffer_release_space(struct intel_batchbuffer *batch, + GLuint bytes); + +GLboolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, + struct _DriBufferObject *buffer, + GLuint flags, + GLuint mask, GLuint offset); + +/* Inline functions - might actually be better off with these + * non-inlined. Certainly better off switching all command packets to + * be passed as structs rather than dwords, but that's a little bit of + * work... + */ +static INLINE GLuint +intel_batchbuffer_space(struct intel_batchbuffer *batch) +{ + return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map); +} + + +static INLINE void +intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword) +{ + assert(batch->map); + assert(intel_batchbuffer_space(batch) >= 4); + *(GLuint *) (batch->ptr) = dword; + batch->ptr += 4; +} + +static INLINE void +intel_batchbuffer_require_space(struct intel_batchbuffer *batch, + GLuint sz, GLuint flags) +{ + assert(sz < batch->size - 8); + if (intel_batchbuffer_space(batch) < sz || + (batch->flags != 0 && flags != 0 && batch->flags != flags)) + intel_batchbuffer_flush(batch); + + batch->flags |= flags; +} + +/* Here are the crusty old macros, to be removed: + */ +#define BATCH_LOCALS + +#define BEGIN_BATCH(n, flags) do { \ + assert(!intel->prim.flush); \ + intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \ +} while (0) + +#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) + +#define OUT_RELOC(buf,flags,mask,delta) do { \ + assert((delta) >= 0); \ + intel_batchbuffer_emit_reloc(intel->batch, buf, flags, mask, delta); \ +} while (0) + +#define ADVANCE_BATCH() do { } while(0) + + +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_batchpool.c b/src/mesa/drivers/dri/i915tex/intel_batchpool.c new file mode 100644 index 0000000000..3c17c50204 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_batchpool.c @@ -0,0 +1,418 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * THE COPYRIGHT HOLDERS, AUTHORS 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + */ + +#include +#include +#include +#include "imports.h" +#include "glthread.h" +#include "dri_bufpool.h" +#include "dri_bufmgr.h" +#include "intel_screen.h" + +typedef struct +{ + drmMMListHead head; + struct _BPool *parent; + struct _DriFenceObject *fence; + unsigned long start; + int unfenced; + int mapped; +} BBuf; + +typedef struct _BPool +{ + _glthread_Mutex mutex; + unsigned long bufSize; + unsigned poolSize; + unsigned numFree; + unsigned numTot; + unsigned numDelayed; + unsigned checkDelayed; + drmMMListHead free; + drmMMListHead delayed; + drmMMListHead head; + drmBO kernelBO; + void *virtual; + BBuf *bufs; +} BPool; + + +static BPool * +createBPool(int fd, unsigned long bufSize, unsigned numBufs, unsigned flags, + unsigned checkDelayed) +{ + BPool *p = (BPool *) malloc(sizeof(*p)); + BBuf *buf; + int i; + + if (!p) + return NULL; + + p->bufs = (BBuf *) malloc(numBufs * sizeof(*p->bufs)); + if (!p->bufs) { + free(p); + return NULL; + } + + DRMINITLISTHEAD(&p->free); + DRMINITLISTHEAD(&p->head); + DRMINITLISTHEAD(&p->delayed); + + p->numTot = numBufs; + p->numFree = numBufs; + p->bufSize = bufSize; + p->numDelayed = 0; + p->checkDelayed = checkDelayed; + + _glthread_INIT_MUTEX(p->mutex); + + if (drmBOCreate(fd, 0, numBufs * bufSize, 0, NULL, drm_bo_type_dc, + flags, 0, &p->kernelBO)) { + free(p->bufs); + free(p); + return NULL; + } + if (drmBOMap(fd, &p->kernelBO, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, + &p->virtual)) { + drmBODestroy(fd, &p->kernelBO); + free(p->bufs); + free(p); + return NULL; + } + + /* + * We unmap the buffer so that we can validate it later. Note that this is + * just a synchronizing operation. The buffer will have a virtual mapping + * until it is destroyed. + */ + + drmBOUnmap(fd, &p->kernelBO); + + buf = p->bufs; + for (i = 0; i < numBufs; ++i) { + buf->parent = p; + buf->fence = NULL; + buf->start = i * bufSize; + buf->mapped = 0; + buf->unfenced = 0; + DRMLISTADDTAIL(&buf->head, &p->free); + buf++; + } + + return p; +} + + +static void +pool_checkFree(BPool * p, int wait) +{ + drmMMListHead *list, *prev; + BBuf *buf; + int signaled = 0; + int i; + + list = p->delayed.next; + + if (p->numDelayed > 3) { + for (i = 0; i < p->numDelayed; i += 3) { + list = list->next; + } + } + + prev = list->prev; + for (; list != &p->delayed; list = prev, prev = list->prev) { + + buf = DRMLISTENTRY(BBuf, list, head); + + if (!signaled) { + if (wait) { + driFenceFinish(buf->fence, DRM_FENCE_TYPE_EXE, 1); + signaled = 1; + } + else { + signaled = driFenceSignaled(buf->fence, DRM_FENCE_TYPE_EXE); + } + } + + if (!signaled) + break; + + driFenceUnReference(buf->fence); + buf->fence = NULL; + DRMLISTDEL(list); + p->numDelayed--; + DRMLISTADD(list, &p->free); + p->numFree++; + } +} + +static void * +pool_create(struct _DriBufferPool *pool, + unsigned long size, unsigned flags, unsigned hint, + unsigned alignment) +{ + BPool *p = (BPool *) pool->data; + + drmMMListHead *item; + + if (alignment && (alignment != 4096)) + return NULL; + + _glthread_LOCK_MUTEX(p->mutex); + + if (p->numFree == 0) + pool_checkFree(p, GL_TRUE); + + if (p->numFree == 0) { + fprintf(stderr, "Out of fixed size buffer objects\n"); + BM_CKFATAL(-ENOMEM); + } + + item = p->free.next; + + if (item == &p->free) { + fprintf(stderr, "Fixed size buffer pool corruption\n"); + } + + DRMLISTDEL(item); + --p->numFree; + + _glthread_UNLOCK_MUTEX(p->mutex); + return (void *) DRMLISTENTRY(BBuf, item, head); +} + + +static int +pool_destroy(struct _DriBufferPool *pool, void *private) +{ + BBuf *buf = (BBuf *) private; + BPool *p = buf->parent; + + _glthread_LOCK_MUTEX(p->mutex); + + if (buf->fence) { + DRMLISTADDTAIL(&buf->head, &p->delayed); + p->numDelayed++; + } + else { + buf->unfenced = 0; + DRMLISTADD(&buf->head, &p->free); + p->numFree++; + } + + if ((p->numDelayed % p->checkDelayed) == 0) + pool_checkFree(p, 0); + + _glthread_UNLOCK_MUTEX(p->mutex); + return 0; +} + + +static int +pool_map(struct _DriBufferPool *pool, void *private, unsigned flags, + int hint, void **virtual) +{ + + BBuf *buf = (BBuf *) private; + BPool *p = buf->parent; + + _glthread_LOCK_MUTEX(p->mutex); + + /* + * Currently Mesa doesn't have any condition variables to resolve this + * cleanly in a multithreading environment. + * We bail out instead. + */ + + if (buf->mapped) { + fprintf(stderr, "Trying to map already mapped buffer object\n"); + BM_CKFATAL(-EINVAL); + } + +#if 0 + if (buf->unfenced && !(hint & DRM_BO_HINT_ALLOW_UNFENCED_MAP)) { + fprintf(stderr, "Trying to map an unfenced buffer object 0x%08x" + " 0x%08x %d\n", hint, flags, buf->start); + BM_CKFATAL(-EINVAL); + } + +#endif + + if (buf->fence) { + _glthread_UNLOCK_MUTEX(p->mutex); + return -EBUSY; + } + + buf->mapped = GL_TRUE; + *virtual = (unsigned char *) p->virtual + buf->start; + _glthread_UNLOCK_MUTEX(p->mutex); + return 0; +} + +static int +pool_waitIdle(struct _DriBufferPool *pool, void *private, int lazy) +{ + BBuf *buf = (BBuf *) private; + driFenceFinish(buf->fence, 0, lazy); + return 0; +} + +static int +pool_unmap(struct _DriBufferPool *pool, void *private) +{ + BBuf *buf = (BBuf *) private; + + buf->mapped = 0; + return 0; +} + +static unsigned long +pool_offset(struct _DriBufferPool *pool, void *private) +{ + BBuf *buf = (BBuf *) private; + BPool *p = buf->parent; + + return p->kernelBO.offset + buf->start; +} + +static unsigned +pool_flags(struct _DriBufferPool *pool, void *private) +{ + BPool *p = (BPool *) pool->data; + + return p->kernelBO.flags; +} + +static unsigned long +pool_size(struct _DriBufferPool *pool, void *private) +{ + BPool *p = (BPool *) pool->data; + + return p->bufSize; +} + + +static int +pool_fence(struct _DriBufferPool *pool, void *private, + struct _DriFenceObject *fence) +{ + BBuf *buf = (BBuf *) private; + BPool *p = buf->parent; + + _glthread_LOCK_MUTEX(p->mutex); + if (buf->fence) { + driFenceUnReference(buf->fence); + } + buf->fence = fence; + buf->unfenced = 0; + driFenceReference(buf->fence); + _glthread_UNLOCK_MUTEX(p->mutex); + + return 0; +} + +static drmBO * +pool_kernel(struct _DriBufferPool *pool, void *private) +{ + BBuf *buf = (BBuf *) private; + BPool *p = buf->parent; + + return &p->kernelBO; +} + +static int +pool_validate(struct _DriBufferPool *pool, void *private) +{ + BBuf *buf = (BBuf *) private; + BPool *p = buf->parent; + _glthread_LOCK_MUTEX(p->mutex); + buf->unfenced = GL_TRUE; + _glthread_UNLOCK_MUTEX(p->mutex); + return 0; +} + +static void +pool_takedown(struct _DriBufferPool *pool) +{ + BPool *p = (BPool *) pool->data; + + /* + * Wait on outstanding fences. + */ + + _glthread_LOCK_MUTEX(p->mutex); + while ((p->numFree < p->numTot) && p->numDelayed) { + _glthread_UNLOCK_MUTEX(p->mutex); + sched_yield(); + pool_checkFree(p, GL_TRUE); + _glthread_LOCK_MUTEX(p->mutex); + } + + drmBODestroy(pool->fd, &p->kernelBO); + free(p->bufs); + _glthread_UNLOCK_MUTEX(p->mutex); + free(p); + free(pool); +} + + +struct _DriBufferPool * +driBatchPoolInit(int fd, unsigned flags, + unsigned long bufSize, + unsigned numBufs, unsigned checkDelayed) +{ + struct _DriBufferPool *pool; + + pool = (struct _DriBufferPool *) malloc(sizeof(*pool)); + if (!pool) + return NULL; + + pool->data = createBPool(fd, bufSize, numBufs, flags, checkDelayed); + if (!pool->data) + return NULL; + + pool->fd = fd; + pool->map = &pool_map; + pool->unmap = &pool_unmap; + pool->destroy = &pool_destroy; + pool->offset = &pool_offset; + pool->flags = &pool_flags; + pool->size = &pool_size; + pool->create = &pool_create; + pool->fence = &pool_fence; + pool->kernel = &pool_kernel; + pool->validate = &pool_validate; + pool->waitIdle = &pool_waitIdle; + pool->setstatic = NULL; + pool->takeDown = &pool_takedown; + return pool; +} diff --git a/src/mesa/drivers/dri/i915tex/intel_blit.c b/src/mesa/drivers/dri/i915tex/intel_blit.c new file mode 100644 index 0000000000..b6b6543908 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_blit.c @@ -0,0 +1,552 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 +#include + +#include "mtypes.h" +#include "context.h" +#include "enums.h" + +#include "intel_batchbuffer.h" +#include "intel_blit.h" +#include "intel_buffers.h" +#include "intel_context.h" +#include "intel_fbo.h" +#include "intel_reg.h" +#include "intel_regions.h" +#include "vblank.h" + +#define FILE_DEBUG_FLAG DEBUG_BLIT + +/** + * Copy the back color buffer to the front color buffer. + * Used for SwapBuffers(). + */ +void +intelCopyBuffer(const __DRIdrawablePrivate * dPriv, + const drm_clip_rect_t * rect) +{ + + struct intel_context *intel; + const intelScreenPrivate *intelScreen; + GLboolean missed_target; + int64_t ust; + + DBG("%s\n", __FUNCTION__); + + assert(dPriv); + + intel = intelScreenContext(dPriv->driScreenPriv->private); + if (!intel) + return; + + intelScreen = intel->intelScreen; + + if (!rect && !intel->swap_scheduled && intelScreen->drmMinor >= 6 && + !(intel->vblank_flags & VBLANK_FLAG_NO_IRQ) && + intelScreen->current_rotation == 0) { + unsigned int interval = driGetVBlankInterval(dPriv, intel->vblank_flags); + unsigned int target; + drm_i915_vblank_swap_t swap; + + swap.drawable = dPriv->hHWDrawable; + swap.seqtype = DRM_VBLANK_ABSOLUTE; + target = swap.sequence = intel->vbl_seq + interval; + + if (intel->vblank_flags & VBLANK_FLAG_SYNC) { + swap.seqtype |= DRM_VBLANK_NEXTONMISS; + } else if (interval == 0) { + goto noschedule; + } + + if ( intel->vblank_flags & VBLANK_FLAG_SECONDARY ) { + swap.seqtype |= DRM_VBLANK_SECONDARY; + } + + intel_batchbuffer_flush(intel->batch); + + if (!drmCommandWriteRead(intel->driFd, DRM_I915_VBLANK_SWAP, &swap, + sizeof(swap))) { + intel->swap_scheduled = 1; + intel->vbl_seq = swap.sequence; + swap.sequence -= target; + missed_target = swap.sequence > 0 && swap.sequence <= (1 << 23); + } + } else { + intel->swap_scheduled = 0; + } +noschedule: + + if (intel->last_swap_fence) { + driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); + driFenceUnReference(intel->last_swap_fence); + intel->last_swap_fence = NULL; + } + intel->last_swap_fence = intel->first_swap_fence; + intel->first_swap_fence = NULL; + + if (!intel->swap_scheduled) { + if (!rect) { + driWaitForVBlank(dPriv, &intel->vbl_seq, intel->vblank_flags, + &missed_target); + } + + + /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets + * should work regardless. + */ + LOCK_HARDWARE(intel); + + if (intel->driDrawable && intel->driDrawable->numClipRects) { + const intelScreenPrivate *intelScreen = intel->intelScreen; + struct gl_framebuffer *fb + = (struct gl_framebuffer *) dPriv->driverPrivate; + const struct intel_region *frontRegion + = intel_get_rb_region(fb, BUFFER_FRONT_LEFT); + const struct intel_region *backRegion + = intel_get_rb_region(fb, BUFFER_BACK_LEFT); + const int nbox = dPriv->numClipRects; + const drm_clip_rect_t *pbox = dPriv->pClipRects; + const int pitch = frontRegion->pitch; + const int cpp = frontRegion->cpp; + int BR13, CMD; + int i; + + ASSERT(fb); + ASSERT(fb->Name == 0); /* Not a user-created FBO */ + ASSERT(frontRegion); + ASSERT(backRegion); + ASSERT(frontRegion->pitch == backRegion->pitch); + ASSERT(frontRegion->cpp == backRegion->cpp); + + if (cpp == 2) { + BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24); + CMD = XY_SRC_COPY_BLT_CMD; + } + else { + BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25); + CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB); + } + + for (i = 0; i < nbox; i++, pbox++) { + drm_clip_rect_t box; + + if (pbox->x1 > pbox->x2 || + pbox->y1 > pbox->y2 || + pbox->x2 > intelScreen->width || pbox->y2 > intelScreen->height) + continue; + + box = *pbox; + + if (rect) { + if (rect->x1 > box.x1) + box.x1 = rect->x1; + if (rect->y1 > box.y1) + box.y1 = rect->y1; + if (rect->x2 < box.x2) + box.x2 = rect->x2; + if (rect->y2 < box.y2) + box.y2 = rect->y2; + + if (box.x1 > box.x2 || box.y1 > box.y2) + continue; + } + + BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((pbox->y1 << 16) | pbox->x1); + OUT_BATCH((pbox->y2 << 16) | pbox->x2); + + if (intel->sarea->pf_current_page == 0) + OUT_RELOC(frontRegion->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); + else + OUT_RELOC(backRegion->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0); + OUT_BATCH((pbox->y1 << 16) | pbox->x1); + OUT_BATCH(BR13 & 0xffff); + + if (intel->sarea->pf_current_page == 0) + OUT_RELOC(backRegion->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); + else + OUT_RELOC(frontRegion->buffer, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0); + + ADVANCE_BATCH(); + } + + if (intel->first_swap_fence) + driFenceUnReference(intel->first_swap_fence); + intel->first_swap_fence = intel_batchbuffer_flush(intel->batch); + driFenceReference(intel->first_swap_fence); + } + + UNLOCK_HARDWARE(intel); + } + + if (!rect) { + intel->swap_count++; + (*dri_interface->getUST) (&ust); + if (missed_target) { + intel->swap_missed_count++; + intel->swap_missed_ust = ust - intel->swap_ust; + } + + intel->swap_ust = ust; + } +} + + + + +void +intelEmitFillBlit(struct intel_context *intel, + GLuint cpp, + GLshort dst_pitch, + struct _DriBufferObject *dst_buffer, + GLuint dst_offset, + GLshort x, GLshort y, GLshort w, GLshort h, GLuint color) +{ + GLuint BR13, CMD; + BATCH_LOCALS; + + dst_pitch *= cpp; + + switch (cpp) { + case 1: + case 2: + case 3: + BR13 = dst_pitch | (0xF0 << 16) | (1 << 24); + CMD = XY_COLOR_BLT_CMD; + break; + case 4: + BR13 = dst_pitch | (0xF0 << 16) | (1 << 24) | (1 << 25); + CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA | + XY_COLOR_BLT_WRITE_RGB); + break; + default: + return; + } + + DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", + __FUNCTION__, dst_buffer, dst_pitch, dst_offset, x, y, w, h); + + + BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((y << 16) | x); + OUT_BATCH(((y + h) << 16) | (x + w)); + OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, dst_offset); + OUT_BATCH(color); + ADVANCE_BATCH(); +} + + +/* Copy BitBlt + */ +void +intelEmitCopyBlit(struct intel_context *intel, + GLuint cpp, + GLshort src_pitch, + struct _DriBufferObject *src_buffer, + GLuint src_offset, + GLshort dst_pitch, + struct _DriBufferObject *dst_buffer, + GLuint dst_offset, + GLshort src_x, GLshort src_y, + GLshort dst_x, GLshort dst_y, GLshort w, GLshort h) +{ + GLuint CMD, BR13; + int dst_y2 = dst_y + h; + int dst_x2 = dst_x + w; + BATCH_LOCALS; + + + DBG("%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", + __FUNCTION__, + src_buffer, src_pitch, src_offset, src_x, src_y, + dst_buffer, dst_pitch, dst_offset, dst_x, dst_y, w, h); + + src_pitch *= cpp; + dst_pitch *= cpp; + + switch (cpp) { + case 1: + case 2: + case 3: + BR13 = (((GLint) dst_pitch) & 0xffff) | (0xCC << 16) | (1 << 24); + CMD = XY_SRC_COPY_BLT_CMD; + break; + case 4: + BR13 = + (((GLint) dst_pitch) & 0xffff) | (0xCC << 16) | (1 << 24) | (1 << + 25); + CMD = + (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB); + break; + default: + return; + } + + if (dst_y2 < dst_y || dst_x2 < dst_x) { + return; + } + + /* Initial y values don't seem to work with negative pitches. If + * we adjust the offsets manually (below), it seems to work fine. + * + * On the other hand, if we always adjust, the hardware doesn't + * know which blit directions to use, so overlapping copypixels get + * the wrong result. + */ + if (dst_pitch > 0 && src_pitch > 0) { + BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((dst_y << 16) | dst_x); + OUT_BATCH((dst_y2 << 16) | dst_x2); + OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, dst_offset); + OUT_BATCH((src_y << 16) | src_x); + OUT_BATCH(((GLint) src_pitch & 0xffff)); + OUT_RELOC(src_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, src_offset); + ADVANCE_BATCH(); + } + else { + BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((0 << 16) | dst_x); + OUT_BATCH((h << 16) | dst_x2); + OUT_RELOC(dst_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, + dst_offset + dst_y * dst_pitch); + OUT_BATCH((0 << 16) | src_x); + OUT_BATCH(((GLint) src_pitch & 0xffff)); + OUT_RELOC(src_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, + DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, + src_offset + src_y * src_pitch); + ADVANCE_BATCH(); + } +} + + +/** + * Use blitting to clear the renderbuffers named by 'flags'. + * Note: we can't use the ctx->DrawBuffer->_ColorDrawBufferMask field + * since that might include software renderbuffers or renderbuffers + * which we're clearing with triangles. + * \param mask bitmask of BUFFER_BIT_* values indicating buffers to clear + */ +void +intelClearWithBlit(GLcontext * ctx, GLbitfield mask) +{ + struct intel_context *intel = intel_context(ctx); + GLuint clear_depth; + GLbitfield skipBuffers = 0; + BATCH_LOCALS; + + DBG("%s %x\n", __FUNCTION__, mask); + + /* + * Compute values for clearing the buffers. + */ + clear_depth = 0; + if (mask & BUFFER_BIT_DEPTH) { + clear_depth = (GLuint) (ctx->DrawBuffer->_DepthMax * ctx->Depth.Clear); + } + if (mask & BUFFER_BIT_STENCIL) { + clear_depth |= (ctx->Stencil.Clear & 0xff) << 24; + } + + /* If clearing both depth and stencil, skip BUFFER_BIT_STENCIL in + * the loop below. + */ + if ((mask & BUFFER_BIT_DEPTH) && (mask & BUFFER_BIT_STENCIL)) { + skipBuffers = BUFFER_BIT_STENCIL; + } + + /* XXX Move this flush/lock into the following conditional? */ + intelFlush(&intel->ctx); + LOCK_HARDWARE(intel); + + if (intel->numClipRects) { + GLint cx, cy, cw, ch; + drm_clip_rect_t clear; + int i; + + /* Get clear bounds after locking */ + cx = ctx->DrawBuffer->_Xmin; + cy = ctx->DrawBuffer->_Ymin; + cw = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; + ch = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; + + if (intel->ctx.DrawBuffer->Name == 0) { + /* clearing a window */ + + /* flip top to bottom */ + clear.x1 = cx + intel->drawX; + clear.y1 = intel->driDrawable->y + intel->driDrawable->h - cy - ch; + clear.x2 = clear.x1 + cw; + clear.y2 = clear.y1 + ch; + + /* adjust for page flipping */ + if (intel->sarea->pf_current_page == 1) { + const GLuint tmp = mask; + mask &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT); + if (tmp & BUFFER_BIT_FRONT_LEFT) + mask |= BUFFER_BIT_BACK_LEFT; + if (tmp & BUFFER_BIT_BACK_LEFT) + mask |= BUFFER_BIT_FRONT_LEFT; + } + } + else { + /* clearing FBO */ + assert(intel->numClipRects == 1); + assert(intel->pClipRects == &intel->fboRect); + clear.x1 = cx; + clear.y1 = cy; + clear.x2 = clear.x1 + cw; + clear.y2 = clear.y1 + ch; + /* no change to mask */ + } + + for (i = 0; i < intel->numClipRects; i++) { + const drm_clip_rect_t *box = &intel->pClipRects[i]; + drm_clip_rect_t b; + GLuint buf; + GLuint clearMask = mask; /* use copy, since we modify it below */ + GLboolean all = (cw == ctx->DrawBuffer->Width && + ch == ctx->DrawBuffer->Height); + + if (!all) { + intel_intersect_cliprects(&b, &clear, box); + } + else { + b = *box; + } + + if (0) + _mesa_printf("clear %d,%d..%d,%d, mask %x\n", + b.x1, b.y1, b.x2, b.y2, mask); + + /* Loop over all renderbuffers */ + for (buf = 0; buf < BUFFER_COUNT && clearMask; buf++) { + const GLbitfield bufBit = 1 << buf; + if ((clearMask & bufBit) && !(bufBit & skipBuffers)) { + /* OK, clear this renderbuffer */ + const struct intel_renderbuffer *irb + = intel_renderbuffer(ctx->DrawBuffer-> + Attachment[buf].Renderbuffer); + struct _DriBufferObject *write_buffer = + intel_region_buffer(intel->intelScreen, irb->region, + all ? INTEL_WRITE_FULL : + INTEL_WRITE_PART); + + GLuint clearVal; + GLint pitch, cpp; + GLuint BR13, CMD; + + ASSERT(irb); + ASSERT(irb->region); + + pitch = irb->region->pitch; + cpp = irb->region->cpp; + + DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", + __FUNCTION__, + irb->region->buffer, (pitch * cpp), + irb->region->draw_offset, + b.x1, b.y1, b.x2 - b.x1, b.y2 - b.y1); + + + /* Setup the blit command */ + if (cpp == 4) { + BR13 = (0xF0 << 16) | (pitch * cpp) | (1 << 24) | (1 << 25); + if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) { + CMD = XY_COLOR_BLT_CMD; + if (clearMask & BUFFER_BIT_DEPTH) + CMD |= XY_COLOR_BLT_WRITE_RGB; + if (clearMask & BUFFER_BIT_STENCIL) + CMD |= XY_COLOR_BLT_WRITE_ALPHA; + } + else { + /* clearing RGBA */ + CMD = (XY_COLOR_BLT_CMD | + XY_COLOR_BLT_WRITE_ALPHA | + XY_COLOR_BLT_WRITE_RGB); + } + } + else { + ASSERT(cpp == 2 || cpp == 0); + BR13 = (0xF0 << 16) | (pitch * cpp) | (1 << 24); + CMD = XY_COLOR_BLT_CMD; + } + + if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL) { + clearVal = clear_depth; + } + else { + clearVal = (cpp == 4) + ? intel->ClearColor8888 : intel->ClearColor565; + } + /* + _mesa_debug(ctx, "hardware blit clear buf %d rb id %d\n", + buf, irb->Base.Name); + */ + BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS); + OUT_BATCH(CMD); + OUT_BATCH(BR13); + OUT_BATCH((b.y1 << 16) | b.x1); + OUT_BATCH((b.y2 << 16) | b.x2); + OUT_RELOC(write_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, + DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, + irb->region->draw_offset); + OUT_BATCH(clearVal); + ADVANCE_BATCH(); + clearMask &= ~bufBit; /* turn off bit, for faster loop exit */ + } + } + } + intel_batchbuffer_flush(intel->batch); + } + + UNLOCK_HARDWARE(intel); +} diff --git a/src/mesa/drivers/dri/i915tex/intel_blit.h b/src/mesa/drivers/dri/i915tex/intel_blit.h new file mode 100644 index 0000000000..ee85c62633 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_blit.h @@ -0,0 +1,61 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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. + * + **************************************************************************/ + +#ifndef INTEL_BLIT_H +#define INTEL_BLIT_H + +#include "intel_context.h" +#include "intel_ioctl.h" +#include "dri_bufmgr.h" + +extern void intelCopyBuffer(const __DRIdrawablePrivate * dpriv, + const drm_clip_rect_t * rect); + +extern void intelClearWithBlit(GLcontext * ctx, GLbitfield mask); + +extern void intelEmitCopyBlit(struct intel_context *intel, + GLuint cpp, + GLshort src_pitch, + struct _DriBufferObject *src_buffer, + GLuint src_offset, + GLshort dst_pitch, + struct _DriBufferObject *dst_buffer, + GLuint dst_offset, + GLshort srcx, GLshort srcy, + GLshort dstx, GLshort dsty, + GLshort w, GLshort h); + +extern void intelEmitFillBlit(struct intel_context *intel, + GLuint cpp, + GLshort dst_pitch, + struct _DriBufferObject *dst_buffer, + GLuint dst_offset, + GLshort x, GLshort y, + GLshort w, GLshort h, GLuint color); + + +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c new file mode 100644 index 0000000000..31c41d8685 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c @@ -0,0 +1,250 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "imports.h" +#include "mtypes.h" +#include "bufferobj.h" + +#include "intel_context.h" +#include "intel_buffer_objects.h" +#include "intel_regions.h" +#include "dri_bufmgr.h" + +/** + * There is some duplication between mesa's bufferobjects and our + * bufmgr buffers. Both have an integer handle and a hashtable to + * lookup an opaque structure. It would be nice if the handles and + * internal structure where somehow shared. + */ +static struct gl_buffer_object * +intel_bufferobj_alloc(GLcontext * ctx, GLuint name, GLenum target) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_buffer_object *obj = CALLOC_STRUCT(intel_buffer_object); + + _mesa_initialize_buffer_object(&obj->Base, name, target); + + driGenBuffers(intel->intelScreen->regionPool, + "bufferobj", 1, &obj->buffer, 64, 0, 0); + + return &obj->Base; +} + + +/* Break the COW tie to the region. The region gets to keep the data. + */ +void +intel_bufferobj_release_region(struct intel_context *intel, + struct intel_buffer_object *intel_obj) +{ + assert(intel_obj->region->buffer == intel_obj->buffer); + intel_obj->region->pbo = NULL; + intel_obj->region = NULL; + driBOUnReference(intel_obj->buffer); + intel_obj->buffer = NULL; + + /* This leads to a large number of buffer deletion/creation events. + * Currently the drm doesn't like that: + */ + driGenBuffers(intel->intelScreen->regionPool, + "buffer object", 1, &intel_obj->buffer, 64, 0, 0); + driBOData(intel_obj->buffer, intel_obj->Base.Size, NULL, 0); +} + +/* Break the COW tie to the region. Both the pbo and the region end + * up with a copy of the data. + */ +void +intel_bufferobj_cow(struct intel_context *intel, + struct intel_buffer_object *intel_obj) +{ + assert(intel_obj->region); + intel_region_cow(intel->intelScreen, intel_obj->region); +} + + +/** + * Deallocate/free a vertex/pixel buffer object. + * Called via glDeleteBuffersARB(). + */ +static void +intel_bufferobj_free(GLcontext * ctx, struct gl_buffer_object *obj) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_buffer_object *intel_obj = intel_buffer_object(obj); + + assert(intel_obj); + + if (intel_obj->region) { + intel_bufferobj_release_region(intel, intel_obj); + } + else if (intel_obj->buffer) { + driDeleteBuffers(1, &intel_obj->buffer); + } + + _mesa_free(intel_obj); +} + + + +/** + * Allocate space for and store data in a buffer object. Any data that was + * previously stored in the buffer object is lost. If data is NULL, + * memory will be allocated, but no copy will occur. + * Called via glBufferDataARB(). + */ +static void +intel_bufferobj_data(GLcontext * ctx, + GLenum target, + GLsizeiptrARB size, + const GLvoid * data, + GLenum usage, struct gl_buffer_object *obj) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_buffer_object *intel_obj = intel_buffer_object(obj); + + intel_obj->Base.Size = size; + intel_obj->Base.Usage = usage; + + if (intel_obj->region) + intel_bufferobj_release_region(intel, intel_obj); + + driBOData(intel_obj->buffer, size, data, 0); +} + + +/** + * Replace data in a subrange of buffer object. If the data range + * specified by size + offset extends beyond the end of the buffer or + * if data is NULL, no copy is performed. + * Called via glBufferSubDataARB(). + */ +static void +intel_bufferobj_subdata(GLcontext * ctx, + GLenum target, + GLintptrARB offset, + GLsizeiptrARB size, + const GLvoid * data, struct gl_buffer_object *obj) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_buffer_object *intel_obj = intel_buffer_object(obj); + + assert(intel_obj); + + if (intel_obj->region) + intel_bufferobj_cow(intel, intel_obj); + + driBOSubData(intel_obj->buffer, offset, size, data); +} + + +/** + * Called via glGetBufferSubDataARB(). + */ +static void +intel_bufferobj_get_subdata(GLcontext * ctx, + GLenum target, + GLintptrARB offset, + GLsizeiptrARB size, + GLvoid * data, struct gl_buffer_object *obj) +{ + struct intel_buffer_object *intel_obj = intel_buffer_object(obj); + + assert(intel_obj); + driBOGetSubData(intel_obj->buffer, offset, size, data); +} + + + +/** + * Called via glMapBufferARB(). + */ +static void * +intel_bufferobj_map(GLcontext * ctx, + GLenum target, + GLenum access, struct gl_buffer_object *obj) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_buffer_object *intel_obj = intel_buffer_object(obj); + + /* XXX: Translate access to flags arg below: + */ + assert(intel_obj); + + if (intel_obj->region) + intel_bufferobj_cow(intel, intel_obj); + + obj->Pointer = driBOMap(intel_obj->buffer, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); + return obj->Pointer; +} + + +/** + * Called via glMapBufferARB(). + */ +static GLboolean +intel_bufferobj_unmap(GLcontext * ctx, + GLenum target, struct gl_buffer_object *obj) +{ + struct intel_buffer_object *intel_obj = intel_buffer_object(obj); + + assert(intel_obj); + assert(obj->Pointer); + driBOUnmap(intel_obj->buffer); + obj->Pointer = NULL; + return GL_TRUE; +} + +struct _DriBufferObject * +intel_bufferobj_buffer(struct intel_context *intel, + struct intel_buffer_object *intel_obj, GLuint flag) +{ + if (intel_obj->region) { + if (flag == INTEL_WRITE_PART) + intel_bufferobj_cow(intel, intel_obj); + else if (flag == INTEL_WRITE_FULL) + intel_bufferobj_release_region(intel, intel_obj); + } + + return intel_obj->buffer; +} + +void +intel_bufferobj_init(struct intel_context *intel) +{ + GLcontext *ctx = &intel->ctx; + + ctx->Driver.NewBufferObject = intel_bufferobj_alloc; + ctx->Driver.DeleteBuffer = intel_bufferobj_free; + ctx->Driver.BufferData = intel_bufferobj_data; + ctx->Driver.BufferSubData = intel_bufferobj_subdata; + ctx->Driver.GetBufferSubData = intel_bufferobj_get_subdata; + ctx->Driver.MapBuffer = intel_bufferobj_map; + ctx->Driver.UnmapBuffer = intel_bufferobj_unmap; +} diff --git a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.h b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.h new file mode 100644 index 0000000000..afe9b2f7cf --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.h @@ -0,0 +1,86 @@ + /************************************************************************** + * + * Copyright 2005 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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. + * + **************************************************************************/ + +#ifndef INTEL_BUFFEROBJ_H +#define INTEL_BUFFEROBJ_H + +#include "mtypes.h" + +struct intel_context; +struct intel_region; +struct gl_buffer_object; + + +/** + * Intel vertex/pixel buffer object, derived from Mesa's gl_buffer_object. + */ +struct intel_buffer_object +{ + struct gl_buffer_object Base; + struct _DriBufferObject *buffer; /* the low-level buffer manager's buffer handle */ + + struct intel_region *region; /* Is there a zero-copy texture + associated with this (pixel) + buffer object? */ +}; + + +/* Get the bm buffer associated with a GL bufferobject: + */ +struct _DriBufferObject *intel_bufferobj_buffer(struct intel_context *intel, + struct intel_buffer_object + *obj, GLuint flag); + +/* Hook the bufferobject implementation into mesa: + */ +void intel_bufferobj_init(struct intel_context *intel); + + + +/* Are the obj->Name tests necessary? Unfortunately yes, mesa + * allocates a couple of gl_buffer_object structs statically, and + * the Name == 0 test is the only way to identify them and avoid + * casting them erroneously to our structs. + */ +static INLINE struct intel_buffer_object * +intel_buffer_object(struct gl_buffer_object *obj) +{ + if (obj->Name) + return (struct intel_buffer_object *) obj; + else + return NULL; +} + +/* Helpers for zerocopy image uploads. See also intel_regions.h: + */ +void intel_bufferobj_cow(struct intel_context *intel, + struct intel_buffer_object *intel_obj); +void intel_bufferobj_release_region(struct intel_context *intel, + struct intel_buffer_object *intel_obj); + + +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_buffers.c b/src/mesa/drivers/dri/i915tex/intel_buffers.c new file mode 100644 index 0000000000..d3925bbc1e --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_buffers.c @@ -0,0 +1,956 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "intel_screen.h" +#include "intel_context.h" +#include "intel_blit.h" +#include "intel_buffers.h" +#include "intel_depthstencil.h" +#include "intel_fbo.h" +#include "intel_tris.h" +#include "intel_regions.h" +#include "intel_batchbuffer.h" +#include "context.h" +#include "utils.h" +#include "framebuffer.h" +#include "swrast/swrast.h" +#include "vblank.h" + + +/** + * XXX move this into a new dri/common/cliprects.c file. + */ +GLboolean +intel_intersect_cliprects(drm_clip_rect_t * dst, + const drm_clip_rect_t * a, + const drm_clip_rect_t * b) +{ + GLint bx = b->x1; + GLint by = b->y1; + GLint bw = b->x2 - bx; + GLint bh = b->y2 - by; + + if (bx < a->x1) + bw -= a->x1 - bx, bx = a->x1; + if (by < a->y1) + bh -= a->y1 - by, by = a->y1; + if (bx + bw > a->x2) + bw = a->x2 - bx; + if (by + bh > a->y2) + bh = a->y2 - by; + if (bw <= 0) + return GL_FALSE; + if (bh <= 0) + return GL_FALSE; + + dst->x1 = bx; + dst->y1 = by; + dst->x2 = bx + bw; + dst->y2 = by + bh; + + return GL_TRUE; +} + +/** + * Return pointer to current color drawing region, or NULL. + */ +struct intel_region * +intel_drawbuf_region(struct intel_context *intel) +{ + struct intel_renderbuffer *irbColor = + intel_renderbuffer(intel->ctx.DrawBuffer->_ColorDrawBuffers[0][0]); + if (irbColor) + return irbColor->region; + else + return NULL; +} + +/** + * Return pointer to current color reading region, or NULL. + */ +struct intel_region * +intel_readbuf_region(struct intel_context *intel) +{ + struct intel_renderbuffer *irb + = intel_renderbuffer(intel->ctx.ReadBuffer->_ColorReadBuffer); + if (irb) + return irb->region; + else + return NULL; +} + + + +static void +intelBufferSize(GLframebuffer * buffer, GLuint * width, GLuint * height) +{ + GET_CURRENT_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); + /* Need to lock to make sure the driDrawable is uptodate. This + * information is used to resize Mesa's software buffers, so it has + * to be correct. + */ + /* XXX This isn't 100% correct, the given buffer might not be + * bound to the current context! + */ + LOCK_HARDWARE(intel); + if (intel->driDrawable) { + *width = intel->driDrawable->w; + *height = intel->driDrawable->h; + } + else { + *width = 0; + *height = 0; + } + UNLOCK_HARDWARE(intel); +} + + + +/** + * Update the following fields for rendering to a user-created FBO: + * intel->numClipRects + * intel->pClipRects + * intel->drawX + * intel->drawY + */ +static void +intelSetRenderbufferClipRects(struct intel_context *intel) +{ + assert(intel->ctx.DrawBuffer->Width > 0); + assert(intel->ctx.DrawBuffer->Height > 0); + intel->fboRect.x1 = 0; + intel->fboRect.y1 = 0; + intel->fboRect.x2 = intel->ctx.DrawBuffer->Width; + intel->fboRect.y2 = intel->ctx.DrawBuffer->Height; + intel->numClipRects = 1; + intel->pClipRects = &intel->fboRect; + intel->drawX = 0; + intel->drawY = 0; +} + + +/** + * As above, but for rendering to front buffer of a window. + * \sa intelSetRenderbufferClipRects + */ +static void +intelSetFrontClipRects(struct intel_context *intel) +{ + __DRIdrawablePrivate *dPriv = intel->driDrawable; + + if (!dPriv) + return; + + intel->numClipRects = dPriv->numClipRects; + intel->pClipRects = dPriv->pClipRects; + intel->drawX = dPriv->x; + intel->drawY = dPriv->y; +} + + +/** + * As above, but for rendering to back buffer of a window. + */ +static void +intelSetBackClipRects(struct intel_context *intel) +{ + __DRIdrawablePrivate *dPriv = intel->driDrawable; + + if (!dPriv) + return; + + if (intel->sarea->pf_enabled == 0 && dPriv->numBackClipRects == 0) { + /* use the front clip rects */ + intel->numClipRects = dPriv->numClipRects; + intel->pClipRects = dPriv->pClipRects; + intel->drawX = dPriv->x; + intel->drawY = dPriv->y; + } + else { + /* use the back clip rects */ + intel->numClipRects = dPriv->numBackClipRects; + intel->pClipRects = dPriv->pBackClipRects; + intel->drawX = dPriv->backX; + intel->drawY = dPriv->backY; + } +} + + +/** + * This will be called whenever the currently bound window is moved/resized. + * XXX: actually, it seems to NOT be called when the window is only moved (BP). + */ +void +intelWindowMoved(struct intel_context *intel) +{ + GLcontext *ctx = &intel->ctx; + + if (!intel->ctx.DrawBuffer) { + /* when would this happen? -BP */ + intelSetFrontClipRects(intel); + } + else if (intel->ctx.DrawBuffer->Name != 0) { + /* drawing to user-created FBO - do nothing */ + /* Cliprects would be set from intelDrawBuffer() */ + } + else { + /* drawing to a window */ + switch (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0]) { + case BUFFER_BIT_FRONT_LEFT: + intelSetFrontClipRects(intel); + break; + case BUFFER_BIT_BACK_LEFT: + intelSetBackClipRects(intel); + break; + default: + /* glDrawBuffer(GL_NONE or GL_FRONT_AND_BACK): software fallback */ + intelSetFrontClipRects(intel); + } + } + + /* this update Mesa's notion of window size */ + if (ctx->WinSysDrawBuffer) { + _mesa_resize_framebuffer(ctx, ctx->WinSysDrawBuffer, + intel->driDrawable->w, intel->driDrawable->h); + } + + if (intel->intelScreen->driScrnPriv->ddxMinor >= 7 && intel->driDrawable) { + __DRIdrawablePrivate *dPriv = intel->driDrawable; + drmI830Sarea *sarea = intel->sarea; + drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w, + .y1 = dPriv->y, .y2 = dPriv->y + dPriv->h }; + drm_clip_rect_t pipeA_rect = { .x1 = sarea->pipeA_x, .y1 = sarea->pipeA_y, + .x2 = sarea->pipeA_x + sarea->pipeA_w, + .y2 = sarea->pipeA_y + sarea->pipeA_h }; + drm_clip_rect_t pipeB_rect = { .x1 = sarea->pipeB_x, .y1 = sarea->pipeB_y, + .x2 = sarea->pipeB_x + sarea->pipeB_w, + .y2 = sarea->pipeB_y + sarea->pipeB_h }; + GLint areaA = driIntersectArea( drw_rect, pipeA_rect ); + GLint areaB = driIntersectArea( drw_rect, pipeB_rect ); + GLuint flags = intel->vblank_flags; + + if (areaB > areaA || (areaA == areaB && areaB > 0)) { + flags = intel->vblank_flags | VBLANK_FLAG_SECONDARY; + } else { + flags = intel->vblank_flags & ~VBLANK_FLAG_SECONDARY; + } + + if (flags != intel->vblank_flags) { + intel->vblank_flags = flags; + driGetCurrentVBlank(dPriv, intel->vblank_flags, &intel->vbl_seq); + } + } else { + intel->vblank_flags &= ~VBLANK_FLAG_SECONDARY; + } + + /* Update hardware scissor */ + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); +} + + + +/* A true meta version of this would be very simple and additionally + * machine independent. Maybe we'll get there one day. + */ +static void +intelClearWithTris(struct intel_context *intel, GLbitfield mask) +{ + GLcontext *ctx = &intel->ctx; + drm_clip_rect_t clear; + + if (INTEL_DEBUG & DEBUG_BLIT) + _mesa_printf("%s 0x%x\n", __FUNCTION__, mask); + + LOCK_HARDWARE(intel); + + /* XXX FBO: was: intel->driDrawable->numClipRects */ + if (intel->numClipRects) { + GLint cx, cy, cw, ch; + GLuint buf; + + intel->vtbl.install_meta_state(intel); + + /* Get clear bounds after locking */ + cx = ctx->DrawBuffer->_Xmin; + cy = ctx->DrawBuffer->_Ymin; + ch = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; + cw = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; + + /* note: regardless of 'all', cx, cy, cw, ch are now correct */ + clear.x1 = cx; + clear.y1 = cy; + clear.x2 = cx + cw; + clear.y2 = cy + ch; + + /* Back and stencil cliprects are the same. Try and do both + * buffers at once: + */ + if (mask & + (BUFFER_BIT_BACK_LEFT | BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH)) { + struct intel_region *backRegion = + intel_get_rb_region(ctx->DrawBuffer, BUFFER_BACK_LEFT); + struct intel_region *depthRegion = + intel_get_rb_region(ctx->DrawBuffer, BUFFER_DEPTH); + const GLuint clearColor = (backRegion && backRegion->cpp == 4) + ? intel->ClearColor8888 : intel->ClearColor565; + + intel->vtbl.meta_draw_region(intel, backRegion, depthRegion); + + if (mask & BUFFER_BIT_BACK_LEFT) + intel->vtbl.meta_color_mask(intel, GL_TRUE); + else + intel->vtbl.meta_color_mask(intel, GL_FALSE); + + if (mask & BUFFER_BIT_STENCIL) + intel->vtbl.meta_stencil_replace(intel, + intel->ctx.Stencil.WriteMask[0], + intel->ctx.Stencil.Clear); + else + intel->vtbl.meta_no_stencil_write(intel); + + if (mask & BUFFER_BIT_DEPTH) + intel->vtbl.meta_depth_replace(intel); + else + intel->vtbl.meta_no_depth_write(intel); + + /* XXX: Using INTEL_BATCH_NO_CLIPRECTS here is dangerous as the + * drawing origin may not be correctly emitted. + */ + intel_meta_draw_quad(intel, clear.x1, clear.x2, clear.y1, clear.y2, intel->ctx.Depth.Clear, clearColor, 0, 0, 0, 0); /* texcoords */ + + mask &= + ~(BUFFER_BIT_BACK_LEFT | BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH); + } + + /* clear the remaining (color) renderbuffers */ + for (buf = 0; buf < BUFFER_COUNT && mask; buf++) { + const GLuint bufBit = 1 << buf; + if (mask & bufBit) { + struct intel_renderbuffer *irbColor = + intel_renderbuffer(ctx->DrawBuffer-> + Attachment[buf].Renderbuffer); + GLuint color = (irbColor->region->cpp == 4) + ? intel->ClearColor8888 : intel->ClearColor565; + + ASSERT(irbColor); + + intel->vtbl.meta_no_depth_write(intel); + intel->vtbl.meta_no_stencil_write(intel); + intel->vtbl.meta_color_mask(intel, GL_TRUE); + intel->vtbl.meta_draw_region(intel, irbColor->region, NULL); + + /* XXX: Using INTEL_BATCH_NO_CLIPRECTS here is dangerous as the + * drawing origin may not be correctly emitted. + */ + intel_meta_draw_quad(intel, clear.x1, clear.x2, clear.y1, clear.y2, 0, /* depth clear val */ + color, 0, 0, 0, 0); /* texcoords */ + + mask &= ~bufBit; + } + } + + intel->vtbl.leave_meta_state(intel); + intel_batchbuffer_flush(intel->batch); + } + UNLOCK_HARDWARE(intel); +} + + + + +/** + * Copy the window contents named by dPriv to the rotated (or reflected) + * color buffer. + * srcBuf is BUFFER_BIT_FRONT_LEFT or BUFFER_BIT_BACK_LEFT to indicate the source. + */ +void +intelRotateWindow(struct intel_context *intel, + __DRIdrawablePrivate * dPriv, GLuint srcBuf) +{ + intelScreenPrivate *screen = intel->intelScreen; + drm_clip_rect_t fullRect; + struct intel_region *src; + const drm_clip_rect_t *clipRects; + int numClipRects; + int i; + GLenum format, type; + + int xOrig, yOrig; + int origNumClipRects; + drm_clip_rect_t *origRects; + + /* + * set up hardware state + */ + intelFlush(&intel->ctx); + + LOCK_HARDWARE(intel); + + if (!intel->numClipRects) { + UNLOCK_HARDWARE(intel); + return; + } + + intel->vtbl.install_meta_state(intel); + + intel->vtbl.meta_no_depth_write(intel); + intel->vtbl.meta_no_stencil_write(intel); + intel->vtbl.meta_color_mask(intel, GL_FALSE); + + + /* save current drawing origin and cliprects (restored at end) */ + xOrig = intel->drawX; + yOrig = intel->drawY; + origNumClipRects = intel->numClipRects; + origRects = intel->pClipRects; + + /* + * set drawing origin, cliprects for full-screen access to rotated screen + */ + fullRect.x1 = 0; + fullRect.y1 = 0; + fullRect.x2 = screen->rotatedWidth; + fullRect.y2 = screen->rotatedHeight; + intel->drawX = 0; + intel->drawY = 0; + intel->numClipRects = 1; + intel->pClipRects = &fullRect; + + intel->vtbl.meta_draw_region(intel, screen->rotated_region, NULL); /* ? */ + + if (srcBuf == BUFFER_BIT_FRONT_LEFT) { + src = intel->intelScreen->front_region; + clipRects = dPriv->pClipRects; + numClipRects = dPriv->numClipRects; + } + else { + src = intel->intelScreen->back_region; + clipRects = dPriv->pBackClipRects; + numClipRects = dPriv->numBackClipRects; + } + + if (src->cpp == 4) { + format = GL_BGRA; + type = GL_UNSIGNED_BYTE; + } + else { + format = GL_BGR; + type = GL_UNSIGNED_SHORT_5_6_5_REV; + } + + /* set the whole screen up as a texture to avoid alignment issues */ + intel->vtbl.meta_tex_rect_source(intel, + src->buffer, + screen->width, + screen->height, src->pitch, format, type); + + intel->vtbl.meta_texture_blend_replace(intel); + + /* + * loop over the source window's cliprects + */ + for (i = 0; i < numClipRects; i++) { + int srcX0 = clipRects[i].x1; + int srcY0 = clipRects[i].y1; + int srcX1 = clipRects[i].x2; + int srcY1 = clipRects[i].y2; + GLfloat verts[4][2], tex[4][2]; + int j; + + /* build vertices for four corners of clip rect */ + verts[0][0] = srcX0; + verts[0][1] = srcY0; + verts[1][0] = srcX1; + verts[1][1] = srcY0; + verts[2][0] = srcX1; + verts[2][1] = srcY1; + verts[3][0] = srcX0; + verts[3][1] = srcY1; + + /* .. and texcoords */ + tex[0][0] = srcX0; + tex[0][1] = srcY0; + tex[1][0] = srcX1; + tex[1][1] = srcY0; + tex[2][0] = srcX1; + tex[2][1] = srcY1; + tex[3][0] = srcX0; + tex[3][1] = srcY1; + + /* transform coords to rotated screen coords */ + + for (j = 0; j < 4; j++) { + matrix23TransformCoordf(&screen->rotMatrix, + &verts[j][0], &verts[j][1]); + } + + /* draw polygon to map source image to dest region */ + intel_meta_draw_poly(intel, 4, verts, 0, 0, tex); + + } /* cliprect loop */ + + intel->vtbl.leave_meta_state(intel); + intel_batchbuffer_flush(intel->batch); + + /* restore original drawing origin and cliprects */ + intel->drawX = xOrig; + intel->drawY = yOrig; + intel->numClipRects = origNumClipRects; + intel->pClipRects = origRects; + + UNLOCK_HARDWARE(intel); +} + + +/** + * Called by ctx->Driver.Clear. + */ +static void +intelClear(GLcontext *ctx, GLbitfield mask) +{ + struct intel_context *intel = intel_context(ctx); + const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask); + GLbitfield tri_mask = 0; + GLbitfield blit_mask = 0; + GLbitfield swrast_mask = 0; + GLuint i; + + if (0) + fprintf(stderr, "%s\n", __FUNCTION__); + + /* HW color buffers (front, back, aux, generic FBO, etc) */ + if (colorMask == ~0) { + /* clear all R,G,B,A */ + /* XXX FBO: need to check if colorbuffers are software RBOs! */ + blit_mask |= (mask & BUFFER_BITS_COLOR); + } + else { + /* glColorMask in effect */ + tri_mask |= (mask & BUFFER_BITS_COLOR); + } + + /* HW stencil */ + if (mask & BUFFER_BIT_STENCIL) { + const struct intel_region *stencilRegion + = intel_get_rb_region(ctx->DrawBuffer, BUFFER_STENCIL); + if (stencilRegion) { + /* have hw stencil */ + if ((ctx->Stencil.WriteMask[0] & 0xff) != 0xff) { + /* not clearing all stencil bits, so use triangle clearing */ + tri_mask |= BUFFER_BIT_STENCIL; + } + else { + /* clearing all stencil bits, use blitting */ + blit_mask |= BUFFER_BIT_STENCIL; + } + } + } + + /* HW depth */ + if (mask & BUFFER_BIT_DEPTH) { + /* clear depth with whatever method is used for stencil (see above) */ + if (tri_mask & BUFFER_BIT_STENCIL) + tri_mask |= BUFFER_BIT_DEPTH; + else + blit_mask |= BUFFER_BIT_DEPTH; + } + + /* SW fallback clearing */ + swrast_mask = mask & ~tri_mask & ~blit_mask; + + for (i = 0; i < BUFFER_COUNT; i++) { + GLuint bufBit = 1 << i; + if ((blit_mask | tri_mask) & bufBit) { + if (!ctx->DrawBuffer->Attachment[i].Renderbuffer->ClassID) { + blit_mask &= ~bufBit; + tri_mask &= ~bufBit; + swrast_mask |= bufBit; + } + } + } + + + intelFlush(ctx); /* XXX intelClearWithBlit also does this */ + + if (blit_mask) + intelClearWithBlit(ctx, blit_mask); + + if (tri_mask) + intelClearWithTris(intel, tri_mask); + + if (swrast_mask) + _swrast_Clear(ctx, swrast_mask); +} + + + +/* Flip the front & back buffers + */ +static void +intelPageFlip(const __DRIdrawablePrivate * dPriv) +{ +#if 0 + struct intel_context *intel; + int tmp, ret; + + if (INTEL_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s\n", __FUNCTION__); + + assert(dPriv); + assert(dPriv->driContextPriv); + assert(dPriv->driContextPriv->driverPrivate); + + intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate; + + intelFlush(&intel->ctx); + LOCK_HARDWARE(intel); + + if (dPriv->pClipRects) { + *(drm_clip_rect_t *) intel->sarea->boxes = dPriv->pClipRects[0]; + intel->sarea->nbox = 1; + } + + ret = drmCommandNone(intel->driFd, DRM_I830_FLIP); + if (ret) { + fprintf(stderr, "%s: %d\n", __FUNCTION__, ret); + UNLOCK_HARDWARE(intel); + exit(1); + } + + tmp = intel->sarea->last_enqueue; + intelRefillBatchLocked(intel); + UNLOCK_HARDWARE(intel); + + + intelSetDrawBuffer(&intel->ctx, intel->ctx.Color.DriverDrawBuffer); +#endif +} + +#if 0 +void +intelSwapBuffers(__DRIdrawablePrivate * dPriv) +{ + if (dPriv->driverPrivate) { + const struct gl_framebuffer *fb + = (struct gl_framebuffer *) dPriv->driverPrivate; + if (fb->Visual.doubleBufferMode) { + GET_CURRENT_CONTEXT(ctx); + if (ctx && ctx->DrawBuffer == fb) { + _mesa_notifySwapBuffers(ctx); /* flush pending rendering */ + } + if (0 /*intel->doPageFlip */ ) { /* doPageFlip is never set !!! */ + intelPageFlip(dPriv); + } + else { + intelCopyBuffer(dPriv); + } + } + } + else { + _mesa_problem(NULL, + "dPriv has no gl_framebuffer pointer in intelSwapBuffers"); + } +} +#else +/* Trunk version: + */ +void +intelSwapBuffers(__DRIdrawablePrivate * dPriv) +{ + if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { + GET_CURRENT_CONTEXT(ctx); + struct intel_context *intel; + + if (ctx == NULL) + return; + + intel = intel_context(ctx); + + if (ctx->Visual.doubleBufferMode) { + intelScreenPrivate *screen = intel->intelScreen; + _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */ + if (0 /*intel->doPageFlip */ ) { /* doPageFlip is never set !!! */ + intelPageFlip(dPriv); + } + else { + intelCopyBuffer(dPriv, NULL); + } + if (screen->current_rotation != 0) { + intelRotateWindow(intel, dPriv, BUFFER_BIT_FRONT_LEFT); + } + } + } + else { + /* XXX this shouldn't be an error but we can't handle it for now */ + fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__); + } +} +#endif + +void +intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) +{ + if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { + struct intel_context *intel = + (struct intel_context *) dPriv->driContextPriv->driverPrivate; + GLcontext *ctx = &intel->ctx; + + if (ctx->Visual.doubleBufferMode) { + drm_clip_rect_t rect; + rect.x1 = x + dPriv->x; + rect.y1 = (dPriv->h - y - h) + dPriv->y; + rect.x2 = rect.x1 + w; + rect.y2 = rect.y1 + h; + _mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */ + intelCopyBuffer(dPriv, &rect); + } + } + else { + /* XXX this shouldn't be an error but we can't handle it for now */ + fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__); + } +} + + +/** + * Update the hardware state for drawing into a window or framebuffer object. + * + * Called by glDrawBuffer, glBindFramebufferEXT, MakeCurrent, and other + * places within the driver. + * + * Basically, this needs to be called any time the current framebuffer + * changes, the renderbuffers change, or we need to draw into different + * color buffers. + */ +void +intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_region *colorRegion, *depthRegion = NULL; + struct intel_renderbuffer *irbDepth = NULL, *irbStencil = NULL; + int front = 0; /* drawing to front color buffer? */ + + if (!fb) { + /* this can happen during the initial context initialization */ + return; + } + + /* Do this here, note core Mesa, since this function is called from + * many places within the driver. + */ + if (ctx->NewState & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { + /* this updates the DrawBuffer->_NumColorDrawBuffers fields, etc */ + _mesa_update_framebuffer(ctx); + /* this updates the DrawBuffer's Width/Height if it's a FBO */ + _mesa_update_draw_buffer_bounds(ctx); + } + + if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { + /* this may occur when we're called by glBindFrameBuffer() during + * the process of someone setting up renderbuffers, etc. + */ + /*_mesa_debug(ctx, "DrawBuffer: incomplete user FBO\n");*/ + return; + } + + if (fb->Name) + intel_validate_paired_depth_stencil(ctx, fb); + + /* + * How many color buffers are we drawing into? + */ + if (fb->_NumColorDrawBuffers[0] != 1 +#if 0 + /* XXX FBO temporary - always use software rendering */ + || 1 +#endif + ) { + /* writing to 0 or 2 or 4 color buffers */ + /*_mesa_debug(ctx, "Software rendering\n");*/ + FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE); + front = 1; /* might not have back color buffer */ + } + else { + /* draw to exactly one color buffer */ + /*_mesa_debug(ctx, "Hardware rendering\n");*/ + FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE); + if (fb->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT) { + front = 1; + } + } + + /* + * Get the intel_renderbuffer for the colorbuffer we're drawing into. + * And set up cliprects. + */ + if (fb->Name == 0) { + /* drawing to window system buffer */ + if (intel->sarea->pf_current_page == 1) { + /* page flipped back/front */ + front ^= 1; + } + if (front) { + intelSetFrontClipRects(intel); + colorRegion = intel_get_rb_region(fb, BUFFER_FRONT_LEFT); + } + else { + intelSetBackClipRects(intel); + colorRegion = intel_get_rb_region(fb, BUFFER_BACK_LEFT); + } + } + else { + /* drawing to user-created FBO */ + struct intel_renderbuffer *irb; + intelSetRenderbufferClipRects(intel); + irb = intel_renderbuffer(fb->_ColorDrawBuffers[0][0]); + colorRegion = (irb && irb->region) ? irb->region : NULL; + } + + /* Update culling direction which changes depending on the + * orientation of the buffer: + */ + if (ctx->Driver.FrontFace) + ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace); + else + ctx->NewState |= _NEW_POLYGON; + + if (!colorRegion) { + FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE); + } + else { + FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE); + } + + /*** + *** Get depth buffer region and check if we need a software fallback. + *** Note that the depth buffer is usually a DEPTH_STENCIL buffer. + ***/ + if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) { + irbDepth = intel_renderbuffer(fb->_DepthBuffer->Wrapped); + if (irbDepth->region) { + FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE); + depthRegion = irbDepth->region; + } + else { + FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_TRUE); + depthRegion = NULL; + } + } + else { + /* not using depth buffer */ + FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE); + depthRegion = NULL; + } + + /*** + *** Stencil buffer + *** This can only be hardware accelerated if we're using a + *** combined DEPTH_STENCIL buffer (for now anyway). + ***/ + if (fb->_StencilBuffer && fb->_StencilBuffer->Wrapped) { + irbStencil = intel_renderbuffer(fb->_StencilBuffer->Wrapped); + if (irbStencil && irbStencil->region) { + ASSERT(irbStencil->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); + FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE); + /* need to re-compute stencil hw state */ + ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); + if (!depthRegion) + depthRegion = irbStencil->region; + } + else { + FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_TRUE); + } + } + else { + /* XXX FBO: instead of FALSE, pass ctx->Stencil.Enabled ??? */ + FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE); + /* need to re-compute stencil hw state */ + ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); + } + + + /** + ** Release old regions, reference new regions + **/ +#if 0 /* XXX FBO: this seems to be redundant with i915_state_draw_region() */ + if (intel->draw_region != colorRegion) { + intel_region_release(&intel->draw_region); + intel_region_reference(&intel->draw_region, colorRegion); + } + if (intel->intelScreen->depth_region != depthRegion) { + intel_region_release(&intel->intelScreen->depth_region); + intel_region_reference(&intel->intelScreen->depth_region, depthRegion); + } +#endif + + intel->vtbl.set_draw_region(intel, colorRegion, depthRegion); + + /* update viewport since it depends on window size */ + ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y, + ctx->Viewport.Width, ctx->Viewport.Height); + + /* Update hardware scissor */ + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); +} + + +static void +intelDrawBuffer(GLcontext * ctx, GLenum mode) +{ + intel_draw_buffer(ctx, ctx->DrawBuffer); +} + + +static void +intelReadBuffer(GLcontext * ctx, GLenum mode) +{ + if (ctx->ReadBuffer == ctx->DrawBuffer) { + /* This will update FBO completeness status. + * A framebuffer will be incomplete if the GL_READ_BUFFER setting + * refers to a missing renderbuffer. Calling glReadBuffer can set + * that straight and can make the drawing buffer complete. + */ + intel_draw_buffer(ctx, ctx->DrawBuffer); + } + /* Generally, functions which read pixels (glReadPixels, glCopyPixels, etc) + * reference ctx->ReadBuffer and do appropriate state checks. + */ +} + + +void +intelInitBufferFuncs(struct dd_function_table *functions) +{ + functions->Clear = intelClear; + functions->GetBufferSize = intelBufferSize; + functions->ResizeBuffers = _mesa_resize_framebuffer; + functions->DrawBuffer = intelDrawBuffer; + functions->ReadBuffer = intelReadBuffer; +} diff --git a/src/mesa/drivers/dri/i915tex/intel_buffers.h b/src/mesa/drivers/dri/i915tex/intel_buffers.h new file mode 100644 index 0000000000..0faf055347 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_buffers.h @@ -0,0 +1,56 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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. + * + **************************************************************************/ + +#ifndef INTEL_BUFFERS_H +#define INTEL_BUFFERS_H + + +struct intel_context; + + +extern GLboolean +intel_intersect_cliprects(drm_clip_rect_t * dest, + const drm_clip_rect_t * a, + const drm_clip_rect_t * b); + +extern struct intel_region *intel_readbuf_region(struct intel_context *intel); + +extern struct intel_region *intel_drawbuf_region(struct intel_context *intel); + +extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); + +extern void intelWindowMoved(struct intel_context *intel); + +extern void intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb); + +extern void intelInitBufferFuncs(struct dd_function_table *functions); + +extern void +intelRotateWindow(struct intel_context *intel, + __DRIdrawablePrivate * dPriv, GLuint srcBuf); + +#endif /* INTEL_BUFFERS_H */ diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c new file mode 100644 index 0000000000..3d51a6341c --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_context.c @@ -0,0 +1,707 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "glheader.h" +#include "context.h" +#include "matrix.h" +#include "simple_list.h" +#include "extensions.h" +#include "framebuffer.h" +#include "imports.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/tnl.h" +#include "array_cache/acache.h" + +#include "tnl/t_pipeline.h" +#include "tnl/t_vertex.h" + +#include "drivers/common/driverfuncs.h" + +#include "intel_screen.h" + +#include "i830_dri.h" + +#include "intel_buffers.h" +#include "intel_tex.h" +#include "intel_span.h" +#include "intel_tris.h" +#include "intel_ioctl.h" +#include "intel_batchbuffer.h" +#include "intel_blit.h" +#include "intel_pixel.h" +#include "intel_regions.h" +#include "intel_buffer_objects.h" +#include "intel_fbo.h" + +#include "vblank.h" +#include "utils.h" +#include "xmlpool.h" /* for symbolic values of enum-type options */ +#ifndef INTEL_DEBUG +int INTEL_DEBUG = (0); +#endif + +#define need_GL_ARB_multisample +#define need_GL_ARB_point_parameters +#define need_GL_ARB_texture_compression +#define need_GL_ARB_vertex_buffer_object +#define need_GL_ARB_vertex_program +#define need_GL_ARB_window_pos +#define need_GL_EXT_blend_color +#define need_GL_EXT_blend_equation_separate +#define need_GL_EXT_blend_func_separate +#define need_GL_EXT_blend_minmax +#define need_GL_EXT_cull_vertex +#define need_GL_EXT_fog_coord +#define need_GL_EXT_framebuffer_object +#define need_GL_EXT_multi_draw_arrays +#define need_GL_EXT_secondary_color +#define need_GL_NV_vertex_program +#include "extension_helper.h" + + +#define DRIVER_DATE "20060929" + +_glthread_Mutex lockMutex; +static GLboolean lockMutexInit = GL_FALSE; + + +static const GLubyte * +intelGetString(GLcontext * ctx, GLenum name) +{ + const char *chipset; + static char buffer[128]; + + switch (name) { + case GL_VENDOR: + return (GLubyte *) "Tungsten Graphics, Inc"; + break; + + case GL_RENDERER: + switch (intel_context(ctx)->intelScreen->deviceID) { + case PCI_CHIP_845_G: + chipset = "Intel(R) 845G"; + break; + case PCI_CHIP_I830_M: + chipset = "Intel(R) 830M"; + break; + case PCI_CHIP_I855_GM: + chipset = "Intel(R) 852GM/855GM"; + break; + case PCI_CHIP_I865_G: + chipset = "Intel(R) 865G"; + break; + case PCI_CHIP_I915_G: + chipset = "Intel(R) 915G"; + break; + case PCI_CHIP_I915_GM: + chipset = "Intel(R) 915GM"; + break; + case PCI_CHIP_I945_G: + chipset = "Intel(R) 945G"; + break; + case PCI_CHIP_I945_GM: + chipset = "Intel(R) 945GM"; + break; + default: + chipset = "Unknown Intel Chipset"; + break; + } + + (void) driGetRendererString(buffer, chipset, DRIVER_DATE, 0); + return (GLubyte *) buffer; + + default: + return NULL; + } +} + + +/** + * Extension strings exported by the intel driver. + * + * \note + * It appears that ARB_texture_env_crossbar has "disappeared" compared to the + * old i830-specific driver. + */ +const struct dri_extension card_extensions[] = { + {"GL_ARB_multisample", GL_ARB_multisample_functions}, + {"GL_ARB_multitexture", NULL}, + {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, + {"GL_ARB_texture_border_clamp", NULL}, + {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions}, + {"GL_ARB_texture_cube_map", NULL}, + {"GL_ARB_texture_env_add", NULL}, + {"GL_ARB_texture_env_combine", NULL}, + {"GL_ARB_texture_env_dot3", NULL}, + {"GL_ARB_texture_mirrored_repeat", NULL}, + {"GL_ARB_texture_rectangle", NULL}, + {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, + {"GL_ARB_pixel_buffer_object", NULL}, + {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, + {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, + {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, + {"GL_EXT_blend_equation_separate", + GL_EXT_blend_equation_separate_functions}, + {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, + {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, + {"GL_EXT_blend_subtract", NULL}, + {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, + {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, + {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, + {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, +#if 1 /* XXX FBO temporary? */ + {"GL_EXT_packed_depth_stencil", NULL}, +#endif + {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, + {"GL_EXT_stencil_wrap", NULL}, + {"GL_EXT_texture_edge_clamp", NULL}, + {"GL_EXT_texture_env_combine", NULL}, + {"GL_EXT_texture_env_dot3", NULL}, + {"GL_EXT_texture_filter_anisotropic", NULL}, + {"GL_EXT_texture_lod_bias", NULL}, + {"GL_3DFX_texture_compression_FXT1", NULL}, + {"GL_APPLE_client_storage", NULL}, + {"GL_MESA_pack_invert", NULL}, + {"GL_MESA_ycbcr_texture", NULL}, + {"GL_NV_blend_square", NULL}, + {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, + {"GL_NV_vertex_program1_1", NULL}, +/* { "GL_SGIS_generate_mipmap", NULL }, */ + {NULL, NULL} +}; + +extern const struct tnl_pipeline_stage _intel_render_stage; + +static const struct tnl_pipeline_stage *intel_pipeline[] = { + &_tnl_vertex_transform_stage, + &_tnl_vertex_cull_stage, + &_tnl_normal_transform_stage, + &_tnl_lighting_stage, + &_tnl_fog_coordinate_stage, + &_tnl_texgen_stage, + &_tnl_texture_transform_stage, + &_tnl_point_attenuation_stage, + &_tnl_arb_vertex_program_stage, + &_tnl_vertex_program_stage, +#if 1 + &_intel_render_stage, /* ADD: unclipped rastersetup-to-dma */ +#endif + &_tnl_render_stage, + 0, +}; + + +static const struct dri_debug_control debug_control[] = { + {"tex", DEBUG_TEXTURE}, + {"state", DEBUG_STATE}, + {"ioctl", DEBUG_IOCTL}, + {"blit", DEBUG_BLIT}, + {"mip", DEBUG_MIPTREE}, + {"fall", DEBUG_FALLBACKS}, + {"verb", DEBUG_VERBOSE}, + {"bat", DEBUG_BATCH}, + {"pix", DEBUG_PIXEL}, + {"buf", DEBUG_BUFMGR}, + {"reg", DEBUG_REGION}, + {"fbo", DEBUG_FBO}, + {"lock", DEBUG_LOCK}, + {NULL, 0} +}; + + +static void +intelInvalidateState(GLcontext * ctx, GLuint new_state) +{ + _swrast_InvalidateState(ctx, new_state); + _swsetup_InvalidateState(ctx, new_state); + _ac_InvalidateState(ctx, new_state); + _tnl_InvalidateState(ctx, new_state); + _tnl_invalidate_vertex_state(ctx, new_state); + intel_context(ctx)->NewGLState |= new_state; +} + + +void +intelFlush(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + + if (intel->Fallback) + _swrast_flush(ctx); + + INTEL_FIREVERTICES(intel); + + if (intel->batch->map != intel->batch->ptr) + intel_batchbuffer_flush(intel->batch); + + /* XXX: Need to do an MI_FLUSH here. + */ +} + + +/** + * Check if we need to rotate/warp the front color buffer to the + * rotated screen. We generally need to do this when we get a glFlush + * or glFinish after drawing to the front color buffer. + */ +static void +intelCheckFrontRotate(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + if (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0] == + BUFFER_BIT_FRONT_LEFT) { + intelScreenPrivate *screen = intel->intelScreen; + if (screen->current_rotation != 0) { + __DRIdrawablePrivate *dPriv = intel->driDrawable; + intelRotateWindow(intel, dPriv, BUFFER_BIT_FRONT_LEFT); + } + } +} + + +/** + * Called via glFlush. + */ +static void +intelglFlush(GLcontext * ctx) +{ + intelFlush(ctx); + intelCheckFrontRotate(ctx); +} + +void +intelFinish(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + intelFlush(ctx); + if (intel->batch->last_fence) { + driFenceFinish(intel->batch->last_fence, + 0, GL_FALSE); + driFenceUnReference(intel->batch->last_fence); + intel->batch->last_fence = NULL; + } + intelCheckFrontRotate(ctx); +} + + +void +intelInitDriverFunctions(struct dd_function_table *functions) +{ + _mesa_init_driver_functions(functions); + + functions->Flush = intelglFlush; + functions->Finish = intelFinish; + functions->GetString = intelGetString; + functions->UpdateState = intelInvalidateState; + functions->CopyColorTable = _swrast_CopyColorTable; + functions->CopyColorSubTable = _swrast_CopyColorSubTable; + functions->CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; + functions->CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; + + intelInitTextureFuncs(functions); + intelInitPixelFuncs(functions); + intelInitStateFuncs(functions); + intelInitBufferFuncs(functions); +} + + +GLboolean +intelInitContext(struct intel_context *intel, + const __GLcontextModes * mesaVis, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate, + struct dd_function_table *functions) +{ + GLcontext *ctx = &intel->ctx; + GLcontext *shareCtx = (GLcontext *) sharedContextPrivate; + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; + drmI830Sarea *saPriv = (drmI830Sarea *) + (((GLubyte *) sPriv->pSAREA) + intelScreen->sarea_priv_offset); + int fthrottle_mode; + + if (!_mesa_initialize_context(&intel->ctx, + mesaVis, shareCtx, + functions, (void *) intel)) + return GL_FALSE; + + driContextPriv->driverPrivate = intel; + intel->intelScreen = intelScreen; + intel->driScreen = sPriv; + intel->sarea = saPriv; + + if (!lockMutexInit) { + lockMutexInit = GL_TRUE; + _glthread_INIT_MUTEX(lockMutex); + } + + driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache, + intel->driScreen->myNum, "i915"); + + ctx->Const.MaxTextureMaxAnisotropy = 2.0; + + /* This doesn't yet catch all non-conformant rendering, but it's a + * start. + */ + if (getenv("INTEL_STRICT_CONFORMANCE")) { + intel->strict_conformance = 1; + } + + ctx->Const.MinLineWidth = 1.0; + ctx->Const.MinLineWidthAA = 1.0; + ctx->Const.MaxLineWidth = 3.0; + ctx->Const.MaxLineWidthAA = 3.0; + ctx->Const.LineWidthGranularity = 1.0; + + ctx->Const.MinPointSize = 1.0; + ctx->Const.MinPointSizeAA = 1.0; + ctx->Const.MaxPointSize = 255.0; + ctx->Const.MaxPointSizeAA = 3.0; + ctx->Const.PointSizeGranularity = 1.0; + + ctx->Const.MaxColorAttachments = 4; /* XXX FBO: review this */ + + /* Initialize the software rasterizer and helper modules. */ + _swrast_CreateContext(ctx); + _ac_CreateContext(ctx); + _tnl_CreateContext(ctx); + _swsetup_CreateContext(ctx); + + /* Install the customized pipeline: */ + _tnl_destroy_pipeline(ctx); + _tnl_install_pipeline(ctx, intel_pipeline); + + /* Configure swrast to match hardware characteristics: */ + _swrast_allow_pixel_fog(ctx, GL_FALSE); + _swrast_allow_vertex_fog(ctx, GL_TRUE); + + /* Dri stuff */ + intel->hHWContext = driContextPriv->hHWContext; + intel->driFd = sPriv->fd; + intel->driHwLock = (drmLock *) & sPriv->pSAREA->lock; + + intel->hw_stipple = 1; + + /* XXX FBO: this doesn't seem to be used anywhere */ + switch (mesaVis->depthBits) { + case 0: /* what to do in this case? */ + case 16: + intel->polygon_offset_scale = 1.0 / 0xffff; + break; + case 24: + intel->polygon_offset_scale = 2.0 / 0xffffff; /* req'd to pass glean */ + break; + default: + assert(0); + break; + } + + /* Initialize swrast, tnl driver tables: */ + intelInitSpanFuncs(ctx); + intelInitTriFuncs(ctx); + + + intel->RenderIndex = ~0; + + fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode"); + intel->iw.irq_seq = -1; + intel->irqsEmitted = 0; + + intel->do_irqs = (intel->intelScreen->irq_active && + fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS); + + intel->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS); + + intel->vblank_flags = (intel->intelScreen->irq_active != 0) + ? driGetDefaultVBlankFlags(&intel->optionCache) : VBLANK_FLAG_NO_IRQ; + + (*dri_interface->getUST) (&intel->swap_ust); + _math_matrix_ctr(&intel->ViewportMatrix); + + /* Disable imaging extension until convolution is working in + * teximage paths: + */ + driInitExtensions(ctx, card_extensions, +/* GL_TRUE, */ + GL_FALSE); + + + intel->batch = intel_batchbuffer_alloc(intel); + intel->last_swap_fence = NULL; + intel->first_swap_fence = NULL; + + intel_bufferobj_init(intel); + intel_fbo_init(intel); + + if (intel->ctx.Mesa_DXTn) { + _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc"); + _mesa_enable_extension(ctx, "GL_S3_s3tc"); + } + else if (driQueryOptionb(&intel->optionCache, "force_s3tc_enable")) { + _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc"); + } + + intel->prim.primitive = ~0; + + +#if DO_DEBUG + INTEL_DEBUG = driParseDebugString(getenv("INTEL_DEBUG"), debug_control); +#endif + + if (getenv("INTEL_NO_RAST")) { + fprintf(stderr, "disabling 3D rasterization\n"); + FALLBACK(intel, INTEL_FALLBACK_USER, 1); + } + + return GL_TRUE; +} + +void +intelDestroyContext(__DRIcontextPrivate * driContextPriv) +{ + struct intel_context *intel = + (struct intel_context *) driContextPriv->driverPrivate; + + assert(intel); /* should never be null */ + if (intel) { + GLboolean release_texture_heaps; + + INTEL_FIREVERTICES(intel); + + intel->vtbl.destroy(intel); + + release_texture_heaps = (intel->ctx.Shared->RefCount == 1); + _swsetup_DestroyContext(&intel->ctx); + _tnl_DestroyContext(&intel->ctx); + _ac_DestroyContext(&intel->ctx); + + _swrast_DestroyContext(&intel->ctx); + intel->Fallback = 0; /* don't call _swrast_Flush later */ + + intel_batchbuffer_free(intel->batch); + + if (intel->last_swap_fence) { + driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); + driFenceUnReference(intel->last_swap_fence); + intel->last_swap_fence = NULL; + } + if (intel->first_swap_fence) { + driFenceFinish(intel->first_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE); + driFenceUnReference(intel->first_swap_fence); + intel->first_swap_fence = NULL; + } + + + if (release_texture_heaps) { + /* This share group is about to go away, free our private + * texture object data. + */ + if (INTEL_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, "do something to free texture heaps\n"); + } + + /* free the Mesa context */ + _mesa_free_context_data(&intel->ctx); + } +} + +GLboolean +intelUnbindContext(__DRIcontextPrivate * driContextPriv) +{ + return GL_TRUE; +} + +GLboolean +intelMakeCurrent(__DRIcontextPrivate * driContextPriv, + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv) +{ + + if (driContextPriv) { + struct intel_context *intel = + (struct intel_context *) driContextPriv->driverPrivate; + GLframebuffer *drawFb = (GLframebuffer *) driDrawPriv->driverPrivate; + GLframebuffer *readFb = (GLframebuffer *) driReadPriv->driverPrivate; + + + /* XXX FBO temporary fix-ups! */ + /* if the renderbuffers don't have regions, init them from the context */ + { + struct intel_renderbuffer *irbFront + = intel_get_renderbuffer(drawFb, BUFFER_FRONT_LEFT); + struct intel_renderbuffer *irbBack + = intel_get_renderbuffer(drawFb, BUFFER_BACK_LEFT); + struct intel_renderbuffer *irbDepth + = intel_get_renderbuffer(drawFb, BUFFER_DEPTH); + struct intel_renderbuffer *irbStencil + = intel_get_renderbuffer(drawFb, BUFFER_STENCIL); + + if (irbFront && !irbFront->region) { + intel_region_reference(&irbFront->region, intel->intelScreen->front_region); + } + if (irbBack && !irbBack->region) { + intel_region_reference(&irbBack->region, intel->intelScreen->back_region); + } + if (irbDepth && !irbDepth->region) { + intel_region_reference(&irbDepth->region, intel->intelScreen->depth_region); + } + if (irbStencil && !irbStencil->region) { + intel_region_reference(&irbStencil->region, intel->intelScreen->depth_region); + } + } + + _mesa_make_current(&intel->ctx, drawFb, readFb); + + /* The drawbuffer won't always be updated by _mesa_make_current: + */ + if (intel->ctx.DrawBuffer == drawFb) { + + if (intel->driDrawable != driDrawPriv) { + driDrawableInitVBlank(driDrawPriv, intel->vblank_flags, &intel->vbl_seq); + intel->driDrawable = driDrawPriv; + intelWindowMoved(intel); + } + + intel_draw_buffer(&intel->ctx, drawFb); + } + } + else { + _mesa_make_current(NULL, NULL, NULL); + } + + return GL_TRUE; +} + +static void +intelContendedLock(struct intel_context *intel, GLuint flags) +{ + __DRIdrawablePrivate *dPriv = intel->driDrawable; + __DRIscreenPrivate *sPriv = intel->driScreen; + intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; + drmI830Sarea *sarea = intel->sarea; + + drmGetLock(intel->driFd, intel->hHWContext, flags); + + if (INTEL_DEBUG & DEBUG_LOCK) + _mesa_printf("%s - got contended lock\n", __progname); + + /* If the window moved, may need to set a new cliprect now. + * + * NOTE: This releases and regains the hw lock, so all state + * checking must be done *after* this call: + */ + if (dPriv) + DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); + + if (sarea->width != intelScreen->width || + sarea->height != intelScreen->height || + sarea->rotation != intelScreen->current_rotation) { + + intelUpdateScreenRotation(sPriv, sarea); + + /* + * This will drop the outstanding batchbuffer on the floor + * FIXME: This should be done for all contexts? + */ + + intel_batchbuffer_reset(intel->batch); + + /* lose all primitives */ + intel->prim.primitive = ~0; + intel->prim.start_ptr = 0; + intel->prim.flush = 0; + + /* re-emit all state */ + intel->vtbl.lost_hardware(intel); + + /* force window update */ + intel->lastStamp = 0; + } + + + /* Drawable changed? + */ + if (dPriv && intel->lastStamp != dPriv->lastStamp) { + intelWindowMoved(intel); + intel->lastStamp = dPriv->lastStamp; + } +} + + +extern _glthread_Mutex lockMutex; + + +/* Lock the hardware and validate our state. + */ +void LOCK_HARDWARE( struct intel_context *intel ) +{ + char __ret=0; + + _glthread_LOCK_MUTEX(lockMutex); + assert(!intel->locked); + + if (intel->swap_scheduled) { + drmVBlank vbl; + vbl.request.type = DRM_VBLANK_ABSOLUTE; + if ( intel->vblank_flags & VBLANK_FLAG_SECONDARY ) { + vbl.request.type |= DRM_VBLANK_SECONDARY; + } + vbl.request.sequence = intel->vbl_seq; + drmWaitVBlank(intel->driFd, &vbl); + intel->swap_scheduled = 0; + } + + DRM_CAS(intel->driHwLock, intel->hHWContext, + (DRM_LOCK_HELD|intel->hHWContext), __ret); + + if (__ret) + intelContendedLock( intel, 0 ); + + if (INTEL_DEBUG & DEBUG_LOCK) + _mesa_printf("%s - locked\n", __progname); + + intel->locked = 1; +} + + + /* Unlock the hardware using the global current context + */ +void UNLOCK_HARDWARE( struct intel_context *intel ) +{ + intel->locked = 0; + + DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext); + + _glthread_UNLOCK_MUTEX(lockMutex); + + if (INTEL_DEBUG & DEBUG_LOCK) + _mesa_printf("%s - unlocked\n", __progname); +} + diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h new file mode 100644 index 0000000000..fa3cf58571 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_context.h @@ -0,0 +1,502 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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. + * + **************************************************************************/ + +#ifndef INTELCONTEXT_INC +#define INTELCONTEXT_INC + + + +#include "mtypes.h" +#include "drm.h" +#include "mm.h" +#include "texmem.h" + +#include "intel_screen.h" +#include "i915_drm.h" +#include "i830_common.h" +#include "tnl/t_vertex.h" + +#define TAG(x) intel##x +#include "tnl_dd/t_dd_vertex.h" +#undef TAG + +#define DV_PF_555 (1<<8) +#define DV_PF_565 (2<<8) +#define DV_PF_8888 (3<<8) + +struct intel_region; +struct intel_context; +struct _DriBufferObject; + +typedef void (*intel_tri_func) (struct intel_context *, intelVertex *, + intelVertex *, intelVertex *); +typedef void (*intel_line_func) (struct intel_context *, intelVertex *, + intelVertex *); +typedef void (*intel_point_func) (struct intel_context *, intelVertex *); + +#define INTEL_FALLBACK_DRAW_BUFFER 0x1 +#define INTEL_FALLBACK_READ_BUFFER 0x2 +#define INTEL_FALLBACK_DEPTH_BUFFER 0x4 +#define INTEL_FALLBACK_STENCIL_BUFFER 0x8 +#define INTEL_FALLBACK_USER 0x10 +#define INTEL_FALLBACK_RENDERMODE 0x20 + +extern void intelFallback(struct intel_context *intel, GLuint bit, + GLboolean mode); +#define FALLBACK( intel, bit, mode ) intelFallback( intel, bit, mode ) + + +#define INTEL_WRITE_PART 0x1 +#define INTEL_WRITE_FULL 0x2 +#define INTEL_READ 0x4 + +struct intel_texture_object +{ + struct gl_texture_object base; /* The "parent" object */ + + /* The mipmap tree must include at least these levels once + * validated: + */ + GLuint firstLevel; + GLuint lastLevel; + + /* Offset for firstLevel image: + */ + GLuint textureOffset; + + /* On validation any active images held in main memory or in other + * regions will be copied to this region and the old storage freed. + */ + struct intel_mipmap_tree *mt; +}; + + + +struct intel_texture_image +{ + struct gl_texture_image base; + + /* These aren't stored in gl_texture_image + */ + GLuint level; + GLuint face; + + /* If intelImage->mt != NULL, image data is stored here. + * Else if intelImage->base.Data != NULL, image is stored there. + * Else there is no image data. + */ + struct intel_mipmap_tree *mt; +}; + + +#define INTEL_MAX_FIXUP 64 + +struct intel_context +{ + GLcontext ctx; /* the parent class */ + + struct + { + void (*destroy) (struct intel_context * intel); + void (*emit_state) (struct intel_context * intel); + void (*lost_hardware) (struct intel_context * intel); + void (*update_texture_state) (struct intel_context * intel); + + void (*render_start) (struct intel_context * intel); + void (*set_draw_region) (struct intel_context * intel, + struct intel_region * draw_region, + struct intel_region * depth_region); + + GLuint(*flush_cmd) (void); + + void (*reduced_primitive_state) (struct intel_context * intel, + GLenum rprim); + + GLboolean(*check_vertex_size) (struct intel_context * intel, + GLuint expected); + + + /* Metaops: + */ + void (*install_meta_state) (struct intel_context * intel); + void (*leave_meta_state) (struct intel_context * intel); + + void (*meta_draw_region) (struct intel_context * intel, + struct intel_region * draw_region, + struct intel_region * depth_region); + + void (*meta_color_mask) (struct intel_context * intel, GLboolean); + + void (*meta_stencil_replace) (struct intel_context * intel, + GLuint mask, GLuint clear); + + void (*meta_depth_replace) (struct intel_context * intel); + + void (*meta_texture_blend_replace) (struct intel_context * intel); + + void (*meta_no_stencil_write) (struct intel_context * intel); + void (*meta_no_depth_write) (struct intel_context * intel); + void (*meta_no_texture) (struct intel_context * intel); + + void (*meta_import_pixel_state) (struct intel_context * intel); + + GLboolean(*meta_tex_rect_source) (struct intel_context * intel, + struct _DriBufferObject * buffer, + GLuint offset, + GLuint pitch, + GLuint height, + GLenum format, GLenum type); + void (*rotate_window) (struct intel_context * intel, + __DRIdrawablePrivate * dPriv, GLuint srcBuf); + + void (*assert_not_dirty) (struct intel_context *intel); + + } vtbl; + + GLint refcount; + GLuint Fallback; + GLuint NewGLState; + + struct _DriFenceObject *last_swap_fence; + struct _DriFenceObject *first_swap_fence; + + struct intel_batchbuffer *batch; + + struct + { + GLuint id; + GLuint primitive; + GLubyte *start_ptr; + void (*flush) (struct intel_context *); + } prim; + + GLboolean locked; + char *prevLockFile; + int prevLockLine; + + GLuint ClearColor565; + GLuint ClearColor8888; + + /* Offsets of fields within the current vertex: + */ + GLuint coloroffset; + GLuint specoffset; + GLuint wpos_offset; + GLuint wpos_size; + + struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; + GLuint vertex_attr_count; + + GLfloat polygon_offset_scale; /* dependent on depth_scale, bpp */ + + GLboolean hw_stipple; + GLboolean strict_conformance; + + /* AGP memory buffer manager: + */ + struct bufmgr *bm; + + + /* State for intelvb.c and inteltris.c. + */ + GLuint RenderIndex; + GLmatrix ViewportMatrix; + GLenum render_primitive; + GLenum reduced_primitive; + GLuint vertex_size; + GLubyte *verts; /* points to tnl->clipspace.vertex_buf */ + +#if 0 + struct intel_region *front_region; /* XXX FBO: obsolete */ + struct intel_region *rotated_region; /* XXX FBO: obsolete */ + struct intel_region *back_region; /* XXX FBO: obsolete */ + struct intel_region *draw_region; /* XXX FBO: rename to color_region */ + struct intel_region *depth_region; /**< currently bound depth/Z region */ +#endif + + /* Fallback rasterization functions + */ + intel_point_func draw_point; + intel_line_func draw_line; + intel_tri_func draw_tri; + + /* These refer to the current drawing buffer: + */ + int drawX, drawY; /**< origin of drawing area within region */ + GLuint numClipRects; /**< cliprects for drawing */ + drm_clip_rect_t *pClipRects; + drm_clip_rect_t fboRect; /**< cliprect for FBO rendering */ + + int perf_boxes; + + GLuint do_usleeps; + int do_irqs; + GLuint irqsEmitted; + drm_i915_irq_wait_t iw; + + drm_context_t hHWContext; + drmLock *driHwLock; + int driFd; + + __DRIdrawablePrivate *driDrawable; + __DRIscreenPrivate *driScreen; + intelScreenPrivate *intelScreen; + drmI830Sarea *sarea; + + GLuint lastStamp; + + /** + * Configuration cache + */ + driOptionCache optionCache; + + /* VBI + */ + GLuint vbl_seq; + GLuint vblank_flags; + + int64_t swap_ust; + int64_t swap_missed_ust; + + GLuint swap_count; + GLuint swap_missed_count; + + GLuint swap_scheduled; +}; + +/* These are functions now: + */ +void LOCK_HARDWARE( struct intel_context *intel ); +void UNLOCK_HARDWARE( struct intel_context *intel ); + +extern char *__progname; + + +#define SUBPIXEL_X 0.125 +#define SUBPIXEL_Y 0.125 + +#define INTEL_FIREVERTICES(intel) \ +do { \ + if ((intel)->prim.flush) \ + (intel)->prim.flush(intel); \ +} while (0) + +/* ================================================================ + * Color packing: + */ + +#define INTEL_PACKCOLOR4444(r,g,b,a) \ + ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) + +#define INTEL_PACKCOLOR1555(r,g,b,a) \ + ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ + ((a) ? 0x8000 : 0)) + +#define INTEL_PACKCOLOR565(r,g,b) \ + ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) + +#define INTEL_PACKCOLOR8888(r,g,b,a) \ + ((a<<24) | (r<<16) | (g<<8) | b) + + + +/* ================================================================ + * From linux kernel i386 header files, copes with odd sizes better + * than COPY_DWORDS would: + * XXX Put this in src/mesa/main/imports.h ??? + */ +#if defined(i386) || defined(__i386__) +static INLINE void * +__memcpy(void *to, const void *from, size_t n) +{ + int d0, d1, d2; + __asm__ __volatile__("rep ; movsl\n\t" + "testb $2,%b4\n\t" + "je 1f\n\t" + "movsw\n" + "1:\ttestb $1,%b4\n\t" + "je 2f\n\t" + "movsb\n" "2:":"=&c"(d0), "=&D"(d1), "=&S"(d2) + :"0"(n / 4), "q"(n), "1"((long) to), "2"((long) from) + :"memory"); + return (to); +} +#else +#define __memcpy(a,b,c) memcpy(a,b,c) +#endif + + + +/* ================================================================ + * Debugging: + */ +#define DO_DEBUG 1 +#if DO_DEBUG +extern int INTEL_DEBUG; +#else +#define INTEL_DEBUG 0 +#endif + +#define DEBUG_TEXTURE 0x1 +#define DEBUG_STATE 0x2 +#define DEBUG_IOCTL 0x4 +#define DEBUG_BLIT 0x8 +#define DEBUG_MIPTREE 0x10 +#define DEBUG_FALLBACKS 0x20 +#define DEBUG_VERBOSE 0x40 +#define DEBUG_BATCH 0x80 +#define DEBUG_PIXEL 0x100 +#define DEBUG_BUFMGR 0x200 +#define DEBUG_REGION 0x400 +#define DEBUG_FBO 0x800 +#define DEBUG_LOCK 0x1000 + +#define DBG(...) do { if (INTEL_DEBUG & FILE_DEBUG_FLAG) _mesa_printf(__VA_ARGS__); } while(0) + + +#define PCI_CHIP_845_G 0x2562 +#define PCI_CHIP_I830_M 0x3577 +#define PCI_CHIP_I855_GM 0x3582 +#define PCI_CHIP_I865_G 0x2572 +#define PCI_CHIP_I915_G 0x2582 +#define PCI_CHIP_I915_GM 0x2592 +#define PCI_CHIP_I945_G 0x2772 +#define PCI_CHIP_I945_GM 0x27A2 + + +/* ================================================================ + * intel_context.c: + */ + +extern GLboolean intelInitContext(struct intel_context *intel, + const __GLcontextModes * mesaVis, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate, + struct dd_function_table *functions); + +extern void intelGetLock(struct intel_context *intel, GLuint flags); + +extern void intelInitState(GLcontext * ctx); +extern void intelFinish(GLcontext * ctx); +extern void intelFlush(GLcontext * ctx); + +extern void intelInitDriverFunctions(struct dd_function_table *functions); + + +/* ================================================================ + * intel_state.c: + */ +extern void intelInitStateFuncs(struct dd_function_table *functions); + +#define COMPAREFUNC_ALWAYS 0 +#define COMPAREFUNC_NEVER 0x1 +#define COMPAREFUNC_LESS 0x2 +#define COMPAREFUNC_EQUAL 0x3 +#define COMPAREFUNC_LEQUAL 0x4 +#define COMPAREFUNC_GREATER 0x5 +#define COMPAREFUNC_NOTEQUAL 0x6 +#define COMPAREFUNC_GEQUAL 0x7 + +#define STENCILOP_KEEP 0 +#define STENCILOP_ZERO 0x1 +#define STENCILOP_REPLACE 0x2 +#define STENCILOP_INCRSAT 0x3 +#define STENCILOP_DECRSAT 0x4 +#define STENCILOP_INCR 0x5 +#define STENCILOP_DECR 0x6 +#define STENCILOP_INVERT 0x7 + +#define LOGICOP_CLEAR 0 +#define LOGICOP_NOR 0x1 +#define LOGICOP_AND_INV 0x2 +#define LOGICOP_COPY_INV 0x3 +#define LOGICOP_AND_RVRSE 0x4 +#define LOGICOP_INV 0x5 +#define LOGICOP_XOR 0x6 +#define LOGICOP_NAND 0x7 +#define LOGICOP_AND 0x8 +#define LOGICOP_EQUIV 0x9 +#define LOGICOP_NOOP 0xa +#define LOGICOP_OR_INV 0xb +#define LOGICOP_COPY 0xc +#define LOGICOP_OR_RVRSE 0xd +#define LOGICOP_OR 0xe +#define LOGICOP_SET 0xf + +#define BLENDFACT_ZERO 0x01 +#define BLENDFACT_ONE 0x02 +#define BLENDFACT_SRC_COLR 0x03 +#define BLENDFACT_INV_SRC_COLR 0x04 +#define BLENDFACT_SRC_ALPHA 0x05 +#define BLENDFACT_INV_SRC_ALPHA 0x06 +#define BLENDFACT_DST_ALPHA 0x07 +#define BLENDFACT_INV_DST_ALPHA 0x08 +#define BLENDFACT_DST_COLR 0x09 +#define BLENDFACT_INV_DST_COLR 0x0a +#define BLENDFACT_SRC_ALPHA_SATURATE 0x0b +#define BLENDFACT_CONST_COLOR 0x0c +#define BLENDFACT_INV_CONST_COLOR 0x0d +#define BLENDFACT_CONST_ALPHA 0x0e +#define BLENDFACT_INV_CONST_ALPHA 0x0f +#define BLENDFACT_MASK 0x0f + +#define MI_BATCH_BUFFER_END (0xA<<23) + + +extern int intel_translate_compare_func(GLenum func); +extern int intel_translate_stencil_op(GLenum op); +extern int intel_translate_blend_factor(GLenum factor); +extern int intel_translate_logic_op(GLenum opcode); + + +/*====================================================================== + * Inline conversion functions. + * These are better-typed than the macros used previously: + */ +static INLINE struct intel_context * +intel_context(GLcontext * ctx) +{ + return (struct intel_context *) ctx; +} + +static INLINE struct intel_texture_object * +intel_texture_object(struct gl_texture_object *obj) +{ + return (struct intel_texture_object *) obj; +} + +static INLINE struct intel_texture_image * +intel_texture_image(struct gl_texture_image *img) +{ + return (struct intel_texture_image *) img; +} + +extern struct intel_renderbuffer *intel_renderbuffer(struct gl_renderbuffer + *rb); + + +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_depthstencil.c b/src/mesa/drivers/dri/i915tex/intel_depthstencil.c new file mode 100644 index 0000000000..d269a85a3c --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_depthstencil.c @@ -0,0 +1,282 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "glheader.h" +#include "imports.h" +#include "context.h" +#include "depthstencil.h" +#include "fbobject.h" +#include "framebuffer.h" +#include "hash.h" +#include "mtypes.h" +#include "renderbuffer.h" + +#include "intel_context.h" +#include "intel_fbo.h" +#include "intel_depthstencil.h" +#include "intel_regions.h" + + +/** + * The GL_EXT_framebuffer_object allows the user to create their own + * framebuffer objects consisting of color renderbuffers (0 or more), + * depth renderbuffers (0 or 1) and stencil renderbuffers (0 or 1). + * + * The spec considers depth and stencil renderbuffers to be totally independent + * buffers. In reality, most graphics hardware today uses a combined + * depth+stencil buffer (one 32-bit pixel = 24 bits of Z + 8 bits of stencil). + * + * This causes difficulty because the user may create some number of depth + * renderbuffers and some number of stencil renderbuffers and bind them + * together in framebuffers in any combination. + * + * This code manages all that. + * + * 1. Depth renderbuffers are always allocated in hardware as 32bpp + * GL_DEPTH24_STENCIL8 buffers. + * + * 2. Stencil renderbuffers are initially allocated in software as 8bpp + * GL_STENCIL_INDEX8 buffers. + * + * 3. Depth and Stencil renderbuffers use the PairedStencil and PairedDepth + * fields (respectively) to indicate if the buffer's currently paired + * with another stencil or depth buffer (respectively). + * + * 4. When a depth and stencil buffer are initially both attached to the + * current framebuffer, we merge the stencil buffer values into the + * depth buffer (really a depth+stencil buffer). The then hardware uses + * the combined buffer. + * + * 5. Whenever a depth or stencil buffer is reallocated (with + * glRenderbufferStorage) we undo the pairing and copy the stencil values + * from the combined depth/stencil buffer back to the stencil-only buffer. + * + * 6. We also undo the pairing when we find a change in buffer bindings. + * + * 7. If a framebuffer is only using a depth renderbuffer (no stencil), we + * just use the combined depth/stencil buffer and ignore the stencil values. + * + * 8. If a framebuffer is only using a stencil renderbuffer (no depth) we have + * to promote the 8bpp software stencil buffer to a 32bpp hardware + * depth+stencil buffer. + * + */ + + + +static void +map_regions(GLcontext * ctx, + struct intel_renderbuffer *depthRb, + struct intel_renderbuffer *stencilRb) +{ + struct intel_context *intel = intel_context(ctx); + if (depthRb && depthRb->region) { + intel_region_map(intel->intelScreen, depthRb->region); + depthRb->pfMap = depthRb->region->map; + depthRb->pfPitch = depthRb->region->pitch; + } + if (stencilRb && stencilRb->region) { + intel_region_map(intel->intelScreen, stencilRb->region); + stencilRb->pfMap = stencilRb->region->map; + stencilRb->pfPitch = stencilRb->region->pitch; + } +} + +static void +unmap_regions(GLcontext * ctx, + struct intel_renderbuffer *depthRb, + struct intel_renderbuffer *stencilRb) +{ + struct intel_context *intel = intel_context(ctx); + if (depthRb && depthRb->region) { + intel_region_unmap(intel->intelScreen, depthRb->region); + depthRb->pfMap = NULL; + depthRb->pfPitch = 0; + } + if (stencilRb && stencilRb->region) { + intel_region_unmap(intel->intelScreen, stencilRb->region); + stencilRb->pfMap = NULL; + stencilRb->pfPitch = 0; + } +} + + + +/** + * Undo the pairing/interleaving between depth and stencil buffers. + * irb should be a depth/stencil or stencil renderbuffer. + */ +void +intel_unpair_depth_stencil(GLcontext * ctx, struct intel_renderbuffer *irb) +{ + if (irb->PairedStencil) { + /* irb is a depth/stencil buffer */ + struct gl_renderbuffer *stencilRb; + struct intel_renderbuffer *stencilIrb; + + ASSERT(irb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); + + stencilRb = _mesa_lookup_renderbuffer(ctx, irb->PairedStencil); + stencilIrb = intel_renderbuffer(stencilRb); + if (stencilIrb) { + /* need to extract stencil values from the depth buffer */ + ASSERT(stencilIrb->PairedDepth == irb->Base.Name); + map_regions(ctx, irb, stencilIrb); + _mesa_extract_stencil(ctx, &irb->Base, &stencilIrb->Base); + unmap_regions(ctx, irb, stencilIrb); + stencilIrb->PairedDepth = 0; + } + irb->PairedStencil = 0; + } + else if (irb->PairedDepth) { + /* irb is a stencil buffer */ + struct gl_renderbuffer *depthRb; + struct intel_renderbuffer *depthIrb; + + ASSERT(irb->Base._ActualFormat == GL_STENCIL_INDEX8_EXT || + irb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); + + depthRb = _mesa_lookup_renderbuffer(ctx, irb->PairedDepth); + depthIrb = intel_renderbuffer(depthRb); + if (depthIrb) { + /* need to extract stencil values from the depth buffer */ + ASSERT(depthIrb->PairedStencil == irb->Base.Name); + map_regions(ctx, depthIrb, irb); + _mesa_extract_stencil(ctx, &depthIrb->Base, &irb->Base); + unmap_regions(ctx, depthIrb, irb); + depthIrb->PairedStencil = 0; + } + irb->PairedDepth = 0; + } + else { + _mesa_problem(ctx, "Problem in undo_depth_stencil_pairing"); + } + + ASSERT(irb->PairedStencil == 0); + ASSERT(irb->PairedDepth == 0); +} + + +/** + * Examine the depth and stencil renderbuffers which are attached to the + * framebuffer. If both depth and stencil are attached, make sure that the + * renderbuffers are 'paired' (combined). If only depth or only stencil is + * attached, undo any previous pairing. + * + * Must be called if NewState & _NEW_BUFFER (when renderbuffer attachments + * change, for example). + */ +void +intel_validate_paired_depth_stencil(GLcontext * ctx, + struct gl_framebuffer *fb) +{ + struct intel_renderbuffer *depthRb, *stencilRb; + + depthRb = intel_get_renderbuffer(fb, BUFFER_DEPTH); + stencilRb = intel_get_renderbuffer(fb, BUFFER_STENCIL); + + if (depthRb && stencilRb) { + if (depthRb == stencilRb) { + /* Using a user-created combined depth/stencil buffer. + * Nothing to do. + */ + ASSERT(depthRb->Base._BaseFormat == GL_DEPTH_STENCIL_EXT); + ASSERT(depthRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); + } + else { + /* Separate depth/stencil buffers, need to interleave now */ + ASSERT(depthRb->Base._BaseFormat == GL_DEPTH_COMPONENT); + ASSERT(stencilRb->Base._BaseFormat == GL_STENCIL_INDEX); + /* may need to interleave depth/stencil now */ + if (depthRb->PairedStencil == stencilRb->Base.Name) { + /* OK, the depth and stencil buffers are already interleaved */ + ASSERT(stencilRb->PairedDepth == depthRb->Base.Name); + } + else { + /* need to setup new pairing/interleaving */ + if (depthRb->PairedStencil) { + intel_unpair_depth_stencil(ctx, depthRb); + } + if (stencilRb->PairedDepth) { + intel_unpair_depth_stencil(ctx, stencilRb); + } + + ASSERT(depthRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); + ASSERT(stencilRb->Base._ActualFormat == GL_STENCIL_INDEX8_EXT || + stencilRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); + + /* establish new pairing: interleave stencil into depth buffer */ + map_regions(ctx, depthRb, stencilRb); + _mesa_insert_stencil(ctx, &depthRb->Base, &stencilRb->Base); + unmap_regions(ctx, depthRb, stencilRb); + depthRb->PairedStencil = stencilRb->Base.Name; + stencilRb->PairedDepth = depthRb->Base.Name; + } + + } + } + else if (depthRb) { + /* Depth buffer but no stencil buffer. + * We'll use a GL_DEPTH24_STENCIL8 buffer and ignore the stencil bits. + */ + /* can't assert this until storage is allocated: + ASSERT(depthRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); + */ + /* intel_undo any previous pairing */ + if (depthRb->PairedStencil) { + intel_unpair_depth_stencil(ctx, depthRb); + } + } + else if (stencilRb) { + /* Stencil buffer but no depth buffer. + * Since h/w doesn't typically support just 8bpp stencil w/out Z, + * we'll use a GL_DEPTH24_STENCIL8 buffer and ignore the depth bits. + */ + /* undo any previous pairing */ + if (stencilRb->PairedDepth) { + intel_unpair_depth_stencil(ctx, stencilRb); + } + if (stencilRb->Base._ActualFormat == GL_STENCIL_INDEX8_EXT) { + /* promote buffer to GL_DEPTH24_STENCIL8 for hw rendering */ + _mesa_promote_stencil(ctx, &stencilRb->Base); + ASSERT(stencilRb->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT); + } + } + + /* Finally, update the fb->_DepthBuffer and fb->_StencilBuffer fields */ + _mesa_update_depth_buffer(ctx, fb, BUFFER_DEPTH); + if (depthRb && depthRb->PairedStencil) + _mesa_update_stencil_buffer(ctx, fb, BUFFER_DEPTH); + else + _mesa_update_stencil_buffer(ctx, fb, BUFFER_STENCIL); + + + /* The hardware should use fb->Attachment[BUFFER_DEPTH].Renderbuffer + * first, if present, then fb->Attachment[BUFFER_STENCIL].Renderbuffer + * if present. + */ +} diff --git a/src/mesa/drivers/dri/i915tex/intel_depthstencil.h b/src/mesa/drivers/dri/i915tex/intel_depthstencil.h new file mode 100644 index 0000000000..2d3fc48b3a --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_depthstencil.h @@ -0,0 +1,14 @@ + +#ifndef INTEL_DEPTH_STENCIL_H +#define INTEL_DEPTH_STENCIL_H + + +extern void +intel_unpair_depth_stencil(GLcontext * ctx, struct intel_renderbuffer *irb); + +extern void +intel_validate_paired_depth_stencil(GLcontext * ctx, + struct gl_framebuffer *fb); + + +#endif /* INTEL_DEPTH_STENCIL_H */ diff --git a/src/mesa/drivers/dri/i915tex/intel_fbo.c b/src/mesa/drivers/dri/i915tex/intel_fbo.c new file mode 100644 index 0000000000..ab0e569bd9 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_fbo.c @@ -0,0 +1,622 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "imports.h" +#include "mtypes.h" +#include "fbobject.h" +#include "framebuffer.h" +#include "renderbuffer.h" +#include "context.h" +#include "texformat.h" +#include "texrender.h" + +#include "intel_context.h" +#include "intel_buffers.h" +#include "intel_depthstencil.h" +#include "intel_fbo.h" +#include "intel_mipmap_tree.h" +#include "intel_regions.h" +#include "intel_span.h" + + +#define FILE_DEBUG_FLAG DEBUG_FBO + +#define INTEL_RB_CLASS 0x12345678 + + +/* XXX FBO: move this to intel_context.h (inlined) */ +/** + * Return a gl_renderbuffer ptr casted to intel_renderbuffer. + * NULL will be returned if the rb isn't really an intel_renderbuffer. + * This is determiend by checking the ClassID. + */ +struct intel_renderbuffer * +intel_renderbuffer(struct gl_renderbuffer *rb) +{ + struct intel_renderbuffer *irb = (struct intel_renderbuffer *) rb; + if (irb && irb->Base.ClassID == INTEL_RB_CLASS) { + /*_mesa_warning(NULL, "Returning non-intel Rb\n");*/ + return irb; + } + else + return NULL; +} + + +struct intel_renderbuffer * +intel_get_renderbuffer(struct gl_framebuffer *fb, GLuint attIndex) +{ + return intel_renderbuffer(fb->Attachment[attIndex].Renderbuffer); +} + + +struct intel_region * +intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex) +{ + struct intel_renderbuffer *irb + = intel_renderbuffer(fb->Attachment[attIndex].Renderbuffer); + if (irb) + return irb->region; + else + return NULL; +} + + + +/** + * Create a new framebuffer object. + */ +static struct gl_framebuffer * +intel_new_framebuffer(GLcontext * ctx, GLuint name) +{ + /* there's no intel_framebuffer at this time, just use Mesa's class */ + return _mesa_new_framebuffer(ctx, name); +} + + +static void +intel_delete_renderbuffer(struct gl_renderbuffer *rb) +{ + GET_CURRENT_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); + struct intel_renderbuffer *irb = intel_renderbuffer(rb); + + ASSERT(irb); + + if (irb->PairedStencil || irb->PairedDepth) { + intel_unpair_depth_stencil(ctx, irb); + } + + if (intel && irb->region) { + intel_region_release(&irb->region); + } + + _mesa_free(irb); +} + + + +/** + * Return a pointer to a specific pixel in a renderbuffer. + */ +static void * +intel_get_pointer(GLcontext * ctx, struct gl_renderbuffer *rb, + GLint x, GLint y) +{ + /* By returning NULL we force all software rendering to go through + * the span routines. + */ + return NULL; +} + + + +/** + * Called via glRenderbufferStorageEXT() to set the format and allocate + * storage for a user-created renderbuffer. + */ +static GLboolean +intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, GLuint height) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_renderbuffer *irb = intel_renderbuffer(rb); + GLboolean softwareBuffer = GL_FALSE; + int cpp; + + ASSERT(rb->Name != 0); + + switch (internalFormat) { + case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + rb->_ActualFormat = GL_RGB5; + rb->DataType = GL_UNSIGNED_BYTE; + rb->RedBits = 5; + rb->GreenBits = 6; + rb->BlueBits = 5; + cpp = 2; + break; + case GL_RGB: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + case GL_RGBA: + case GL_RGBA2: + case GL_RGBA4: + case GL_RGB5_A1: + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + rb->_ActualFormat = GL_RGBA8; + rb->DataType = GL_UNSIGNED_BYTE; + rb->RedBits = 8; + rb->GreenBits = 8; + rb->BlueBits = 8; + rb->AlphaBits = 8; + cpp = 4; + break; + case GL_STENCIL_INDEX: + case GL_STENCIL_INDEX1_EXT: + case GL_STENCIL_INDEX4_EXT: + case GL_STENCIL_INDEX8_EXT: + case GL_STENCIL_INDEX16_EXT: + /* alloc a depth+stencil buffer */ + rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT; + rb->DataType = GL_UNSIGNED_INT_24_8_EXT; + rb->StencilBits = 8; + cpp = 4; + break; + case GL_DEPTH_COMPONENT16: + rb->_ActualFormat = GL_DEPTH_COMPONENT16; + rb->DataType = GL_UNSIGNED_SHORT; + rb->DepthBits = 16; + cpp = 2; + break; + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT32: + rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT; + rb->DataType = GL_UNSIGNED_INT_24_8_EXT; + rb->DepthBits = 24; + cpp = 4; + break; + case GL_DEPTH_STENCIL_EXT: + case GL_DEPTH24_STENCIL8_EXT: + rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT; + rb->DataType = GL_UNSIGNED_INT_24_8_EXT; + rb->DepthBits = 24; + rb->StencilBits = 8; + cpp = 4; + break; + default: + _mesa_problem(ctx, + "Unexpected format in intel_alloc_renderbuffer_storage"); + return GL_FALSE; + } + + intelFlush(ctx); + + /* free old region */ + if (irb->region) { + intel_region_release(&irb->region); + } + + /* allocate new memory region/renderbuffer */ + if (softwareBuffer) { + return _mesa_soft_renderbuffer_storage(ctx, rb, internalFormat, + width, height); + } + else { + /* Choose a pitch to match hardware requirements: + */ + GLuint pitch = ((cpp * width + 63) & ~63) / cpp; + + /* alloc hardware renderbuffer */ + DBG("Allocating %d x %d Intel RBO (pitch %d)\n", width, + height, pitch); + + irb->region = intel_region_alloc(intel->intelScreen, cpp, pitch, height); + if (!irb->region) + return GL_FALSE; /* out of memory? */ + + ASSERT(irb->region->buffer); + + rb->Width = width; + rb->Height = height; + + /* This sets the Get/PutRow/Value functions */ + intel_set_span_functions(&irb->Base); + + return GL_TRUE; + } +} + + + +/** + * Called for each hardware renderbuffer when a _window_ is resized. + * Just update fields. + * Not used for user-created renderbuffers! + */ +static GLboolean +intel_alloc_window_storage(GLcontext * ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, GLuint width, GLuint height) +{ + ASSERT(rb->Name == 0); + rb->Width = width; + rb->Height = height; + rb->_ActualFormat = internalFormat; + return GL_TRUE; +} + + +static GLboolean +intel_nop_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, GLuint width, GLuint height) +{ + _mesa_problem(ctx, "intel_op_alloc_storage should never be called."); + return GL_FALSE; +} + + + +/** + * Create a new intel_renderbuffer which corresponds to an on-screen window, + * not a user-created renderbuffer. + * \param width the screen width + * \param height the screen height + */ +struct intel_renderbuffer * +intel_create_renderbuffer(GLenum intFormat, GLsizei width, GLsizei height, + int offset, int pitch, int cpp, void *map) +{ + GET_CURRENT_CONTEXT(ctx); + + struct intel_renderbuffer *irb; + const GLuint name = 0; + + irb = CALLOC_STRUCT(intel_renderbuffer); + if (!irb) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer"); + return NULL; + } + + _mesa_init_renderbuffer(&irb->Base, name); + irb->Base.ClassID = INTEL_RB_CLASS; + + switch (intFormat) { + case GL_RGB5: + irb->Base._ActualFormat = GL_RGB5; + irb->Base._BaseFormat = GL_RGBA; + irb->Base.RedBits = 5; + irb->Base.GreenBits = 6; + irb->Base.BlueBits = 5; + irb->Base.DataType = GL_UNSIGNED_BYTE; + cpp = 2; + break; + case GL_RGBA8: + irb->Base._ActualFormat = GL_RGBA8; + irb->Base._BaseFormat = GL_RGBA; + irb->Base.RedBits = 8; + irb->Base.GreenBits = 8; + irb->Base.BlueBits = 8; + irb->Base.AlphaBits = 8; + irb->Base.DataType = GL_UNSIGNED_BYTE; + cpp = 4; + break; + case GL_STENCIL_INDEX8_EXT: + irb->Base._ActualFormat = GL_STENCIL_INDEX8_EXT; + irb->Base._BaseFormat = GL_STENCIL_INDEX; + irb->Base.StencilBits = 8; + irb->Base.DataType = GL_UNSIGNED_BYTE; + cpp = 1; + break; + case GL_DEPTH_COMPONENT16: + irb->Base._ActualFormat = GL_DEPTH_COMPONENT16; + irb->Base._BaseFormat = GL_DEPTH_COMPONENT; + irb->Base.DepthBits = 16; + irb->Base.DataType = GL_UNSIGNED_SHORT; + cpp = 2; + break; + case GL_DEPTH_COMPONENT24: + irb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; + irb->Base._BaseFormat = GL_DEPTH_COMPONENT; + irb->Base.DepthBits = 24; + irb->Base.DataType = GL_UNSIGNED_INT; + cpp = 4; + break; + case GL_DEPTH24_STENCIL8_EXT: + irb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; + irb->Base._BaseFormat = GL_DEPTH_STENCIL_EXT; + irb->Base.DepthBits = 24; + irb->Base.StencilBits = 8; + irb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT; + cpp = 4; + break; + default: + _mesa_problem(NULL, + "Unexpected intFormat in intel_create_renderbuffer"); + return NULL; + } + + irb->Base.InternalFormat = intFormat; + + /* intel-specific methods */ + irb->Base.Delete = intel_delete_renderbuffer; + irb->Base.AllocStorage = intel_alloc_window_storage; + irb->Base.GetPointer = intel_get_pointer; + /* This sets the Get/PutRow/Value functions */ + intel_set_span_functions(&irb->Base); + + irb->pfMap = map; + irb->pfPitch = pitch / cpp; /* in pixels */ + +#if 00 + irb->region = intel_region_create_static(intel, + DRM_MM_TT, + offset, map, cpp, width, height); +#endif + + return irb; +} + + +/** + * Create a new renderbuffer object. + * Typically called via glBindRenderbufferEXT(). + */ +static struct gl_renderbuffer * +intel_new_renderbuffer(GLcontext * ctx, GLuint name) +{ + /*struct intel_context *intel = intel_context(ctx); */ + struct intel_renderbuffer *irb; + + irb = CALLOC_STRUCT(intel_renderbuffer); + if (!irb) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer"); + return NULL; + } + + _mesa_init_renderbuffer(&irb->Base, name); + irb->Base.ClassID = INTEL_RB_CLASS; + + /* intel-specific methods */ + irb->Base.Delete = intel_delete_renderbuffer; + irb->Base.AllocStorage = intel_alloc_renderbuffer_storage; + irb->Base.GetPointer = intel_get_pointer; + /* span routines set in alloc_storage function */ + + return &irb->Base; +} + + +/** + * Called via glBindFramebufferEXT(). + */ +static void +intel_bind_framebuffer(GLcontext * ctx, GLenum target, + struct gl_framebuffer *fb) +{ + if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) { + intel_draw_buffer(ctx, fb); + /* Integer depth range depends on depth buffer bits */ + ctx->Driver.DepthRange(ctx, ctx->Viewport.Near, ctx->Viewport.Far); + } + else { + /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */ + } +} + + +/** + * Called via glFramebufferRenderbufferEXT(). + */ +static void +intel_framebuffer_renderbuffer(GLcontext * ctx, + struct gl_framebuffer *fb, + GLenum attachment, struct gl_renderbuffer *rb) +{ + DBG("Intel FramebufferRenderbuffer %u %u\n", fb->Name, rb ? rb->Name : 0); + + intelFlush(ctx); + + _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb); + intel_draw_buffer(ctx, fb); +} + + +/** + * When glFramebufferTexture[123]D is called this function sets up the + * gl_renderbuffer wrapp around the texture image. + * This will have the region info needed for hardware rendering. + */ +static struct intel_renderbuffer * +intel_wrap_texture(GLcontext * ctx, struct gl_texture_image *texImage) +{ + const GLuint name = ~0; /* not significant, but distinct for debugging */ + struct intel_renderbuffer *irb; + + /* make an intel_renderbuffer to wrap the texture image */ + irb = CALLOC_STRUCT(intel_renderbuffer); + if (!irb) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture"); + return NULL; + } + + _mesa_init_renderbuffer(&irb->Base, name); + irb->Base.ClassID = INTEL_RB_CLASS; + + if (texImage->TexFormat == &_mesa_texformat_argb8888) { + irb->Base._ActualFormat = GL_RGBA8; + irb->Base._BaseFormat = GL_RGBA; + DBG("Render to RGBA8 texture OK\n"); + } + else if (texImage->TexFormat == &_mesa_texformat_rgb565) { + irb->Base._ActualFormat = GL_RGB5; + irb->Base._BaseFormat = GL_RGB; + DBG("Render to RGB5 texture OK\n"); + } + else if (texImage->TexFormat == &_mesa_texformat_z16) { + irb->Base._ActualFormat = GL_DEPTH_COMPONENT16; + irb->Base._BaseFormat = GL_DEPTH_COMPONENT; + DBG("Render to DEPTH16 texture OK\n"); + } + else { + DBG("Render to texture BAD FORMAT %d\n", + texImage->TexFormat->MesaFormat); + _mesa_free(irb); + return NULL; + } + + irb->Base.InternalFormat = irb->Base._ActualFormat; + irb->Base.Width = texImage->Width; + irb->Base.Height = texImage->Height; + irb->Base.DataType = GL_UNSIGNED_BYTE; /* FBO XXX fix */ + irb->Base.RedBits = texImage->TexFormat->RedBits; + irb->Base.GreenBits = texImage->TexFormat->GreenBits; + irb->Base.BlueBits = texImage->TexFormat->BlueBits; + irb->Base.AlphaBits = texImage->TexFormat->AlphaBits; + irb->Base.DepthBits = texImage->TexFormat->DepthBits; + + irb->Base.Delete = intel_delete_renderbuffer; + irb->Base.AllocStorage = intel_nop_alloc_storage; + intel_set_span_functions(&irb->Base); + + irb->RenderToTexture = GL_TRUE; + + return irb; +} + + +/** + * Called by glFramebufferTexture[123]DEXT() (and other places) to + * prepare for rendering into texture memory. This might be called + * many times to choose different texture levels, cube faces, etc + * before intel_finish_render_texture() is ever called. + */ +static void +intel_render_texture(GLcontext * ctx, + struct gl_framebuffer *fb, + struct gl_renderbuffer_attachment *att) +{ + struct gl_texture_image *newImage + = att->Texture->Image[att->CubeMapFace][att->TextureLevel]; + struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer); + struct intel_texture_image *intel_image; + GLuint imageOffset; + + (void) fb; + + ASSERT(newImage); + + if (!irb) { + irb = intel_wrap_texture(ctx, newImage); + if (irb) { + /* bind the wrapper to the attachment point */ + att->Renderbuffer = &irb->Base; + } + else { + /* fallback to software rendering */ + _mesa_render_texture(ctx, fb, att); + return; + } + } + + DBG("Begin render texture tid %x tex=%u w=%d h=%d refcount=%d\n", + _glthread_GetID(), + att->Texture->Name, newImage->Width, newImage->Height, + irb->Base.RefCount); + + /* point the renderbufer's region to the texture image region */ + intel_image = intel_texture_image(newImage); + if (irb->region != intel_image->mt->region) { + if (irb->region) + intel_region_release(&irb->region); + intel_region_reference(&irb->region, intel_image->mt->region); + } + + /* compute offset of the particular 2D image within the texture region */ + imageOffset = intel_miptree_image_offset(intel_image->mt, + att->CubeMapFace, + att->TextureLevel); + + if (att->Texture->Target == GL_TEXTURE_3D) { + const GLuint *offsets = intel_miptree_depth_offsets(intel_image->mt, + att->TextureLevel); + imageOffset += offsets[att->Zoffset]; + } + + /* store that offset in the region */ + intel_image->mt->region->draw_offset = imageOffset; + + /* update drawing region, etc */ + intel_draw_buffer(ctx, fb); +} + + +/** + * Called by Mesa when rendering to a texture is done. + */ +static void +intel_finish_render_texture(GLcontext * ctx, + struct gl_renderbuffer_attachment *att) +{ + struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer); + + DBG("End render texture (tid %x) tex %u\n", _glthread_GetID(), att->Texture->Name); + + if (irb) { + /* just release the region */ + intel_region_release(&irb->region); + } + else if (att->Renderbuffer) { + /* software fallback */ + _mesa_finish_render_texture(ctx, att); + /* XXX FBO: Need to unmap the buffer (or in intelSpanRenderStart???) */ + } +} + + +/** + * Do one-time context initializations related to GL_EXT_framebuffer_object. + * Hook in device driver functions. + */ +void +intel_fbo_init(struct intel_context *intel) +{ + intel->ctx.Driver.NewFramebuffer = intel_new_framebuffer; + intel->ctx.Driver.NewRenderbuffer = intel_new_renderbuffer; + intel->ctx.Driver.BindFramebuffer = intel_bind_framebuffer; + intel->ctx.Driver.FramebufferRenderbuffer = intel_framebuffer_renderbuffer; + intel->ctx.Driver.RenderTexture = intel_render_texture; + intel->ctx.Driver.FinishRenderTexture = intel_finish_render_texture; +} diff --git a/src/mesa/drivers/dri/i915tex/intel_fbo.h b/src/mesa/drivers/dri/i915tex/intel_fbo.h new file mode 100644 index 0000000000..221f09b39a --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_fbo.h @@ -0,0 +1,80 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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. + * + **************************************************************************/ + +#ifndef INTEL_FBO_H +#define INTEL_FBO_H + + +struct intel_context; +struct intel_region; + + +/** + * Intel renderbuffer, derived from gl_renderbuffer. + * Note: The PairedDepth and PairedStencil fields use renderbuffer IDs, + * not pointers because in some circumstances a deleted renderbuffer could + * result in a dangling pointer here. + */ +struct intel_renderbuffer +{ + struct gl_renderbuffer Base; + struct intel_region *region; + void *pfMap; /* possibly paged flipped map pointer */ + GLuint pfPitch; /* possibly paged flipped pitch */ + GLboolean RenderToTexture; /* RTT? */ + + GLuint PairedDepth; /**< only used if this is a depth renderbuffer */ + GLuint PairedStencil; /**< only used if this is a stencil renderbuffer */ +}; + + +extern struct intel_renderbuffer *intel_create_renderbuffer(GLenum intFormat, + GLsizei width, + GLsizei height, + int offset, + int pitch, + int cpp, + void *map); + + +extern void intel_fbo_init(struct intel_context *intel); + + +/* XXX make inline or macro */ +extern struct intel_renderbuffer *intel_get_renderbuffer(struct gl_framebuffer + *fb, + GLuint attIndex); + + +/* XXX make inline or macro */ +extern struct intel_region *intel_get_rb_region(struct gl_framebuffer *fb, + GLuint attIndex); + + + + +#endif /* INTEL_FBO_H */ diff --git a/src/mesa/drivers/dri/i915tex/intel_ioctl.c b/src/mesa/drivers/dri/i915tex/intel_ioctl.c new file mode 100644 index 0000000000..3250c6b3a9 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_ioctl.c @@ -0,0 +1,138 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 +#include +#include +#include + +#include "mtypes.h" +#include "context.h" +#include "swrast/swrast.h" + +#include "intel_context.h" +#include "intel_ioctl.h" +#include "intel_batchbuffer.h" +#include "intel_blit.h" +#include "intel_regions.h" +#include "drm.h" + +#define FILE_DEBUG_FLAG DEBUG_IOCTL + +int +intelEmitIrqLocked(struct intel_context *intel) +{ + drmI830IrqEmit ie; + int ret, seq; + + assert(((*(int *) intel->driHwLock) & ~DRM_LOCK_CONT) == + (DRM_LOCK_HELD | intel->hHWContext)); + + ie.irq_seq = &seq; + + ret = drmCommandWriteRead(intel->driFd, DRM_I830_IRQ_EMIT, + &ie, sizeof(ie)); + if (ret) { + fprintf(stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret); + exit(1); + } + + DBG("%s --> %d\n", __FUNCTION__, seq); + + return seq; +} + +void +intelWaitIrq(struct intel_context *intel, int seq) +{ + int ret; + + DBG("%s %d\n", __FUNCTION__, seq); + + intel->iw.irq_seq = seq; + + do { + ret = + drmCommandWrite(intel->driFd, DRM_I830_IRQ_WAIT, &intel->iw, + sizeof(intel->iw)); + } while (ret == -EAGAIN || ret == -EINTR); + + if (ret) { + fprintf(stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret); + exit(1); + } +} + + +void +intel_batch_ioctl(struct intel_context *intel, + GLuint start_offset, + GLuint used, + GLboolean ignore_cliprects, GLboolean allow_unlock) +{ + drmI830BatchBuffer batch; + + assert(intel->locked); + assert(used); + + DBG("%s used %d offset %x..%x ignore_cliprects %d\n", + __FUNCTION__, + used, start_offset, start_offset + used, ignore_cliprects); + + /* Throw away non-effective packets. Won't work once we have + * hardware contexts which would preserve statechanges beyond a + * single buffer. + */ + + + + batch.start = start_offset; + batch.used = used; + batch.cliprects = intel->pClipRects; + batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; + batch.DR1 = 0; + batch.DR4 = ((((GLuint) intel->drawX) & 0xffff) | + (((GLuint) intel->drawY) << 16)); + + DBG("%s: 0x%x..0x%x DR4: %x cliprects: %d\n", + __FUNCTION__, + batch.start, + batch.start + batch.used * 4, batch.DR4, batch.num_cliprects); + + if (drmCommandWrite(intel->driFd, DRM_I830_BATCHBUFFER, &batch, + sizeof(batch))) { + fprintf(stderr, "DRM_I830_BATCHBUFFER: %d\n", -errno); + UNLOCK_HARDWARE(intel); + exit(1); + } + + /* FIXME: use hardware contexts to avoid 'losing' hardware after + * each buffer flush. + */ + intel->vtbl.lost_hardware(intel); +} diff --git a/src/mesa/drivers/dri/i915tex/intel_ioctl.h b/src/mesa/drivers/dri/i915tex/intel_ioctl.h new file mode 100644 index 0000000000..e8d07de893 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_ioctl.h @@ -0,0 +1,40 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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. + * + **************************************************************************/ + +#ifndef INTEL_IOCTL_H +#define INTEL_IOCTL_H + +#include "intel_context.h" + +void intelWaitIrq(struct intel_context *intel, int seq); +int intelEmitIrqLocked(struct intel_context *intel); + +void intel_batch_ioctl(struct intel_context *intel, + GLuint start_offset, + GLuint used, + GLboolean ignore_cliprects, GLboolean allow_unlock); +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c new file mode 100644 index 0000000000..2ebe3ae14e --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c @@ -0,0 +1,341 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "intel_context.h" +#include "intel_mipmap_tree.h" +#include "intel_regions.h" +#include "enums.h" + +#define FILE_DEBUG_FLAG DEBUG_MIPTREE + +static GLenum +target_to_target(GLenum target) +{ + switch (target) { + case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: + return GL_TEXTURE_CUBE_MAP_ARB; + default: + return target; + } +} + +struct intel_mipmap_tree * +intel_miptree_create(struct intel_context *intel, + GLenum target, + GLenum internal_format, + GLuint first_level, + GLuint last_level, + GLuint width0, + GLuint height0, + GLuint depth0, GLuint cpp, GLboolean compressed) +{ + GLboolean ok; + struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1); + + DBG("%s target %s format %s level %d..%d\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(target), + _mesa_lookup_enum_by_nr(internal_format), first_level, last_level); + + mt->target = target_to_target(target); + mt->internal_format = internal_format; + mt->first_level = first_level; + mt->last_level = last_level; + mt->width0 = width0; + mt->height0 = height0; + mt->depth0 = depth0; + mt->cpp = compressed ? 2 : cpp; + mt->compressed = compressed; + mt->refcount = 1; + + switch (intel->intelScreen->deviceID) { + case PCI_CHIP_I945_G: + case PCI_CHIP_I945_GM: + ok = i945_miptree_layout(mt); + break; + case PCI_CHIP_I915_G: + case PCI_CHIP_I915_GM: + case PCI_CHIP_I830_M: + case PCI_CHIP_I855_GM: + case PCI_CHIP_I865_G: + default: + /* All the i830 chips and the i915 use this layout: + */ + ok = i915_miptree_layout(mt); + break; + } + + if (ok) + mt->region = intel_region_alloc(intel->intelScreen, + mt->cpp, mt->pitch, mt->total_height); + + if (!mt->region) { + free(mt); + return NULL; + } + + return mt; +} + + +void +intel_miptree_reference(struct intel_mipmap_tree **dst, + struct intel_mipmap_tree *src) +{ + src->refcount++; + *dst = src; + DBG("%s %p refcount now %d\n", __FUNCTION__, src, src->refcount); +} + +void +intel_miptree_release(struct intel_context *intel, + struct intel_mipmap_tree **mt) +{ + if (!*mt) + return; + + DBG("%s %p refcount will be %d\n", __FUNCTION__, *mt, (*mt)->refcount - 1); + if (--(*mt)->refcount <= 0) { + GLuint i; + + DBG("%s deleting %p\n", __FUNCTION__, *mt); + + intel_region_release(&((*mt)->region)); + + for (i = 0; i < MAX_TEXTURE_LEVELS; i++) + if ((*mt)->level[i].image_offset) + free((*mt)->level[i].image_offset); + + free(*mt); + } + *mt = NULL; +} + + + + +/* Can the image be pulled into a unified mipmap tree. This mirrors + * the completeness test in a lot of ways. + * + * Not sure whether I want to pass gl_texture_image here. + */ +GLboolean +intel_miptree_match_image(struct intel_mipmap_tree *mt, + struct gl_texture_image *image, + GLuint face, GLuint level) +{ + /* Images with borders are never pulled into mipmap trees. + */ + if (image->Border) + return GL_FALSE; + + if (image->InternalFormat != mt->internal_format || + image->IsCompressed != mt->compressed) + return GL_FALSE; + + /* Test image dimensions against the base level image adjusted for + * minification. This will also catch images not present in the + * tree, changed targets, etc. + */ + if (image->Width != mt->level[level].width || + image->Height != mt->level[level].height || + image->Depth != mt->level[level].depth) + return GL_FALSE; + + return GL_TRUE; +} + + +void +intel_miptree_set_level_info(struct intel_mipmap_tree *mt, + GLuint level, + GLuint nr_images, + GLuint x, GLuint y, GLuint w, GLuint h, GLuint d) +{ + + mt->level[level].width = w; + mt->level[level].height = h; + mt->level[level].depth = d; + mt->level[level].level_offset = (x + y * mt->pitch) * mt->cpp; + mt->level[level].nr_images = nr_images; + + DBG("%s level %d size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__, + level, w, h, d, x, y, mt->level[level].level_offset); + + /* Not sure when this would happen, but anyway: + */ + if (mt->level[level].image_offset) { + free(mt->level[level].image_offset); + mt->level[level].image_offset = NULL; + } + + assert(nr_images); + + mt->level[level].image_offset = malloc(nr_images * sizeof(GLuint)); + mt->level[level].image_offset[0] = 0; +} + + + +void +intel_miptree_set_image_offset(struct intel_mipmap_tree *mt, + GLuint level, GLuint img, GLuint x, GLuint y) +{ + if (img == 0 && level == 0) + assert(x == 0 && y == 0); + + assert(img < mt->level[level].nr_images); + + mt->level[level].image_offset[img] = (x + y * mt->pitch); + + DBG("%s level %d img %d pos %d,%d image_offset %x\n", + __FUNCTION__, level, img, x, y, mt->level[level].image_offset[img]); +} + + +/* Although we use the image_offset[] array to store relative offsets + * to cube faces, Mesa doesn't know anything about this and expects + * each cube face to be treated as a separate image. + * + * These functions present that view to mesa: + */ +const GLuint * +intel_miptree_depth_offsets(struct intel_mipmap_tree *mt, GLuint level) +{ + static const GLuint zero = 0; + + if (mt->target != GL_TEXTURE_3D || mt->level[level].nr_images == 1) + return &zero; + else + return mt->level[level].image_offset; +} + + +GLuint +intel_miptree_image_offset(struct intel_mipmap_tree * mt, + GLuint face, GLuint level) +{ + if (mt->target == GL_TEXTURE_CUBE_MAP_ARB) + return (mt->level[level].level_offset + + mt->level[level].image_offset[face] * mt->cpp); + else + return mt->level[level].level_offset; +} + + + +/** + * Map a teximage in a mipmap tree. + * \param row_stride returns row stride in bytes + * \param image_stride returns image stride in bytes (for 3D textures). + * \return address of mapping + */ +GLubyte * +intel_miptree_image_map(struct intel_context * intel, + struct intel_mipmap_tree * mt, + GLuint face, + GLuint level, + GLuint * row_stride, GLuint * image_offsets) +{ + DBG("%s \n", __FUNCTION__); + + if (row_stride) + *row_stride = mt->pitch * mt->cpp; + + if (image_offsets) + memcpy(image_offsets, mt->level[level].image_offset, + mt->level[level].depth * sizeof(GLuint)); + + return (intel_region_map(intel->intelScreen, mt->region) + + intel_miptree_image_offset(mt, face, level)); +} + +void +intel_miptree_image_unmap(struct intel_context *intel, + struct intel_mipmap_tree *mt) +{ + DBG("%s\n", __FUNCTION__); + intel_region_unmap(intel->intelScreen, mt->region); +} + + + +/* Upload data for a particular image. + */ +void +intel_miptree_image_data(struct intel_context *intel, + struct intel_mipmap_tree *dst, + GLuint face, + GLuint level, + void *src, + GLuint src_row_pitch, GLuint src_image_pitch) +{ + GLuint depth = dst->level[level].depth; + GLuint dst_offset = intel_miptree_image_offset(dst, face, level); + const GLuint *dst_depth_offset = intel_miptree_depth_offsets(dst, level); + GLuint i; + + DBG("%s\n", __FUNCTION__); + for (i = 0; i < depth; i++) { + intel_region_data(intel->intelScreen, dst->region, dst_offset + dst_depth_offset[i], 0, 0, src, src_row_pitch, 0, 0, /* source x,y */ + dst->level[level].width, dst->level[level].height); + + src += src_image_pitch; + } +} + +/* Copy mipmap image between trees + */ +void +intel_miptree_image_copy(struct intel_context *intel, + struct intel_mipmap_tree *dst, + GLuint face, GLuint level, + struct intel_mipmap_tree *src) +{ + GLuint width = src->level[level].width; + GLuint height = src->level[level].height; + GLuint depth = src->level[level].depth; + GLuint dst_offset = intel_miptree_image_offset(dst, face, level); + GLuint src_offset = intel_miptree_image_offset(src, face, level); + const GLuint *dst_depth_offset = intel_miptree_depth_offsets(dst, level); + const GLuint *src_depth_offset = intel_miptree_depth_offsets(src, level); + GLuint i; + + for (i = 0; i < depth; i++) { + intel_region_copy(intel->intelScreen, + dst->region, dst_offset + dst_depth_offset[i], + 0, + 0, + src->region, src_offset + src_depth_offset[i], + 0, 0, width, height); + } + +} diff --git a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.h b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.h new file mode 100644 index 0000000000..e6dd5bb600 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.h @@ -0,0 +1,198 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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. + * + **************************************************************************/ + +#ifndef INTEL_MIPMAP_TREE_H +#define INTEL_MIPMAP_TREE_H + +#include "intel_regions.h" + +/* A layer on top of the intel_regions code which adds: + * + * - Code to size and layout a region to hold a set of mipmaps. + * - Query to determine if a new image fits in an existing tree. + * - More refcounting + * - maybe able to remove refcounting from intel_region? + * - ? + * + * The fixed mipmap layout of intel hardware where one offset + * specifies the position of all images in a mipmap hierachy + * complicates the implementation of GL texture image commands, + * compared to hardware where each image is specified with an + * independent offset. + * + * In an ideal world, each texture object would be associated with a + * single bufmgr buffer or 2d intel_region, and all the images within + * the texture object would slot into the tree as they arrive. The + * reality can be a little messier, as images can arrive from the user + * with sizes that don't fit in the existing tree, or in an order + * where the tree layout cannot be guessed immediately. + * + * This structure encodes an idealized mipmap tree. The GL image + * commands build these where possible, otherwise store the images in + * temporary system buffers. + */ + + +/** + * Describes the location of each texture image within a texture region. + */ +struct intel_mipmap_level +{ + GLuint level_offset; + GLuint width; + GLuint height; + GLuint depth; + GLuint nr_images; + + /* Explicitly store the offset of each image for each cube face or + * depth value. Pretty much have to accept that hardware formats + * are going to be so diverse that there is no unified way to + * compute the offsets of depth/cube images within a mipmap level, + * so have to store them as a lookup table: + */ + GLuint *image_offset; +}; + +struct intel_mipmap_tree +{ + /* Effectively the key: + */ + GLenum target; + GLenum internal_format; + + GLuint first_level; + GLuint last_level; + + GLuint width0, height0, depth0; /**< Level zero image dimensions */ + GLuint cpp; + GLboolean compressed; + + /* Derived from the above: + */ + GLuint pitch; + GLuint depth_pitch; /* per-image on i945? */ + GLuint total_height; + + /* Includes image offset tables: + */ + struct intel_mipmap_level level[MAX_TEXTURE_LEVELS]; + + /* The data is held here: + */ + struct intel_region *region; + + /* These are also refcounted: + */ + GLuint refcount; +}; + + + +struct intel_mipmap_tree *intel_miptree_create(struct intel_context *intel, + GLenum target, + GLenum internal_format, + GLuint first_level, + GLuint last_level, + GLuint width0, + GLuint height0, + GLuint depth0, + GLuint cpp, + GLboolean compressed); + +void intel_miptree_reference(struct intel_mipmap_tree **dst, + struct intel_mipmap_tree *src); + +void intel_miptree_release(struct intel_context *intel, + struct intel_mipmap_tree **mt); + +/* Check if an image fits an existing mipmap tree layout + */ +GLboolean intel_miptree_match_image(struct intel_mipmap_tree *mt, + struct gl_texture_image *image, + GLuint face, GLuint level); + +/* Return a pointer to an image within a tree. Return image stride as + * well. + */ +GLubyte *intel_miptree_image_map(struct intel_context *intel, + struct intel_mipmap_tree *mt, + GLuint face, + GLuint level, + GLuint * row_stride, GLuint * image_stride); + +void intel_miptree_image_unmap(struct intel_context *intel, + struct intel_mipmap_tree *mt); + + +/* Return the linear offset of an image relative to the start of the + * tree: + */ +GLuint intel_miptree_image_offset(struct intel_mipmap_tree *mt, + GLuint face, GLuint level); + +/* Return pointers to each 2d slice within an image. Indexed by depth + * value. + */ +const GLuint *intel_miptree_depth_offsets(struct intel_mipmap_tree *mt, + GLuint level); + + +void intel_miptree_set_level_info(struct intel_mipmap_tree *mt, + GLuint level, + GLuint nr_images, + GLuint x, GLuint y, + GLuint w, GLuint h, GLuint d); + +void intel_miptree_set_image_offset(struct intel_mipmap_tree *mt, + GLuint level, + GLuint img, GLuint x, GLuint y); + + +/* Upload an image into a tree + */ +void intel_miptree_image_data(struct intel_context *intel, + struct intel_mipmap_tree *dst, + GLuint face, + GLuint level, + void *src, + GLuint src_row_pitch, GLuint src_image_pitch); + +/* Copy an image between two trees + */ +void intel_miptree_image_copy(struct intel_context *intel, + struct intel_mipmap_tree *dst, + GLuint face, GLuint level, + struct intel_mipmap_tree *src); + +/* i915_mipmap_tree.c: + */ +GLboolean i915_miptree_layout(struct intel_mipmap_tree *mt); +GLboolean i945_miptree_layout(struct intel_mipmap_tree *mt); + + + +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel.c b/src/mesa/drivers/dri/i915tex/intel_pixel.c new file mode 100644 index 0000000000..4fe128deea --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_pixel.c @@ -0,0 +1,119 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 portionsalloc + * 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 TUNGSTEN 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 "enums.h" +#include "state.h" +#include "swrast/swrast.h" + +#include "intel_context.h" +#include "intel_pixel.h" +#include "intel_regions.h" + + +/** + * Check if any fragment operations are in effect which might effect + * glDraw/CopyPixels. + */ +GLboolean +intel_check_blit_fragment_ops(GLcontext * ctx) +{ + if (ctx->NewState) + _mesa_update_state(ctx); + + /* XXX Note: Scissor could be done with the blitter: + */ + return !(ctx->_ImageTransferState || + ctx->Color.AlphaEnabled || + ctx->Depth.Test || + ctx->Fog.Enabled || + ctx->Scissor.Enabled || + ctx->Stencil.Enabled || + !ctx->Color.ColorMask[0] || + !ctx->Color.ColorMask[1] || + !ctx->Color.ColorMask[2] || + !ctx->Color.ColorMask[3] || + ctx->Color.ColorLogicOpEnabled || + ctx->Texture._EnabledUnits || ctx->FragmentProgram._Enabled); +} + + +GLboolean +intel_check_meta_tex_fragment_ops(GLcontext * ctx) +{ + if (ctx->NewState) + _mesa_update_state(ctx); + + /* Some of _ImageTransferState (scale, bias) could be done with + * fragment programs on i915. + */ + return !(ctx->_ImageTransferState || ctx->Fog.Enabled || /* not done yet */ + ctx->Texture._EnabledUnits || ctx->FragmentProgram._Enabled); +} + +/* The intel_region struct doesn't really do enough to capture the + * format of the pixels in the region. For now this code assumes that + * the region is a display surface and hence is either ARGB8888 or + * RGB565. + * XXX FBO: If we'd pass in the intel_renderbuffer instead of region, we'd + * know the buffer's pixel format. + * + * \param format as given to glDraw/ReadPixels + * \param type as given to glDraw/ReadPixels + */ +GLboolean +intel_check_blit_format(struct intel_region * region, + GLenum format, GLenum type) +{ + if (region->cpp == 4 && + (type == GL_UNSIGNED_INT_8_8_8_8_REV || + type == GL_UNSIGNED_BYTE) && format == GL_BGRA) { + return GL_TRUE; + } + + if (region->cpp == 2 && + type == GL_UNSIGNED_SHORT_5_6_5_REV && format == GL_BGR) { + return GL_TRUE; + } + + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s: bad format for blit (cpp %d, type %s format %s)\n", + __FUNCTION__, region->cpp, + _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format)); + + return GL_FALSE; +} + + +void +intelInitPixelFuncs(struct dd_function_table *functions) +{ + functions->Accum = _swrast_Accum; + functions->Bitmap = _swrast_Bitmap; + functions->CopyPixels = intelCopyPixels; + functions->ReadPixels = intelReadPixels; + functions->DrawPixels = intelDrawPixels; +} diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel.h b/src/mesa/drivers/dri/i915tex/intel_pixel.h new file mode 100644 index 0000000000..a6fcf90ce0 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_pixel.h @@ -0,0 +1,63 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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. + * + **************************************************************************/ + +#ifndef INTEL_PIXEL_H +#define INTEL_PIXEL_H + +#include "mtypes.h" + +void intelInitPixelFuncs(struct dd_function_table *functions); + +GLboolean intel_check_blit_fragment_ops(GLcontext * ctx); + +GLboolean intel_check_meta_tex_fragment_ops(GLcontext * ctx); + +GLboolean intel_check_blit_format(struct intel_region *region, + GLenum format, GLenum type); + + +void intelReadPixels(GLcontext * ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, + GLvoid * pixels); + +void intelDrawPixels(GLcontext * ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, + GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid * pixels); + +void intelCopyPixels(GLcontext * ctx, + GLint srcx, GLint srcy, + GLsizei width, GLsizei height, + GLint destx, GLint desty, GLenum type); + +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel_bitmap.c b/src/mesa/drivers/dri/i915tex/intel_pixel_bitmap.c new file mode 100644 index 0000000000..65bf338589 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_pixel_bitmap.c @@ -0,0 +1,350 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 portionsalloc + * 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 TUNGSTEN 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 "glheader.h" +#include "enums.h" +#include "image.h" +#include "colormac.h" +#include "mtypes.h" +#include "macros.h" +#include "bufferobj.h" +#include "swrast/swrast.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_ioctl.h" +#include "intel_batchbuffer.h" +#include "intel_blit.h" +#include "intel_regions.h" +#include "intel_buffer_objects.h" + + + +#define FILE_DEBUG_FLAG DEBUG_PIXEL + + +/* Unlike the other intel_pixel_* functions, the expectation here is + * that the incoming data is not in a PBO. With the XY_TEXT blit + * method, there's no benefit haveing it in a PBO, but we could + * implement a path based on XY_MONO_SRC_COPY_BLIT which might benefit + * PBO bitmaps. I think they are probably pretty rare though - I + * wonder if Xgl uses them? + */ +static const GLubyte *map_pbo( GLcontext *ctx, + GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap ) +{ + GLubyte *buf; + + if (!_mesa_validate_pbo_access(2, unpack, width, height, 1, + GL_COLOR_INDEX, GL_BITMAP, + (GLvoid *) bitmap)) { + _mesa_error(ctx, GL_INVALID_OPERATION,"glBitmap(invalid PBO access)"); + return NULL; + } + + buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, + GL_READ_ONLY_ARB, + unpack->BufferObj); + if (!buf) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap(PBO is mapped)"); + return NULL; + } + + return ADD_POINTERS(buf, bitmap); +} + +static GLboolean test_bit( const GLubyte *src, + GLuint bit ) +{ + return (src[bit/8] & (1<<(bit % 8))) ? 1 : 0; +} + +static void set_bit( GLubyte *dest, + GLuint bit ) +{ + dest[bit/8] |= 1 << (bit % 8); +} + +static int align(int x, int align) +{ + return (x + align - 1) & ~(align - 1); +} + +/* Extract a rectangle's worth of data from the bitmap. Called + * per-cliprect. + */ +static GLuint get_bitmap_rect(GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap, + GLuint x, GLuint y, + GLuint w, GLuint h, + GLubyte *dest, + GLuint row_align, + GLboolean invert) +{ + GLuint src_offset = (x + unpack->SkipPixels) & 0x7; + GLuint mask = unpack->LsbFirst ? 0 : 7; + GLuint bit = 0; + GLint row, col; + GLint first, last; + GLint incr; + GLuint count = 0; + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s %d,%d %dx%d bitmap %dx%d skip %d src_offset %d mask %d\n", + __FUNCTION__, x,y,w,h,width,height,unpack->SkipPixels, src_offset, mask); + + if (invert) { + first = h-1; + last = 0; + incr = -1; + } + else { + first = 0; + last = h-1; + incr = 1; + } + + /* Require that dest be pre-zero'd. + */ + for (row = first; row != (last+incr); row += incr) { + const GLubyte *rowsrc = _mesa_image_address2d(unpack, bitmap, + width, height, + GL_COLOR_INDEX, GL_BITMAP, + y + row, x); + + for (col = 0; col < w; col++, bit++) { + if (test_bit(rowsrc, (col + src_offset) ^ mask)) { + set_bit(dest, bit ^ 7); + count++; + } + } + + if (row_align) + bit = (bit + row_align - 1) & ~(row_align - 1); + } + + return count; +} + + + + +/* + * Render a bitmap. + */ +static GLboolean +do_blit_bitmap( GLcontext *ctx, + GLint dstx, GLint dsty, + GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap ) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_region *dst = intel_drawbuf_region(intel); + + union { + GLuint ui; + GLubyte ub[4]; + } color; + + + if (unpack->BufferObj->Name) { + bitmap = map_pbo(ctx, width, height, unpack, bitmap); + if (bitmap == NULL) + return GL_TRUE; /* even though this is an error, we're done */ + } + + UNCLAMPED_FLOAT_TO_CHAN(color.ub[0], ctx->Current.RasterColor[2]); + UNCLAMPED_FLOAT_TO_CHAN(color.ub[1], ctx->Current.RasterColor[1]); + UNCLAMPED_FLOAT_TO_CHAN(color.ub[2], ctx->Current.RasterColor[0]); + UNCLAMPED_FLOAT_TO_CHAN(color.ub[3], ctx->Current.RasterColor[3]); + + /* Does zoom apply to bitmaps? + */ + if (!intel_check_blit_fragment_ops(ctx) || + ctx->Pixel.ZoomX != 1.0F || + ctx->Pixel.ZoomY != 1.0F) + return GL_FALSE; + + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + __DRIdrawablePrivate *dPriv = intel->driDrawable; + drm_clip_rect_t *box = dPriv->pClipRects; + drm_clip_rect_t dest_rect; + GLint nbox = dPriv->numClipRects; + GLint srcx = 0, srcy = 0; + GLint orig_screen_x1, orig_screen_y2; + GLuint i; + + + orig_screen_x1 = dPriv->x + dstx; + orig_screen_y2 = dPriv->y + (dPriv->h - dsty); + + /* Do scissoring in GL coordinates: + */ +x if (ctx->Scissor.Enabled) + { + GLint x = ctx->Scissor.X; + GLint y = ctx->Scissor.Y; + GLuint w = ctx->Scissor.Width; + GLuint h = ctx->Scissor.Height; + + if (!_mesa_clip_to_region(x, y, x+w-1, y+h-1, &dstx, &dsty, &width, &height)) + goto out; + } + + /* Convert from GL to hardware coordinates: + */ + dsty = dPriv->y + (dPriv->h - dsty - height); + dstx = dPriv->x + dstx; + + dest_rect.x1 = dstx; + dest_rect.y1 = dsty; + dest_rect.x2 = dstx + width; + dest_rect.y2 = dsty + height; + + for (i = 0; i < nbox; i++) { + drm_clip_rect_t rect; + int box_w, box_h; + GLint px, py; + GLuint stipple[32]; + + if (!intel_intersect_cliprects(&rect, &dest_rect, &box[i])) + continue; + + /* Now go back to GL coordinates to figure out what subset of + * the bitmap we are uploading for this cliprect: + */ + box_w = rect.x2 - rect.x1; + box_h = rect.y2 - rect.y1; + srcx = rect.x1 - orig_screen_x1; + srcy = orig_screen_y2 - rect.y2; + + +#define DY 32 +#define DX 32 + + /* Then, finally, chop it all into chunks that can be + * digested by hardware: + */ + for (py = 0; py < box_h; py += DY) { + for (px = 0; px < box_w; px += DX) { + int h = MIN2(DY, box_h - py); + int w = MIN2(DX, box_w - px); + GLuint sz = align(align(w,8) * h, 64)/8; + + assert(sz <= sizeof(stipple)); + memset(stipple, 0, sz); + + /* May need to adjust this when padding has been introduced in + * sz above: + */ + if (get_bitmap_rect(width, height, unpack, + bitmap, + srcx + px, srcy + py, w, h, + (GLubyte *)stipple, + 8, + GL_TRUE) == 0) + continue; + + /* + */ + intelEmitImmediateColorExpandBlit( intel, + dst->cpp, + (GLubyte *)stipple, + sz, + color.ui, + dst->pitch, + dst->buffer, + 0, + dst->tiled, + rect.x1 + px, + rect.y2 - (py + h), + w, h); + } + } + } + intel->need_flush = GL_TRUE; + out: + intel_batchbuffer_flush(intel->batch); + } + UNLOCK_HARDWARE(intel); + + + if (unpack->BufferObj->Name) { + /* done with PBO so unmap it now */ + ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, + unpack->BufferObj); + } + + return GL_TRUE; +} + + + + + +/* There are a large number of possible ways to implement bitmap on + * this hardware, most of them have some sort of drawback. Here are a + * few that spring to mind: + * + * Blit: + * - XY_MONO_SRC_BLT_CMD + * - use XY_SETUP_CLIP_BLT for cliprect clipping. + * - XY_TEXT_BLT + * - XY_TEXT_IMMEDIATE_BLT + * - blit per cliprect, subject to maximum immediate data size. + * - XY_COLOR_BLT + * - per pixel or run of pixels + * - XY_PIXEL_BLT + * - good for sparse bitmaps + * + * 3D engine: + * - Point per pixel + * - Translate bitmap to an alpha texture and render as a quad + * - Chop bitmap up into 32x32 squares and render w/polygon stipple. + */ +void +intelBitmap(GLcontext * ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte * pixels) +{ + if (do_blit_bitmap(ctx, x, y, width, height, + unpack, pixels)) + return; + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s: fallback to swrast\n", __FUNCTION__); + + _swrast_Bitmap(ctx, x, y, width, height, unpack, pixels); +} diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel_copy.c b/src/mesa/drivers/dri/i915tex/intel_pixel_copy.c new file mode 100644 index 0000000000..5eb021f008 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_pixel_copy.c @@ -0,0 +1,380 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "glheader.h" +#include "enums.h" +#include "image.h" +#include "state.h" +#include "mtypes.h" +#include "macros.h" +#include "swrast/swrast.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_ioctl.h" +#include "intel_batchbuffer.h" +#include "intel_buffers.h" +#include "intel_blit.h" +#include "intel_regions.h" +#include "intel_tris.h" +#include "intel_pixel.h" + +#define FILE_DEBUG_FLAG DEBUG_PIXEL + +static struct intel_region * +copypix_src_region(struct intel_context *intel, GLenum type) +{ + switch (type) { + case GL_COLOR: + return intel_readbuf_region(intel); + case GL_DEPTH: + /* Don't think this is really possible execpt at 16bpp, when we have no stencil. + */ + if (intel->intelScreen->depth_region && + intel->intelScreen->depth_region->cpp == 2) + return intel->intelScreen->depth_region; + case GL_STENCIL: + /* Don't think this is really possible. + */ + break; + case GL_DEPTH_STENCIL_EXT: + /* Does it matter whether it is stencil/depth or depth/stencil? + */ + return intel->intelScreen->depth_region; + default: + break; + } + + return NULL; +} + + +/** + * Check if any fragment operations are in effect which might effect + * glCopyPixels. Differs from intel_check_blit_fragment_ops in that + * we allow Scissor. + */ +static GLboolean +intel_check_copypixel_blit_fragment_ops(GLcontext * ctx) +{ + if (ctx->NewState) + _mesa_update_state(ctx); + + /* Could do logicop with the blitter: + */ + return !(ctx->_ImageTransferState || + ctx->Color.AlphaEnabled || + ctx->Depth.Test || + ctx->Fog.Enabled || + ctx->Stencil.Enabled || + !ctx->Color.ColorMask[0] || + !ctx->Color.ColorMask[1] || + !ctx->Color.ColorMask[2] || + !ctx->Color.ColorMask[3] || + ctx->Color.ColorLogicOpEnabled || + ctx->Texture._EnabledUnits || + ctx->FragmentProgram._Enabled); +} + +/* Doesn't work for overlapping regions. Could do a double copy or + * just fallback. + */ +static GLboolean +do_texture_copypixels(GLcontext * ctx, + GLint srcx, GLint srcy, + GLsizei width, GLsizei height, + GLint dstx, GLint dsty, GLenum type) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_region *dst = intel_drawbuf_region(intel); + struct intel_region *src = copypix_src_region(intel, type); + GLenum src_format; + GLenum src_type; + + DBG("%s %d,%d %dx%d --> %d,%d\n", __FUNCTION__, + srcx, srcy, width, height, dstx, dsty); + + if (!src || !dst || type != GL_COLOR) + return GL_FALSE; + + /* Can't handle overlapping regions. Don't have sufficient control + * over rasterization to pull it off in-place. Punt on these for + * now. + * + * XXX: do a copy to a temporary. + */ + if (src->buffer == dst->buffer) { + drm_clip_rect_t srcbox; + drm_clip_rect_t dstbox; + drm_clip_rect_t tmp; + + srcbox.x1 = srcx; + srcbox.y1 = srcy; + srcbox.x2 = srcx + width; + srcbox.y2 = srcy + height; + + dstbox.x1 = dstx; + dstbox.y1 = dsty; + dstbox.x2 = dstx + width * ctx->Pixel.ZoomX; + dstbox.y2 = dsty + height * ctx->Pixel.ZoomY; + + DBG("src %d,%d %d,%d\n", srcbox.x1, srcbox.y1, srcbox.x2, srcbox.y2); + DBG("dst %d,%d %d,%d (%dx%d) (%f,%f)\n", dstbox.x1, dstbox.y1, dstbox.x2, dstbox.y2, + width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY); + + if (intel_intersect_cliprects(&tmp, &srcbox, &dstbox)) { + DBG("%s: regions overlap\n", __FUNCTION__); + return GL_FALSE; + } + } + + intelFlush(&intel->ctx); + + intel->vtbl.install_meta_state(intel); + + /* Is this true? Also will need to turn depth testing on according + * to state: + */ + intel->vtbl.meta_no_stencil_write(intel); + intel->vtbl.meta_no_depth_write(intel); + + /* Set the 3d engine to draw into the destination region: + */ + intel->vtbl.meta_draw_region(intel, dst, intel->intelScreen->depth_region); + + intel->vtbl.meta_import_pixel_state(intel); + + if (src->cpp == 2) { + src_format = GL_RGB; + src_type = GL_UNSIGNED_SHORT_5_6_5; + } + else { + src_format = GL_BGRA; + src_type = GL_UNSIGNED_BYTE; + } + + /* Set the frontbuffer up as a large rectangular texture. + */ + if (!intel->vtbl.meta_tex_rect_source(intel, src->buffer, 0, + src->pitch, + src->height, src_format, src_type)) { + intel->vtbl.leave_meta_state(intel); + return GL_FALSE; + } + + + intel->vtbl.meta_texture_blend_replace(intel); + + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + __DRIdrawablePrivate *dPriv = intel->driDrawable; + + + srcy = dPriv->h - srcy - height; /* convert from gl to hardware coords */ + + srcx += dPriv->x; + srcy += dPriv->y; + + /* Clip against the source region. This is the only source + * clipping we do. XXX: Just set the texcord wrap mode to clamp + * or similar. + * + */ + if (0) { + GLint orig_x = srcx; + GLint orig_y = srcy; + + if (!_mesa_clip_to_region(0, 0, src->pitch, src->height, + &srcx, &srcy, &width, &height)) + goto out; + + dstx += srcx - orig_x; + dsty += (srcy - orig_y) * ctx->Pixel.ZoomY; + } + + /* Just use the regular cliprect mechanism... Does this need to + * even hold the lock??? + */ + intel_meta_draw_quad(intel, + dstx, + dstx + width * ctx->Pixel.ZoomX, + dPriv->h - (dsty + height * ctx->Pixel.ZoomY), + dPriv->h - (dsty), 0, /* XXX: what z value? */ + 0x00ff00ff, + srcx, srcx + width, srcy, srcy + height); + + out: + intel->vtbl.leave_meta_state(intel); + intel_batchbuffer_flush(intel->batch); + } + UNLOCK_HARDWARE(intel); + + DBG("%s: success\n", __FUNCTION__); + return GL_TRUE; +} + + + + + +/** + * CopyPixels with the blitter. Don't support zooming, pixel transfer, etc. + */ +static GLboolean +do_blit_copypixels(GLcontext * ctx, + GLint srcx, GLint srcy, + GLsizei width, GLsizei height, + GLint dstx, GLint dsty, GLenum type) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_region *dst = intel_drawbuf_region(intel); + struct intel_region *src = copypix_src_region(intel, type); + + /* Copypixels can be more than a straight copy. Ensure all the + * extra operations are disabled: + */ + if (!intel_check_copypixel_blit_fragment_ops(ctx) || + ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F) + return GL_FALSE; + + if (!src || !dst) + return GL_FALSE; + + + + intelFlush(&intel->ctx); + + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + __DRIdrawablePrivate *dPriv = intel->driDrawable; + drm_clip_rect_t *box = dPriv->pClipRects; + drm_clip_rect_t dest_rect; + GLint nbox = dPriv->numClipRects; + GLint delta_x = 0; + GLint delta_y = 0; + GLuint i; + + /* Do scissoring in GL coordinates: + */ + if (ctx->Scissor.Enabled) + { + GLint x = ctx->Scissor.X; + GLint y = ctx->Scissor.Y; + GLuint w = ctx->Scissor.Width; + GLuint h = ctx->Scissor.Height; + GLint dx = dstx - srcx; + GLint dy = dsty - srcy; + + if (!_mesa_clip_to_region(x, y, x+w-1, y+h-1, &dstx, &dsty, &width, &height)) + goto out; + + srcx = dstx - dx; + srcy = dsty - dy; + } + + /* Convert from GL to hardware coordinates: + */ + dsty = dPriv->h - dsty - height; + srcy = dPriv->h - srcy - height; + dstx += dPriv->x; + dsty += dPriv->y; + srcx += dPriv->x; + srcy += dPriv->y; + + /* Clip against the source region. This is the only source + * clipping we do. Dst is clipped with cliprects below. + */ + { + delta_x = srcx - dstx; + delta_y = srcy - dsty; + + if (!_mesa_clip_to_region(0, 0, src->pitch, src->height, + &srcx, &srcy, &width, &height)) + goto out; + + dstx = srcx - delta_x; + dsty = srcy - delta_y; + } + + dest_rect.x1 = dstx; + dest_rect.y1 = dsty; + dest_rect.x2 = dstx + width; + dest_rect.y2 = dsty + height; + + /* Could do slightly more clipping: Eg, take the intersection of + * the existing set of cliprects and those cliprects translated + * by delta_x, delta_y: + * + * This code will not overwrite other windows, but will + * introduce garbage when copying from obscured window regions. + */ + for (i = 0; i < nbox; i++) { + drm_clip_rect_t rect; + + if (!intel_intersect_cliprects(&rect, &dest_rect, &box[i])) + continue; + + + intelEmitCopyBlit(intel, dst->cpp, + src->pitch, src->buffer, 0, + dst->pitch, dst->buffer, 0, + rect.x1 + delta_x, rect.y1 + delta_y, /* srcx, srcy */ + rect.x1, rect.y1, /* dstx, dsty */ + rect.x2 - rect.x1, rect.y2 - rect.y1); + } + + out: + intel_batchbuffer_flush(intel->batch); + } + UNLOCK_HARDWARE(intel); + + DBG("%s: success\n", __FUNCTION__); + return GL_TRUE; +} + + +void +intelCopyPixels(GLcontext * ctx, + GLint srcx, GLint srcy, + GLsizei width, GLsizei height, + GLint destx, GLint desty, GLenum type) +{ + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (do_blit_copypixels(ctx, srcx, srcy, width, height, destx, desty, type)) + return; + + if (do_texture_copypixels(ctx, srcx, srcy, width, height, destx, desty, type)) + return; + + DBG("fallback to _swrast_CopyPixels\n"); + + _swrast_CopyPixels(ctx, srcx, srcy, width, height, destx, desty, type); +} diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c b/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c new file mode 100644 index 0000000000..616101aef9 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_pixel_draw.c @@ -0,0 +1,365 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 portionsalloc + * 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 TUNGSTEN 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 "glheader.h" +#include "enums.h" +#include "image.h" +#include "mtypes.h" +#include "macros.h" +#include "bufferobj.h" +#include "swrast/swrast.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_ioctl.h" +#include "intel_batchbuffer.h" +#include "intel_blit.h" +#include "intel_buffers.h" +#include "intel_regions.h" +#include "intel_pixel.h" +#include "intel_buffer_objects.h" +#include "intel_tris.h" + + + +static GLboolean +do_texture_drawpixels(GLcontext * ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid * pixels) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_region *dst = intel_drawbuf_region(intel); + struct intel_buffer_object *src = intel_buffer_object(unpack->BufferObj); + GLuint rowLength = unpack->RowLength ? unpack->RowLength : width; + GLuint src_offset; + + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + intelFlush(&intel->ctx); + intel->vtbl.render_start(intel); + intel->vtbl.emit_state(intel); + + if (!dst) + return GL_FALSE; + + if (src) { + if (!_mesa_validate_pbo_access(2, unpack, width, height, 1, + format, type, pixels)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels"); + return GL_TRUE; + } + } + else { + /* PBO only for now: + */ +/* _mesa_printf("%s - not PBO\n", __FUNCTION__); */ + return GL_FALSE; + } + + /* There are a couple of things we can't do yet, one of which is + * set the correct state for pixel operations when GL texturing is + * enabled. That's a pretty rare state and probably not worth the + * effort. A completely device-independent version of this may do + * more. + * + * Similarly, we make no attempt to merge metaops processing with + * an enabled fragment program, though it would certainly be + * possible. + */ + if (!intel_check_meta_tex_fragment_ops(ctx)) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - bad GL fragment state for metaops texture\n", + __FUNCTION__); + return GL_FALSE; + } + + intel->vtbl.install_meta_state(intel); + + + /* Is this true? Also will need to turn depth testing on according + * to state: + */ + intel->vtbl.meta_no_stencil_write(intel); + intel->vtbl.meta_no_depth_write(intel); + + /* Set the 3d engine to draw into the destination region: + */ + intel->vtbl.meta_draw_region(intel, dst, intel->intelScreen->depth_region); + + intel->vtbl.meta_import_pixel_state(intel); + + src_offset = (GLuint) _mesa_image_address(2, unpack, pixels, width, height, + format, type, 0, 0, 0); + + + /* Setup the pbo up as a rectangular texture, if possible. + * + * TODO: This is almost always possible if the i915 fragment + * program is adjusted to correctly swizzle the sampled colors. + * The major exception is any 24bit texture, like RGB888, for which + * there is no hardware support. + */ + if (!intel->vtbl.meta_tex_rect_source(intel, src->buffer, src_offset, + rowLength, height, format, type)) { + intel->vtbl.leave_meta_state(intel); + return GL_FALSE; + } + + intel->vtbl.meta_texture_blend_replace(intel); + + + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + __DRIdrawablePrivate *dPriv = intel->driDrawable; + GLint srcx, srcy; + GLint dstx, dsty; + + dstx = x; + dsty = dPriv->h - (y + height); + + srcx = 0; /* skiprows/pixels already done */ + srcy = 0; + + if (0) { + const GLint orig_x = dstx; + const GLint orig_y = dsty; + + if (!_mesa_clip_to_region(0, 0, dst->pitch, dst->height, + &dstx, &dsty, &width, &height)) + goto out; + + srcx += dstx - orig_x; + srcy += dsty - orig_y; + } + + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("draw %d,%d %dx%d\n", dstx, dsty, width, height); + + /* Must use the regular cliprect mechanism in order to get the + * drawing origin set correctly. Otherwise scissor state is in + * incorrect coordinate space. Does this even need to hold the + * lock??? + */ + intel_meta_draw_quad(intel, + dstx, dstx + width * ctx->Pixel.ZoomX, + dPriv->h - (y + height * ctx->Pixel.ZoomY), + dPriv->h - (y), + -ctx->Current.RasterPos[2] * .5, + 0x00ff00ff, + srcx, srcx + width, srcy + height, srcy); + out: + intel->vtbl.leave_meta_state(intel); + intel_batchbuffer_flush(intel->batch); + } + UNLOCK_HARDWARE(intel); + return GL_TRUE; +} + + + + + +/* Pros: + * - no waiting for idle before updating framebuffer. + * + * Cons: + * - if upload is by memcpy, this may actually be slower than fallback path. + * - uploads the whole image even if destination is clipped + * + * Need to benchmark. + * + * Given the questions about performance, implement for pbo's only. + * This path is definitely a win if the pbo is already in agp. If it + * turns out otherwise, we can add the code necessary to upload client + * data to agp space before performing the blit. (Though it may turn + * out to be better/simpler just to use the texture engine). + */ +static GLboolean +do_blit_drawpixels(GLcontext * ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid * pixels) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_region *dest = intel_drawbuf_region(intel); + struct intel_buffer_object *src = intel_buffer_object(unpack->BufferObj); + GLuint src_offset; + GLuint rowLength; + struct _DriFenceObject *fence = NULL; + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s\n", __FUNCTION__); + + + if (!dest) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - no dest\n", __FUNCTION__); + return GL_FALSE; + } + + if (src) { + /* This validation should be done by core mesa: + */ + if (!_mesa_validate_pbo_access(2, unpack, width, height, 1, + format, type, pixels)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels"); + return GL_TRUE; + } + } + else { + /* PBO only for now: + */ + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - not PBO\n", __FUNCTION__); + return GL_FALSE; + } + + if (!intel_check_blit_format(dest, format, type)) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - bad format for blit\n", __FUNCTION__); + return GL_FALSE; + } + + if (!intel_check_meta_tex_fragment_ops(ctx)) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - bad GL fragment state for meta tex\n", + __FUNCTION__); + return GL_FALSE; + } + + if (ctx->Pixel.ZoomX != 1.0F) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - bad PixelZoomX for blit\n", __FUNCTION__); + return GL_FALSE; + } + + + if (unpack->RowLength > 0) + rowLength = unpack->RowLength; + else + rowLength = width; + + if (ctx->Pixel.ZoomY == -1.0F) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - bad PixelZoomY for blit\n", __FUNCTION__); + return GL_FALSE; /* later */ + y -= height; + } + else if (ctx->Pixel.ZoomY == 1.0F) { + rowLength = -rowLength; + } + else { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - bad PixelZoomY for blit\n", __FUNCTION__); + return GL_FALSE; + } + + src_offset = (GLuint) _mesa_image_address(2, unpack, pixels, width, height, + format, type, 0, 0, 0); + + intelFlush(&intel->ctx); + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + __DRIdrawablePrivate *dPriv = intel->driDrawable; + int nbox = dPriv->numClipRects; + drm_clip_rect_t *box = dPriv->pClipRects; + drm_clip_rect_t rect; + drm_clip_rect_t dest_rect; + struct _DriBufferObject *src_buffer = + intel_bufferobj_buffer(intel, src, INTEL_READ); + int i; + + dest_rect.x1 = dPriv->x + x; + dest_rect.y1 = dPriv->y + dPriv->h - (y + height); + dest_rect.x2 = dest_rect.x1 + width; + dest_rect.y2 = dest_rect.y1 + height; + + for (i = 0; i < nbox; i++) { + if (!intel_intersect_cliprects(&rect, &dest_rect, &box[i])) + continue; + + intelEmitCopyBlit(intel, + dest->cpp, + rowLength, + src_buffer, src_offset, + dest->pitch, + dest->buffer, 0, + rect.x1 - dest_rect.x1, + rect.y2 - dest_rect.y2, + rect.x1, + rect.y1, rect.x2 - rect.x1, rect.y2 - rect.y1); + } + fence = intel_batchbuffer_flush(intel->batch); + driFenceReference(fence); + } + UNLOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) + driFenceFinish(fence, DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW, GL_FALSE); + + driFenceUnReference(fence); + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - DONE\n", __FUNCTION__); + + return GL_TRUE; +} + + + +void +intelDrawPixels(GLcontext * ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, + GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid * pixels) +{ + if (do_blit_drawpixels(ctx, x, y, width, height, format, type, + unpack, pixels)) + return; + + if (do_texture_drawpixels(ctx, x, y, width, height, format, type, + unpack, pixels)) + return; + + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s: fallback to swrast\n", __FUNCTION__); + + _swrast_DrawPixels(ctx, x, y, width, height, format, type, unpack, pixels); +} diff --git a/src/mesa/drivers/dri/i915tex/intel_pixel_read.c b/src/mesa/drivers/dri/i915tex/intel_pixel_read.c new file mode 100644 index 0000000000..c1cc65674d --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_pixel_read.c @@ -0,0 +1,317 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "glheader.h" +#include "enums.h" +#include "mtypes.h" +#include "macros.h" +#include "image.h" +#include "bufferobj.h" +#include "swrast/swrast.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_ioctl.h" +#include "intel_batchbuffer.h" +#include "intel_blit.h" +#include "intel_buffers.h" +#include "intel_regions.h" +#include "intel_pixel.h" +#include "intel_buffer_objects.h" + +/* For many applications, the new ability to pull the source buffers + * back out of the GTT and then do the packing/conversion operations + * in software will be as much of an improvement as trying to get the + * blitter and/or texture engine to do the work. + * + * This step is gated on private backbuffers. + * + * Obviously the frontbuffer can't be pulled back, so that is either + * an argument for blit/texture readpixels, or for blitting to a + * temporary and then pulling that back. + * + * When the destination is a pbo, however, it's not clear if it is + * ever going to be pulled to main memory (though the access param + * will be a good hint). So it sounds like we do want to be able to + * choose between blit/texture implementation on the gpu and pullback + * and cpu-based copying. + * + * Unless you can magically turn client memory into a PBO for the + * duration of this call, there will be a cpu-based copying step in + * any case. + */ + + +static GLboolean +do_texture_readpixels(GLcontext * ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, + struct intel_region *dest_region) +{ +#if 0 + struct intel_context *intel = intel_context(ctx); + intelScreenPrivate *screen = intel->intelScreen; + GLint pitch = pack->RowLength ? pack->RowLength : width; + __DRIdrawablePrivate *dPriv = intel->driDrawable; + int textureFormat; + GLenum glTextureFormat; + int destFormat, depthFormat, destPitch; + drm_clip_rect_t tmp; + + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + + if (ctx->_ImageTransferState || + pack->SwapBytes || pack->LsbFirst || !pack->Invert) { + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s: check_color failed\n", __FUNCTION__); + return GL_FALSE; + } + + intel->vtbl.meta_texrect_source(intel, intel_readbuf_region(intel)); + + if (!intel->vtbl.meta_render_dest(intel, dest_region, type, format)) { + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s: couldn't set dest %s/%s\n", + __FUNCTION__, + _mesa_lookup_enum_by_nr(type), + _mesa_lookup_enum_by_nr(format)); + return GL_FALSE; + } + + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + intel->vtbl.install_meta_state(intel); + intel->vtbl.meta_no_depth_write(intel); + intel->vtbl.meta_no_stencil_write(intel); + + if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) { + UNLOCK_HARDWARE(intel); + SET_STATE(i830, state); + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__); + return GL_TRUE; + } + + y = dPriv->h - y - height; + x += dPriv->x; + y += dPriv->y; + + + /* Set the frontbuffer up as a large rectangular texture. + */ + intel->vtbl.meta_tex_rect_source(intel, src_region, textureFormat); + + + intel->vtbl.meta_texture_blend_replace(i830, glTextureFormat); + + + /* Set the 3d engine to draw into the destination region: + */ + + intel->vtbl.meta_draw_region(intel, dest_region); + intel->vtbl.meta_draw_format(intel, destFormat, depthFormat); /* ?? */ + + + /* Draw a single quad, no cliprects: + */ + intel->vtbl.meta_disable_cliprects(intel); + + intel->vtbl.draw_quad(intel, + 0, width, 0, height, + 0x00ff00ff, x, x + width, y, y + height); + + intel->vtbl.leave_meta_state(intel); + } + UNLOCK_HARDWARE(intel); + + intel_region_wait_fence(ctx, dest_region); /* required by GL */ + return GL_TRUE; +#endif + + return GL_FALSE; +} + + + + +static GLboolean +do_blit_readpixels(GLcontext * ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, GLvoid * pixels) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_region *src = intel_readbuf_region(intel); + struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj); + GLuint dst_offset; + GLuint rowLength; + struct _DriFenceObject *fence = NULL; + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s\n", __FUNCTION__); + + if (!src) + return GL_FALSE; + + if (dst) { + /* XXX This validation should be done by core mesa: + */ + if (!_mesa_validate_pbo_access(2, pack, width, height, 1, + format, type, pixels)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels"); + return GL_TRUE; + } + } + else { + /* PBO only for now: + */ + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - not PBO\n", __FUNCTION__); + return GL_FALSE; + } + + + if (ctx->_ImageTransferState || + !intel_check_blit_format(src, format, type)) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - bad format for blit\n", __FUNCTION__); + return GL_FALSE; + } + + if (pack->Alignment != 1 || pack->SwapBytes || pack->LsbFirst) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s: bad packing params\n", __FUNCTION__); + return GL_FALSE; + } + + if (pack->RowLength > 0) + rowLength = pack->RowLength; + else + rowLength = width; + + if (pack->Invert) { + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s: MESA_PACK_INVERT not done yet\n", __FUNCTION__); + return GL_FALSE; + } + else { + rowLength = -rowLength; + } + + /* XXX 64-bit cast? */ + dst_offset = (GLuint) _mesa_image_address(2, pack, pixels, width, height, + format, type, 0, 0, 0); + + + /* Although the blits go on the command buffer, need to do this and + * fire with lock held to guarentee cliprects are correct. + */ + intelFlush(&intel->ctx); + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + GLboolean all = (width * height * src->cpp == dst->Base.Size && + x == 0 && dst_offset == 0); + + struct _DriBufferObject *dst_buffer = + intel_bufferobj_buffer(intel, dst, all ? INTEL_WRITE_FULL : + INTEL_WRITE_PART); + __DRIdrawablePrivate *dPriv = intel->driDrawable; + int nbox = dPriv->numClipRects; + drm_clip_rect_t *box = dPriv->pClipRects; + drm_clip_rect_t rect; + drm_clip_rect_t src_rect; + int i; + + src_rect.x1 = dPriv->x + x; + src_rect.y1 = dPriv->y + dPriv->h - (y + height); + src_rect.x2 = src_rect.x1 + width; + src_rect.y2 = src_rect.y1 + height; + + + + for (i = 0; i < nbox; i++) { + if (!intel_intersect_cliprects(&rect, &src_rect, &box[i])) + continue; + + intelEmitCopyBlit(intel, + src->cpp, + src->pitch, src->buffer, 0, + rowLength, + dst_buffer, dst_offset, + rect.x1, + rect.y1, + rect.x1 - src_rect.x1, + rect.y2 - src_rect.y2, + rect.x2 - rect.x1, rect.y2 - rect.y1); + } + + fence = intel_batchbuffer_flush(intel->batch); + driFenceReference(fence); + + } + UNLOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) + driFenceFinish(fence, DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW, + GL_FALSE); + + driFenceUnReference(fence); + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s - DONE\n", __FUNCTION__); + + return GL_TRUE; +} + +void +intelReadPixels(GLcontext * ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, GLvoid * pixels) +{ + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + intelFlush(ctx); + + if (do_blit_readpixels + (ctx, x, y, width, height, format, type, pack, pixels)) + return; + + if (do_texture_readpixels + (ctx, x, y, width, height, format, type, pack, pixels)) + return; + + if (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("%s: fallback to swrast\n", __FUNCTION__); + + _swrast_ReadPixels(ctx, x, y, width, height, format, type, pack, pixels); +} diff --git a/src/mesa/drivers/dri/i915tex/intel_reg.h b/src/mesa/drivers/dri/i915tex/intel_reg.h new file mode 100644 index 0000000000..1ec153266c --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_reg.h @@ -0,0 +1,84 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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. + * + **************************************************************************/ + + +#ifndef _INTEL_REG_H_ +#define _INTEL_REG_H_ + + + +#define CMD_3D (0x3<<29) + + +#define _3DPRIMITIVE ((0x3<<29)|(0x1f<<24)) +#define PRIM_INDIRECT (1<<23) +#define PRIM_INLINE (0<<23) +#define PRIM_INDIRECT_SEQUENTIAL (0<<17) +#define PRIM_INDIRECT_ELTS (1<<17) + +#define PRIM3D_TRILIST (0x0<<18) +#define PRIM3D_TRISTRIP (0x1<<18) +#define PRIM3D_TRISTRIP_RVRSE (0x2<<18) +#define PRIM3D_TRIFAN (0x3<<18) +#define PRIM3D_POLY (0x4<<18) +#define PRIM3D_LINELIST (0x5<<18) +#define PRIM3D_LINESTRIP (0x6<<18) +#define PRIM3D_RECTLIST (0x7<<18) +#define PRIM3D_POINTLIST (0x8<<18) +#define PRIM3D_DIB (0x9<<18) +#define PRIM3D_MASK (0x1f<<18) + +#define I915PACKCOLOR4444(r,g,b,a) \ + ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) + +#define I915PACKCOLOR1555(r,g,b,a) \ + ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ + ((a) ? 0x8000 : 0)) + +#define I915PACKCOLOR565(r,g,b) \ + ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) + +#define I915PACKCOLOR8888(r,g,b,a) \ + ((a<<24) | (r<<16) | (g<<8) | b) + + + + +#define BR00_BITBLT_CLIENT 0x40000000 +#define BR00_OP_COLOR_BLT 0x10000000 +#define BR00_OP_SRC_COPY_BLT 0x10C00000 +#define BR13_SOLID_PATTERN 0x80000000 + +#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4) +#define XY_COLOR_BLT_WRITE_ALPHA (1<<21) +#define XY_COLOR_BLT_WRITE_RGB (1<<20) + +#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) +#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) +#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) + +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_regions.c b/src/mesa/drivers/dri/i915tex/intel_regions.c new file mode 100644 index 0000000000..064a34cda8 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_regions.c @@ -0,0 +1,466 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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. + * + **************************************************************************/ + +/* Provide additional functionality on top of bufmgr buffers: + * - 2d semantics and blit operations + * - refcounting of buffers for multiple images in a buffer. + * - refcounting of buffer mappings. + * - some logic for moving the buffers to the best memory pools for + * given operations. + * + * Most of this is to make it easier to implement the fixed-layout + * mipmap tree required by intel hardware in the face of GL's + * programming interface where each image can be specifed in random + * order and it isn't clear what layout the tree should have until the + * last moment. + */ + +#include "intel_context.h" +#include "intel_regions.h" +#include "intel_blit.h" +#include "intel_buffer_objects.h" +#include "dri_bufmgr.h" +#include "intel_batchbuffer.h" + +#define FILE_DEBUG_FLAG DEBUG_REGION + +void +intel_region_idle(intelScreenPrivate *intelScreen, struct intel_region *region) +{ + DBG("%s\n", __FUNCTION__); + if (region && region->buffer) + driBOWaitIdle(region->buffer, GL_FALSE); +} + +/* XXX: Thread safety? + */ +GLubyte * +intel_region_map(intelScreenPrivate *intelScreen, struct intel_region *region) +{ + DBG("%s\n", __FUNCTION__); + if (!region->map_refcount++) { + if (region->pbo) + intel_region_cow(intelScreen, region); + + region->map = driBOMap(region->buffer, + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); + } + + return region->map; +} + +void +intel_region_unmap(intelScreenPrivate *intelScreen, struct intel_region *region) +{ + DBG("%s\n", __FUNCTION__); + if (!--region->map_refcount) { + driBOUnmap(region->buffer); + region->map = NULL; + } +} + +#undef TEST_CACHED_TEXTURES + +struct intel_region * +intel_region_alloc(intelScreenPrivate *intelScreen, + GLuint cpp, GLuint pitch, GLuint height) +{ + struct intel_region *region = calloc(sizeof(*region), 1); + + DBG("%s\n", __FUNCTION__); + + region->cpp = cpp; + region->pitch = pitch; + region->height = height; /* needed? */ + region->refcount = 1; + + driGenBuffers(intelScreen->regionPool, + "region", 1, ®ion->buffer, 64, +#ifdef TEST_CACHED_TEXTURES + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_BIND_CACHED | + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, +#else + 0, +#endif + 0); + driBOData(region->buffer, pitch * cpp * height, NULL, 0); + return region; +} + +void +intel_region_reference(struct intel_region **dst, struct intel_region *src) +{ + assert(*dst == NULL); + if (src) { + src->refcount++; + *dst = src; + } +} + +void +intel_region_release(struct intel_region **region) +{ + if (!*region) + return; + + DBG("%s %d\n", __FUNCTION__, (*region)->refcount - 1); + + ASSERT((*region)->refcount > 0); + (*region)->refcount--; + + if ((*region)->refcount == 0) { + assert((*region)->map_refcount == 0); + + if ((*region)->pbo) + (*region)->pbo->region = NULL; + (*region)->pbo = NULL; + driBOUnReference((*region)->buffer); + free(*region); + } + *region = NULL; +} + + +struct intel_region * +intel_region_create_static(intelScreenPrivate *intelScreen, + GLuint mem_type, + GLuint offset, + void *virtual, + GLuint cpp, GLuint pitch, GLuint height) +{ + struct intel_region *region = calloc(sizeof(*region), 1); + DBG("%s\n", __FUNCTION__); + + region->cpp = cpp; + region->pitch = pitch; + region->height = height; /* needed? */ + region->refcount = 1; + + /* + * We use a "shared" buffer type to indicate buffers created and + * shared by others. + */ + + driGenBuffers(intelScreen->staticPool, "static region", 1, + ®ion->buffer, 64, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_NO_MOVE | + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); + driBOSetStatic(region->buffer, offset, pitch * cpp * height, virtual, 0); + + return region; +} + + + +void +intel_region_update_static(intelScreenPrivate *intelScreen, + struct intel_region *region, + GLuint mem_type, + GLuint offset, + void *virtual, + GLuint cpp, GLuint pitch, GLuint height) +{ + DBG("%s\n", __FUNCTION__); + + region->cpp = cpp; + region->pitch = pitch; + region->height = height; /* needed? */ + + /* + * We use a "shared" buffer type to indicate buffers created and + * shared by others. + */ + + driDeleteBuffers(1, ®ion->buffer); + driGenBuffers(intelScreen->staticPool, "static region", 1, + ®ion->buffer, 64, + DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_NO_MOVE | + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0); + driBOSetStatic(region->buffer, offset, pitch * cpp * height, virtual, 0); + +} + + + +/* + * XXX Move this into core Mesa? + */ +static void +_mesa_copy_rect(GLubyte * dst, + GLuint cpp, + GLuint dst_pitch, + GLuint dst_x, + GLuint dst_y, + GLuint width, + GLuint height, + GLubyte * src, GLuint src_pitch, GLuint src_x, GLuint src_y) +{ + GLuint i; + + dst_pitch *= cpp; + src_pitch *= cpp; + dst += dst_x * cpp; + src += src_x * cpp; + dst += dst_y * dst_pitch; + src += src_y * dst_pitch; + width *= cpp; + + if (width == dst_pitch && width == src_pitch) + memcpy(dst, src, height * width); + else { + for (i = 0; i < height; i++) { + memcpy(dst, src, width); + dst += dst_pitch; + src += src_pitch; + } + } +} + + +/* Upload data to a rectangular sub-region. Lots of choices how to do this: + * + * - memcpy by span to current destination + * - upload data as new buffer and blit + * + * Currently always memcpy. + */ +void +intel_region_data(intelScreenPrivate *intelScreen, + struct intel_region *dst, + GLuint dst_offset, + GLuint dstx, GLuint dsty, + void *src, GLuint src_pitch, + GLuint srcx, GLuint srcy, GLuint width, GLuint height) +{ + struct intel_context *intel = intelScreenContext(intelScreen); + + DBG("%s\n", __FUNCTION__); + + if (intel == NULL) + return; + + if (dst->pbo) { + if (dstx == 0 && + dsty == 0 && width == dst->pitch && height == dst->height) + intel_region_release_pbo(intelScreen, dst); + else + intel_region_cow(intelScreen, dst); + } + + + LOCK_HARDWARE(intel); + + _mesa_copy_rect(intel_region_map(intelScreen, dst) + dst_offset, + dst->cpp, + dst->pitch, + dstx, dsty, width, height, src, src_pitch, srcx, srcy); + + intel_region_unmap(intelScreen, dst); + + UNLOCK_HARDWARE(intel); + +} + +/* Copy rectangular sub-regions. Need better logic about when to + * push buffers into AGP - will currently do so whenever possible. + */ +void +intel_region_copy(intelScreenPrivate *intelScreen, + struct intel_region *dst, + GLuint dst_offset, + GLuint dstx, GLuint dsty, + struct intel_region *src, + GLuint src_offset, + GLuint srcx, GLuint srcy, GLuint width, GLuint height) +{ + struct intel_context *intel = intelScreenContext(intelScreen); + + DBG("%s\n", __FUNCTION__); + + if (intel == NULL) + return; + + if (dst->pbo) { + if (dstx == 0 && + dsty == 0 && width == dst->pitch && height == dst->height) + intel_region_release_pbo(intelScreen, dst); + else + intel_region_cow(intelScreen, dst); + } + + assert(src->cpp == dst->cpp); + + intelEmitCopyBlit(intel, + dst->cpp, + src->pitch, src->buffer, src_offset, + dst->pitch, dst->buffer, dst_offset, + srcx, srcy, dstx, dsty, width, height); +} + +/* Fill a rectangular sub-region. Need better logic about when to + * push buffers into AGP - will currently do so whenever possible. + */ +void +intel_region_fill(intelScreenPrivate *intelScreen, + struct intel_region *dst, + GLuint dst_offset, + GLuint dstx, GLuint dsty, + GLuint width, GLuint height, GLuint color) +{ + struct intel_context *intel = intelScreenContext(intelScreen); + + DBG("%s\n", __FUNCTION__); + + if (intel == NULL) + return; + + if (dst->pbo) { + if (dstx == 0 && + dsty == 0 && width == dst->pitch && height == dst->height) + intel_region_release_pbo(intelScreen, dst); + else + intel_region_cow(intelScreen, dst); + } + + intelEmitFillBlit(intel, + dst->cpp, + dst->pitch, dst->buffer, dst_offset, + dstx, dsty, width, height, color); +} + +/* Attach to a pbo, discarding our data. Effectively zero-copy upload + * the pbo's data. + */ +void +intel_region_attach_pbo(intelScreenPrivate *intelScreen, + struct intel_region *region, + struct intel_buffer_object *pbo) +{ + if (region->pbo == pbo) + return; + + /* If there is already a pbo attached, break the cow tie now. + * Don't call intel_region_release_pbo() as that would + * unnecessarily allocate a new buffer we would have to immediately + * discard. + */ + if (region->pbo) { + region->pbo->region = NULL; + region->pbo = NULL; + } + + if (region->buffer) { + driDeleteBuffers(1, ®ion->buffer); + region->buffer = NULL; + } + + region->pbo = pbo; + region->pbo->region = region; + region->buffer = driBOReference(pbo->buffer); +} + + +/* Break the COW tie to the pbo. The pbo gets to keep the data. + */ +void +intel_region_release_pbo(intelScreenPrivate *intelScreen, + struct intel_region *region) +{ + assert(region->buffer == region->pbo->buffer); + region->pbo->region = NULL; + region->pbo = NULL; + driBOUnReference(region->buffer); + region->buffer = NULL; + + driGenBuffers(intelScreen->regionPool, + "region", 1, ®ion->buffer, 64, 0, 0); + driBOData(region->buffer, + region->cpp * region->pitch * region->height, NULL, 0); +} + +/* Break the COW tie to the pbo. Both the pbo and the region end up + * with a copy of the data. + */ +void +intel_region_cow(intelScreenPrivate *intelScreen, struct intel_region *region) +{ + struct intel_context *intel = intelScreenContext(intelScreen); + struct intel_buffer_object *pbo = region->pbo; + + if (intel == NULL) + return; + + intel_region_release_pbo(intelScreen, region); + + assert(region->cpp * region->pitch * region->height == pbo->Base.Size); + + DBG("%s (%d bytes)\n", __FUNCTION__, pbo->Base.Size); + + /* Now blit from the texture buffer to the new buffer: + */ + + intel_batchbuffer_flush(intel->batch); + + if (!intel->locked) { + LOCK_HARDWARE(intel); + intelEmitCopyBlit(intel, + region->cpp, + region->pitch, + region->buffer, 0, + region->pitch, + pbo->buffer, 0, + 0, 0, 0, 0, region->pitch, region->height); + + intel_batchbuffer_flush(intel->batch); + UNLOCK_HARDWARE(intel); + } + else { + intelEmitCopyBlit(intel, + region->cpp, + region->pitch, + region->buffer, 0, + region->pitch, + pbo->buffer, 0, + 0, 0, 0, 0, region->pitch, region->height); + + intel_batchbuffer_flush(intel->batch); + } +} + +struct _DriBufferObject * +intel_region_buffer(intelScreenPrivate *intelScreen, + struct intel_region *region, GLuint flag) +{ + if (region->pbo) { + if (flag == INTEL_WRITE_PART) + intel_region_cow(intelScreen, region); + else if (flag == INTEL_WRITE_FULL) + intel_region_release_pbo(intelScreen, region); + } + + return region->buffer; +} diff --git a/src/mesa/drivers/dri/i915tex/intel_regions.h b/src/mesa/drivers/dri/i915tex/intel_regions.h new file mode 100644 index 0000000000..1415bace69 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_regions.h @@ -0,0 +1,141 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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. + * + **************************************************************************/ + +#ifndef INTEL_REGIONS_H +#define INTEL_REGIONS_H + +#include "mtypes.h" +#include "intel_screen.h" + +struct intel_context; +struct intel_buffer_object; + +/** + * A layer on top of the bufmgr buffers that adds a few useful things: + * + * - Refcounting for local buffer references. + * - Refcounting for buffer maps + * - Buffer dimensions - pitch and height. + * - Blitter commands for copying 2D regions between buffers. (really???) + */ +struct intel_region +{ + struct _DriBufferObject *buffer; /**< buffer manager's buffer ID */ + GLuint refcount; /**< Reference count for region */ + GLuint cpp; /**< bytes per pixel */ + GLuint pitch; /**< in pixels */ + GLuint height; /**< in pixels */ + GLubyte *map; /**< only non-NULL when region is actually mapped */ + GLuint map_refcount; /**< Reference count for mapping */ + + GLuint draw_offset; /**< Offset of drawing address within the region */ + + struct intel_buffer_object *pbo; /* zero-copy uploads */ +}; + + +/* Allocate a refcounted region. Pointers to regions should only be + * copied by calling intel_reference_region(). + */ +struct intel_region *intel_region_alloc(intelScreenPrivate *intelScreen, + GLuint cpp, + GLuint pitch, GLuint height); + +void intel_region_reference(struct intel_region **dst, + struct intel_region *src); + +void intel_region_release(struct intel_region **ib); + +extern struct intel_region +*intel_region_create_static(intelScreenPrivate *intelScreen, + GLuint mem_type, + GLuint offset, + void *virtual, + GLuint cpp, + GLuint pitch, GLuint height); +extern void +intel_region_update_static(intelScreenPrivate *intelScreen, + struct intel_region *region, + GLuint mem_type, + GLuint offset, + void *virtual, + GLuint cpp, GLuint pitch, GLuint height); + + +void intel_region_idle(intelScreenPrivate *intelScreen, + struct intel_region *ib); + +/* Map/unmap regions. This is refcounted also: + */ +GLubyte *intel_region_map(intelScreenPrivate *intelScreen, + struct intel_region *ib); + +void intel_region_unmap(intelScreenPrivate *intelScreen, struct intel_region *ib); + + +/* Upload data to a rectangular sub-region + */ +void intel_region_data(intelScreenPrivate *intelScreen, + struct intel_region *dest, + GLuint dest_offset, + GLuint destx, GLuint desty, + void *src, GLuint src_stride, + GLuint srcx, GLuint srcy, GLuint width, GLuint height); + +/* Copy rectangular sub-regions + */ +void intel_region_copy(intelScreenPrivate *intelScreen, + struct intel_region *dest, + GLuint dest_offset, + GLuint destx, GLuint desty, + struct intel_region *src, + GLuint src_offset, + GLuint srcx, GLuint srcy, GLuint width, GLuint height); + +/* Fill a rectangular sub-region + */ +void intel_region_fill(intelScreenPrivate *intelScreen, + struct intel_region *dest, + GLuint dest_offset, + GLuint destx, GLuint desty, + GLuint width, GLuint height, GLuint color); + +/* Helpers for zerocopy uploads, particularly texture image uploads: + */ +void intel_region_attach_pbo(intelScreenPrivate *intelScreen, + struct intel_region *region, + struct intel_buffer_object *pbo); +void intel_region_release_pbo(intelScreenPrivate *intelScreen, + struct intel_region *region); +void intel_region_cow(intelScreenPrivate *intelScreen, + struct intel_region *region); + +struct _DriBufferObject *intel_region_buffer(intelScreenPrivate *intelScreen, + struct intel_region *region, + GLuint flag); + +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_render.c b/src/mesa/drivers/dri/i915tex/intel_render.c new file mode 100644 index 0000000000..f9fa55051e --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_render.c @@ -0,0 +1,242 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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. + * + **************************************************************************/ + +/* + * Render unclipped vertex buffers by emitting vertices directly to + * dma buffers. Use strip/fan hardware acceleration where possible. + * + */ +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "imports.h" +#include "mtypes.h" +#include "enums.h" + +#include "tnl/t_context.h" +#include "tnl/t_vertex.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_tris.h" +#include "intel_batchbuffer.h" +#include "intel_reg.h" + +/* + * Render unclipped vertex buffers by emitting vertices directly to + * dma buffers. Use strip/fan hardware primitives where possible. + * Try to simulate missing primitives with indexed vertices. + */ +#define HAVE_POINTS 0 /* Has it, but can't use because subpixel has to + * be adjusted for points on the INTEL/I845G + */ +#define HAVE_LINES 1 +#define HAVE_LINE_STRIPS 1 +#define HAVE_TRIANGLES 1 +#define HAVE_TRI_STRIPS 1 +#define HAVE_TRI_STRIP_1 0 /* has it, template can't use it yet */ +#define HAVE_TRI_FANS 1 +#define HAVE_POLYGONS 1 +#define HAVE_QUADS 0 +#define HAVE_QUAD_STRIPS 0 + +#define HAVE_ELTS 0 + +static GLuint hw_prim[GL_POLYGON + 1] = { + 0, + PRIM3D_LINELIST, + PRIM3D_LINESTRIP, + PRIM3D_LINESTRIP, + PRIM3D_TRILIST, + PRIM3D_TRISTRIP, + PRIM3D_TRIFAN, + 0, + 0, + PRIM3D_POLY +}; + +static const GLenum reduced_prim[GL_POLYGON + 1] = { + GL_POINTS, + GL_LINES, + GL_LINES, + GL_LINES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES +}; + +static const int scale_prim[GL_POLYGON + 1] = { + 0, /* fallback case */ + 1, + 2, + 2, + 1, + 3, + 3, + 0, /* fallback case */ + 0, /* fallback case */ + 3 +}; + + +static void +intelDmaPrimitive(struct intel_context *intel, GLenum prim) +{ + if (0) + fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(prim)); + INTEL_FIREVERTICES(intel); + intel->vtbl.reduced_primitive_state(intel, reduced_prim[prim]); + intelStartInlinePrimitive(intel, hw_prim[prim], INTEL_BATCH_CLIPRECTS); +} + + +#define LOCAL_VARS struct intel_context *intel = intel_context(ctx) +#define INIT( prim ) \ +do { \ + intelDmaPrimitive( intel, prim ); \ +} while (0) + +#define FLUSH() INTEL_FIREVERTICES(intel) + +#define GET_SUBSEQUENT_VB_MAX_VERTS() \ + ((intel->batch->size - 1500) / (intel->vertex_size*4)) +#define GET_CURRENT_VB_MAX_VERTS() GET_SUBSEQUENT_VB_MAX_VERTS() + +#define ALLOC_VERTS( nr ) \ + intelExtendInlinePrimitive( intel, (nr) * intel->vertex_size ) + +#define EMIT_VERTS( ctx, j, nr, buf ) \ + _tnl_emit_vertices_to_buffer(ctx, j, (j)+(nr), buf ) + +#define TAG(x) intel_##x +#include "tnl_dd/t_dd_dmatmp.h" + + +/**********************************************************************/ +/* Render pipeline stage */ +/**********************************************************************/ + +/* Heuristic to choose between the two render paths: + */ +static GLboolean +choose_render(struct intel_context *intel, struct vertex_buffer *VB) +{ + int vertsz = intel->vertex_size; + int cost_render = 0; + int cost_fallback = 0; + int nr_prims = 0; + int nr_rprims = 0; + int nr_rverts = 0; + int rprim = intel->reduced_primitive; + int i = 0; + + for (i = 0; i < VB->PrimitiveCount; i++) { + GLuint prim = VB->Primitive[i].mode; + GLuint length = VB->Primitive[i].count; + + if (!length) + continue; + + nr_prims++; + nr_rverts += length * scale_prim[prim & PRIM_MODE_MASK]; + + if (reduced_prim[prim & PRIM_MODE_MASK] != rprim) { + nr_rprims++; + rprim = reduced_prim[prim & PRIM_MODE_MASK]; + } + } + + /* One point for each generated primitive: + */ + cost_render = nr_prims; + cost_fallback = nr_rprims; + + /* One point for every 1024 dwords (4k) of dma: + */ + cost_render += (vertsz * i) / 1024; + cost_fallback += (vertsz * nr_rverts) / 1024; + + if (0) + fprintf(stderr, "cost render: %d fallback: %d\n", + cost_render, cost_fallback); + + if (cost_render > cost_fallback) + return GL_FALSE; + + return GL_TRUE; +} + + +static GLboolean +intel_run_render(GLcontext * ctx, struct tnl_pipeline_stage *stage) +{ + struct intel_context *intel = intel_context(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint i; + + /* Don't handle clipping or indexed vertices. + */ + if (intel->RenderIndex != 0 || + !intel_validate_render(ctx, VB) || !choose_render(intel, VB)) { + return GL_TRUE; + } + + tnl->clipspace.new_inputs |= VERT_BIT_POS; + + tnl->Driver.Render.Start(ctx); + + for (i = 0; i < VB->PrimitiveCount; i++) { + GLuint prim = VB->Primitive[i].mode; + GLuint start = VB->Primitive[i].start; + GLuint length = VB->Primitive[i].count; + + if (!length) + continue; + + intel_render_tab_verts[prim & PRIM_MODE_MASK] (ctx, start, + start + length, prim); + } + + tnl->Driver.Render.Finish(ctx); + + INTEL_FIREVERTICES(intel); + + return GL_FALSE; /* finished the pipe */ +} + +const struct tnl_pipeline_stage _intel_render_stage = { + "intel render", + NULL, + NULL, + NULL, + NULL, + intel_run_render /* run */ +}; diff --git a/src/mesa/drivers/dri/i915tex/intel_rotate.c b/src/mesa/drivers/dri/i915tex/intel_rotate.c new file mode 100644 index 0000000000..12d98c4ad2 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_rotate.c @@ -0,0 +1,237 @@ + +/** + * Routines for simple 2D->2D transformations for rotated, flipped screens. + * + * XXX This code is not intel-specific. Move it into a common/utility + * someday. + */ + +#include "intel_rotate.h" + +#define MIN2(A, B) ( ((A) < (B)) ? (A) : (B) ) + +#define ABS(A) ( ((A) < 0) ? -(A) : (A) ) + + +void +matrix23Set(struct matrix23 *m, + int m00, int m01, int m02, int m10, int m11, int m12) +{ + m->m00 = m00; + m->m01 = m01; + m->m02 = m02; + m->m10 = m10; + m->m11 = m11; + m->m12 = m12; +} + + +/* + * Transform (x,y) coordinate by the given matrix. + */ +void +matrix23TransformCoordf(const struct matrix23 *m, float *x, float *y) +{ + const float x0 = *x; + const float y0 = *y; + + *x = m->m00 * x0 + m->m01 * y0 + m->m02; + *y = m->m10 * x0 + m->m11 * y0 + m->m12; +} + + +void +matrix23TransformCoordi(const struct matrix23 *m, int *x, int *y) +{ + const int x0 = *x; + const int y0 = *y; + + *x = m->m00 * x0 + m->m01 * y0 + m->m02; + *y = m->m10 * x0 + m->m11 * y0 + m->m12; +} + + +/* + * Transform a width and height by the given matrix. + * XXX this could be optimized quite a bit. + */ +void +matrix23TransformDistance(const struct matrix23 *m, int *xDist, int *yDist) +{ + int x0 = 0, y0 = 0; + int x1 = *xDist, y1 = 0; + int x2 = 0, y2 = *yDist; + matrix23TransformCoordi(m, &x0, &y0); + matrix23TransformCoordi(m, &x1, &y1); + matrix23TransformCoordi(m, &x2, &y2); + + *xDist = (x1 - x0) + (x2 - x0); + *yDist = (y1 - y0) + (y2 - y0); + + if (*xDist < 0) + *xDist = -*xDist; + if (*yDist < 0) + *yDist = -*yDist; +} + + +/** + * Transform the rect defined by (x, y, w, h) by m. + */ +void +matrix23TransformRect(const struct matrix23 *m, int *x, int *y, int *w, + int *h) +{ + int x0 = *x, y0 = *y; + int x1 = *x + *w, y1 = *y; + int x2 = *x + *w, y2 = *y + *h; + int x3 = *x, y3 = *y + *h; + matrix23TransformCoordi(m, &x0, &y0); + matrix23TransformCoordi(m, &x1, &y1); + matrix23TransformCoordi(m, &x2, &y2); + matrix23TransformCoordi(m, &x3, &y3); + *w = ABS(x1 - x0) + ABS(x2 - x1); + /**w = ABS(*w);*/ + *h = ABS(y1 - y0) + ABS(y2 - y1); + /**h = ABS(*h);*/ + *x = MIN2(x0, x1); + *x = MIN2(*x, x2); + *y = MIN2(y0, y1); + *y = MIN2(*y, y2); +} + + +/* + * Make rotation matrix for width X height screen. + */ +void +matrix23Rotate(struct matrix23 *m, int width, int height, int angle) +{ + switch (angle) { + case 0: + matrix23Set(m, 1, 0, 0, 0, 1, 0); + break; + case 90: + matrix23Set(m, 0, 1, 0, -1, 0, width); + break; + case 180: + matrix23Set(m, -1, 0, width, 0, -1, height); + break; + case 270: + matrix23Set(m, 0, -1, height, 1, 0, 0); + break; + default: + /*abort() */ ; + } +} + + +/* + * Make flip/reflection matrix for width X height screen. + */ +void +matrix23Flip(struct matrix23 *m, int width, int height, int xflip, int yflip) +{ + if (xflip) { + m->m00 = -1; + m->m01 = 0; + m->m02 = width - 1; + } + else { + m->m00 = 1; + m->m01 = 0; + m->m02 = 0; + } + if (yflip) { + m->m10 = 0; + m->m11 = -1; + m->m12 = height - 1; + } + else { + m->m10 = 0; + m->m11 = 1; + m->m12 = 0; + } +} + + +/* + * result = a * b + */ +void +matrix23Multiply(struct matrix23 *result, + const struct matrix23 *a, const struct matrix23 *b) +{ + result->m00 = a->m00 * b->m00 + a->m01 * b->m10; + result->m01 = a->m00 * b->m01 + a->m01 * b->m11; + result->m02 = a->m00 * b->m02 + a->m01 * b->m12 + a->m02; + + result->m10 = a->m10 * b->m00 + a->m11 * b->m10; + result->m11 = a->m10 * b->m01 + a->m11 * b->m11; + result->m12 = a->m10 * b->m02 + a->m11 * b->m12 + a->m12; +} + + +#if 000 + +#include + +int +main(int argc, char *argv[]) +{ + int width = 500, height = 400; + int rot; + int fx = 0, fy = 0; /* flip x and/or y ? */ + int coords[4][2]; + + /* four corner coords to test with */ + coords[0][0] = 0; + coords[0][1] = 0; + coords[1][0] = width - 1; + coords[1][1] = 0; + coords[2][0] = width - 1; + coords[2][1] = height - 1; + coords[3][0] = 0; + coords[3][1] = height - 1; + + + for (rot = 0; rot < 360; rot += 90) { + struct matrix23 rotate, flip, m; + int i; + + printf("Rot %d, xFlip %d, yFlip %d:\n", rot, fx, fy); + + /* make transformation matrix 'm' */ + matrix23Rotate(&rotate, width, height, rot); + matrix23Flip(&flip, width, height, fx, fy); + matrix23Multiply(&m, &rotate, &flip); + + /* xform four coords */ + for (i = 0; i < 4; i++) { + int x = coords[i][0]; + int y = coords[i][1]; + matrix23TransformCoordi(&m, &x, &y); + printf(" %d, %d -> %d %d\n", coords[i][0], coords[i][1], x, y); + } + + /* xform width, height */ + { + int x = width; + int y = height; + matrix23TransformDistance(&m, &x, &y); + printf(" %d x %d -> %d x %d\n", width, height, x, y); + } + + /* xform rect */ + { + int x = 50, y = 10, w = 200, h = 100; + matrix23TransformRect(&m, &x, &y, &w, &h); + printf(" %d,%d %d x %d -> %d, %d %d x %d\n", 50, 10, 200, 100, + x, y, w, h); + } + + } + + return 0; +} +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_rotate.h b/src/mesa/drivers/dri/i915tex/intel_rotate.h new file mode 100644 index 0000000000..9c8802ca47 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_rotate.h @@ -0,0 +1,39 @@ +#ifndef INTEL_ROTATE_H +#define INTEL_ROTATE_H 1 + +struct matrix23 +{ + int m00, m01, m02; + int m10, m11, m12; +}; + + + +extern void +matrix23Set(struct matrix23 *m, + int m00, int m01, int m02, int m10, int m11, int m12); + +extern void matrix23TransformCoordi(const struct matrix23 *m, int *x, int *y); + +extern void +matrix23TransformCoordf(const struct matrix23 *m, float *x, float *y); + +extern void +matrix23TransformDistance(const struct matrix23 *m, int *xDist, int *yDist); + +extern void +matrix23TransformRect(const struct matrix23 *m, + int *x, int *y, int *w, int *h); + +extern void +matrix23Rotate(struct matrix23 *m, int width, int height, int angle); + +extern void +matrix23Flip(struct matrix23 *m, int width, int height, int xflip, int yflip); + +extern void +matrix23Multiply(struct matrix23 *result, + const struct matrix23 *a, const struct matrix23 *b); + + +#endif /* INTEL_ROTATE_H */ diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c new file mode 100644 index 0000000000..9bbfabbb8c --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_screen.c @@ -0,0 +1,864 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "glheader.h" +#include "context.h" +#include "framebuffer.h" +#include "matrix.h" +#include "renderbuffer.h" +#include "simple_list.h" +#include "utils.h" +#include "vblank.h" +#include "xmlpool.h" + + +#include "intel_screen.h" + +#include "intel_buffers.h" +#include "intel_tex.h" +#include "intel_span.h" +#include "intel_tris.h" +#include "intel_ioctl.h" +#include "intel_fbo.h" + +#include "i830_dri.h" +#include "dri_bufpool.h" +#include "intel_regions.h" +#include "intel_batchbuffer.h" + +PUBLIC const char __driConfigOptions[] = + DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE + DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) + DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) + DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY + DRI_CONF_FORCE_S3TC_ENABLE(false) + DRI_CONF_ALLOW_LARGE_TEXTURES(1) + DRI_CONF_SECTION_END DRI_CONF_END; + const GLuint __driNConfigOptions = 4; + +#ifdef USE_NEW_INTERFACE + static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; +#endif /*USE_NEW_INTERFACE */ + + extern const struct dri_extension card_extensions[]; + +/** + * Map all the memory regions described by the screen. + * \return GL_TRUE if success, GL_FALSE if error. + */ +GLboolean +intelMapScreenRegions(__DRIscreenPrivate * sPriv) +{ + intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; + + if (intelScreen->front.handle) { + if (drmMap(sPriv->fd, + intelScreen->front.handle, + intelScreen->front.size, + (drmAddress *) & intelScreen->front.map) != 0) { + _mesa_problem(NULL, "drmMap(frontbuffer) failed!"); + return GL_FALSE; + } + } + else { + _mesa_warning(NULL, "no front buffer handle in intelMapScreenRegions!"); + } + + if (0) + _mesa_printf("Back 0x%08x ", intelScreen->back.handle); + if (drmMap(sPriv->fd, + intelScreen->back.handle, + intelScreen->back.size, + (drmAddress *) & intelScreen->back.map) != 0) { + intelUnmapScreenRegions(intelScreen); + return GL_FALSE; + } + + if (0) + _mesa_printf("Depth 0x%08x ", intelScreen->depth.handle); + if (drmMap(sPriv->fd, + intelScreen->depth.handle, + intelScreen->depth.size, + (drmAddress *) & intelScreen->depth.map) != 0) { + intelUnmapScreenRegions(intelScreen); + return GL_FALSE; + } + +#if 0 + _mesa_printf("TEX 0x%08x ", intelScreen->tex.handle); + if (drmMap(sPriv->fd, + intelScreen->tex.handle, + intelScreen->tex.size, + (drmAddress *) & intelScreen->tex.map) != 0) { + intelUnmapScreenRegions(intelScreen); + return GL_FALSE; + } +#endif + if (0) + printf("Mappings: front: %p back: %p depth: %p tex: %p\n", + intelScreen->front.map, + intelScreen->back.map, + intelScreen->depth.map, intelScreen->tex.map); + return GL_TRUE; +} + + +static struct intel_region * +intel_recreate_static(intelScreenPrivate *intelScreen, + struct intel_region *region, + GLuint mem_type, + GLuint offset, + void *virtual, + GLuint cpp, GLuint pitch, GLuint height) +{ + if (region) { + intel_region_update_static(intelScreen, region, mem_type, offset, + virtual, cpp, pitch, height); + } else { + region = intel_region_create_static(intelScreen, mem_type, offset, + virtual, cpp, pitch, height); + } + return region; +} + + +/* Create intel_region structs to describe the static front,back,depth + * buffers created by the xserver. + * + * Although FBO's mean we now no longer use these as render targets in + * all circumstances, they won't go away until the back and depth + * buffers become private, and the front and rotated buffers will + * remain even then. + * + * Note that these don't allocate video memory, just describe + * allocations alread made by the X server. + */ +static void +intel_recreate_static_regions(intelScreenPrivate *intelScreen) +{ + intelScreen->front_region = + intel_recreate_static(intelScreen, + intelScreen->front_region, + DRM_BO_FLAG_MEM_TT, + intelScreen->front.offset, + intelScreen->front.map, + intelScreen->cpp, + intelScreen->front.pitch / intelScreen->cpp, + intelScreen->height); + + intelScreen->rotated_region = + intel_recreate_static(intelScreen, + intelScreen->rotated_region, + DRM_BO_FLAG_MEM_TT, + intelScreen->rotated.offset, + intelScreen->rotated.map, + intelScreen->cpp, + intelScreen->rotated.pitch / + intelScreen->cpp, intelScreen->height); + + + intelScreen->back_region = + intel_recreate_static(intelScreen, + intelScreen->back_region, + DRM_BO_FLAG_MEM_TT, + intelScreen->back.offset, + intelScreen->back.map, + intelScreen->cpp, + intelScreen->back.pitch / intelScreen->cpp, + intelScreen->height); + + /* Still assuming front.cpp == depth.cpp + */ + intelScreen->depth_region = + intel_recreate_static(intelScreen, + intelScreen->depth_region, + DRM_BO_FLAG_MEM_TT, + intelScreen->depth.offset, + intelScreen->depth.map, + intelScreen->cpp, + intelScreen->depth.pitch / intelScreen->cpp, + intelScreen->height); +} + +/** + * Use the information in the sarea to update the screen parameters + * related to screen rotation. Needs to be called locked. + */ +void +intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea) +{ + intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; + + intelUnmapScreenRegions(intelScreen); + intelUpdateScreenFromSAREA(intelScreen, sarea); + if (!intelMapScreenRegions(sPriv)) { + fprintf(stderr, "ERROR Remapping screen regions!!!\n"); + } + intel_recreate_static_regions(intelScreen); +} + + +void +intelUnmapScreenRegions(intelScreenPrivate * intelScreen) +{ +#define REALLY_UNMAP 1 + if (intelScreen->front.map) { +#if REALLY_UNMAP + if (drmUnmap(intelScreen->front.map, intelScreen->front.size) != 0) + printf("drmUnmap front failed!\n"); +#endif + intelScreen->front.map = NULL; + } + if (intelScreen->back.map) { +#if REALLY_UNMAP + if (drmUnmap(intelScreen->back.map, intelScreen->back.size) != 0) + printf("drmUnmap back failed!\n"); +#endif + intelScreen->back.map = NULL; + } + if (intelScreen->depth.map) { +#if REALLY_UNMAP + drmUnmap(intelScreen->depth.map, intelScreen->depth.size); + intelScreen->depth.map = NULL; +#endif + } + if (intelScreen->tex.map) { +#if REALLY_UNMAP + drmUnmap(intelScreen->tex.map, intelScreen->tex.size); + intelScreen->tex.map = NULL; +#endif + } +} + + +static void +intelPrintDRIInfo(intelScreenPrivate * intelScreen, + __DRIscreenPrivate * sPriv, I830DRIPtr gDRIPriv) +{ + fprintf(stderr, "*** Front size: 0x%x offset: 0x%x pitch: %d\n", + intelScreen->front.size, intelScreen->front.offset, + intelScreen->front.pitch); + fprintf(stderr, "*** Back size: 0x%x offset: 0x%x pitch: %d\n", + intelScreen->back.size, intelScreen->back.offset, + intelScreen->back.pitch); + fprintf(stderr, "*** Depth size: 0x%x offset: 0x%x pitch: %d\n", + intelScreen->depth.size, intelScreen->depth.offset, + intelScreen->depth.pitch); + fprintf(stderr, "*** Rotated size: 0x%x offset: 0x%x pitch: %d\n", + intelScreen->rotated.size, intelScreen->rotated.offset, + intelScreen->rotated.pitch); + fprintf(stderr, "*** Texture size: 0x%x offset: 0x%x\n", + intelScreen->tex.size, intelScreen->tex.offset); + fprintf(stderr, "*** Memory : 0x%x\n", gDRIPriv->mem); +} + + +static void +intelPrintSAREA(const drmI830Sarea * sarea) +{ + fprintf(stderr, "SAREA: sarea width %d height %d\n", sarea->width, + sarea->height); + fprintf(stderr, "SAREA: pitch: %d\n", sarea->pitch); + fprintf(stderr, + "SAREA: front offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->front_offset, sarea->front_size, + (unsigned) sarea->front_handle); + fprintf(stderr, + "SAREA: back offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->back_offset, sarea->back_size, + (unsigned) sarea->back_handle); + fprintf(stderr, "SAREA: depth offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->depth_offset, sarea->depth_size, + (unsigned) sarea->depth_handle); + fprintf(stderr, "SAREA: tex offset: 0x%08x size: 0x%x handle: 0x%x\n", + sarea->tex_offset, sarea->tex_size, (unsigned) sarea->tex_handle); + fprintf(stderr, "SAREA: rotation: %d\n", sarea->rotation); + fprintf(stderr, + "SAREA: rotated offset: 0x%08x size: 0x%x\n", + sarea->rotated_offset, sarea->rotated_size); + fprintf(stderr, "SAREA: rotated pitch: %d\n", sarea->rotated_pitch); +} + + +/** + * A number of the screen parameters are obtained/computed from + * information in the SAREA. This function updates those parameters. + */ +void +intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen, + drmI830Sarea * sarea) +{ + intelScreen->width = sarea->width; + intelScreen->height = sarea->height; + + intelScreen->front.offset = sarea->front_offset; + intelScreen->front.pitch = sarea->pitch * intelScreen->cpp; + intelScreen->front.handle = sarea->front_handle; + intelScreen->front.size = sarea->front_size; + + intelScreen->back.offset = sarea->back_offset; + intelScreen->back.pitch = sarea->pitch * intelScreen->cpp; + intelScreen->back.handle = sarea->back_handle; + intelScreen->back.size = sarea->back_size; + + intelScreen->depth.offset = sarea->depth_offset; + intelScreen->depth.pitch = sarea->pitch * intelScreen->cpp; + intelScreen->depth.handle = sarea->depth_handle; + intelScreen->depth.size = sarea->depth_size; + + intelScreen->tex.offset = sarea->tex_offset; + intelScreen->logTextureGranularity = sarea->log_tex_granularity; + intelScreen->tex.handle = sarea->tex_handle; + intelScreen->tex.size = sarea->tex_size; + + intelScreen->rotated.offset = sarea->rotated_offset; + intelScreen->rotated.pitch = sarea->rotated_pitch * intelScreen->cpp; + intelScreen->rotated.size = sarea->rotated_size; + intelScreen->current_rotation = sarea->rotation; + matrix23Rotate(&intelScreen->rotMatrix, + sarea->width, sarea->height, sarea->rotation); + intelScreen->rotatedWidth = sarea->virtualX; + intelScreen->rotatedHeight = sarea->virtualY; + + if (0) + intelPrintSAREA(sarea); +} + + +static GLboolean +intelInitDriver(__DRIscreenPrivate * sPriv) +{ + intelScreenPrivate *intelScreen; + I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv; + drmI830Sarea *sarea; + unsigned batchPoolSize = 1024*1024; + + PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = + (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface-> + getProcAddress("glxEnableExtension")); + void *const psc = sPriv->psc->screenConfigs; + + if (sPriv->devPrivSize != sizeof(I830DRIRec)) { + fprintf(stderr, + "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n"); + return GL_FALSE; + } + + /* Allocate the private area */ + intelScreen = (intelScreenPrivate *) CALLOC(sizeof(intelScreenPrivate)); + if (!intelScreen) { + fprintf(stderr, "\nERROR! Allocating private area failed\n"); + return GL_FALSE; + } + /* parse information in __driConfigOptions */ + driParseOptionInfo(&intelScreen->optionCache, + __driConfigOptions, __driNConfigOptions); + + intelScreen->driScrnPriv = sPriv; + sPriv->private = (void *) intelScreen; + intelScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset; + sarea = (drmI830Sarea *) + (((GLubyte *) sPriv->pSAREA) + intelScreen->sarea_priv_offset); + + intelScreen->maxBatchSize = BATCH_SZ; + intelScreen->deviceID = gDRIPriv->deviceID; + if (intelScreen->deviceID == PCI_CHIP_I865_G) + intelScreen->maxBatchSize = 4096; + batchPoolSize /= intelScreen->maxBatchSize; + + intelScreen->mem = gDRIPriv->mem; + intelScreen->cpp = gDRIPriv->cpp; + + switch (gDRIPriv->bitsPerPixel) { + case 16: + intelScreen->fbFormat = DV_PF_565; + break; + case 32: + intelScreen->fbFormat = DV_PF_8888; + break; + default: + exit(1); + break; + } + + intelUpdateScreenFromSAREA(intelScreen, sarea); + + if (!intelMapScreenRegions(sPriv)) { + fprintf(stderr, "\nERROR! mapping regions\n"); + _mesa_free(intelScreen); + sPriv->private = NULL; + return GL_FALSE; + } + +#if 0 + + /* + * FIXME: Remove this code and its references. + */ + + intelScreen->tex.offset = gDRIPriv->textureOffset; + intelScreen->logTextureGranularity = gDRIPriv->logTextureGranularity; + intelScreen->tex.handle = gDRIPriv->textures; + intelScreen->tex.size = gDRIPriv->textureSize; + +#else + intelScreen->tex.offset = 0; + intelScreen->logTextureGranularity = 0; + intelScreen->tex.handle = 0; + intelScreen->tex.size = 0; +#endif + + intelScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset; + + if (0) + intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv); + + intelScreen->drmMinor = sPriv->drmMinor; + + /* Determine if IRQs are active? */ + { + int ret; + drmI830GetParam gp; + + gp.param = I830_PARAM_IRQ_ACTIVE; + gp.value = &intelScreen->irq_active; + + ret = drmCommandWriteRead(sPriv->fd, DRM_I830_GETPARAM, + &gp, sizeof(gp)); + if (ret) { + fprintf(stderr, "drmI830GetParam: %d\n", ret); + return GL_FALSE; + } + } + + /* Determine if batchbuffers are allowed */ + { + int ret; + drmI830GetParam gp; + + gp.param = I830_PARAM_ALLOW_BATCHBUFFER; + gp.value = &intelScreen->allow_batchbuffer; + + ret = drmCommandWriteRead(sPriv->fd, DRM_I830_GETPARAM, + &gp, sizeof(gp)); + if (ret) { + fprintf(stderr, "drmI830GetParam: (%d) %d\n", gp.param, ret); + return GL_FALSE; + } + } + + if (glx_enable_extension != NULL) { + (*glx_enable_extension) (psc, "GLX_SGI_swap_control"); + (*glx_enable_extension) (psc, "GLX_SGI_video_sync"); + (*glx_enable_extension) (psc, "GLX_MESA_swap_control"); + (*glx_enable_extension) (psc, "GLX_MESA_swap_frame_usage"); + (*glx_enable_extension) (psc, "GLX_SGI_make_current_read"); + } + + intelScreen->regionPool = driDRMPoolInit(sPriv->fd); + + if (!intelScreen->regionPool) + return GL_FALSE; + + intelScreen->staticPool = driDRMStaticPoolInit(sPriv->fd); + + if (!intelScreen->staticPool) + return GL_FALSE; + + intelScreen->texPool = intelScreen->regionPool; + + intelScreen->batchPool = driBatchPoolInit(sPriv->fd, + DRM_BO_FLAG_EXE | + DRM_BO_FLAG_MEM_TT | + DRM_BO_FLAG_MEM_LOCAL, + intelScreen->maxBatchSize, + batchPoolSize, 5); + if (!intelScreen->batchPool) { + fprintf(stderr, "Failed to initialize batch pool - possible incorrect agpgart installed\n"); + return GL_FALSE; + } + + intel_recreate_static_regions(intelScreen); + + return GL_TRUE; +} + + +static void +intelDestroyScreen(__DRIscreenPrivate * sPriv) +{ + intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; + + intelUnmapScreenRegions(intelScreen); + + driPoolTakeDown(intelScreen->regionPool); + driPoolTakeDown(intelScreen->staticPool); + driPoolTakeDown(intelScreen->batchPool); + FREE(intelScreen); + sPriv->private = NULL; +} + + +/** + * This is called when we need to set up GL rendering to a new X window. + */ +static GLboolean +intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, + __DRIdrawablePrivate * driDrawPriv, + const __GLcontextModes * mesaVis, GLboolean isPixmap) +{ + intelScreenPrivate *screen = (intelScreenPrivate *) driScrnPriv->private; + + if (isPixmap) { + return GL_FALSE; /* not implemented */ + } + else { + GLboolean swStencil = (mesaVis->stencilBits > 0 && + mesaVis->depthBits != 24); + GLenum rgbFormat = (mesaVis->redBits == 5 ? GL_RGB5 : GL_RGBA8); + + struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis); + + /* setup the hardware-based renderbuffers */ + { + struct intel_renderbuffer *frontRb + = intel_create_renderbuffer(rgbFormat, + screen->width, screen->height, + screen->front.offset, + screen->front.pitch, + screen->cpp, + screen->front.map); + intel_set_span_functions(&frontRb->Base); + _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base); + } + + if (mesaVis->doubleBufferMode) { + struct intel_renderbuffer *backRb + = intel_create_renderbuffer(rgbFormat, + screen->width, screen->height, + screen->back.offset, + screen->back.pitch, + screen->cpp, + screen->back.map); + intel_set_span_functions(&backRb->Base); + _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base); + } + + if (mesaVis->depthBits == 24 && mesaVis->stencilBits == 8) { + /* combined depth/stencil buffer */ + struct intel_renderbuffer *depthStencilRb + = intel_create_renderbuffer(GL_DEPTH24_STENCIL8_EXT, + screen->width, screen->height, + screen->depth.offset, + screen->depth.pitch, + screen->cpp, /* 4! */ + screen->depth.map); + intel_set_span_functions(&depthStencilRb->Base); + /* note: bind RB to two attachment points */ + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthStencilRb->Base); + _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &depthStencilRb->Base); + } + else if (mesaVis->depthBits == 16) { + /* just 16-bit depth buffer, no hw stencil */ + struct intel_renderbuffer *depthRb + = intel_create_renderbuffer(GL_DEPTH_COMPONENT16, + screen->width, screen->height, + screen->depth.offset, + screen->depth.pitch, + screen->cpp, /* 2! */ + screen->depth.map); + intel_set_span_functions(&depthRb->Base); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base); + } + + /* now add any/all software-based renderbuffers we may need */ + _mesa_add_soft_renderbuffers(fb, GL_FALSE, /* never sw color */ + GL_FALSE, /* never sw depth */ + swStencil, mesaVis->accumRedBits > 0, GL_FALSE, /* never sw alpha */ + GL_FALSE /* never sw aux */ ); + driDrawPriv->driverPrivate = (void *) fb; + + return (driDrawPriv->driverPrivate != NULL); + } +} + +static void +intelDestroyBuffer(__DRIdrawablePrivate * driDrawPriv) +{ + _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); +} + + +/** + * Get information about previous buffer swaps. + */ +static int +intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo) +{ + struct intel_context *intel; + + if ((dPriv == NULL) || (dPriv->driContextPriv == NULL) + || (dPriv->driContextPriv->driverPrivate == NULL) + || (sInfo == NULL)) { + return -1; + } + + intel = dPriv->driContextPriv->driverPrivate; + sInfo->swap_count = intel->swap_count; + sInfo->swap_ust = intel->swap_ust; + sInfo->swap_missed_count = intel->swap_missed_count; + + sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0) + ? driCalculateSwapUsage(dPriv, 0, intel->swap_missed_ust) + : 0.0; + + return 0; +} + + +/* There are probably better ways to do this, such as an + * init-designated function to register chipids and createcontext + * functions. + */ +extern GLboolean i830CreateContext(const __GLcontextModes * mesaVis, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate); + +extern GLboolean i915CreateContext(const __GLcontextModes * mesaVis, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate); + + + + +static GLboolean +intelCreateContext(const __GLcontextModes * mesaVis, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate) +{ + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; + + switch (intelScreen->deviceID) { + /* Don't deal with i830 until texture work complete: + */ + case PCI_CHIP_845_G: + case PCI_CHIP_I830_M: + case PCI_CHIP_I855_GM: + case PCI_CHIP_I865_G: + return i830CreateContext(mesaVis, driContextPriv, sharedContextPrivate); + + case PCI_CHIP_I915_G: + case PCI_CHIP_I915_GM: + case PCI_CHIP_I945_G: + case PCI_CHIP_I945_GM: + return i915CreateContext(mesaVis, driContextPriv, sharedContextPrivate); + + default: + fprintf(stderr, "Unrecognized deviceID %x\n", intelScreen->deviceID); + return GL_FALSE; + } +} + + +static const struct __DriverAPIRec intelAPI = { + .InitDriver = intelInitDriver, + .DestroyScreen = intelDestroyScreen, + .CreateContext = intelCreateContext, + .DestroyContext = intelDestroyContext, + .CreateBuffer = intelCreateBuffer, + .DestroyBuffer = intelDestroyBuffer, + .SwapBuffers = intelSwapBuffers, + .MakeCurrent = intelMakeCurrent, + .UnbindContext = intelUnbindContext, + .GetSwapInfo = intelGetSwapInfo, + .GetMSC = driGetMSC32, + .WaitForMSC = driWaitForMSC32, + .WaitForSBC = NULL, + .SwapBuffersMSC = NULL, + .CopySubBuffer = intelCopySubBuffer +}; + + +static __GLcontextModes * +intelFillInModes(unsigned pixel_bits, unsigned depth_bits, + unsigned stencil_bits, GLboolean have_back_buffer) +{ + __GLcontextModes *modes; + __GLcontextModes *m; + unsigned num_modes; + unsigned depth_buffer_factor; + unsigned back_buffer_factor; + GLenum fb_format; + GLenum fb_type; + + /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't + * support pageflipping at all. + */ + static const GLenum back_buffer_modes[] = { + GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML + }; + + u_int8_t depth_bits_array[3]; + u_int8_t stencil_bits_array[3]; + + + depth_bits_array[0] = 0; + depth_bits_array[1] = depth_bits; + depth_bits_array[2] = depth_bits; + + /* Just like with the accumulation buffer, always provide some modes + * with a stencil buffer. It will be a sw fallback, but some apps won't + * care about that. + */ + stencil_bits_array[0] = 0; + stencil_bits_array[1] = 0; + stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits; + + depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1; + back_buffer_factor = (have_back_buffer) ? 3 : 1; + + num_modes = depth_buffer_factor * back_buffer_factor * 4; + + if (pixel_bits == 16) { + fb_format = GL_RGB; + fb_type = GL_UNSIGNED_SHORT_5_6_5; + } + else { + fb_format = GL_BGRA; + fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; + } + + modes = + (*dri_interface->createContextModes) (num_modes, + sizeof(__GLcontextModes)); + m = modes; + if (!driFillInModes(&m, fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor, GLX_TRUE_COLOR)) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + __LINE__); + return NULL; + } + if (!driFillInModes(&m, fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor, GLX_DIRECT_COLOR)) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + __LINE__); + return NULL; + } + + /* Mark the visual as slow if there are "fake" stencil bits. + */ + for (m = modes; m != NULL; m = m->next) { + if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) { + m->visualRating = GLX_SLOW_CONFIG; + } + } + + return modes; +} + + +/** + * This is the bootstrap function for the driver. libGL supplies all of the + * requisite information about the system, and the driver initializes itself. + * This routine also fills in the linked list pointed to by \c driver_modes + * with the \c __GLcontextModes that the driver can support for windows or + * pbuffers. + * + * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on + * failure. + */ +PUBLIC void * +__driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn, + __DRIscreen * psc, + const __GLcontextModes * modes, + const __DRIversion * ddx_version, + const __DRIversion * dri_version, + const __DRIversion * drm_version, + const __DRIframebuffer * frame_buffer, + drmAddress pSAREA, int fd, + int internal_api_version, + const __DRIinterfaceMethods * interface, + __GLcontextModes ** driver_modes) +{ + __DRIscreenPrivate *psp; + static const __DRIversion ddx_expected = { 1, 5, 0 }; + static const __DRIversion dri_expected = { 4, 0, 0 }; + static const __DRIversion drm_expected = { 1, 7, 0 }; + + dri_interface = interface; + + if (!driCheckDriDdxDrmVersions2("i915", + dri_version, &dri_expected, + ddx_version, &ddx_expected, + drm_version, &drm_expected)) { + return NULL; + } + + psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, + ddx_version, dri_version, drm_version, + frame_buffer, pSAREA, fd, + internal_api_version, &intelAPI); + if (psp != NULL) { + I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; + *driver_modes = intelFillInModes(dri_priv->cpp * 8, + (dri_priv->cpp == 2) ? 16 : 24, + (dri_priv->cpp == 2) ? 0 : 8, 1); + + /* Calling driInitExtensions here, with a NULL context pointer, does not actually + * enable the extensions. It just makes sure that all the dispatch offsets for all + * the extensions that *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is called, but we can't + * enable the extensions until we have a context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions(NULL, card_extensions, GL_FALSE); + } + + return (void *) psp; +} + +struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen) +{ + /* + * This should probably change to have the screen allocate a dummy + * context at screen creation. For now just use the current context. + */ + + GET_CURRENT_CONTEXT(ctx); + if (ctx == NULL) { + _mesa_problem(NULL, "No current context in intelScreenContext\n"); + return NULL; + } + return intel_context(ctx); +} + diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.h b/src/mesa/drivers/dri/i915tex/intel_screen.h new file mode 100644 index 0000000000..17698773f3 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_screen.h @@ -0,0 +1,132 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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. + * + **************************************************************************/ + +#ifndef _INTEL_INIT_H_ +#define _INTEL_INIT_H_ + +#include +#include "dri_util.h" +#include "intel_rotate.h" +#include "i830_common.h" +#include "xmlconfig.h" +#include "dri_bufpool.h" + +/* XXX: change name or eliminate to avoid conflict with "struct + * intel_region"!!! + */ +typedef struct +{ + drm_handle_t handle; + drmSize size; /* region size in bytes */ + char *map; /* memory map */ + int offset; /* from start of video mem, in bytes */ + int pitch; /* row stride, in bytes */ +} intelRegion; + +typedef struct +{ + intelRegion front; + intelRegion back; + intelRegion rotated; + intelRegion depth; + intelRegion tex; + + struct intel_region *front_region; + struct intel_region *back_region; + struct intel_region *depth_region; + struct intel_region *rotated_region; + + int deviceID; + int width; + int height; + int mem; /* unused */ + + int cpp; /* for front and back buffers */ +/* int bitsPerPixel; */ + int fbFormat; /* XXX FBO: this is obsolete - remove after i830 updates */ + + int logTextureGranularity; + + __DRIscreenPrivate *driScrnPriv; + unsigned int sarea_priv_offset; + + int drmMinor; + + int irq_active; + int allow_batchbuffer; + + struct matrix23 rotMatrix; + + int current_rotation; /* 0, 90, 180 or 270 */ + int rotatedWidth, rotatedHeight; + + /** + * Configuration cache with default values for all contexts + */ + driOptionCache optionCache; + struct _DriBufferPool *batchPool; + struct _DriBufferPool *texPool; + struct _DriBufferPool *regionPool; + struct _DriBufferPool *staticPool; + unsigned int maxBatchSize; +} intelScreenPrivate; + + + +extern GLboolean intelMapScreenRegions(__DRIscreenPrivate * sPriv); + +extern void intelUnmapScreenRegions(intelScreenPrivate * intelScreen); + +extern void +intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen, + drmI830Sarea * sarea); + +extern void intelDestroyContext(__DRIcontextPrivate * driContextPriv); + +extern GLboolean intelUnbindContext(__DRIcontextPrivate * driContextPriv); + +extern GLboolean +intelMakeCurrent(__DRIcontextPrivate * driContextPriv, + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv); + +extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv); + +extern void +intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h); + +extern struct _DriBufferPool *driBatchPoolInit(int fd, unsigned flags, + unsigned long bufSize, + unsigned numBufs, + unsigned checkDelayed); + +extern struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen); + +extern void +intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea); + +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_span.c b/src/mesa/drivers/dri/i915tex/intel_span.c new file mode 100644 index 0000000000..ab0874e4fd --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_span.c @@ -0,0 +1,409 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "glheader.h" +#include "macros.h" +#include "mtypes.h" +#include "colormac.h" + +#include "intel_fbo.h" +#include "intel_screen.h" +#include "intel_span.h" +#include "intel_regions.h" +#include "intel_ioctl.h" +#include "intel_tex.h" + +#include "swrast/swrast.h" + +/* + break intelWriteRGBASpan_ARGB8888 +*/ + +#undef DBG +#define DBG 0 + +#define LOCAL_VARS \ + struct intel_context *intel = intel_context(ctx); \ + struct intel_renderbuffer *irb = intel_renderbuffer(rb); \ + const GLint yScale = irb->RenderToTexture ? 1 : -1; \ + const GLint yBias = irb->RenderToTexture ? 0 : irb->Base.Height - 1; \ + GLubyte *buf = (GLubyte *) irb->pfMap \ + + (intel->drawY * irb->pfPitch + intel->drawX) * irb->region->cpp;\ + GLuint p; \ + assert(irb->pfMap);\ + (void) p; + +/* XXX FBO: this is identical to the macro in spantmp2.h except we get + * the cliprect info from the context, not the driDrawable. + * Move this into spantmp2.h someday. + */ +#define HW_CLIPLOOP() \ + do { \ + int _nc = intel->numClipRects; \ + while ( _nc-- ) { \ + int minx = intel->pClipRects[_nc].x1 - intel->drawX; \ + int miny = intel->pClipRects[_nc].y1 - intel->drawY; \ + int maxx = intel->pClipRects[_nc].x2 - intel->drawX; \ + int maxy = intel->pClipRects[_nc].y2 - intel->drawY; + + + + +#define Y_FLIP(_y) ((_y) * yScale + yBias) + +#define HW_LOCK() + +#define HW_UNLOCK() + +/* 16 bit, RGB565 color spanline and pixel functions + */ +#define SPANTMP_PIXEL_FMT GL_RGB +#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5 + +#define TAG(x) intel##x##_RGB565 +#define TAG2(x,y) intel##x##_RGB565##y +#define GET_PTR(X,Y) (buf + ((Y) * irb->pfPitch + (X)) * 2) +#include "spantmp2.h" + +/* 32 bit, ARGB8888 color spanline and pixel functions + */ +#define SPANTMP_PIXEL_FMT GL_BGRA +#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV + +#define TAG(x) intel##x##_ARGB8888 +#define TAG2(x,y) intel##x##_ARGB8888##y +#define GET_PTR(X,Y) (buf + ((Y) * irb->pfPitch + (X)) * 4) +#include "spantmp2.h" + + +#define LOCAL_DEPTH_VARS \ + struct intel_context *intel = intel_context(ctx); \ + struct intel_renderbuffer *irb = intel_renderbuffer(rb); \ + const GLuint pitch = irb->pfPitch/***XXX region->pitch*/; /* in pixels */ \ + const GLint yScale = irb->RenderToTexture ? 1 : -1; \ + const GLint yBias = irb->RenderToTexture ? 0 : irb->Base.Height - 1; \ + char *buf = (char *) irb->pfMap/*XXX use region->map*/ + \ + (intel->drawY * pitch + intel->drawX) * irb->region->cpp; + + +#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS + +/** + ** 16-bit depthbuffer functions. + **/ +#define WRITE_DEPTH( _x, _y, d ) \ + ((GLushort *)buf)[(_x) + (_y) * pitch] = d; + +#define READ_DEPTH( d, _x, _y ) \ + d = ((GLushort *)buf)[(_x) + (_y) * pitch]; + + +#define TAG(x) intel##x##_z16 +#include "depthtmp.h" + + +/** + ** 24/8-bit interleaved depth/stencil functions + ** Note: we're actually reading back combined depth+stencil values. + ** The wrappers in main/depthstencil.c are used to extract the depth + ** and stencil values. + **/ +/* Change ZZZS -> SZZZ */ +#define WRITE_DEPTH( _x, _y, d ) { \ + GLuint tmp = ((d) >> 8) | ((d) << 24); \ + ((GLuint *)buf)[(_x) + (_y) * pitch] = tmp; \ +} + +/* Change SZZZ -> ZZZS */ +#define READ_DEPTH( d, _x, _y ) { \ + GLuint tmp = ((GLuint *)buf)[(_x) + (_y) * pitch]; \ + d = (tmp << 8) | (tmp >> 24); \ +} + +#define TAG(x) intel##x##_z24_s8 +#include "depthtmp.h" + + +/** + ** 8-bit stencil function (XXX FBO: This is obsolete) + **/ +#define WRITE_STENCIL( _x, _y, d ) { \ + GLuint tmp = ((GLuint *)buf)[(_x) + (_y) * pitch]; \ + tmp &= 0xffffff; \ + tmp |= ((d) << 24); \ + ((GLuint *) buf)[(_x) + (_y) * pitch] = tmp; \ +} + +#define READ_STENCIL( d, _x, _y ) \ + d = ((GLuint *)buf)[(_x) + (_y) * pitch] >> 24; + +#define TAG(x) intel##x##_z24_s8 +#include "stenciltmp.h" + + + +/** + * Map or unmap all the renderbuffers which we may need during + * software rendering. + * XXX in the future, we could probably convey extra information to + * reduce the number of mappings needed. I.e. if doing a glReadPixels + * from the depth buffer, we really only need one mapping. + * + * XXX Rewrite this function someday. + * We can probably just loop over all the renderbuffer attachments, + * map/unmap all of them, and not worry about the _ColorDrawBuffers + * _ColorReadBuffer, _DepthBuffer or _StencilBuffer fields. + */ +static void +intel_map_unmap_buffers(struct intel_context *intel, GLboolean map) +{ + GLcontext *ctx = &intel->ctx; + GLuint i, j; + struct intel_renderbuffer *irb; + + /* color draw buffers */ + for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { + for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers[i]; j++) { + struct gl_renderbuffer *rb = + ctx->DrawBuffer->_ColorDrawBuffers[i][j]; + irb = intel_renderbuffer(rb); + if (irb) { + /* this is a user-created intel_renderbuffer */ + if (irb->region) { + if (map) + intel_region_map(intel->intelScreen, irb->region); + else + intel_region_unmap(intel->intelScreen, irb->region); + } + irb->pfMap = irb->region->map; + irb->pfPitch = irb->region->pitch; + } + } + } + + /* check for render to textures */ + for (i = 0; i < BUFFER_COUNT; i++) { + struct gl_renderbuffer_attachment *att = + ctx->DrawBuffer->Attachment + i; + struct gl_texture_object *tex = att->Texture; + if (tex) { + /* render to texture */ + ASSERT(att->Renderbuffer); + if (map) { + struct gl_texture_image *texImg; + texImg = tex->Image[att->CubeMapFace][att->TextureLevel]; + intel_tex_map_images(intel, intel_texture_object(tex)); + } + else { + intel_tex_unmap_images(intel, intel_texture_object(tex)); + } + } + } + + /* color read buffers */ + irb = intel_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer); + if (irb && irb->region) { + if (map) + intel_region_map(intel->intelScreen, irb->region); + else + intel_region_unmap(intel->intelScreen, irb->region); + irb->pfMap = irb->region->map; + irb->pfPitch = irb->region->pitch; + } + + /* Account for front/back color page flipping. + * The span routines use the pfMap and pfPitch fields which will + * swap the front/back region map/pitch if we're page flipped. + * Do this after mapping, above, so the map field is valid. + */ +#if 0 + if (map && ctx->DrawBuffer->Name == 0) { + struct intel_renderbuffer *irbFront + = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_FRONT_LEFT); + struct intel_renderbuffer *irbBack + = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_BACK_LEFT); + if (irbBack) { + /* double buffered */ + if (intel->sarea->pf_current_page == 0) { + irbFront->pfMap = irbFront->region->map; + irbFront->pfPitch = irbFront->region->pitch; + irbBack->pfMap = irbBack->region->map; + irbBack->pfPitch = irbBack->region->pitch; + } + else { + irbFront->pfMap = irbBack->region->map; + irbFront->pfPitch = irbBack->region->pitch; + irbBack->pfMap = irbFront->region->map; + irbBack->pfPitch = irbFront->region->pitch; + } + } + } +#endif + + /* depth buffer (Note wrapper!) */ + if (ctx->DrawBuffer->_DepthBuffer) { + irb = intel_renderbuffer(ctx->DrawBuffer->_DepthBuffer->Wrapped); + if (irb && irb->region && irb->Base.Name != 0) { + if (map) { + intel_region_map(intel->intelScreen, irb->region); + irb->pfMap = irb->region->map; + irb->pfPitch = irb->region->pitch; + } + else { + intel_region_unmap(intel->intelScreen, irb->region); + irb->pfMap = NULL; + irb->pfPitch = 0; + } + } + } + + /* stencil buffer (Note wrapper!) */ + if (ctx->DrawBuffer->_StencilBuffer) { + irb = intel_renderbuffer(ctx->DrawBuffer->_StencilBuffer->Wrapped); + if (irb && irb->region && irb->Base.Name != 0) { + if (map) { + intel_region_map(intel->intelScreen, irb->region); + irb->pfMap = irb->region->map; + irb->pfPitch = irb->region->pitch; + } + else { + intel_region_unmap(intel->intelScreen, irb->region); + irb->pfMap = NULL; + irb->pfPitch = 0; + } + } + } +} + + + +/** + * Prepare for softare rendering. Map current read/draw framebuffers' + * renderbuffes and all currently bound texture objects. + * + * Old note: Moved locking out to get reasonable span performance. + */ +void +intelSpanRenderStart(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + GLuint i; + + intelFinish(&intel->ctx); + LOCK_HARDWARE(intel); + +#if 0 + /* Just map the framebuffer and all textures. Bufmgr code will + * take care of waiting on the necessary fences: + */ + intel_region_map(intel->intelScreen, intel->front_region); + intel_region_map(intel->intelScreen, intel->back_region); + intel_region_map(intel->intelScreen, intel->intelScreen->depth_region); +#endif + + for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { + if (ctx->Texture.Unit[i]._ReallyEnabled) { + struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current; + intel_tex_map_images(intel, intel_texture_object(texObj)); + } + } + + intel_map_unmap_buffers(intel, GL_TRUE); +} + +/** + * Called when done softare rendering. Unmap the buffers we mapped in + * the above function. + */ +void +intelSpanRenderFinish(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + GLuint i; + + _swrast_flush(ctx); + + /* Now unmap the framebuffer: + */ +#if 0 + intel_region_unmap(intel, intel->front_region); + intel_region_unmap(intel, intel->back_region); + intel_region_unmap(intel, intel->intelScreen->depth_region); +#endif + + for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { + if (ctx->Texture.Unit[i]._ReallyEnabled) { + struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current; + intel_tex_unmap_images(intel, intel_texture_object(texObj)); + } + } + + intel_map_unmap_buffers(intel, GL_FALSE); + + UNLOCK_HARDWARE(intel); +} + + +void +intelInitSpanFuncs(GLcontext * ctx) +{ + struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx); + swdd->SpanRenderStart = intelSpanRenderStart; + swdd->SpanRenderFinish = intelSpanRenderFinish; +} + + +/** + * Plug in appropriate span read/write functions for the given renderbuffer. + * These are used for the software fallbacks. + */ +void +intel_set_span_functions(struct gl_renderbuffer *rb) +{ + if (rb->_ActualFormat == GL_RGB5) { + /* 565 RGB */ + intelInitPointers_RGB565(rb); + } + else if (rb->_ActualFormat == GL_RGBA8) { + /* 8888 RGBA */ + intelInitPointers_ARGB8888(rb); + } + else if (rb->_ActualFormat == GL_DEPTH_COMPONENT16) { + intelInitDepthPointers_z16(rb); + } + else if (rb->_ActualFormat == GL_DEPTH_COMPONENT24 || /* XXX FBO remove */ + rb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT) { + intelInitDepthPointers_z24_s8(rb); + } + else if (rb->_ActualFormat == GL_STENCIL_INDEX8_EXT) { /* XXX FBO remove */ + intelInitStencilPointers_z24_s8(rb); + } + else { + _mesa_problem(NULL, + "Unexpected _ActualFormat in intelSetSpanFunctions"); + } +} diff --git a/src/mesa/drivers/dri/i915tex/intel_span.h b/src/mesa/drivers/dri/i915tex/intel_span.h new file mode 100644 index 0000000000..5201f6d6c6 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_span.h @@ -0,0 +1,38 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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. + * + **************************************************************************/ + +#ifndef _INTEL_SPAN_H +#define _INTEL_SPAN_H + +extern void intelInitSpanFuncs(GLcontext * ctx); + +extern void intelSpanRenderFinish(GLcontext * ctx); +extern void intelSpanRenderStart(GLcontext * ctx); + +extern void intel_set_span_functions(struct gl_renderbuffer *rb); + +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_state.c b/src/mesa/drivers/dri/i915tex/intel_state.c new file mode 100644 index 0000000000..f85d8ef835 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_state.c @@ -0,0 +1,363 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "glheader.h" +#include "context.h" +#include "macros.h" +#include "enums.h" +#include "colormac.h" +#include "dd.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_fbo.h" +#include "intel_regions.h" +#include "swrast/swrast.h" + +int +intel_translate_compare_func(GLenum func) +{ + switch (func) { + case GL_NEVER: + return COMPAREFUNC_NEVER; + case GL_LESS: + return COMPAREFUNC_LESS; + case GL_LEQUAL: + return COMPAREFUNC_LEQUAL; + case GL_GREATER: + return COMPAREFUNC_GREATER; + case GL_GEQUAL: + return COMPAREFUNC_GEQUAL; + case GL_NOTEQUAL: + return COMPAREFUNC_NOTEQUAL; + case GL_EQUAL: + return COMPAREFUNC_EQUAL; + case GL_ALWAYS: + return COMPAREFUNC_ALWAYS; + } + + fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, func); + return COMPAREFUNC_ALWAYS; +} + +int +intel_translate_stencil_op(GLenum op) +{ + switch (op) { + case GL_KEEP: + return STENCILOP_KEEP; + case GL_ZERO: + return STENCILOP_ZERO; + case GL_REPLACE: + return STENCILOP_REPLACE; + case GL_INCR: + return STENCILOP_INCRSAT; + case GL_DECR: + return STENCILOP_DECRSAT; + case GL_INCR_WRAP: + return STENCILOP_INCR; + case GL_DECR_WRAP: + return STENCILOP_DECR; + case GL_INVERT: + return STENCILOP_INVERT; + default: + return STENCILOP_ZERO; + } +} + +int +intel_translate_blend_factor(GLenum factor) +{ + switch (factor) { + case GL_ZERO: + return BLENDFACT_ZERO; + case GL_SRC_ALPHA: + return BLENDFACT_SRC_ALPHA; + case GL_ONE: + return BLENDFACT_ONE; + case GL_SRC_COLOR: + return BLENDFACT_SRC_COLR; + case GL_ONE_MINUS_SRC_COLOR: + return BLENDFACT_INV_SRC_COLR; + case GL_DST_COLOR: + return BLENDFACT_DST_COLR; + case GL_ONE_MINUS_DST_COLOR: + return BLENDFACT_INV_DST_COLR; + case GL_ONE_MINUS_SRC_ALPHA: + return BLENDFACT_INV_SRC_ALPHA; + case GL_DST_ALPHA: + return BLENDFACT_DST_ALPHA; + case GL_ONE_MINUS_DST_ALPHA: + return BLENDFACT_INV_DST_ALPHA; + case GL_SRC_ALPHA_SATURATE: + return BLENDFACT_SRC_ALPHA_SATURATE; + case GL_CONSTANT_COLOR: + return BLENDFACT_CONST_COLOR; + case GL_ONE_MINUS_CONSTANT_COLOR: + return BLENDFACT_INV_CONST_COLOR; + case GL_CONSTANT_ALPHA: + return BLENDFACT_CONST_ALPHA; + case GL_ONE_MINUS_CONSTANT_ALPHA: + return BLENDFACT_INV_CONST_ALPHA; + } + + fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, factor); + return BLENDFACT_ZERO; +} + +int +intel_translate_logic_op(GLenum opcode) +{ + switch (opcode) { + case GL_CLEAR: + return LOGICOP_CLEAR; + case GL_AND: + return LOGICOP_AND; + case GL_AND_REVERSE: + return LOGICOP_AND_RVRSE; + case GL_COPY: + return LOGICOP_COPY; + case GL_COPY_INVERTED: + return LOGICOP_COPY_INV; + case GL_AND_INVERTED: + return LOGICOP_AND_INV; + case GL_NOOP: + return LOGICOP_NOOP; + case GL_XOR: + return LOGICOP_XOR; + case GL_OR: + return LOGICOP_OR; + case GL_OR_INVERTED: + return LOGICOP_OR_INV; + case GL_NOR: + return LOGICOP_NOR; + case GL_EQUIV: + return LOGICOP_EQUIV; + case GL_INVERT: + return LOGICOP_INV; + case GL_OR_REVERSE: + return LOGICOP_OR_RVRSE; + case GL_NAND: + return LOGICOP_NAND; + case GL_SET: + return LOGICOP_SET; + default: + return LOGICOP_SET; + } +} + + +static void +intelClearColor(GLcontext * ctx, const GLfloat color[4]) +{ + struct intel_context *intel = intel_context(ctx); + GLubyte clear[4]; + + CLAMPED_FLOAT_TO_UBYTE(clear[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(clear[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(clear[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(clear[3], color[3]); + + /* compute both 32 and 16-bit clear values */ + intel->ClearColor8888 = INTEL_PACKCOLOR8888(clear[0], clear[1], + clear[2], clear[3]); + intel->ClearColor565 = INTEL_PACKCOLOR565(clear[0], clear[1], clear[2]); +} + + +/** + * Update the viewport transformation matrix. Depends on: + * - viewport pos/size + * - depthrange + * - window pos/size or FBO size + */ +static void +intelCalcViewport(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + const GLfloat *v = ctx->Viewport._WindowMap.m; + const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF; + GLfloat *m = intel->ViewportMatrix.m; + GLfloat yScale, yBias; + + if (ctx->DrawBuffer->Name) { + /* User created FBO */ + struct intel_renderbuffer *irb + = intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]); + if (irb && !irb->RenderToTexture) { + /* y=0=top */ + yScale = -1.0; + yBias = irb->Base.Height; + } + else { + /* y=0=bottom */ + yScale = 1.0; + yBias = 0.0; + } + } + else { + /* window buffer, y=0=top */ + yScale = -1.0; + yBias = (intel->driDrawable) ? intel->driDrawable->h : 0.0F; + } + + m[MAT_SX] = v[MAT_SX]; + m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X; + + m[MAT_SY] = v[MAT_SY] * yScale; + m[MAT_TY] = v[MAT_TY] * yScale + yBias + SUBPIXEL_Y; + + m[MAT_SZ] = v[MAT_SZ] * depthScale; + m[MAT_TZ] = v[MAT_TZ] * depthScale; +} + +static void +intelViewport(GLcontext * ctx, + GLint x, GLint y, GLsizei width, GLsizei height) +{ + intelCalcViewport(ctx); +} + +static void +intelDepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval) +{ + intelCalcViewport(ctx); +} + +/* Fallback to swrast for select and feedback. + */ +static void +intelRenderMode(GLcontext * ctx, GLenum mode) +{ + struct intel_context *intel = intel_context(ctx); + FALLBACK(intel, INTEL_FALLBACK_RENDERMODE, (mode != GL_RENDER)); +} + + +void +intelInitStateFuncs(struct dd_function_table *functions) +{ + functions->RenderMode = intelRenderMode; + functions->Viewport = intelViewport; + functions->DepthRange = intelDepthRange; + functions->ClearColor = intelClearColor; +} + + + + +void +intelInitState(GLcontext * ctx) +{ + /* Mesa should do this for us: + */ + ctx->Driver.AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef); + + ctx->Driver.BlendColor(ctx, ctx->Color.BlendColor); + + ctx->Driver.BlendEquationSeparate(ctx, + ctx->Color.BlendEquationRGB, + ctx->Color.BlendEquationA); + + ctx->Driver.BlendFuncSeparate(ctx, + ctx->Color.BlendSrcRGB, + ctx->Color.BlendDstRGB, + ctx->Color.BlendSrcA, ctx->Color.BlendDstA); + + ctx->Driver.ColorMask(ctx, + ctx->Color.ColorMask[RCOMP], + ctx->Color.ColorMask[GCOMP], + ctx->Color.ColorMask[BCOMP], + ctx->Color.ColorMask[ACOMP]); + + ctx->Driver.CullFace(ctx, ctx->Polygon.CullFaceMode); + ctx->Driver.DepthFunc(ctx, ctx->Depth.Func); + ctx->Driver.DepthMask(ctx, ctx->Depth.Mask); + + ctx->Driver.Enable(ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled); + ctx->Driver.Enable(ctx, GL_BLEND, ctx->Color.BlendEnabled); + ctx->Driver.Enable(ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled); + ctx->Driver.Enable(ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled); + ctx->Driver.Enable(ctx, GL_CULL_FACE, ctx->Polygon.CullFlag); + ctx->Driver.Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test); + ctx->Driver.Enable(ctx, GL_DITHER, ctx->Color.DitherFlag); + ctx->Driver.Enable(ctx, GL_FOG, ctx->Fog.Enabled); + ctx->Driver.Enable(ctx, GL_LIGHTING, ctx->Light.Enabled); + ctx->Driver.Enable(ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag); + ctx->Driver.Enable(ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag); + ctx->Driver.Enable(ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled); + ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); + ctx->Driver.Enable(ctx, GL_TEXTURE_1D, GL_FALSE); + ctx->Driver.Enable(ctx, GL_TEXTURE_2D, GL_FALSE); + ctx->Driver.Enable(ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE); + ctx->Driver.Enable(ctx, GL_TEXTURE_3D, GL_FALSE); + ctx->Driver.Enable(ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE); + + ctx->Driver.Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color); + ctx->Driver.Fogfv(ctx, GL_FOG_MODE, 0); + ctx->Driver.Fogfv(ctx, GL_FOG_DENSITY, &ctx->Fog.Density); + ctx->Driver.Fogfv(ctx, GL_FOG_START, &ctx->Fog.Start); + ctx->Driver.Fogfv(ctx, GL_FOG_END, &ctx->Fog.End); + + ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace); + + { + GLfloat f = (GLfloat) ctx->Light.Model.ColorControl; + ctx->Driver.LightModelfv(ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f); + } + + ctx->Driver.LineWidth(ctx, ctx->Line.Width); + ctx->Driver.LogicOpcode(ctx, ctx->Color.LogicOp); + ctx->Driver.PointSize(ctx, ctx->Point.Size); + ctx->Driver.PolygonStipple(ctx, (const GLubyte *) ctx->PolygonStipple); + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); + ctx->Driver.ShadeModel(ctx, ctx->Light.ShadeModel); + ctx->Driver.StencilFuncSeparate(ctx, GL_FRONT, + ctx->Stencil.Function[0], + ctx->Stencil.Ref[0], + ctx->Stencil.ValueMask[0]); + ctx->Driver.StencilFuncSeparate(ctx, GL_BACK, + ctx->Stencil.Function[1], + ctx->Stencil.Ref[1], + ctx->Stencil.ValueMask[1]); + ctx->Driver.StencilMaskSeparate(ctx, GL_FRONT, ctx->Stencil.WriteMask[0]); + ctx->Driver.StencilMaskSeparate(ctx, GL_BACK, ctx->Stencil.WriteMask[1]); + ctx->Driver.StencilOpSeparate(ctx, GL_FRONT, + ctx->Stencil.FailFunc[0], + ctx->Stencil.ZFailFunc[0], + ctx->Stencil.ZPassFunc[0]); + ctx->Driver.StencilOpSeparate(ctx, GL_BACK, + ctx->Stencil.FailFunc[1], + ctx->Stencil.ZFailFunc[1], + ctx->Stencil.ZPassFunc[1]); + + + /* XXX this isn't really needed */ + ctx->Driver.DrawBuffer(ctx, ctx->Color.DrawBuffer[0]); +} diff --git a/src/mesa/drivers/dri/i915tex/intel_structs.h b/src/mesa/drivers/dri/i915tex/intel_structs.h new file mode 100644 index 0000000000..522e3bd92c --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_structs.h @@ -0,0 +1,132 @@ +#ifndef INTEL_STRUCTS_H +#define INTEL_STRUCTS_H + +struct br0 { + GLuint length:8; + GLuint pad0:3; + GLuint dst_tiled:1; + GLuint pad1:8; + GLuint write_rgb:1; + GLuint write_alpha:1; + GLuint opcode:7; + GLuint client:3; +}; + + +struct br13 { + GLint dest_pitch:16; + GLuint rop:8; + GLuint color_depth:2; + GLuint pad1:3; + GLuint mono_source_transparency:1; + GLuint clipping_enable:1; + GLuint pad0:1; +}; + + + +/* This is an attempt to move some of the 2D interaction in this + * driver to using structs for packets rather than a bunch of #defines + * and dwords. + */ +struct xy_color_blit { + struct br0 br0; + struct br13 br13; + + struct { + GLuint dest_x1:16; + GLuint dest_y1:16; + } dw2; + + struct { + GLuint dest_x2:16; + GLuint dest_y2:16; + } dw3; + + GLuint dest_base_addr; + GLuint color; +}; + +struct xy_src_copy_blit { + struct br0 br0; + struct br13 br13; + + struct { + GLuint dest_x1:16; + GLuint dest_y1:16; + } dw2; + + struct { + GLuint dest_x2:16; + GLuint dest_y2:16; + } dw3; + + GLuint dest_base_addr; + + struct { + GLuint src_x1:16; + GLuint src_y1:16; + } dw5; + + struct { + GLint src_pitch:16; + GLuint pad:16; + } dw6; + + GLuint src_base_addr; +}; + +struct xy_setup_blit { + struct br0 br0; + struct br13 br13; + + struct { + GLuint clip_x1:16; + GLuint clip_y1:16; + } dw2; + + struct { + GLuint clip_x2:16; + GLuint clip_y2:16; + } dw3; + + GLuint dest_base_addr; + GLuint background_color; + GLuint foreground_color; + GLuint pattern_base_addr; +}; + + +struct xy_text_immediate_blit { + struct { + GLuint length:8; + GLuint pad2:3; + GLuint dst_tiled:1; + GLuint pad1:4; + GLuint byte_packed:1; + GLuint pad0:5; + GLuint opcode:7; + GLuint client:3; + } dw0; + + struct { + GLuint dest_x1:16; + GLuint dest_y1:16; + } dw1; + + struct { + GLuint dest_x2:16; + GLuint dest_y2:16; + } dw2; + + /* Src bitmap data follows as inline dwords. + */ +}; + + +#define CLIENT_2D 0x2 +#define OPCODE_XY_SETUP_BLT 0x1 +#define OPCODE_XY_COLOR_BLT 0x50 +#define OPCODE_XY_TEXT_IMMEDIATE_BLT 0x31 + +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_tex.c b/src/mesa/drivers/dri/i915tex/intel_tex.c new file mode 100644 index 0000000000..51875ab292 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_tex.c @@ -0,0 +1,182 @@ +#include "texobj.h" +#include "intel_context.h" +#include "intel_mipmap_tree.h" +#include "intel_tex.h" + +#define FILE_DEBUG_FLAG DEBUG_TEXTURE + +static GLboolean +intelIsTextureResident(GLcontext * ctx, struct gl_texture_object *texObj) +{ +#if 0 + struct intel_context *intel = intel_context(ctx); + struct intel_texture_object *intelObj = intel_texture_object(texObj); + + return + intelObj->mt && + intelObj->mt->region && + intel_is_region_resident(intel, intelObj->mt->region); +#endif + return 1; +} + + + +static struct gl_texture_image * +intelNewTextureImage(GLcontext * ctx) +{ + DBG("%s\n", __FUNCTION__); + (void) ctx; + return (struct gl_texture_image *) CALLOC_STRUCT(intel_texture_image); +} + + +static struct gl_texture_object * +intelNewTextureObject(GLcontext * ctx, GLuint name, GLenum target) +{ + struct intel_texture_object *obj = CALLOC_STRUCT(intel_texture_object); + + DBG("%s\n", __FUNCTION__); + _mesa_initialize_texture_object(&obj->base, name, target); + + return &obj->base; +} + +static void +intelDeleteTextureObject(GLcontext *ctx, + struct gl_texture_object *texObj) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_texture_object *intelObj = intel_texture_object(texObj); + + if (intelObj->mt) + intel_miptree_release(intel, &intelObj->mt); + + _mesa_delete_texture_object(ctx, texObj); +} + + +static void +intelFreeTextureImageData(GLcontext * ctx, struct gl_texture_image *texImage) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_texture_image *intelImage = intel_texture_image(texImage); + + DBG("%s\n", __FUNCTION__); + + if (intelImage->mt) { + intel_miptree_release(intel, &intelImage->mt); + } + + if (texImage->Data) { + free(texImage->Data); + texImage->Data = NULL; + } +} + + +#ifndef __x86_64__ +static unsigned +fastrdtsc(void) +{ + unsigned eax; + __asm__ volatile ("\t" + "pushl %%ebx\n\t" + "cpuid\n\t" ".byte 0x0f, 0x31\n\t" + "popl %%ebx\n":"=a" (eax) + :"0"(0) + :"ecx", "edx", "cc"); + + return eax; +} +#else +static unsigned +fastrdtsc(void) +{ + unsigned eax; + __asm__ volatile ("\t" "cpuid\n\t" ".byte 0x0f, 0x31\n\t":"=a" (eax) + :"0"(0) + :"ecx", "edx", "ebx", "cc"); + + return eax; +} +#endif + +static unsigned +time_diff(unsigned t, unsigned t2) +{ + return ((t < t2) ? t2 - t : 0xFFFFFFFFU - (t - t2 - 1)); +} + + +/* The system memcpy (at least on ubuntu 5.10) has problems copying + * to agp (writecombined) memory from a source which isn't 64-byte + * aligned - there is a 4x performance falloff. + * + * The x86 __memcpy is immune to this but is slightly slower + * (10%-ish) than the system memcpy. + * + * The sse_memcpy seems to have a slight cliff at 64/32 bytes, but + * isn't much faster than x86_memcpy for agp copies. + * + * TODO: switch dynamically. + */ +static void * +do_memcpy(void *dest, const void *src, size_t n) +{ + if ((((unsigned) src) & 63) || (((unsigned) dest) & 63)) { + return __memcpy(dest, src, n); + } + else + return memcpy(dest, src, n); +} + + +static void * +timed_memcpy(void *dest, const void *src, size_t n) +{ + void *ret; + unsigned t1, t2; + double rate; + + if ((((unsigned) src) & 63) || (((unsigned) dest) & 63)) + _mesa_printf("Warning - non-aligned texture copy!\n"); + + t1 = fastrdtsc(); + ret = do_memcpy(dest, src, n); + t2 = fastrdtsc(); + + rate = time_diff(t1, t2); + rate /= (double) n; + _mesa_printf("timed_memcpy: %u %u --> %f clocks/byte\n", t1, t2, rate); + return ret; +} + + +void +intelInitTextureFuncs(struct dd_function_table *functions) +{ + functions->ChooseTextureFormat = intelChooseTextureFormat; + functions->TexImage1D = intelTexImage1D; + functions->TexImage2D = intelTexImage2D; + functions->TexImage3D = intelTexImage3D; + functions->TexSubImage1D = intelTexSubImage1D; + functions->TexSubImage2D = intelTexSubImage2D; + functions->TexSubImage3D = intelTexSubImage3D; + functions->CopyTexImage1D = intelCopyTexImage1D; + functions->CopyTexImage2D = intelCopyTexImage2D; + functions->CopyTexSubImage1D = intelCopyTexSubImage1D; + functions->CopyTexSubImage2D = intelCopyTexSubImage2D; + functions->GetTexImage = intelGetTexImage; + functions->NewTextureObject = intelNewTextureObject; + functions->NewTextureImage = intelNewTextureImage; + functions->DeleteTexture = intelDeleteTextureObject; + functions->FreeTexImageData = intelFreeTextureImageData; + functions->UpdateTexturePalette = 0; + functions->IsTextureResident = intelIsTextureResident; + + if (INTEL_DEBUG & DEBUG_BUFMGR) + functions->TextureMemCpy = timed_memcpy; + else + functions->TextureMemCpy = do_memcpy; +} diff --git a/src/mesa/drivers/dri/i915tex/intel_tex.h b/src/mesa/drivers/dri/i915tex/intel_tex.h new file mode 100644 index 0000000000..2f3d4ec2d1 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_tex.h @@ -0,0 +1,134 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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. + * + **************************************************************************/ + +#ifndef INTELTEX_INC +#define INTELTEX_INC + +#include "mtypes.h" +#include "intel_context.h" +#include "texmem.h" + + +void intelInitTextureFuncs(struct dd_function_table *functions); + +const struct gl_texture_format *intelChooseTextureFormat(GLcontext * ctx, + GLint internalFormat, + GLenum format, + GLenum type); + + +void intelTexImage3D(GLcontext * ctx, + GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint depth, + GLint border, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +void intelTexSubImage3D(GLcontext * ctx, + GLenum target, + GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +void intelTexImage2D(GLcontext * ctx, + GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +void intelTexSubImage2D(GLcontext * ctx, + GLenum target, + GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +void intelTexImage1D(GLcontext * ctx, + GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint border, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +void intelTexSubImage1D(GLcontext * ctx, + GLenum target, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +void intelCopyTexImage1D(GLcontext * ctx, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLint border); + +void intelCopyTexImage2D(GLcontext * ctx, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLsizei height, + GLint border); + +void intelCopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, GLsizei width); + +void intelCopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, GLsizei width, GLsizei height); + +void intelGetTexImage(GLcontext * ctx, GLenum target, GLint level, + GLenum format, GLenum type, GLvoid * pixels, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +GLuint intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit); + +void intel_tex_map_images(struct intel_context *intel, + struct intel_texture_object *intelObj); + +void intel_tex_unmap_images(struct intel_context *intel, + struct intel_texture_object *intelObj); + +#endif diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_copy.c b/src/mesa/drivers/dri/i915tex/intel_tex_copy.c new file mode 100644 index 0000000000..88b62e781c --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_tex_copy.c @@ -0,0 +1,301 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "mtypes.h" +#include "enums.h" +#include "image.h" +#include "teximage.h" +#include "swrast/swrast.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_batchbuffer.h" +#include "intel_buffers.h" +#include "intel_mipmap_tree.h" +#include "intel_regions.h" +#include "intel_fbo.h" +#include "intel_tex.h" +#include "intel_blit.h" +#include "intel_pixel.h" + +#define FILE_DEBUG_FLAG DEBUG_TEXTURE + +/** + * Get the intel_region which is the source for any glCopyTex[Sub]Image call. + * + * Do the best we can using the blitter. A future project is to use + * the texture engine and fragment programs for these copies. + */ +static const struct intel_region * +get_teximage_source(struct intel_context *intel, GLenum internalFormat) +{ + struct intel_renderbuffer *irb; + + DBG("%s %s\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(internalFormat)); + + switch (internalFormat) { + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16_ARB: + irb = intel_get_renderbuffer(intel->ctx.ReadBuffer, BUFFER_DEPTH); + if (irb && irb->region && irb->region->cpp == 2) + return irb->region; + return NULL; + case GL_DEPTH24_STENCIL8_EXT: + case GL_DEPTH_STENCIL_EXT: + irb = intel_get_renderbuffer(intel->ctx.ReadBuffer, BUFFER_DEPTH); + if (irb && irb->region && irb->region->cpp == 4) + return irb->region; + return NULL; + case GL_RGBA: + case GL_RGBA8: + return intel_readbuf_region(intel); + case GL_RGB: + if (intel->intelScreen->cpp == 2) + return intel_readbuf_region(intel); + return NULL; + default: + return NULL; + } +} + + +static GLboolean +do_copy_texsubimage(struct intel_context *intel, + struct intel_texture_image *intelImage, + GLenum internalFormat, + GLint dstx, GLint dsty, + GLint x, GLint y, GLsizei width, GLsizei height) +{ + GLcontext *ctx = &intel->ctx; + const struct intel_region *src = + get_teximage_source(intel, internalFormat); + + if (!intelImage->mt || !src) { + DBG("%s fail %p %p\n", __FUNCTION__, intelImage->mt, src); + return GL_FALSE; + } + + intelFlush(ctx); + LOCK_HARDWARE(intel); + { + GLuint image_offset = intel_miptree_image_offset(intelImage->mt, + intelImage->face, + intelImage->level); + const GLint orig_x = x; + const GLint orig_y = y; + const struct gl_framebuffer *fb = ctx->DrawBuffer; + + if (_mesa_clip_to_region(fb->_Xmin, fb->_Ymin, fb->_Xmax, fb->_Ymax, + &x, &y, &width, &height)) { + /* Update dst for clipped src. Need to also clip the source rect. + */ + dstx += x - orig_x; + dsty += y - orig_y; + + if (ctx->ReadBuffer->Name == 0) { + /* reading from a window, adjust x, y */ + __DRIdrawablePrivate *dPriv = intel->driDrawable; + GLuint window_y; + /* window_y = position of window on screen if y=0=bottom */ + window_y = intel->intelScreen->height - (dPriv->y + dPriv->h); + y = window_y + y; + x += dPriv->x; + } + else { + /* reading from a FBO */ + /* invert Y */ + y = ctx->ReadBuffer->Height - y - 1; + } + + + /* A bit of fiddling to get the blitter to work with -ve + * pitches. But we get a nice inverted blit this way, so it's + * worth it: + */ + intelEmitCopyBlit(intel, + intelImage->mt->cpp, + -src->pitch, + src->buffer, + src->height * src->pitch * src->cpp, + intelImage->mt->pitch, + intelImage->mt->region->buffer, + image_offset, + x, y + height, dstx, dsty, width, height); + + intel_batchbuffer_flush(intel->batch); + } + } + + + UNLOCK_HARDWARE(intel); + +#if 0 + /* GL_SGIS_generate_mipmap -- this can be accelerated now. + * XXX Add a ctx->Driver.GenerateMipmaps() function? + */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + intel_generate_mipmap(ctx, target, + &ctx->Texture.Unit[ctx->Texture.CurrentUnit], + texObj); + } +#endif + + return GL_TRUE; +} + + + + + +void +intelCopyTexImage1D(GLcontext * ctx, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLint border) +{ + struct gl_texture_unit *texUnit = + &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + struct gl_texture_object *texObj = + _mesa_select_tex_object(ctx, texUnit, target); + struct gl_texture_image *texImage = + _mesa_select_tex_image(ctx, texObj, target, level); + + if (border) + goto fail; + + /* Setup or redefine the texture object, mipmap tree and texture + * image. Don't populate yet. + */ + ctx->Driver.TexImage1D(ctx, target, level, internalFormat, + width, border, + GL_RGBA, CHAN_TYPE, NULL, + &ctx->DefaultPacking, texObj, texImage); + + if (!do_copy_texsubimage(intel_context(ctx), + intel_texture_image(texImage), + internalFormat, 0, 0, x, y, width, 1)) + goto fail; + + return; + + fail: + _swrast_copy_teximage1d(ctx, target, level, internalFormat, x, y, + width, border); +} + +void +intelCopyTexImage2D(GLcontext * ctx, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLsizei height, + GLint border) +{ + struct gl_texture_unit *texUnit = + &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + struct gl_texture_object *texObj = + _mesa_select_tex_object(ctx, texUnit, target); + struct gl_texture_image *texImage = + _mesa_select_tex_image(ctx, texObj, target, level); + + if (border) + goto fail; + + /* Setup or redefine the texture object, mipmap tree and texture + * image. Don't populate yet. + */ + ctx->Driver.TexImage2D(ctx, target, level, internalFormat, + width, height, border, + GL_RGBA, CHAN_TYPE, NULL, + &ctx->DefaultPacking, texObj, texImage); + + + if (!do_copy_texsubimage(intel_context(ctx), + intel_texture_image(texImage), + internalFormat, 0, 0, x, y, width, height)) + goto fail; + + return; + + fail: + _swrast_copy_teximage2d(ctx, target, level, internalFormat, x, y, + width, height, border); +} + + +void +intelCopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, GLsizei width) +{ + struct gl_texture_unit *texUnit = + &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + struct gl_texture_object *texObj = + _mesa_select_tex_object(ctx, texUnit, target); + struct gl_texture_image *texImage = + _mesa_select_tex_image(ctx, texObj, target, level); + GLenum internalFormat = texImage->InternalFormat; + + /* XXX need to check as in above function? */ + + /* Need to check texture is compatible with source format. + */ + + if (!do_copy_texsubimage(intel_context(ctx), + intel_texture_image(texImage), + internalFormat, xoffset, 0, x, y, width, 1)) { + _swrast_copy_texsubimage1d(ctx, target, level, xoffset, x, y, width); + } +} + + + +void +intelCopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, GLsizei width, GLsizei height) +{ + struct gl_texture_unit *texUnit = + &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + struct gl_texture_object *texObj = + _mesa_select_tex_object(ctx, texUnit, target); + struct gl_texture_image *texImage = + _mesa_select_tex_image(ctx, texObj, target, level); + GLenum internalFormat = texImage->InternalFormat; + + + /* Need to check texture is compatible with source format. + */ + + if (!do_copy_texsubimage(intel_context(ctx), + intel_texture_image(texImage), + internalFormat, + xoffset, yoffset, x, y, width, height)) { + + DBG("%s - fallback to swrast\n", __FUNCTION__); + + _swrast_copy_texsubimage2d(ctx, target, level, + xoffset, yoffset, x, y, width, height); + } +} diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_format.c b/src/mesa/drivers/dri/i915tex/intel_tex_format.c new file mode 100644 index 0000000000..d7612dcbaa --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_tex_format.c @@ -0,0 +1,146 @@ +#include "intel_context.h" +#include "intel_tex.h" +#include "texformat.h" +#include "enums.h" + +/* It works out that this function is fine for all the supported + * hardware. However, there is still a need to map the formats onto + * hardware descriptors. + */ +/* Note that the i915 can actually support many more formats than + * these if we take the step of simply swizzling the colors + * immediately after sampling... + */ +const struct gl_texture_format * +intelChooseTextureFormat(GLcontext * ctx, GLint internalFormat, + GLenum format, GLenum type) +{ + struct intel_context *intel = intel_context(ctx); + const GLboolean do32bpt = (intel->intelScreen->cpp == 4); + + switch (internalFormat) { + case 4: + case GL_RGBA: + case GL_COMPRESSED_RGBA: + if (format == GL_BGRA) { + if (type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_INT_8_8_8_8_REV) { + return &_mesa_texformat_argb8888; + } + else if (type == GL_UNSIGNED_SHORT_4_4_4_4_REV) { + return &_mesa_texformat_argb4444; + } + else if (type == GL_UNSIGNED_SHORT_1_5_5_5_REV) { + return &_mesa_texformat_argb1555; + } + } + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444; + + case 3: + case GL_RGB: + case GL_COMPRESSED_RGB: + if (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5) { + return &_mesa_texformat_rgb565; + } + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565; + + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444; + + case GL_RGBA4: + case GL_RGBA2: + return &_mesa_texformat_argb4444; + + case GL_RGB5_A1: + return &_mesa_texformat_argb1555; + + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return &_mesa_texformat_argb8888; + + case GL_RGB5: + case GL_RGB4: + case GL_R3_G3_B2: + return &_mesa_texformat_rgb565; + + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + case GL_COMPRESSED_ALPHA: + return &_mesa_texformat_a8; + + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + case GL_COMPRESSED_LUMINANCE: + return &_mesa_texformat_l8; + + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + case GL_COMPRESSED_LUMINANCE_ALPHA: + return &_mesa_texformat_al88; + + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + case GL_COMPRESSED_INTENSITY: + return &_mesa_texformat_i8; + + case GL_YCBCR_MESA: + if (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE) + return &_mesa_texformat_ycbcr; + else + return &_mesa_texformat_ycbcr_rev; + + case GL_COMPRESSED_RGB_FXT1_3DFX: + return &_mesa_texformat_rgb_fxt1; + case GL_COMPRESSED_RGBA_FXT1_3DFX: + return &_mesa_texformat_rgba_fxt1; + + case GL_RGB_S3TC: + case GL_RGB4_S3TC: + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + return &_mesa_texformat_rgb_dxt1; + + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return &_mesa_texformat_rgba_dxt1; + + case GL_RGBA_S3TC: + case GL_RGBA4_S3TC: + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + return &_mesa_texformat_rgba_dxt3; + + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + return &_mesa_texformat_rgba_dxt5; + + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT32: + return &_mesa_texformat_z16; + + default: + fprintf(stderr, "unexpected texture format %s in %s\n", + _mesa_lookup_enum_by_nr(internalFormat), __FUNCTION__); + return NULL; + } + + return NULL; /* never get here */ +} diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_image.c b/src/mesa/drivers/dri/i915tex/intel_tex_image.c new file mode 100644 index 0000000000..48c2f35d3b --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_tex_image.c @@ -0,0 +1,626 @@ + +#include +#include + +#include "glheader.h" +#include "macros.h" +#include "mtypes.h" +#include "enums.h" +#include "colortab.h" +#include "convolve.h" +#include "context.h" +#include "simple_list.h" +#include "texcompress.h" +#include "texformat.h" +#include "texobj.h" +#include "texstore.h" + +#include "intel_context.h" +#include "intel_mipmap_tree.h" +#include "intel_buffer_objects.h" +#include "intel_batchbuffer.h" +#include "intel_tex.h" +#include "intel_ioctl.h" +#include "intel_blit.h" + +#define FILE_DEBUG_FLAG DEBUG_TEXTURE + +/* Functions to store texture images. Where possible, mipmap_tree's + * will be created or further instantiated with image data, otherwise + * images will be stored in malloc'd memory. A validation step is + * required to pull those images into a mipmap tree, or otherwise + * decide a fallback is required. + */ + + +static int +logbase2(int n) +{ + GLint i = 1; + GLint log2 = 0; + + while (n > i) { + i *= 2; + log2++; + } + + return log2; +} + + +/* Otherwise, store it in memory if (Border != 0) or (any dimension == + * 1). + * + * Otherwise, if max_level >= level >= min_level, create tree with + * space for textures from min_level down to max_level. + * + * Otherwise, create tree with space for textures from (level + * 0)..(1x1). Consider pruning this tree at a validation if the + * saving is worth it. + */ +static void +guess_and_alloc_mipmap_tree(struct intel_context *intel, + struct intel_texture_object *intelObj, + struct intel_texture_image *intelImage) +{ + GLuint firstLevel; + GLuint lastLevel; + GLuint width = intelImage->base.Width; + GLuint height = intelImage->base.Height; + GLuint depth = intelImage->base.Depth; + GLuint l2width, l2height, l2depth; + GLuint i; + + DBG("%s\n", __FUNCTION__); + + if (intelImage->base.Border) + return; + + if (intelImage->level > intelObj->base.BaseLevel && + (intelImage->base.Width == 1 || + (intelObj->base.Target != GL_TEXTURE_1D && + intelImage->base.Height == 1) || + (intelObj->base.Target == GL_TEXTURE_3D && + intelImage->base.Depth == 1))) + return; + + /* If this image disrespects BaseLevel, allocate from level zero. + * Usually BaseLevel == 0, so it's unlikely to happen. + */ + if (intelImage->level < intelObj->base.BaseLevel) + firstLevel = 0; + else + firstLevel = intelObj->base.BaseLevel; + + + /* Figure out image dimensions at start level. + */ + for (i = intelImage->level; i > firstLevel; i--) { + width <<= 1; + if (height != 1) + height <<= 1; + if (depth != 1) + depth <<= 1; + } + + /* Guess a reasonable value for lastLevel. This is probably going + * to be wrong fairly often and might mean that we have to look at + * resizable buffers, or require that buffers implement lazy + * pagetable arrangements. + */ + if ((intelObj->base.MinFilter == GL_NEAREST || + intelObj->base.MinFilter == GL_LINEAR) && + intelImage->level == firstLevel) { + lastLevel = firstLevel; + } + else { + l2width = logbase2(width); + l2height = logbase2(height); + l2depth = logbase2(depth); + lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth); + } + + assert(!intelObj->mt); + intelObj->mt = intel_miptree_create(intel, + intelObj->base.Target, + intelImage->base.InternalFormat, + firstLevel, + lastLevel, + width, + height, + depth, + intelImage->base.TexFormat->TexelBytes, + intelImage->base.IsCompressed); + + DBG("%s - success\n", __FUNCTION__); +} + + + + +static GLuint +target_to_face(GLenum target) +{ + switch (target) { + case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: + return ((GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X); + default: + return 0; + } +} + +/* There are actually quite a few combinations this will work for, + * more than what I've listed here. + */ +static GLboolean +check_pbo_format(GLint internalFormat, + GLenum format, GLenum type, + const struct gl_texture_format *mesa_format) +{ + switch (internalFormat) { + case 4: + case GL_RGBA: + return (format == GL_BGRA && + (type == GL_UNSIGNED_BYTE || + type == GL_UNSIGNED_INT_8_8_8_8_REV) && + mesa_format == &_mesa_texformat_argb8888); + case 3: + case GL_RGB: + return (format == GL_RGB && + type == GL_UNSIGNED_SHORT_5_6_5 && + mesa_format == &_mesa_texformat_rgb565); + case GL_YCBCR_MESA: + return (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE); + default: + return GL_FALSE; + } +} + + +/* XXX: Do this for TexSubImage also: + */ +static GLboolean +try_pbo_upload(struct intel_context *intel, + struct intel_texture_image *intelImage, + const struct gl_pixelstore_attrib *unpack, + GLint internalFormat, + GLint width, GLint height, + GLenum format, GLenum type, const void *pixels) +{ + struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj); + GLuint src_offset, src_stride; + GLuint dst_offset, dst_stride; + + if (!pbo || + intel->ctx._ImageTransferState || + unpack->SkipPixels || unpack->SkipRows) { + _mesa_printf("%s: failure 1\n", __FUNCTION__); + return GL_FALSE; + } + + src_offset = (GLuint) pixels; + + if (unpack->RowLength > 0) + src_stride = unpack->RowLength; + else + src_stride = width; + + dst_offset = intel_miptree_image_offset(intelImage->mt, + intelImage->face, + intelImage->level); + + dst_stride = intelImage->mt->pitch; + + intelFlush(&intel->ctx); + LOCK_HARDWARE(intel); + { + struct _DriBufferObject *src_buffer = + intel_bufferobj_buffer(intel, pbo, INTEL_READ); + struct _DriBufferObject *dst_buffer = + intel_region_buffer(intel->intelScreen, intelImage->mt->region, + INTEL_WRITE_FULL); + + + intelEmitCopyBlit(intel, + intelImage->mt->cpp, + src_stride, src_buffer, src_offset, + dst_stride, dst_buffer, dst_offset, + 0, 0, 0, 0, width, height); + + intel_batchbuffer_flush(intel->batch); + } + UNLOCK_HARDWARE(intel); + + return GL_TRUE; +} + + + +static GLboolean +try_pbo_zcopy(struct intel_context *intel, + struct intel_texture_image *intelImage, + const struct gl_pixelstore_attrib *unpack, + GLint internalFormat, + GLint width, GLint height, + GLenum format, GLenum type, const void *pixels) +{ + struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj); + GLuint src_offset, src_stride; + GLuint dst_offset, dst_stride; + + if (!pbo || + intel->ctx._ImageTransferState || + unpack->SkipPixels || unpack->SkipRows) { + _mesa_printf("%s: failure 1\n", __FUNCTION__); + return GL_FALSE; + } + + src_offset = (GLuint) pixels; + + if (unpack->RowLength > 0) + src_stride = unpack->RowLength; + else + src_stride = width; + + dst_offset = intel_miptree_image_offset(intelImage->mt, + intelImage->face, + intelImage->level); + + dst_stride = intelImage->mt->pitch; + + if (src_stride != dst_stride || dst_offset != 0 || src_offset != 0) { + _mesa_printf("%s: failure 2\n", __FUNCTION__); + return GL_FALSE; + } + + intel_region_attach_pbo(intel->intelScreen, intelImage->mt->region, pbo); + + return GL_TRUE; +} + + + + + + +static void +intelTexImage(GLcontext * ctx, + GLint dims, + GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint depth, + GLint border, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *unpack, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_texture_object *intelObj = intel_texture_object(texObj); + struct intel_texture_image *intelImage = intel_texture_image(texImage); + GLint postConvWidth = width; + GLint postConvHeight = height; + GLint texelBytes, sizeInBytes; + GLuint dstRowStride; + + + DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(target), level, width, height, depth, border); + + intelFlush(ctx); + + intelImage->face = target_to_face(target); + intelImage->level = level; + + if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { + _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth, + &postConvHeight); + } + + /* choose the texture format */ + texImage->TexFormat = intelChooseTextureFormat(ctx, internalFormat, + format, type); + + assert(texImage->TexFormat); + + switch (dims) { + case 1: + texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D; + texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df; + break; + case 2: + texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D; + texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df; + break; + case 3: + texImage->FetchTexelc = texImage->TexFormat->FetchTexel3D; + texImage->FetchTexelf = texImage->TexFormat->FetchTexel3Df; + break; + default: + assert(0); + break; + } + + texelBytes = texImage->TexFormat->TexelBytes; + + + /* Minimum pitch of 32 bytes */ + if (postConvWidth * texelBytes < 32) { + postConvWidth = 32 / texelBytes; + texImage->RowStride = postConvWidth; + } + + assert(texImage->RowStride == postConvWidth); + + /* Release the reference to a potentially orphaned buffer. + * Release any old malloced memory. + */ + if (intelImage->mt) { + intel_miptree_release(intel, &intelImage->mt); + assert(!texImage->Data); + } + else if (texImage->Data) { + _mesa_align_free(texImage->Data); + } + + /* If this is the only texture image in the tree, could call + * bmBufferData with NULL data to free the old block and avoid + * waiting on any outstanding fences. + */ + if (intelObj->mt && + intelObj->mt->first_level == level && + intelObj->mt->last_level == level && + intelObj->mt->target != GL_TEXTURE_CUBE_MAP_ARB && + !intel_miptree_match_image(intelObj->mt, &intelImage->base, + intelImage->face, intelImage->level)) { + + DBG("release it\n"); + intel_miptree_release(intel, &intelObj->mt); + assert(!intelObj->mt); + } + + if (!intelObj->mt) { + guess_and_alloc_mipmap_tree(intel, intelObj, intelImage); + if (!intelObj->mt) { + DBG("guess_and_alloc_mipmap_tree: failed\n"); + } + } + + + assert(!intelImage->mt); + + if (intelObj->mt && + intel_miptree_match_image(intelObj->mt, &intelImage->base, + intelImage->face, intelImage->level)) { + + intel_miptree_reference(&intelImage->mt, intelObj->mt); + assert(intelImage->mt); + } + + if (!intelImage->mt) + DBG("XXX: Image did not fit into tree - storing in local memory!\n"); + + /* PBO fastpaths: + */ + if (dims <= 2 && + intelImage->mt && + intel_buffer_object(unpack->BufferObj) && + check_pbo_format(internalFormat, format, + type, intelImage->base.TexFormat)) { + + DBG("trying pbo upload\n"); + + /* Attempt to texture directly from PBO data (zero copy upload). + * + * Currently disable as it can lead to worse as well as better + * performance (in particular when intel_region_cow() is + * required). + */ + if (intelObj->mt == intelImage->mt && + intelObj->mt->first_level == level && + intelObj->mt->last_level == level) { + + if (try_pbo_zcopy(intel, intelImage, unpack, + internalFormat, + width, height, format, type, pixels)) { + + DBG("pbo zcopy upload succeeded\n"); + return; + } + } + + + /* Otherwise, attempt to use the blitter for PBO image uploads. + */ + if (try_pbo_upload(intel, intelImage, unpack, + internalFormat, + width, height, format, type, pixels)) { + DBG("pbo upload succeeded\n"); + return; + } + + DBG("pbo upload failed\n"); + } + + + + /* intelCopyTexImage calls this function with pixels == NULL, with + * the expectation that the mipmap tree will be set up but nothing + * more will be done. This is where those calls return: + */ + pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, + format, type, + pixels, unpack, "glTexImage"); + if (!pixels) + return; + + + if (intelImage->mt) + intel_region_idle(intel->intelScreen, intelImage->mt->region); + + LOCK_HARDWARE(intel); + + if (intelImage->mt) { + texImage->Data = intel_miptree_image_map(intel, + intelImage->mt, + intelImage->face, + intelImage->level, + &dstRowStride, + intelImage->base.ImageOffsets); + } + else { + /* Allocate regular memory and store the image there temporarily. */ + if (texImage->IsCompressed) { + sizeInBytes = texImage->CompressedSize; + dstRowStride = + _mesa_compressed_row_stride(texImage->InternalFormat, width); + assert(dims != 3); + } + else { + dstRowStride = postConvWidth * texelBytes; + sizeInBytes = depth * dstRowStride * postConvHeight; + } + + texImage->Data = malloc(sizeInBytes); + } + + DBG("Upload image %dx%dx%d row_len %x " + "pitch %x\n", + width, height, depth, width * texelBytes, dstRowStride); + + /* Copy data. Would like to know when it's ok for us to eg. use + * the blitter to copy. Or, use the hardware to do the format + * conversion and copy: + */ + if (!texImage->TexFormat->StoreImage(ctx, dims, + texImage->_BaseFormat, + texImage->TexFormat, + texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */ + dstRowStride, + texImage->ImageOffsets, + width, height, depth, + format, type, pixels, unpack)) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); + } + + _mesa_unmap_teximage_pbo(ctx, unpack); + + if (intelImage->mt) { + intel_miptree_image_unmap(intel, intelImage->mt); + texImage->Data = NULL; + } + + UNLOCK_HARDWARE(intel); + +#if 0 + /* GL_SGIS_generate_mipmap -- this can be accelerated now. + */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + intel_generate_mipmap(ctx, target, + &ctx->Texture.Unit[ctx->Texture.CurrentUnit], + texObj); + } +#endif +} + +void +intelTexImage3D(GLcontext * ctx, + GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint depth, + GLint border, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *unpack, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + intelTexImage(ctx, 3, target, level, + internalFormat, width, height, depth, border, + format, type, pixels, unpack, texObj, texImage); +} + + +void +intelTexImage2D(GLcontext * ctx, + GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *unpack, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + intelTexImage(ctx, 2, target, level, + internalFormat, width, height, 1, border, + format, type, pixels, unpack, texObj, texImage); +} + +void +intelTexImage1D(GLcontext * ctx, + GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint border, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *unpack, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + intelTexImage(ctx, 1, target, level, + internalFormat, width, 1, 1, border, + format, type, pixels, unpack, texObj, texImage); +} + + + +/** + * Need to map texture image into memory before copying image data, + * then unmap it. + */ +void +intelGetTexImage(GLcontext * ctx, GLenum target, GLint level, + GLenum format, GLenum type, GLvoid * pixels, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_texture_image *intelImage = intel_texture_image(texImage); + + /* Map */ + if (intelImage->mt) { + /* Image is stored in hardware format in a buffer managed by the + * kernel. Need to explicitly map and unmap it. + */ + intelImage->base.Data = + intel_miptree_image_map(intel, + intelImage->mt, + intelImage->face, + intelImage->level, + &intelImage->base.RowStride, + intelImage->base.ImageOffsets); + } + else { + /* Otherwise, the image should actually be stored in + * intelImage->base.Data. This is pretty confusing for + * everybody, I'd much prefer to separate the two functions of + * texImage->Data - storage for texture images in main memory + * and access (ie mappings) of images. In other words, we'd + * create a new texImage->Map field and leave Data simply for + * storage. + */ + assert(intelImage->base.Data); + } + + _mesa_get_teximage(ctx, target, level, format, type, pixels, + texObj, texImage); + + /* Unmap */ + if (intelImage->mt) { + intel_miptree_image_unmap(intel, intelImage->mt); + intelImage->base.Data = NULL; + } +} diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_subimage.c b/src/mesa/drivers/dri/i915tex/intel_tex_subimage.c new file mode 100644 index 0000000000..25a2dca685 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_tex_subimage.c @@ -0,0 +1,183 @@ + +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "mtypes.h" +#include "texobj.h" +#include "texstore.h" +#include "enums.h" + +#include "intel_context.h" +#include "intel_tex.h" +#include "intel_mipmap_tree.h" + +#define FILE_DEBUG_FLAG DEBUG_TEXTURE + +static void +intelTexSubimage(GLcontext * ctx, + GLint dims, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint width, GLint height, GLint depth, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + struct intel_context *intel = intel_context(ctx); + struct intel_texture_image *intelImage = intel_texture_image(texImage); + GLuint dstImageStride; + GLuint dstRowStride; + + DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(target), + level, xoffset, yoffset, width, height); + + intelFlush(ctx); + + pixels = + _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, format, + type, pixels, packing, "glTexSubImage2D"); + if (!pixels) + return; + + if (intelImage->mt) + intel_region_idle(intel->intelScreen, intelImage->mt->region); + + LOCK_HARDWARE(intel); + + /* Map buffer if necessary. Need to lock to prevent other contexts + * from uploading the buffer under us. + */ + if (intelImage->mt) + texImage->Data = intel_miptree_image_map(intel, + intelImage->mt, + intelImage->face, + intelImage->level, + &dstRowStride, + &dstImageStride); + + assert(dstRowStride); + + if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat, + texImage->TexFormat, + texImage->Data, + xoffset, yoffset, zoffset, + dstRowStride, + texImage->ImageOffsets, + width, height, depth, + format, type, pixels, packing)) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage"); + } + +#if 0 + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + _mesa_generate_mipmap(ctx, target, + &ctx->Texture.Unit[ctx->Texture.CurrentUnit], + texObj); + } +#endif + + _mesa_unmap_teximage_pbo(ctx, packing); + + if (intelImage->mt) { + intel_miptree_image_unmap(intel, intelImage->mt); + texImage->Data = NULL; + } + + UNLOCK_HARDWARE(intel); +} + + + + + +void +intelTexSubImage3D(GLcontext * ctx, + GLenum target, + GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + + intelTexSubimage(ctx, 3, + target, level, + xoffset, yoffset, zoffset, + width, height, depth, + format, type, pixels, packing, texObj, texImage); + +} + + + +void +intelTexSubImage2D(GLcontext * ctx, + GLenum target, + GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + + intelTexSubimage(ctx, 2, + target, level, + xoffset, yoffset, 0, + width, height, 1, + format, type, pixels, packing, texObj, texImage); + +} + + +void +intelTexSubImage1D(GLcontext * ctx, + GLenum target, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, GLenum type, + const GLvoid * pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + intelTexSubimage(ctx, 1, + target, level, + xoffset, 0, 0, + width, 1, 1, + format, type, pixels, packing, texObj, texImage); + +} diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_validate.c b/src/mesa/drivers/dri/i915tex/intel_tex_validate.c new file mode 100644 index 0000000000..e273716b09 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_tex_validate.c @@ -0,0 +1,252 @@ +#include "mtypes.h" +#include "macros.h" + +#include "intel_context.h" +#include "intel_mipmap_tree.h" +#include "intel_tex.h" + +#define FILE_DEBUG_FLAG DEBUG_TEXTURE + +/** + * Compute which mipmap levels that really need to be sent to the hardware. + * This depends on the base image size, GL_TEXTURE_MIN_LOD, + * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. + */ +static void +intel_calculate_first_last_level(struct intel_texture_object *intelObj) +{ + struct gl_texture_object *tObj = &intelObj->base; + const struct gl_texture_image *const baseImage = + tObj->Image[0][tObj->BaseLevel]; + + /* These must be signed values. MinLod and MaxLod can be negative numbers, + * and having firstLevel and lastLevel as signed prevents the need for + * extra sign checks. + */ + int firstLevel; + int lastLevel; + + /* Yes, this looks overly complicated, but it's all needed. + */ + switch (tObj->Target) { + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + case GL_TEXTURE_CUBE_MAP: + if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) { + /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL. + */ + firstLevel = lastLevel = tObj->BaseLevel; + } + else { + firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5); + firstLevel = MAX2(firstLevel, tObj->BaseLevel); + lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5); + lastLevel = MAX2(lastLevel, tObj->BaseLevel); + lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2); + lastLevel = MIN2(lastLevel, tObj->MaxLevel); + lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */ + } + break; + case GL_TEXTURE_RECTANGLE_NV: + case GL_TEXTURE_4D_SGIS: + firstLevel = lastLevel = 0; + break; + default: + return; + } + + /* save these values */ + intelObj->firstLevel = firstLevel; + intelObj->lastLevel = lastLevel; +} + +static void +copy_image_data_to_tree(struct intel_context *intel, + struct intel_texture_object *intelObj, + struct intel_texture_image *intelImage) +{ + if (intelImage->mt) { + /* Copy potentially with the blitter: + */ + intel_miptree_image_copy(intel, + intelObj->mt, + intelImage->face, + intelImage->level, intelImage->mt); + + intel_miptree_release(intel, &intelImage->mt); + } + else { + assert(intelImage->base.Data != NULL); + + /* More straightforward upload. + */ + intel_miptree_image_data(intel, + intelObj->mt, + intelImage->face, + intelImage->level, + intelImage->base.Data, + intelImage->base.RowStride, + intelImage->base.RowStride * + intelImage->base.Height); + _mesa_align_free(intelImage->base.Data); + intelImage->base.Data = NULL; + } + + intel_miptree_reference(&intelImage->mt, intelObj->mt); +} + + +/* + */ +GLuint +intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) +{ + struct gl_texture_object *tObj = intel->ctx.Texture.Unit[unit]._Current; + struct intel_texture_object *intelObj = intel_texture_object(tObj); + + GLuint face, i; + GLuint nr_faces = 0; + struct intel_texture_image *firstImage; + + /* We know/require this is true by now: + */ + assert(intelObj->base.Complete); + + /* What levels must the tree include at a minimum? + */ + intel_calculate_first_last_level(intelObj); + firstImage = + intel_texture_image(intelObj->base.Image[0][intelObj->firstLevel]); + + /* Fallback case: + */ + if (firstImage->base.Border) { + if (intelObj->mt) { + intel_miptree_release(intel, &intelObj->mt); + } + return GL_FALSE; + } + + + /* If both firstImage and intelObj have a tree which can contain + * all active images, favour firstImage. Note that because of the + * completeness requirement, we know that the image dimensions + * will match. + */ + if (firstImage->mt && + firstImage->mt != intelObj->mt && + firstImage->mt->first_level <= intelObj->firstLevel && + firstImage->mt->last_level >= intelObj->lastLevel) { + + if (intelObj->mt) + intel_miptree_release(intel, &intelObj->mt); + + intel_miptree_reference(&intelObj->mt, firstImage->mt); + } + + /* Check tree can hold all active levels. Check tree matches + * target, imageFormat, etc. + * + * XXX: For some layouts (eg i945?), the test might have to be + * first_level == firstLevel, as the tree isn't valid except at the + * original start level. Hope to get around this by + * programming minLod, maxLod, baseLevel into the hardware and + * leaving the tree alone. + */ + if (intelObj->mt && + ((intelObj->mt->first_level > intelObj->firstLevel) || + (intelObj->mt->last_level < intelObj->lastLevel) || + (intelObj->mt->internal_format != firstImage->base.InternalFormat))) { + intel_miptree_release(intel, &intelObj->mt); + } + + + /* May need to create a new tree: + */ + if (!intelObj->mt) { + intelObj->mt = intel_miptree_create(intel, + intelObj->base.Target, + firstImage->base.InternalFormat, + intelObj->firstLevel, + intelObj->lastLevel, + firstImage->base.Width, + firstImage->base.Height, + firstImage->base.Depth, + firstImage->base.TexFormat-> + TexelBytes, + firstImage->base.IsCompressed); + } + + /* Pull in any images not in the object's tree: + */ + nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; + for (face = 0; face < nr_faces; face++) { + for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++) { + struct intel_texture_image *intelImage = + intel_texture_image(intelObj->base.Image[face][i]); + + /* Need to import images in main memory or held in other trees. + */ + if (intelObj->mt != intelImage->mt) { + copy_image_data_to_tree(intel, intelObj, intelImage); + } + } + } + + return GL_TRUE; +} + + + +void +intel_tex_map_images(struct intel_context *intel, + struct intel_texture_object *intelObj) +{ + GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; + GLuint face, i; + + DBG("%s\n", __FUNCTION__); + + for (face = 0; face < nr_faces; face++) { + for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++) { + struct intel_texture_image *intelImage = + intel_texture_image(intelObj->base.Image[face][i]); + + if (intelImage->mt) { + intelImage->base.Data = + intel_miptree_image_map(intel, + intelImage->mt, + intelImage->face, + intelImage->level, + &intelImage->base.RowStride, + intelImage->base.ImageOffsets); + /* convert stride to texels, not bytes */ + intelImage->base.RowStride /= intelImage->mt->cpp; +/* intelImage->base.ImageStride /= intelImage->mt->cpp; */ + } + } + } +} + + + +void +intel_tex_unmap_images(struct intel_context *intel, + struct intel_texture_object *intelObj) +{ + GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; + GLuint face, i; + + for (face = 0; face < nr_faces; face++) { + for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++) { + struct intel_texture_image *intelImage = + intel_texture_image(intelObj->base.Image[face][i]); + + if (intelImage->mt) { + intel_miptree_image_unmap(intel, intelImage->mt); + intelImage->base.Data = NULL; + } + } + } +} diff --git a/src/mesa/drivers/dri/i915tex/intel_tris.c b/src/mesa/drivers/dri/i915tex/intel_tris.c new file mode 100644 index 0000000000..1ba49d8f6e --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_tris.c @@ -0,0 +1,1149 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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 "glheader.h" +#include "context.h" +#include "macros.h" +#include "enums.h" +#include "texobj.h" +#include "state.h" +#include "dd.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" +#include "tnl/t_vertex.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_tris.h" +#include "intel_batchbuffer.h" +#include "intel_reg.h" +#include "intel_span.h" +#include "intel_tex.h" + +static void intelRenderPrimitive(GLcontext * ctx, GLenum prim); +static void intelRasterPrimitive(GLcontext * ctx, GLenum rprim, + GLuint hwprim); + +/* + */ +static void +intel_flush_inline_primitive(struct intel_context *intel) +{ + GLuint used = intel->batch->ptr - intel->prim.start_ptr; + + assert(intel->prim.primitive != ~0); + +/* _mesa_printf("/\n"); */ + + if (used < 8) + goto do_discard; + + *(int *) intel->prim.start_ptr = (_3DPRIMITIVE | + intel->prim.primitive | (used / 4 - 2)); + + goto finished; + + do_discard: + intel->batch->ptr -= used; + + finished: + intel->prim.primitive = ~0; + intel->prim.start_ptr = 0; + intel->prim.flush = 0; +} + + +/* Emit a primitive referencing vertices in a vertex buffer. + */ +void +intelStartInlinePrimitive(struct intel_context *intel, + GLuint prim, GLuint batch_flags) +{ + BATCH_LOCALS; + + intel->vtbl.emit_state(intel); + + /* Need to make sure at the very least that we don't wrap + * batchbuffers in BEGIN_BATCH below, otherwise the primitive will + * be emitted to a batchbuffer missing the required full-state + * preamble. + */ + if (intel_batchbuffer_space(intel->batch) < 100) { + intel_batchbuffer_flush(intel->batch); + intel->vtbl.emit_state(intel); + } + +/* _mesa_printf("%s *", __progname); */ + + /* Emit a slot which will be filled with the inline primitive + * command later. + */ + BEGIN_BATCH(2, batch_flags); + OUT_BATCH(0); + + intel->prim.start_ptr = intel->batch->ptr; + intel->prim.primitive = prim; + intel->prim.flush = intel_flush_inline_primitive; + + OUT_BATCH(0); + ADVANCE_BATCH(); + +/* _mesa_printf(">"); */ +} + + +void +intelWrapInlinePrimitive(struct intel_context *intel) +{ + GLuint prim = intel->prim.primitive; + GLuint batchflags = intel->batch->flags; + + intel_flush_inline_primitive(intel); + intel_batchbuffer_flush(intel->batch); + intelStartInlinePrimitive(intel, prim, batchflags); /* ??? */ +} + +GLuint * +intelExtendInlinePrimitive(struct intel_context *intel, GLuint dwords) +{ + GLuint sz = dwords * sizeof(GLuint); + GLuint *ptr; + + assert(intel->prim.flush == intel_flush_inline_primitive); + + if (intel_batchbuffer_space(intel->batch) < sz) + intelWrapInlinePrimitive(intel); + +/* _mesa_printf("."); */ + + intel->vtbl.assert_not_dirty(intel); + + ptr = (GLuint *) intel->batch->ptr; + intel->batch->ptr += sz; + + return ptr; +} + + + +/*********************************************************************** + * Emit primitives as inline vertices * + ***********************************************************************/ + +#ifdef __i386__ +#define COPY_DWORDS( j, vb, vertsize, v ) \ +do { \ + int __tmp; \ + __asm__ __volatile__( "rep ; movsl" \ + : "=%c" (j), "=D" (vb), "=S" (__tmp) \ + : "0" (vertsize), \ + "D" ((long)vb), \ + "S" ((long)v) ); \ +} while (0) +#else +#define COPY_DWORDS( j, vb, vertsize, v ) \ +do { \ + for ( j = 0 ; j < vertsize ; j++ ) { \ + vb[j] = ((GLuint *)v)[j]; \ + } \ + vb += vertsize; \ +} while (0) +#endif + +static void +intel_draw_quad(struct intel_context *intel, + intelVertexPtr v0, + intelVertexPtr v1, intelVertexPtr v2, intelVertexPtr v3) +{ + GLuint vertsize = intel->vertex_size; + GLuint *vb = intelExtendInlinePrimitive(intel, 6 * vertsize); + int j; + + COPY_DWORDS(j, vb, vertsize, v0); + COPY_DWORDS(j, vb, vertsize, v1); + + /* If smooth shading, draw like a trifan which gives better + * rasterization. Otherwise draw as two triangles with provoking + * vertex in third position as required for flat shading. + */ + if (intel->ctx.Light.ShadeModel == GL_FLAT) { + COPY_DWORDS(j, vb, vertsize, v3); + COPY_DWORDS(j, vb, vertsize, v1); + } + else { + COPY_DWORDS(j, vb, vertsize, v2); + COPY_DWORDS(j, vb, vertsize, v0); + } + + COPY_DWORDS(j, vb, vertsize, v2); + COPY_DWORDS(j, vb, vertsize, v3); +} + +static void +intel_draw_triangle(struct intel_context *intel, + intelVertexPtr v0, intelVertexPtr v1, intelVertexPtr v2) +{ + GLuint vertsize = intel->vertex_size; + GLuint *vb = intelExtendInlinePrimitive(intel, 3 * vertsize); + int j; + + COPY_DWORDS(j, vb, vertsize, v0); + COPY_DWORDS(j, vb, vertsize, v1); + COPY_DWORDS(j, vb, vertsize, v2); +} + + +static void +intel_draw_line(struct intel_context *intel, + intelVertexPtr v0, intelVertexPtr v1) +{ + GLuint vertsize = intel->vertex_size; + GLuint *vb = intelExtendInlinePrimitive(intel, 2 * vertsize); + int j; + + COPY_DWORDS(j, vb, vertsize, v0); + COPY_DWORDS(j, vb, vertsize, v1); +} + + +static void +intel_draw_point(struct intel_context *intel, intelVertexPtr v0) +{ + GLuint vertsize = intel->vertex_size; + GLuint *vb = intelExtendInlinePrimitive(intel, vertsize); + int j; + + /* Adjust for sub pixel position -- still required for conform. */ + *(float *) &vb[0] = v0->v.x - 0.125; + *(float *) &vb[1] = v0->v.y - 0.125; + for (j = 2; j < vertsize; j++) + vb[j] = v0->ui[j]; +} + + + +/*********************************************************************** + * Fixup for ARB_point_parameters * + ***********************************************************************/ + +/* Currently not working - VERT_ATTRIB_POINTSIZE isn't correctly + * represented in the fragment program InputsRead field. + */ +static void +intel_atten_point(struct intel_context *intel, intelVertexPtr v0) +{ + GLcontext *ctx = &intel->ctx; + GLfloat psz[4], col[4], restore_psz, restore_alpha; + + _tnl_get_attr(ctx, v0, _TNL_ATTRIB_POINTSIZE, psz); + _tnl_get_attr(ctx, v0, _TNL_ATTRIB_COLOR0, col); + + restore_psz = psz[0]; + restore_alpha = col[3]; + + if (psz[0] >= ctx->Point.Threshold) { + psz[0] = MIN2(psz[0], ctx->Point.MaxSize); + } + else { + GLfloat dsize = psz[0] / ctx->Point.Threshold; + psz[0] = MAX2(ctx->Point.Threshold, ctx->Point.MinSize); + col[3] *= dsize * dsize; + } + + if (psz[0] < 1.0) + psz[0] = 1.0; + + if (restore_psz != psz[0] || restore_alpha != col[3]) { + _tnl_set_attr(ctx, v0, _TNL_ATTRIB_POINTSIZE, psz); + _tnl_set_attr(ctx, v0, _TNL_ATTRIB_COLOR0, col); + + intel_draw_point(intel, v0); + + psz[0] = restore_psz; + col[3] = restore_alpha; + + _tnl_set_attr(ctx, v0, _TNL_ATTRIB_POINTSIZE, psz); + _tnl_set_attr(ctx, v0, _TNL_ATTRIB_COLOR0, col); + } + else + intel_draw_point(intel, v0); +} + + + + + +/*********************************************************************** + * Fixup for I915 WPOS texture coordinate * + ***********************************************************************/ + + + +static void +intel_wpos_triangle(struct intel_context *intel, + intelVertexPtr v0, intelVertexPtr v1, intelVertexPtr v2) +{ + GLuint offset = intel->wpos_offset; + GLuint size = intel->wpos_size; + + __memcpy(((char *) v0) + offset, v0, size); + __memcpy(((char *) v1) + offset, v1, size); + __memcpy(((char *) v2) + offset, v2, size); + + intel_draw_triangle(intel, v0, v1, v2); +} + + +static void +intel_wpos_line(struct intel_context *intel, + intelVertexPtr v0, intelVertexPtr v1) +{ + GLuint offset = intel->wpos_offset; + GLuint size = intel->wpos_size; + + __memcpy(((char *) v0) + offset, v0, size); + __memcpy(((char *) v1) + offset, v1, size); + + intel_draw_line(intel, v0, v1); +} + + +static void +intel_wpos_point(struct intel_context *intel, intelVertexPtr v0) +{ + GLuint offset = intel->wpos_offset; + GLuint size = intel->wpos_size; + + __memcpy(((char *) v0) + offset, v0, size); + + intel_draw_point(intel, v0); +} + + + + + + +/*********************************************************************** + * Macros for t_dd_tritmp.h to draw basic primitives * + ***********************************************************************/ + +#define TRI( a, b, c ) \ +do { \ + if (DO_FALLBACK) \ + intel->draw_tri( intel, a, b, c ); \ + else \ + intel_draw_triangle( intel, a, b, c ); \ +} while (0) + +#define QUAD( a, b, c, d ) \ +do { \ + if (DO_FALLBACK) { \ + intel->draw_tri( intel, a, b, d ); \ + intel->draw_tri( intel, b, c, d ); \ + } else \ + intel_draw_quad( intel, a, b, c, d ); \ +} while (0) + +#define LINE( v0, v1 ) \ +do { \ + if (DO_FALLBACK) \ + intel->draw_line( intel, v0, v1 ); \ + else \ + intel_draw_line( intel, v0, v1 ); \ +} while (0) + +#define POINT( v0 ) \ +do { \ + if (DO_FALLBACK) \ + intel->draw_point( intel, v0 ); \ + else \ + intel_draw_point( intel, v0 ); \ +} while (0) + + +/*********************************************************************** + * Build render functions from dd templates * + ***********************************************************************/ + +#define INTEL_OFFSET_BIT 0x01 +#define INTEL_TWOSIDE_BIT 0x02 +#define INTEL_UNFILLED_BIT 0x04 +#define INTEL_FALLBACK_BIT 0x08 +#define INTEL_MAX_TRIFUNC 0x10 + + +static struct +{ + tnl_points_func points; + tnl_line_func line; + tnl_triangle_func triangle; + tnl_quad_func quad; +} rast_tab[INTEL_MAX_TRIFUNC]; + + +#define DO_FALLBACK (IND & INTEL_FALLBACK_BIT) +#define DO_OFFSET (IND & INTEL_OFFSET_BIT) +#define DO_UNFILLED (IND & INTEL_UNFILLED_BIT) +#define DO_TWOSIDE (IND & INTEL_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 intelVertex +#define TAB rast_tab + +/* Only used to pull back colors into vertices (ie, we know color is + * floating point). + */ +#define INTEL_COLOR( dst, src ) \ +do { \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[0], (src)[2]); \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[1], (src)[1]); \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[2], (src)[0]); \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[3], (src)[3]); \ +} while (0) + +#define INTEL_SPEC( dst, src ) \ +do { \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[0], (src)[2]); \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[1], (src)[1]); \ + UNCLAMPED_FLOAT_TO_UBYTE((dst)[2], (src)[0]); \ +} while (0) + + +#define DEPTH_SCALE intel->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) (intel->verts + (e * intel->vertex_size * sizeof(GLuint))) + +#define VERT_SET_RGBA( v, c ) if (coloroffset) INTEL_COLOR( v->ub4[coloroffset], c ) +#define VERT_COPY_RGBA( v0, v1 ) if (coloroffset) v0->ui[coloroffset] = v1->ui[coloroffset] +#define VERT_SAVE_RGBA( idx ) if (coloroffset) color[idx] = v[idx]->ui[coloroffset] +#define VERT_RESTORE_RGBA( idx ) if (coloroffset) v[idx]->ui[coloroffset] = color[idx] + +#define VERT_SET_SPEC( v, c ) if (specoffset) INTEL_SPEC( v->ub4[specoffset], c ) +#define VERT_COPY_SPEC( v0, v1 ) if (specoffset) COPY_3V(v0->ub4[specoffset], v1->ub4[specoffset]) +#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 intel_context *intel = intel_context(ctx); \ + GLuint color[n], spec[n]; \ + GLuint coloroffset = intel->coloroffset; \ + GLboolean specoffset = intel->specoffset; \ + (void) color; (void) spec; (void) coloroffset; (void) specoffset; + + +/*********************************************************************** + * Helpers for rendering unfilled primitives * + ***********************************************************************/ + +static const GLuint hw_prim[GL_POLYGON + 1] = { + PRIM3D_POINTLIST, + PRIM3D_LINELIST, + PRIM3D_LINELIST, + PRIM3D_LINELIST, + PRIM3D_TRILIST, + PRIM3D_TRILIST, + PRIM3D_TRILIST, + PRIM3D_TRILIST, + PRIM3D_TRILIST, + PRIM3D_TRILIST +}; + +#define RASTERIZE(x) intelRasterPrimitive( ctx, x, hw_prim[x] ) +#define RENDER_PRIMITIVE intel->render_primitive +#define TAG(x) x +#define IND INTEL_FALLBACK_BIT +#include "tnl_dd/t_dd_unfilled.h" +#undef IND + +/*********************************************************************** + * Generate GL render functions * + ***********************************************************************/ + +#define IND (0) +#define TAG(x) x +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_OFFSET_BIT) +#define TAG(x) x##_offset +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_TWOSIDE_BIT) +#define TAG(x) x##_twoside +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT) +#define TAG(x) x##_twoside_offset +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_UNFILLED_BIT) +#define TAG(x) x##_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT) +#define TAG(x) x##_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_TWOSIDE_BIT|INTEL_UNFILLED_BIT) +#define TAG(x) x##_twoside_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT) +#define TAG(x) x##_twoside_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_FALLBACK_BIT) +#define TAG(x) x##_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_OFFSET_BIT|INTEL_FALLBACK_BIT) +#define TAG(x) x##_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_TWOSIDE_BIT|INTEL_FALLBACK_BIT) +#define TAG(x) x##_twoside_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT|INTEL_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_UNFILLED_BIT|INTEL_FALLBACK_BIT) +#define TAG(x) x##_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT|INTEL_FALLBACK_BIT) +#define TAG(x) x##_offset_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_TWOSIDE_BIT|INTEL_UNFILLED_BIT|INTEL_FALLBACK_BIT) +#define TAG(x) x##_twoside_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (INTEL_TWOSIDE_BIT|INTEL_OFFSET_BIT|INTEL_UNFILLED_BIT| \ + INTEL_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_unfilled_fallback +#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(); +} + + +/*********************************************************************** + * Rasterization fallback helpers * + ***********************************************************************/ + + +/* This code is hit only when a mix of accelerated and unaccelerated + * primitives are being drawn, and only for the unaccelerated + * primitives. + */ +static void +intel_fallback_tri(struct intel_context *intel, + intelVertex * v0, intelVertex * v1, intelVertex * v2) +{ + GLcontext *ctx = &intel->ctx; + SWvertex v[3]; + + if (0) + fprintf(stderr, "\n%s\n", __FUNCTION__); + + INTEL_FIREVERTICES(intel); + + _swsetup_Translate(ctx, v0, &v[0]); + _swsetup_Translate(ctx, v1, &v[1]); + _swsetup_Translate(ctx, v2, &v[2]); + intelSpanRenderStart(ctx); + _swrast_Triangle(ctx, &v[0], &v[1], &v[2]); + intelSpanRenderFinish(ctx); +} + + +static void +intel_fallback_line(struct intel_context *intel, + intelVertex * v0, intelVertex * v1) +{ + GLcontext *ctx = &intel->ctx; + SWvertex v[2]; + + if (0) + fprintf(stderr, "\n%s\n", __FUNCTION__); + + INTEL_FIREVERTICES(intel); + + _swsetup_Translate(ctx, v0, &v[0]); + _swsetup_Translate(ctx, v1, &v[1]); + intelSpanRenderStart(ctx); + _swrast_Line(ctx, &v[0], &v[1]); + intelSpanRenderFinish(ctx); +} + +static void +intel_fallback_point(struct intel_context *intel, + intelVertex * v0) +{ + GLcontext *ctx = &intel->ctx; + SWvertex v[1]; + + if (0) + fprintf(stderr, "\n%s\n", __FUNCTION__); + + INTEL_FIREVERTICES(intel); + + _swsetup_Translate(ctx, v0, &v[0]); + intelSpanRenderStart(ctx); + _swrast_Point(ctx, &v[0]); + intelSpanRenderFinish(ctx); +} + + +/**********************************************************************/ +/* Render unclipped begin/end objects */ +/**********************************************************************/ + +#define IND 0 +#define V(x) (intelVertex *)(vertptr + ((x)*vertsize*sizeof(GLuint))) +#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) intelRenderPrimitive( ctx, x ) +#undef LOCAL_VARS +#define LOCAL_VARS \ + struct intel_context *intel = intel_context(ctx); \ + GLubyte *vertptr = (GLubyte *)intel->verts; \ + const GLuint vertsize = intel->vertex_size; \ + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ + (void) elt; +#define RESET_STIPPLE +#define RESET_OCCLUSION +#define PRESERVE_VB_DEFS +#define ELT(x) x +#define TAG(x) intel_##x##_verts +#include "tnl/t_vb_rendertmp.h" +#undef ELT +#undef TAG +#define TAG(x) intel_##x##_elts +#define ELT(x) elt[x] +#include "tnl/t_vb_rendertmp.h" + +/**********************************************************************/ +/* Render clipped primitives */ +/**********************************************************************/ + + + +static void +intelRenderClippedPoly(GLcontext * ctx, const GLuint * elts, GLuint n) +{ + struct intel_context *intel = intel_context(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLuint prim = intel->render_primitive; + + /* 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) + tnl->Driver.Render.PrimitiveNotify(ctx, prim); +} + +static void +intelRenderClippedLine(GLcontext * ctx, GLuint ii, GLuint jj) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + tnl->Driver.Render.Line(ctx, ii, jj); +} + +static void +intelFastRenderClippedPoly(GLcontext * ctx, const GLuint * elts, GLuint n) +{ + struct intel_context *intel = intel_context(ctx); + const GLuint vertsize = intel->vertex_size; + GLuint *vb = intelExtendInlinePrimitive(intel, (n - 2) * 3 * vertsize); + GLubyte *vertptr = (GLubyte *) intel->verts; + const GLuint *start = (const GLuint *) V(elts[0]); + int i, j; + + for (i = 2; i < n; i++) { + COPY_DWORDS(j, vb, vertsize, V(elts[i - 1])); + COPY_DWORDS(j, vb, vertsize, V(elts[i])); + COPY_DWORDS(j, vb, vertsize, start); + } +} + +/**********************************************************************/ +/* Choose render functions */ +/**********************************************************************/ + + + + +#define ANY_FALLBACK_FLAGS (DD_LINE_STIPPLE | DD_TRI_STIPPLE | DD_POINT_ATTEN | DD_POINT_SMOOTH | DD_TRI_SMOOTH) +#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE | DD_TRI_OFFSET | DD_TRI_UNFILLED) + +void +intelChooseRenderState(GLcontext * ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); + GLuint flags = ctx->_TriangleCaps; + const struct gl_fragment_program *fprog = ctx->FragmentProgram._Current; + GLboolean have_wpos = (fprog && (fprog->Base.InputsRead & FRAG_BIT_WPOS)); + GLuint index = 0; + + if (INTEL_DEBUG & DEBUG_STATE) + fprintf(stderr, "\n%s\n", __FUNCTION__); + + if ((flags & (ANY_FALLBACK_FLAGS | ANY_RASTER_FLAGS)) || have_wpos) { + + if (flags & ANY_RASTER_FLAGS) { + if (flags & DD_TRI_LIGHT_TWOSIDE) + index |= INTEL_TWOSIDE_BIT; + if (flags & DD_TRI_OFFSET) + index |= INTEL_OFFSET_BIT; + if (flags & DD_TRI_UNFILLED) + index |= INTEL_UNFILLED_BIT; + } + + if (have_wpos) { + intel->draw_point = intel_wpos_point; + intel->draw_line = intel_wpos_line; + intel->draw_tri = intel_wpos_triangle; + + /* Make sure these get called: + */ + index |= INTEL_FALLBACK_BIT; + } + else { + intel->draw_point = intel_draw_point; + intel->draw_line = intel_draw_line; + intel->draw_tri = intel_draw_triangle; + } + + /* Hook in fallbacks for specific primitives. + */ + if (flags & ANY_FALLBACK_FLAGS) { + if (flags & DD_LINE_STIPPLE) + intel->draw_line = intel_fallback_line; + + if ((flags & DD_TRI_STIPPLE) && !intel->hw_stipple) + intel->draw_tri = intel_fallback_tri; + + if (flags & DD_TRI_SMOOTH) { + if (intel->strict_conformance) + intel->draw_tri = intel_fallback_tri; + } + + if (flags & DD_POINT_ATTEN) { + if (0) + intel->draw_point = intel_atten_point; + else + intel->draw_point = intel_fallback_point; + } + + if (flags & DD_POINT_SMOOTH) { + if (intel->strict_conformance) + intel->draw_point = intel_fallback_point; + } + + index |= INTEL_FALLBACK_BIT; + } + } + + if (intel->RenderIndex != index) { + intel->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 = intel_render_tab_verts; + tnl->Driver.Render.PrimTabElts = intel_render_tab_elts; + tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */ + tnl->Driver.Render.ClippedPolygon = intelFastRenderClippedPoly; + } + else { + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.ClippedLine = intelRenderClippedLine; + tnl->Driver.Render.ClippedPolygon = intelRenderClippedPoly; + } + } +} + +static const GLenum reduced_prim[GL_POLYGON + 1] = { + GL_POINTS, + GL_LINES, + GL_LINES, + GL_LINES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES +}; + + +/**********************************************************************/ +/* High level hooks for t_vb_render.c */ +/**********************************************************************/ + + + + +static void +intelRunPipeline(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + + _mesa_lock_context_textures(ctx); + + if (ctx->NewState) + _mesa_update_state_locked(ctx); + + if (intel->NewGLState) { + if (intel->NewGLState & _NEW_TEXTURE) { + intel->vtbl.update_texture_state(intel); + } + + if (!intel->Fallback) { + if (intel->NewGLState & _INTEL_NEW_RENDERSTATE) + intelChooseRenderState(ctx); + } + + intel->NewGLState = 0; + } + + _tnl_run_pipeline(ctx); + + _mesa_unlock_context_textures(ctx); +} + +static void +intelRenderStart(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + + intel->vtbl.render_start(intel_context(ctx)); + intel->vtbl.emit_state(intel); +} + +static void +intelRenderFinish(GLcontext * ctx) +{ + struct intel_context *intel = intel_context(ctx); + + if (intel->RenderIndex & INTEL_FALLBACK_BIT) + _swrast_flush(ctx); + + INTEL_FIREVERTICES(intel); +} + + + + + /* System to flush dma and emit state changes based on the rasterized + * primitive. + */ +static void +intelRasterPrimitive(GLcontext * ctx, GLenum rprim, GLuint hwprim) +{ + struct intel_context *intel = intel_context(ctx); + + if (0) + fprintf(stderr, "%s %s %x\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(rprim), hwprim); + + intel->vtbl.reduced_primitive_state(intel, rprim); + + /* Start a new primitive. Arrange to have it flushed later on. + */ + if (hwprim != intel->prim.primitive) { + INTEL_FIREVERTICES(intel); + + intelStartInlinePrimitive(intel, hwprim, INTEL_BATCH_CLIPRECTS); + } +} + + + /* + */ +static void +intelRenderPrimitive(GLcontext * ctx, GLenum prim) +{ + struct intel_context *intel = intel_context(ctx); + + if (0) + fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(prim)); + + /* Let some clipping routines know which primitive they're dealing + * with. + */ + intel->render_primitive = prim; + + /* Shortcircuit this when called from t_dd_rendertmp.h for unfilled + * triangles. The rasterized primitive will always be reset by + * lower level functions in that case, potentially pingponging the + * state: + */ + if (reduced_prim[prim] == GL_TRIANGLES && + (ctx->_TriangleCaps & DD_TRI_UNFILLED)) + return; + + /* Set some primitive-dependent state and Start? a new primitive. + */ + intelRasterPrimitive(ctx, reduced_prim[prim], hw_prim[prim]); +} + + + /**********************************************************************/ + /* Transition to/from hardware rasterization. */ + /**********************************************************************/ + +static char *fallbackStrings[] = { + [0] = "Draw buffer", + [1] = "Read buffer", + [2] = "Depth buffer", + [3] = "Stencil buffer", + [4] = "User disable", + [5] = "Render mode", + + [12] = "Texture", + [13] = "Color mask", + [14] = "Stencil", + [15] = "Stipple", + [16] = "Program", + [17] = "Logic op", + [18] = "Smooth polygon", + [19] = "Smooth point", +}; + + +static char * +getFallbackString(GLuint bit) +{ + int i = 0; + while (bit > 1) { + i++; + bit >>= 1; + } + return fallbackStrings[i]; +} + + + +void +intelFallback(struct intel_context *intel, GLuint bit, GLboolean mode) +{ + GLcontext *ctx = &intel->ctx; + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint oldfallback = intel->Fallback; + + if (mode) { + intel->Fallback |= bit; + if (oldfallback == 0) { + intelFlush(ctx); + if (INTEL_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "ENTER FALLBACK %x: %s\n", + bit, getFallbackString(bit)); + _swsetup_Wakeup(ctx); + intel->RenderIndex = ~0; + } + } + else { + intel->Fallback &= ~bit; + if (oldfallback == bit) { + _swrast_flush(ctx); + if (INTEL_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "LEAVE FALLBACK %s\n", getFallbackString(bit)); + tnl->Driver.Render.Start = intelRenderStart; + tnl->Driver.Render.PrimitiveNotify = intelRenderPrimitive; + tnl->Driver.Render.Finish = intelRenderFinish; + tnl->Driver.Render.BuildVertices = _tnl_build_vertices; + tnl->Driver.Render.CopyPV = _tnl_copy_pv; + tnl->Driver.Render.Interp = _tnl_interp; + + _tnl_invalidate_vertex_state(ctx, ~0); + _tnl_invalidate_vertices(ctx, ~0); + _tnl_install_attrs(ctx, + intel->vertex_attrs, + intel->vertex_attr_count, + intel->ViewportMatrix.m, 0); + + intel->NewGLState |= _INTEL_NEW_RENDERSTATE; + } + } +} + +union fi +{ + GLfloat f; + GLint i; +}; + + +/**********************************************************************/ +/* Used only with the metaops callbacks. */ +/**********************************************************************/ +void +intel_meta_draw_poly(struct intel_context *intel, + GLuint n, + GLfloat xy[][2], + GLfloat z, GLuint color, GLfloat tex[][2]) +{ + union fi *vb; + GLint i; + + /* All 3d primitives should be emitted with INTEL_BATCH_CLIPRECTS, + * otherwise the drawing origin (DR4) might not be set correctly. + */ + intelStartInlinePrimitive(intel, PRIM3D_TRIFAN, INTEL_BATCH_CLIPRECTS); + vb = (union fi *) intelExtendInlinePrimitive(intel, n * 6); + + for (i = 0; i < n; i++) { + vb[0].f = xy[i][0]; + vb[1].f = xy[i][1]; + vb[2].f = z; + vb[3].i = color; + vb[4].f = tex[i][0]; + vb[5].f = tex[i][1]; + vb += 6; + } + + INTEL_FIREVERTICES(intel); +} + +void +intel_meta_draw_quad(struct intel_context *intel, + GLfloat x0, GLfloat x1, + GLfloat y0, GLfloat y1, + GLfloat z, + GLuint color, + GLfloat s0, GLfloat s1, GLfloat t0, GLfloat t1) +{ + GLfloat xy[4][2]; + GLfloat tex[4][2]; + + xy[0][0] = x0; + xy[0][1] = y0; + xy[1][0] = x1; + xy[1][1] = y0; + xy[2][0] = x1; + xy[2][1] = y1; + xy[3][0] = x0; + xy[3][1] = y1; + + tex[0][0] = s0; + tex[0][1] = t0; + tex[1][0] = s1; + tex[1][1] = t0; + tex[2][0] = s1; + tex[2][1] = t1; + tex[3][0] = s0; + tex[3][1] = t1; + + intel_meta_draw_poly(intel, 4, xy, z, color, tex); +} + + + +/**********************************************************************/ +/* Initialization. */ +/**********************************************************************/ + + +void +intelInitTriFuncs(GLcontext * ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + static int firsttime = 1; + + if (firsttime) { + init_rast_tab(); + firsttime = 0; + } + + tnl->Driver.RunPipeline = intelRunPipeline; + tnl->Driver.Render.Start = intelRenderStart; + tnl->Driver.Render.Finish = intelRenderFinish; + tnl->Driver.Render.PrimitiveNotify = intelRenderPrimitive; + tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple; + tnl->Driver.Render.BuildVertices = _tnl_build_vertices; + tnl->Driver.Render.CopyPV = _tnl_copy_pv; + tnl->Driver.Render.Interp = _tnl_interp; +} diff --git a/src/mesa/drivers/dri/i915tex/intel_tris.h b/src/mesa/drivers/dri/i915tex/intel_tris.h new file mode 100644 index 0000000000..b7bae8cd3b --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_tris.h @@ -0,0 +1,69 @@ +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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. + * + **************************************************************************/ + +#ifndef INTELTRIS_INC +#define INTELTRIS_INC + +#include "mtypes.h" + + + +#define _INTEL_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE | \ + _DD_NEW_TRI_UNFILLED | \ + _DD_NEW_TRI_LIGHT_TWOSIDE | \ + _DD_NEW_TRI_OFFSET | \ + _DD_NEW_TRI_STIPPLE | \ + _NEW_PROGRAM | \ + _NEW_POLYGONSTIPPLE) + +extern void intelInitTriFuncs(GLcontext * ctx); + +extern void intelChooseRenderState(GLcontext * ctx); + +extern void intelStartInlinePrimitive(struct intel_context *intel, + GLuint prim, GLuint flags); +extern void intelWrapInlinePrimitive(struct intel_context *intel); + +GLuint *intelExtendInlinePrimitive(struct intel_context *intel, + GLuint dwords); + + +void intel_meta_draw_quad(struct intel_context *intel, + GLfloat x0, GLfloat x1, + GLfloat y0, GLfloat y1, + GLfloat z, + GLuint color, + GLfloat s0, GLfloat s1, GLfloat t0, GLfloat t1); + +void intel_meta_draw_poly(struct intel_context *intel, + GLuint n, + GLfloat xy[][2], + GLfloat z, GLuint color, GLfloat tex[][2]); + + + +#endif diff --git a/src/mesa/drivers/dri/i915tex/server/i830_common.h b/src/mesa/drivers/dri/i915tex/server/i830_common.h new file mode 100644 index 0000000000..fb6ceaa52d --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/server/i830_common.h @@ -0,0 +1,212 @@ +/************************************************************************** + +Copyright 2001 VA Linux Systems Inc., Fremont, California. +Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. + +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 +ATI, VA LINUX SYSTEMS AND/OR THEIR 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. + +**************************************************************************/ + +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h,v 1.1 2002/09/11 00:29:32 dawes Exp $ */ + +#ifndef _I830_COMMON_H_ +#define _I830_COMMON_H_ + + +#define I830_NR_TEX_REGIONS 255 /* maximum due to use of chars for next/prev */ +#define I830_LOG_MIN_TEX_REGION_SIZE 14 + + +/* Driver specific DRM command indices + * NOTE: these are not OS specific, but they are driver specific + */ +#define DRM_I830_INIT 0x00 +#define DRM_I830_FLUSH 0x01 +#define DRM_I830_FLIP 0x02 +#define DRM_I830_BATCHBUFFER 0x03 +#define DRM_I830_IRQ_EMIT 0x04 +#define DRM_I830_IRQ_WAIT 0x05 +#define DRM_I830_GETPARAM 0x06 +#define DRM_I830_SETPARAM 0x07 +#define DRM_I830_ALLOC 0x08 +#define DRM_I830_FREE 0x09 +#define DRM_I830_INIT_HEAP 0x0a +#define DRM_I830_CMDBUFFER 0x0b +#define DRM_I830_DESTROY_HEAP 0x0c + +typedef struct { + enum { + I830_INIT_DMA = 0x01, + I830_CLEANUP_DMA = 0x02, + I830_RESUME_DMA = 0x03 + } func; + unsigned int mmio_offset; + int sarea_priv_offset; + unsigned int ring_start; + unsigned int ring_end; + unsigned int ring_size; + unsigned int front_offset; + unsigned int back_offset; + unsigned int depth_offset; + unsigned int w; + unsigned int h; + unsigned int pitch; + unsigned int pitch_bits; + unsigned int back_pitch; + unsigned int depth_pitch; + unsigned int cpp; + unsigned int chipset; +} drmI830Init; + +typedef struct { + drmTextureRegion texList[I830_NR_TEX_REGIONS+1]; + int last_upload; /* last time texture was uploaded */ + int last_enqueue; /* last time a buffer was enqueued */ + int last_dispatch; /* age of the most recently dispatched buffer */ + int ctxOwner; /* last context to upload state */ + int texAge; + int pf_enabled; /* is pageflipping allowed? */ + int pf_active; + int pf_current_page; /* which buffer is being displayed? */ + int perf_boxes; /* performance boxes to be displayed */ + int width, height; /* screen size in pixels */ + + drm_handle_t front_handle; + int front_offset; + int front_size; + + drm_handle_t back_handle; + int back_offset; + int back_size; + + drm_handle_t depth_handle; + int depth_offset; + int depth_size; + + drm_handle_t tex_handle; + int tex_offset; + int tex_size; + int log_tex_granularity; + int pitch; + int rotation; /* 0, 90, 180 or 270 */ + int rotated_offset; + int rotated_size; + int rotated_pitch; + int virtualX, virtualY; + + unsigned int front_tiled; + unsigned int back_tiled; + unsigned int depth_tiled; + unsigned int rotated_tiled; + unsigned int rotated2_tiled; + + int pipeA_x; + int pipeA_y; + int pipeA_w; + int pipeA_h; + int pipeB_x; + int pipeB_y; + int pipeB_w; + int pipeB_h; +} drmI830Sarea; + +/* Flags for perf_boxes + */ +#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */ +#define I830_BOX_FLIP 0x2 /* populated by kernel */ +#define I830_BOX_WAIT 0x4 /* populated by kernel & client */ +#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */ +#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */ + + +typedef struct { + int start; /* agp offset */ + int used; /* nr bytes in use */ + int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ + int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/ + int num_cliprects; /* mulitpass with multiple cliprects? */ + drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ +} drmI830BatchBuffer; + +typedef struct { + char *buf; /* agp offset */ + int sz; /* nr bytes in use */ + int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ + int DR4; /* window origin for GFX_OP_DRAWRECT_INFO*/ + int num_cliprects; /* mulitpass with multiple cliprects? */ + drm_clip_rect_t *cliprects; /* pointer to userspace cliprects */ +} drmI830CmdBuffer; + +typedef struct { + int *irq_seq; +} drmI830IrqEmit; + +typedef struct { + int irq_seq; +} drmI830IrqWait; + +typedef struct { + int param; + int *value; +} drmI830GetParam; + +#define I830_PARAM_IRQ_ACTIVE 1 +#define I830_PARAM_ALLOW_BATCHBUFFER 2 + +typedef struct { + int param; + int value; +} drmI830SetParam; + +#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1 +#define I830_SETPARAM_TEX_LRU_LOG_GRANULARITY 2 +#define I830_SETPARAM_ALLOW_BATCHBUFFER 3 + + +/* A memory manager for regions of shared memory: + */ +#define I830_MEM_REGION_AGP 1 + +typedef struct { + int region; + int alignment; + int size; + int *region_offset; /* offset from start of fb or agp */ +} drmI830MemAlloc; + +typedef struct { + int region; + int region_offset; +} drmI830MemFree; + +typedef struct { + int region; + int size; + int start; +} drmI830MemInitHeap; + +typedef struct { + int region; +} drmI830MemDestroyHeap; + + +#endif /* _I830_DRM_H_ */ diff --git a/src/mesa/drivers/dri/i915tex/server/i830_dri.h b/src/mesa/drivers/dri/i915tex/server/i830_dri.h new file mode 100644 index 0000000000..6c9a709021 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/server/i830_dri.h @@ -0,0 +1,73 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.h,v 1.4 2002/10/30 12:52:18 alanh Exp $ */ + +#ifndef _I830_DRI_H +#define _I830_DRI_H + +#include "xf86drm.h" +#include "i830_common.h" + +#define I830_MAX_DRAWABLES 256 + +#define I830_MAJOR_VERSION 1 +#define I830_MINOR_VERSION 3 +#define I830_PATCHLEVEL 0 + +#define I830_REG_SIZE 0x80000 + +typedef struct _I830DRIRec { + drm_handle_t regs; + drmSize regsSize; + + drmSize backbufferSize; + drm_handle_t backbuffer; + + drmSize depthbufferSize; + drm_handle_t depthbuffer; + + drmSize rotatedSize; + drm_handle_t rotatedbuffer; + + drm_handle_t textures; + int textureSize; + + drm_handle_t agp_buffers; + drmSize agp_buf_size; + + int deviceID; + int width; + int height; + int mem; + int cpp; + int bitsPerPixel; + + int fbOffset; + int fbStride; + + int backOffset; + int backPitch; + + int depthOffset; + int depthPitch; + + int rotatedOffset; + int rotatedPitch; + + int logTextureGranularity; + int textureOffset; + + int irq; + int sarea_priv_offset; +} I830DRIRec, *I830DRIPtr; + +typedef struct { + /* Nothing here yet */ + int dummy; +} I830ConfigPrivRec, *I830ConfigPrivPtr; + +typedef struct { + /* Nothing here yet */ + int dummy; +} I830DRIContextRec, *I830DRIContextPtr; + + +#endif diff --git a/src/mesa/drivers/dri/i915tex/server/intel.h b/src/mesa/drivers/dri/i915tex/server/intel.h new file mode 100644 index 0000000000..d7858a20c8 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/server/intel.h @@ -0,0 +1,328 @@ +#ifndef _INTEL_H_ +#define _INTEL_H_ + +#include "xf86drm.h" /* drm_handle_t, etc */ + +/* Intel */ +#ifndef PCI_CHIP_I810 +#define PCI_CHIP_I810 0x7121 +#define PCI_CHIP_I810_DC100 0x7123 +#define PCI_CHIP_I810_E 0x7125 +#define PCI_CHIP_I815 0x1132 +#define PCI_CHIP_I810_BRIDGE 0x7120 +#define PCI_CHIP_I810_DC100_BRIDGE 0x7122 +#define PCI_CHIP_I810_E_BRIDGE 0x7124 +#define PCI_CHIP_I815_BRIDGE 0x1130 +#endif + +#define PCI_CHIP_845_G 0x2562 +#define PCI_CHIP_I830_M 0x3577 + +#ifndef PCI_CHIP_I855_GM +#define PCI_CHIP_I855_GM 0x3582 +#define PCI_CHIP_I855_GM_BRIDGE 0x3580 +#endif + +#ifndef PCI_CHIP_I865_G +#define PCI_CHIP_I865_G 0x2572 +#define PCI_CHIP_I865_G_BRIDGE 0x2570 +#endif + +#ifndef PCI_CHIP_I915_G +#define PCI_CHIP_I915_G 0x2582 +#define PCI_CHIP_I915_G_BRIDGE 0x2580 +#endif + +#ifndef PCI_CHIP_I915_GM +#define PCI_CHIP_I915_GM 0x2592 +#define PCI_CHIP_I915_GM_BRIDGE 0x2590 +#endif + +#ifndef PCI_CHIP_E7221_G +#define PCI_CHIP_E7221_G 0x258A +/* Same as I915_G_BRIDGE */ +#define PCI_CHIP_E7221_G_BRIDGE 0x2580 +#endif + +#ifndef PCI_CHIP_I945_G +#define PCI_CHIP_I945_G 0x2772 +#define PCI_CHIP_I945_G_BRIDGE 0x2770 +#endif + +#ifndef PCI_CHIP_I945_GM +#define PCI_CHIP_I945_GM 0x27A2 +#define PCI_CHIP_I945_GM_BRIDGE 0x27A0 +#endif + +#define IS_I810(pI810) (pI810->Chipset == PCI_CHIP_I810 || \ + pI810->Chipset == PCI_CHIP_I810_DC100 || \ + pI810->Chipset == PCI_CHIP_I810_E) +#define IS_I815(pI810) (pI810->Chipset == PCI_CHIP_I815) +#define IS_I830(pI810) (pI810->Chipset == PCI_CHIP_I830_M) +#define IS_845G(pI810) (pI810->Chipset == PCI_CHIP_845_G) +#define IS_I85X(pI810) (pI810->Chipset == PCI_CHIP_I855_GM) +#define IS_I852(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I852_GM || pI810->variant == I852_GME)) +#define IS_I855(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I855_GM || pI810->variant == I855_GME)) +#define IS_I865G(pI810) (pI810->Chipset == PCI_CHIP_I865_G) + +#define IS_I915G(pI810) (pI810->Chipset == PCI_CHIP_I915_G || pI810->Chipset == PCI_CHIP_E7221_G) +#define IS_I915GM(pI810) (pI810->Chipset == PCI_CHIP_I915_GM) +#define IS_I945G(pI810) (pI810->Chipset == PCI_CHIP_I945_G) +#define IS_I945GM(pI810) (pI810->Chipset == PCI_CHIP_I945_GM) +#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810)) + +#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810)) + +#define I830_GMCH_CTRL 0x52 + + +#define I830_GMCH_GMS_MASK 0x70 +#define I830_GMCH_GMS_DISABLED 0x00 +#define I830_GMCH_GMS_LOCAL 0x10 +#define I830_GMCH_GMS_STOLEN_512 0x20 +#define I830_GMCH_GMS_STOLEN_1024 0x30 +#define I830_GMCH_GMS_STOLEN_8192 0x40 + +#define I855_GMCH_GMS_MASK (0x7 << 4) +#define I855_GMCH_GMS_DISABLED 0x00 +#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) +#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4) +#define I855_GMCH_GMS_STOLEN_8M (0x3 << 4) +#define I855_GMCH_GMS_STOLEN_16M (0x4 << 4) +#define I855_GMCH_GMS_STOLEN_32M (0x5 << 4) +#define I915G_GMCH_GMS_STOLEN_48M (0x6 << 4) +#define I915G_GMCH_GMS_STOLEN_64M (0x7 << 4) + +typedef unsigned char Bool; +#define TRUE 1 +#define FALSE 0 + +#define PIPE_NONE 0<<0 +#define PIPE_CRT 1<<0 +#define PIPE_TV 1<<1 +#define PIPE_DFP 1<<2 +#define PIPE_LFP 1<<3 +#define PIPE_CRT2 1<<4 +#define PIPE_TV2 1<<5 +#define PIPE_DFP2 1<<6 +#define PIPE_LFP2 1<<7 + +typedef struct _I830MemPool *I830MemPoolPtr; +typedef struct _I830MemRange *I830MemRangePtr; +typedef struct _I830MemRange { + long Start; + long End; + long Size; + unsigned long Physical; + unsigned long Offset; /* Offset of AGP-allocated portion */ + unsigned long Alignment; + drm_handle_t Key; + unsigned long Pitch; // add pitch + I830MemPoolPtr Pool; +} I830MemRange; + +typedef struct _I830MemPool { + I830MemRange Total; + I830MemRange Free; + I830MemRange Fixed; + I830MemRange Allocated; +} I830MemPool; + +typedef struct { + int tail_mask; + I830MemRange mem; + unsigned char *virtual_start; + int head; + int tail; + int space; +} I830RingBuffer; + +typedef struct _I830Rec { + unsigned char *MMIOBase; + unsigned char *FbBase; + int cpp; + + unsigned int bios_version; + + /* These are set in PreInit and never changed. */ + long FbMapSize; + long TotalVideoRam; + I830MemRange StolenMemory; /* pre-allocated memory */ + long BIOSMemorySize; /* min stolen pool size */ + int BIOSMemSizeLoc; + + /* These change according to what has been allocated. */ + long FreeMemory; + I830MemRange MemoryAperture; + I830MemPool StolenPool; + long allocatedMemory; + + /* Regions allocated either from the above pools, or from agpgart. */ + /* for single and dual head configurations */ + I830MemRange FrontBuffer; + I830MemRange FrontBuffer2; + I830MemRange Scratch; + I830MemRange Scratch2; + + I830RingBuffer *LpRing; + + I830MemRange BackBuffer; + I830MemRange DepthBuffer; + I830MemRange TexMem; + int TexGranularity; + I830MemRange ContextMem; + int drmMinor; + Bool have3DWindows; + + Bool NeedRingBufferLow; + Bool allowPageFlip; + Bool disableTiling; + + int Chipset; + unsigned long LinearAddr; + unsigned long MMIOAddr; + + drmSize registerSize; /**< \brief MMIO register map size */ + drm_handle_t registerHandle; /**< \brief MMIO register map handle */ + // IOADDRESS ioBase; + int irq; /**< \brief IRQ number */ + int GttBound; + + drm_handle_t ring_map; + unsigned int Fence[8]; + +} I830Rec; + +/* + * 12288 is set as the maximum, chosen because it is enough for + * 1920x1440@32bpp with a 2048 pixel line pitch with some to spare. + */ +#define I830_MAXIMUM_VBIOS_MEM 12288 +#define I830_DEFAULT_VIDEOMEM_2D (MB(32) / 1024) +#define I830_DEFAULT_VIDEOMEM_3D (MB(64) / 1024) + +/* Flags for memory allocation function */ +#define FROM_ANYWHERE 0x00000000 +#define FROM_POOL_ONLY 0x00000001 +#define FROM_NEW_ONLY 0x00000002 +#define FROM_MASK 0x0000000f + +#define ALLOCATE_AT_TOP 0x00000010 +#define ALLOCATE_AT_BOTTOM 0x00000020 +#define FORCE_GAPS 0x00000040 + +#define NEED_PHYSICAL_ADDR 0x00000100 +#define ALIGN_BOTH_ENDS 0x00000200 +#define FORCE_LOW 0x00000400 + +#define ALLOC_NO_TILING 0x00001000 +#define ALLOC_INITIAL 0x00002000 + +#define ALLOCATE_DRY_RUN 0x80000000 + +/* Chipset registers for VIDEO BIOS memory RW access */ +#define _855_DRAM_RW_CONTROL 0x58 +#define _845_DRAM_RW_CONTROL 0x90 +#define DRAM_WRITE 0x33330000 + +#define KB(x) ((x) * 1024) +#define MB(x) ((x) * KB(1024)) + +#define GTT_PAGE_SIZE KB(4) +#define ROUND_TO(x, y) (((x) + (y) - 1) / (y) * (y)) +#define ROUND_DOWN_TO(x, y) ((x) / (y) * (y)) +#define ROUND_TO_PAGE(x) ROUND_TO((x), GTT_PAGE_SIZE) +#define ROUND_TO_MB(x) ROUND_TO((x), MB(1)) +#define PRIMARY_RINGBUFFER_SIZE KB(128) + + +/* Ring buffer registers, p277, overview p19 + */ +#define LP_RING 0x2030 +#define HP_RING 0x2040 + +#define RING_TAIL 0x00 +#define TAIL_ADDR 0x000FFFF8 +#define I830_TAIL_MASK 0x001FFFF8 + +#define RING_HEAD 0x04 +#define HEAD_WRAP_COUNT 0xFFE00000 +#define HEAD_WRAP_ONE 0x00200000 +#define HEAD_ADDR 0x001FFFFC +#define I830_HEAD_MASK 0x001FFFFC + +#define RING_START 0x08 +#define START_ADDR 0x03FFFFF8 +#define I830_RING_START_MASK 0xFFFFF000 + +#define RING_LEN 0x0C +#define RING_NR_PAGES 0x001FF000 +#define I830_RING_NR_PAGES 0x001FF000 +#define RING_REPORT_MASK 0x00000006 +#define RING_REPORT_64K 0x00000002 +#define RING_REPORT_128K 0x00000004 +#define RING_NO_REPORT 0x00000000 +#define RING_VALID_MASK 0x00000001 +#define RING_VALID 0x00000001 +#define RING_INVALID 0x00000000 + + +/* Fence/Tiling ranges [0..7] + */ +#define FENCE 0x2000 +#define FENCE_NR 8 + +#define I915G_FENCE_START_MASK 0x0ff00000 + +#define I830_FENCE_START_MASK 0x07f80000 + +#define FENCE_START_MASK 0x03F80000 +#define FENCE_X_MAJOR 0x00000000 +#define FENCE_Y_MAJOR 0x00001000 +#define FENCE_SIZE_MASK 0x00000700 +#define FENCE_SIZE_512K 0x00000000 +#define FENCE_SIZE_1M 0x00000100 +#define FENCE_SIZE_2M 0x00000200 +#define FENCE_SIZE_4M 0x00000300 +#define FENCE_SIZE_8M 0x00000400 +#define FENCE_SIZE_16M 0x00000500 +#define FENCE_SIZE_32M 0x00000600 +#define FENCE_SIZE_64M 0x00000700 +#define I915G_FENCE_SIZE_1M 0x00000000 +#define I915G_FENCE_SIZE_2M 0x00000100 +#define I915G_FENCE_SIZE_4M 0x00000200 +#define I915G_FENCE_SIZE_8M 0x00000300 +#define I915G_FENCE_SIZE_16M 0x00000400 +#define I915G_FENCE_SIZE_32M 0x00000500 +#define I915G_FENCE_SIZE_64M 0x00000600 +#define I915G_FENCE_SIZE_128M 0x00000700 +#define FENCE_PITCH_1 0x00000000 +#define FENCE_PITCH_2 0x00000010 +#define FENCE_PITCH_4 0x00000020 +#define FENCE_PITCH_8 0x00000030 +#define FENCE_PITCH_16 0x00000040 +#define FENCE_PITCH_32 0x00000050 +#define FENCE_PITCH_64 0x00000060 +#define FENCE_VALID 0x00000001 + +#include + +# define MMIO_IN8(base, offset) \ + *(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) +# define MMIO_IN32(base, offset) \ + read_MMIO_LE32(base, offset) +# define MMIO_OUT8(base, offset, val) \ + *(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) = (val) +# define MMIO_OUT32(base, offset, val) \ + *(volatile unsigned int *)(void *)(((unsigned char*)(base)) + (offset)) = CPU_TO_LE32(val) + + + /* Memory mapped register access macros */ +#define INREG8(addr) MMIO_IN8(MMIO, addr) +#define INREG(addr) MMIO_IN32(MMIO, addr) +#define OUTREG8(addr, val) MMIO_OUT8(MMIO, addr, val) +#define OUTREG(addr, val) MMIO_OUT32(MMIO, addr, val) + +#define DSPABASE 0x70184 + +#endif diff --git a/src/mesa/drivers/dri/i915tex/server/intel_dri.c b/src/mesa/drivers/dri/i915tex/server/intel_dri.c new file mode 100644 index 0000000000..169fdbece3 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/server/intel_dri.c @@ -0,0 +1,1282 @@ +/** + * \file server/intel_dri.c + * \brief File to perform the device-specific initialization tasks typically + * done in the X server. + * + * Here they are converted to run in the client (or perhaps a standalone + * process), and to work with the frame buffer device rather than the X + * server infrastructure. + * + * Copyright (C) 2006 Dave Airlie (airlied@linux.ie) + + 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 THE COPYRIGHT HOLDERS AND/OR THEIR 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 +#include +#include +#include +#include + +#include "driver.h" +#include "drm.h" + +#include "intel.h" +#include "i830_dri.h" + +#include "memops.h" +#include "pciaccess.h" + +static size_t drm_page_size; +static int nextTile = 0; +#define xf86DrvMsg(...) do {} while(0) + +static const int pitches[] = { + 128 * 8, + 128 * 16, + 128 * 32, + 128 * 64, + 0 +}; + +static Bool I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea); + +static unsigned long +GetBestTileAlignment(unsigned long size) +{ + unsigned long i; + + for (i = KB(512); i < size; i <<= 1) + ; + + if (i > MB(64)) + i = MB(64); + + return i; +} + +static void SetFenceRegs(const DRIDriverContext *ctx, I830Rec *pI830) +{ + int i; + unsigned char *MMIO = ctx->MMIOAddress; + + for (i = 0; i < 8; i++) { + OUTREG(FENCE + i * 4, pI830->Fence[i]); + // if (I810_DEBUG & DEBUG_VERBOSE_VGA) + fprintf(stderr,"Fence Register : %x\n", pI830->Fence[i]); + } +} + +/* Tiled memory is good... really, really good... + * + * Need to make it less likely that we miss out on this - probably + * need to move the frontbuffer away from the 'guarenteed' alignment + * of the first memory segment, or perhaps allocate a discontigous + * framebuffer to get more alignment 'sweet spots'. + */ +static void +SetFence(const DRIDriverContext *ctx, I830Rec *pI830, + int nr, unsigned int start, unsigned int pitch, + unsigned int size) +{ + unsigned int val; + unsigned int fence_mask = 0; + unsigned int fence_pitch; + + if (nr < 0 || nr > 7) { + fprintf(stderr, + "SetFence: fence %d out of range\n",nr); + return; + } + + pI830->Fence[nr] = 0; + + if (IS_I9XX(pI830)) + fence_mask = ~I915G_FENCE_START_MASK; + else + fence_mask = ~I830_FENCE_START_MASK; + + if (start & fence_mask) { + fprintf(stderr, + "SetFence: %d: start (0x%08x) is not %s aligned\n", + nr, start, (IS_I9XX(pI830)) ? "1MB" : "512k"); + return; + } + + if (start % size) { + fprintf(stderr, + "SetFence: %d: start (0x%08x) is not size (%dk) aligned\n", + nr, start, size / 1024); + return; + } + + if (pitch & 127) { + fprintf(stderr, + "SetFence: %d: pitch (%d) not a multiple of 128 bytes\n", + nr, pitch); + return; + } + + val = (start | FENCE_X_MAJOR | FENCE_VALID); + + if (IS_I9XX(pI830)) { + switch (size) { + case MB(1): + val |= I915G_FENCE_SIZE_1M; + break; + case MB(2): + val |= I915G_FENCE_SIZE_2M; + break; + case MB(4): + val |= I915G_FENCE_SIZE_4M; + break; + case MB(8): + val |= I915G_FENCE_SIZE_8M; + break; + case MB(16): + val |= I915G_FENCE_SIZE_16M; + break; + case MB(32): + val |= I915G_FENCE_SIZE_32M; + break; + case MB(64): + val |= I915G_FENCE_SIZE_64M; + break; + default: + fprintf(stderr, + "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); + return; + } + } else { + switch (size) { + case KB(512): + val |= FENCE_SIZE_512K; + break; + case MB(1): + val |= FENCE_SIZE_1M; + break; + case MB(2): + val |= FENCE_SIZE_2M; + break; + case MB(4): + val |= FENCE_SIZE_4M; + break; + case MB(8): + val |= FENCE_SIZE_8M; + break; + case MB(16): + val |= FENCE_SIZE_16M; + break; + case MB(32): + val |= FENCE_SIZE_32M; + break; + case MB(64): + val |= FENCE_SIZE_64M; + break; + default: + fprintf(stderr, + "SetFence: %d: illegal size (%d kByte)\n", nr, size / 1024); + return; + } + } + + if (IS_I9XX(pI830)) + fence_pitch = pitch / 512; + else + fence_pitch = pitch / 128; + + switch (fence_pitch) { + case 1: + val |= FENCE_PITCH_1; + break; + case 2: + val |= FENCE_PITCH_2; + break; + case 4: + val |= FENCE_PITCH_4; + break; + case 8: + val |= FENCE_PITCH_8; + break; + case 16: + val |= FENCE_PITCH_16; + break; + case 32: + val |= FENCE_PITCH_32; + break; + case 64: + val |= FENCE_PITCH_64; + break; + default: + fprintf(stderr, + "SetFence: %d: illegal pitch (%d)\n", nr, pitch); + return; + } + + pI830->Fence[nr] = val; +} + +static Bool +MakeTiles(const DRIDriverContext *ctx, I830Rec *pI830, I830MemRange *pMem) +{ + int pitch, ntiles, i; + + pitch = pMem->Pitch * ctx->cpp; + /* + * Simply try to break the region up into at most four pieces of size + * equal to the alignment. + */ + ntiles = ROUND_TO(pMem->Size, pMem->Alignment) / pMem->Alignment; + if (ntiles >= 4) { + return FALSE; + } + + for (i = 0; i < ntiles; i++, nextTile++) { + SetFence(ctx, pI830, nextTile, pMem->Start + i * pMem->Alignment, + pitch, pMem->Alignment); + } + return TRUE; +} + +static void I830SetupMemoryTiling(const DRIDriverContext *ctx, I830Rec *pI830) +{ + int i; + + /* Clear out */ + for (i = 0; i < 8; i++) + pI830->Fence[i] = 0; + + nextTile = 0; + + if (pI830->BackBuffer.Alignment >= KB(512)) { + if (MakeTiles(ctx, pI830, &(pI830->BackBuffer))) { + fprintf(stderr, + "Activating tiled memory for the back buffer.\n"); + } else { + fprintf(stderr, + "MakeTiles failed for the back buffer.\n"); + pI830->allowPageFlip = FALSE; + } + } + + if (pI830->DepthBuffer.Alignment >= KB(512)) { + if (MakeTiles(ctx, pI830, &(pI830->DepthBuffer))) { + fprintf(stderr, + "Activating tiled memory for the depth buffer.\n"); + } else { + fprintf(stderr, + "MakeTiles failed for the depth buffer.\n"); + } + } + + return; +} + +static int I830DetectMemory(const DRIDriverContext *ctx, I830Rec *pI830) +{ + struct pci_device host_bridge; + uint32_t gmch_ctrl; + int memsize = 0; + int range; + + memset(&host_bridge, 0, sizeof(host_bridge)); + + pci_device_cfg_read_u32(&host_bridge, &gmch_ctrl, I830_GMCH_CTRL); + + /* We need to reduce the stolen size, by the GTT and the popup. + * The GTT varying according the the FbMapSize and the popup is 4KB */ + range = (ctx->shared.fbSize / (1024*1024)) + 4; + + if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) { + switch (gmch_ctrl & I830_GMCH_GMS_MASK) { + case I855_GMCH_GMS_STOLEN_1M: + memsize = MB(1) - KB(range); + break; + case I855_GMCH_GMS_STOLEN_4M: + memsize = MB(4) - KB(range); + break; + case I855_GMCH_GMS_STOLEN_8M: + memsize = MB(8) - KB(range); + break; + case I855_GMCH_GMS_STOLEN_16M: + memsize = MB(16) - KB(range); + break; + case I855_GMCH_GMS_STOLEN_32M: + memsize = MB(32) - KB(range); + break; + case I915G_GMCH_GMS_STOLEN_48M: + if (IS_I9XX(pI830)) + memsize = MB(48) - KB(range); + break; + case I915G_GMCH_GMS_STOLEN_64M: + if (IS_I9XX(pI830)) + memsize = MB(64) - KB(range); + break; + } + } else { + switch (gmch_ctrl & I830_GMCH_GMS_MASK) { + case I830_GMCH_GMS_STOLEN_512: + memsize = KB(512) - KB(range); + break; + case I830_GMCH_GMS_STOLEN_1024: + memsize = MB(1) - KB(range); + break; + case I830_GMCH_GMS_STOLEN_8192: + memsize = MB(8) - KB(range); + break; + case I830_GMCH_GMS_LOCAL: + memsize = 0; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Local memory found, but won't be used.\n"); + break; + } + } + if (memsize > 0) { + fprintf(stderr, + "detected %d kB stolen memory.\n", memsize / 1024); + } else { + fprintf(stderr, + "no video memory detected.\n"); + } + return memsize; +} + +static int AgpInit(const DRIDriverContext *ctx, I830Rec *info) +{ + unsigned long mode = 0x4; + + if (drmAgpAcquire(ctx->drmFD) < 0) { + fprintf(stderr, "[gart] AGP not available\n"); + return 0; + } + + if (drmAgpEnable(ctx->drmFD, mode) < 0) { + fprintf(stderr, "[gart] AGP not enabled\n"); + drmAgpRelease(ctx->drmFD); + return 0; + } + else + fprintf(stderr, "[gart] AGP enabled at %dx\n", ctx->agpmode); + + return 1; +} + +/* + * Allocate memory from the given pool. Grow the pool if needed and if + * possible. + */ +static unsigned long +AllocFromPool(const DRIDriverContext *ctx, I830Rec *pI830, + I830MemRange *result, I830MemPool *pool, + long size, unsigned long alignment, int flags) +{ + long needed, start, end; + + if (!result || !pool || !size) + return 0; + + /* Calculate how much space is needed. */ + if (alignment <= GTT_PAGE_SIZE) + needed = size; + else { + start = ROUND_TO(pool->Free.Start, alignment); + end = ROUND_TO(start + size, alignment); + needed = end - pool->Free.Start; + } + if (needed > pool->Free.Size) { + return 0; + } + + result->Start = ROUND_TO(pool->Free.Start, alignment); + pool->Free.Start += needed; + result->End = pool->Free.Start; + + pool->Free.Size = pool->Free.End - pool->Free.Start; + result->Size = result->End - result->Start; + result->Pool = pool; + result->Alignment = alignment; + return needed; +} + +static unsigned long AllocFromAGP(const DRIDriverContext *ctx, I830Rec *pI830, long size, unsigned long alignment, I830MemRange *result) +{ + unsigned long start, end; + unsigned long newApStart, newApEnd; + int ret; + if (!result || !size) + return 0; + + if (!alignment) + alignment = 4; + + start = ROUND_TO(pI830->MemoryAperture.Start, alignment); + end = ROUND_TO(start + size, alignment); + newApStart = end; + newApEnd = pI830->MemoryAperture.End; + + ret=drmAgpAlloc(ctx->drmFD, size, 0, &(result->Physical), (drm_handle_t *)&(result->Key)); + + if (ret) + { + fprintf(stderr,"drmAgpAlloc failed %d\n", ret); + return 0; + } + pI830->allocatedMemory += size; + pI830->MemoryAperture.Start = newApStart; + pI830->MemoryAperture.End = newApEnd; + pI830->MemoryAperture.Size = newApEnd - newApStart; + // pI830->FreeMemory -= size; + result->Start = start; + result->End = start + size; + result->Size = size; + result->Offset = start; + result->Alignment = alignment; + result->Pool = NULL; + + return size; +} + +unsigned long +I830AllocVidMem(const DRIDriverContext *ctx, I830Rec *pI830, I830MemRange *result, I830MemPool *pool, long size, unsigned long alignment, int flags) +{ + int ret; + + if (!result) + return 0; + + /* Make sure these are initialised. */ + result->Size = 0; + result->Key = -1; + + if (!size) { + return 0; + } + + if (pool->Free.Size < size) + return AllocFromAGP(ctx, pI830, size, alignment, result); + else + { + ret = AllocFromPool(ctx, pI830, result, pool, size, alignment, flags); + + if (ret==0) + return AllocFromAGP(ctx, pI830, size, alignment, result); + return ret; + } +} + +static Bool BindAgpRange(const DRIDriverContext *ctx, I830MemRange *mem) +{ + if (!mem) + return FALSE; + + if (mem->Key == -1) + return TRUE; + + return !drmAgpBind(ctx->drmFD, mem->Key, mem->Offset); +} + +/* simple memory allocation routines needed */ +/* put ring buffer in low memory */ +/* need to allocate front, back, depth buffers aligned correctly, + allocate ring buffer, +*/ + +/* */ +static Bool +I830AllocateMemory(const DRIDriverContext *ctx, I830Rec *pI830) +{ + unsigned long size, ret; + unsigned long lines, lineSize, align; + + /* allocate ring buffer */ + memset(pI830->LpRing, 0, sizeof(I830RingBuffer)); + pI830->LpRing->mem.Key = -1; + + size = PRIMARY_RINGBUFFER_SIZE; + + ret = I830AllocVidMem(ctx, pI830, &pI830->LpRing->mem, &pI830->StolenPool, size, 0x1000, 0); + + if (ret != size) + { + fprintf(stderr,"unable to allocate ring buffer %ld\n", ret); + return FALSE; + } + + pI830->LpRing->tail_mask = pI830->LpRing->mem.Size - 1; + + + /* allocate front buffer */ + memset(&(pI830->FrontBuffer), 0, sizeof(pI830->FrontBuffer)); + pI830->FrontBuffer.Key = -1; + pI830->FrontBuffer.Pitch = ctx->shared.virtualWidth; + + align = KB(512); + + lineSize = ctx->shared.virtualWidth * ctx->cpp; + lines = (ctx->shared.virtualHeight + 15) / 16 * 16; + size = lineSize * lines; + size = ROUND_TO_PAGE(size); + + align = GetBestTileAlignment(size); + + ret = I830AllocVidMem(ctx, pI830, &pI830->FrontBuffer, &pI830->StolenPool, size, align, 0); + if (ret < size) + { + fprintf(stderr,"unable to allocate front buffer %ld\n", ret); + return FALSE; + } + + memset(&(pI830->BackBuffer), 0, sizeof(pI830->BackBuffer)); + pI830->BackBuffer.Key = -1; + pI830->BackBuffer.Pitch = ctx->shared.virtualWidth; + + ret = I830AllocVidMem(ctx, pI830, &pI830->BackBuffer, &pI830->StolenPool, size, align, 0); + if (ret < size) + { + fprintf(stderr,"unable to allocate back buffer %ld\n", ret); + return FALSE; + } + + memset(&(pI830->DepthBuffer), 0, sizeof(pI830->DepthBuffer)); + pI830->DepthBuffer.Key = -1; + pI830->DepthBuffer.Pitch = ctx->shared.virtualWidth; + + ret = I830AllocVidMem(ctx, pI830, &pI830->DepthBuffer, &pI830->StolenPool, size, align, 0); + if (ret < size) + { + fprintf(stderr,"unable to allocate depth buffer %ld\n", ret); + return FALSE; + } + + memset(&(pI830->ContextMem), 0, sizeof(pI830->ContextMem)); + pI830->ContextMem.Key = -1; + size = KB(32); + + ret = I830AllocVidMem(ctx, pI830, &pI830->ContextMem, &pI830->StolenPool, size, align, 0); + if (ret < size) + { + fprintf(stderr,"unable to allocate context buffer %ld\n", ret); + return FALSE; + } + + memset(&(pI830->TexMem), 0, sizeof(pI830->TexMem)); + pI830->TexMem.Key = -1; + + size = 32768 * 1024; + ret = AllocFromAGP(ctx, pI830, size, align, &pI830->TexMem); + if (ret < size) + { + fprintf(stderr,"unable to allocate texture memory %ld\n", ret); + return FALSE; + } + + return TRUE; +} + +static Bool +I830BindMemory(const DRIDriverContext *ctx, I830Rec *pI830) +{ + if (!BindAgpRange(ctx, &pI830->LpRing->mem)) + return FALSE; + if (!BindAgpRange(ctx, &pI830->FrontBuffer)) + return FALSE; + if (!BindAgpRange(ctx, &pI830->BackBuffer)) + return FALSE; + if (!BindAgpRange(ctx, &pI830->DepthBuffer)) + return FALSE; + if (!BindAgpRange(ctx, &pI830->ContextMem)) + return FALSE; + if (!BindAgpRange(ctx, &pI830->TexMem)) + return FALSE; + + return TRUE; +} + +static Bool +I830CleanupDma(const DRIDriverContext *ctx) +{ + drmI830Init info; + + memset(&info, 0, sizeof(drmI830Init)); + info.func = I830_CLEANUP_DMA; + + if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT, + &info, sizeof(drmI830Init))) { + fprintf(stderr, "I830 Dma Cleanup Failed\n"); + return FALSE; + } + + return TRUE; +} + +static Bool +I830InitDma(const DRIDriverContext *ctx, I830Rec *pI830) +{ + I830RingBuffer *ring = pI830->LpRing; + drmI830Init info; + + memset(&info, 0, sizeof(drmI830Init)); + info.func = I830_INIT_DMA; + + info.ring_start = ring->mem.Start + pI830->LinearAddr; + info.ring_end = ring->mem.End + pI830->LinearAddr; + info.ring_size = ring->mem.Size; + + info.mmio_offset = (unsigned int)ctx->MMIOStart; + + info.sarea_priv_offset = sizeof(drm_sarea_t); + + info.front_offset = pI830->FrontBuffer.Start; + info.back_offset = pI830->BackBuffer.Start; + info.depth_offset = pI830->DepthBuffer.Start; + info.w = ctx->shared.virtualWidth; + info.h = ctx->shared.virtualHeight; + info.pitch = ctx->shared.virtualWidth; + info.back_pitch = pI830->BackBuffer.Pitch; + info.depth_pitch = pI830->DepthBuffer.Pitch; + info.cpp = ctx->cpp; + + if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT, + &info, sizeof(drmI830Init))) { + fprintf(stderr, + "I830 Dma Initialization Failed\n"); + return FALSE; + } + + return TRUE; +} + +static int I830CheckDRMVersion( const DRIDriverContext *ctx, + I830Rec *pI830 ) +{ + drmVersionPtr version; + + version = drmGetVersion(ctx->drmFD); + + if (version) { + int req_minor, req_patch; + + req_minor = 4; + req_patch = 0; + + if (version->version_major != 1 || + version->version_minor < req_minor || + (version->version_minor == req_minor && + version->version_patchlevel < req_patch)) { + /* Incompatible drm version */ + fprintf(stderr, + "[dri] I830DRIScreenInit failed because of a version " + "mismatch.\n" + "[dri] i915.o kernel module version is %d.%d.%d " + "but version 1.%d.%d or newer is needed.\n" + "[dri] Disabling DRI.\n", + version->version_major, + version->version_minor, + version->version_patchlevel, + req_minor, + req_patch); + drmFreeVersion(version); + return 0; + } + + pI830->drmMinor = version->version_minor; + drmFreeVersion(version); + } + return 1; +} + +static void +I830SetRingRegs(const DRIDriverContext *ctx, I830Rec *pI830) +{ + unsigned int itemp; + unsigned char *MMIO = ctx->MMIOAddress; + + OUTREG(LP_RING + RING_LEN, 0); + OUTREG(LP_RING + RING_TAIL, 0); + OUTREG(LP_RING + RING_HEAD, 0); + + if ((long)(pI830->LpRing->mem.Start & I830_RING_START_MASK) != + pI830->LpRing->mem.Start) { + fprintf(stderr, + "I830SetRingRegs: Ring buffer start (%lx) violates its " + "mask (%x)\n", pI830->LpRing->mem.Start, I830_RING_START_MASK); + } + /* Don't care about the old value. Reserved bits must be zero anyway. */ + itemp = pI830->LpRing->mem.Start & I830_RING_START_MASK; + OUTREG(LP_RING + RING_START, itemp); + + if (((pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES) != + pI830->LpRing->mem.Size - 4096) { + fprintf(stderr, + "I830SetRingRegs: Ring buffer size - 4096 (%lx) violates its " + "mask (%x)\n", pI830->LpRing->mem.Size - 4096, + I830_RING_NR_PAGES); + } + /* Don't care about the old value. Reserved bits must be zero anyway. */ + itemp = (pI830->LpRing->mem.Size - 4096) & I830_RING_NR_PAGES; + itemp |= (RING_NO_REPORT | RING_VALID); + OUTREG(LP_RING + RING_LEN, itemp); + + pI830->LpRing->head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK; + pI830->LpRing->tail = INREG(LP_RING + RING_TAIL); + pI830->LpRing->space = pI830->LpRing->head - (pI830->LpRing->tail + 8); + if (pI830->LpRing->space < 0) + pI830->LpRing->space += pI830->LpRing->mem.Size; + + SetFenceRegs(ctx, pI830); + + /* RESET THE DISPLAY PIPE TO POINT TO THE FRONTBUFFER - hacky + hacky hacky */ + OUTREG(DSPABASE, pI830->FrontBuffer.Start + pI830->LinearAddr); + +} + +static Bool +I830SetParam(const DRIDriverContext *ctx, int param, int value) +{ + drmI830SetParam sp; + + memset(&sp, 0, sizeof(sp)); + sp.param = param; + sp.value = value; + + if (drmCommandWrite(ctx->drmFD, DRM_I830_SETPARAM, &sp, sizeof(sp))) { + fprintf(stderr, "I830 SetParam Failed\n"); + return FALSE; + } + + return TRUE; +} + +static Bool +I830DRIMapScreenRegions(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) +{ + fprintf(stderr, + "[drm] Mapping front buffer\n"); + + if (drmAddMap(ctx->drmFD, + (drm_handle_t)(sarea->front_offset + pI830->LinearAddr), + sarea->front_size, + DRM_FRAME_BUFFER, /*DRM_AGP,*/ + 0, + &sarea->front_handle) < 0) { + fprintf(stderr, + "[drm] drmAddMap(front_handle) failed. Disabling DRI\n"); + return FALSE; + } + ctx->shared.hFrameBuffer = sarea->front_handle; + ctx->shared.fbSize = sarea->front_size; + fprintf(stderr, "[drm] Front Buffer = 0x%08x\n", + sarea->front_handle); + + if (drmAddMap(ctx->drmFD, + (drm_handle_t)(sarea->back_offset), + sarea->back_size, DRM_AGP, 0, + &sarea->back_handle) < 0) { + fprintf(stderr, + "[drm] drmAddMap(back_handle) failed. Disabling DRI\n"); + return FALSE; + } + fprintf(stderr, "[drm] Back Buffer = 0x%08x\n", + sarea->back_handle); + + if (drmAddMap(ctx->drmFD, + (drm_handle_t)sarea->depth_offset, + sarea->depth_size, DRM_AGP, 0, + &sarea->depth_handle) < 0) { + fprintf(stderr, + "[drm] drmAddMap(depth_handle) failed. Disabling DRI\n"); + return FALSE; + } + fprintf(stderr, "[drm] Depth Buffer = 0x%08x\n", + sarea->depth_handle); + + if (drmAddMap(ctx->drmFD, + (drm_handle_t)sarea->tex_offset, + sarea->tex_size, DRM_AGP, 0, + &sarea->tex_handle) < 0) { + fprintf(stderr, + "[drm] drmAddMap(tex_handle) failed. Disabling DRI\n"); + return FALSE; + } + fprintf(stderr, "[drm] textures = 0x%08x\n", + sarea->tex_handle); + + return TRUE; +} + + +static void +I830DRIUnmapScreenRegions(const DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) +{ +#if 1 + if (sarea->front_handle) { + drmRmMap(ctx->drmFD, sarea->front_handle); + sarea->front_handle = 0; + } +#endif + if (sarea->back_handle) { + drmRmMap(ctx->drmFD, sarea->back_handle); + sarea->back_handle = 0; + } + if (sarea->depth_handle) { + drmRmMap(ctx->drmFD, sarea->depth_handle); + sarea->depth_handle = 0; + } + if (sarea->tex_handle) { + drmRmMap(ctx->drmFD, sarea->tex_handle); + sarea->tex_handle = 0; + } +} + +static void +I830InitTextureHeap(const DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) +{ + /* Start up the simple memory manager for agp space */ + drmI830MemInitHeap drmHeap; + drmHeap.region = I830_MEM_REGION_AGP; + drmHeap.start = 0; + drmHeap.size = sarea->tex_size; + + if (drmCommandWrite(ctx->drmFD, DRM_I830_INIT_HEAP, + &drmHeap, sizeof(drmHeap))) { + fprintf(stderr, + "[drm] Failed to initialized agp heap manager\n"); + } else { + fprintf(stderr, + "[drm] Initialized kernel agp heap manager, %d\n", + sarea->tex_size); + + I830SetParam(ctx, I830_SETPARAM_TEX_LRU_LOG_GRANULARITY, + sarea->log_tex_granularity); + } +} + +static Bool +I830DRIDoMappings(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) +{ + if (drmAddMap(ctx->drmFD, + (drm_handle_t)pI830->LpRing->mem.Start, + pI830->LpRing->mem.Size, DRM_AGP, 0, + &pI830->ring_map) < 0) { + fprintf(stderr, + "[drm] drmAddMap(ring_map) failed. Disabling DRI\n"); + return FALSE; + } + fprintf(stderr, "[drm] ring buffer = 0x%08x\n", + pI830->ring_map); + + if (I830InitDma(ctx, pI830) == FALSE) { + return FALSE; + } + + /* init to zero to be safe */ + + I830DRIMapScreenRegions(ctx, pI830, sarea); + I830InitTextureHeap(ctx, pI830, sarea); + + if (ctx->pciDevice != PCI_CHIP_845_G && + ctx->pciDevice != PCI_CHIP_I830_M) { + I830SetParam(ctx, I830_SETPARAM_USE_MI_BATCHBUFFER_START, 1 ); + } + + /* Okay now initialize the dma engine */ + { + pI830->irq = drmGetInterruptFromBusID(ctx->drmFD, + ctx->pciBus, + ctx->pciDevice, + ctx->pciFunc); + + if (drmCtlInstHandler(ctx->drmFD, pI830->irq)) { + fprintf(stderr, + "[drm] failure adding irq handler\n"); + pI830->irq = 0; + return FALSE; + } + else + fprintf(stderr, + "[drm] dma control initialized, using IRQ %d\n", + pI830->irq); + } + + fprintf(stderr, "[dri] visual configs initialized\n"); + + return TRUE; +} + +static Bool +I830ClearScreen(DRIDriverContext *ctx, I830Rec *pI830, drmI830Sarea *sarea) +{ + /* need to drmMap front and back buffers and zero them */ + drmAddress map_addr; + int ret; + + ret = drmMap(ctx->drmFD, + sarea->front_handle, + sarea->front_size, + &map_addr); + + if (ret) + { + fprintf(stderr, "Unable to map front buffer\n"); + return FALSE; + } + + drimemsetio((char *)map_addr, + 0, + sarea->front_size); + drmUnmap(map_addr, sarea->front_size); + + + ret = drmMap(ctx->drmFD, + sarea->back_handle, + sarea->back_size, + &map_addr); + + if (ret) + { + fprintf(stderr, "Unable to map back buffer\n"); + return FALSE; + } + + drimemsetio((char *)map_addr, + 0, + sarea->back_size); + drmUnmap(map_addr, sarea->back_size); + + return TRUE; +} + +static Bool +I830ScreenInit(DRIDriverContext *ctx, I830Rec *pI830) + +{ + I830DRIPtr pI830DRI; + drmI830Sarea *pSAREAPriv; + int err; + + drm_page_size = getpagesize(); + + pI830->registerSize = ctx->MMIOSize; + /* This is a hack for now. We have to have more than a 4k page here + * because of the size of the state. However, the state should be + * in a per-context mapping. This will be added in the Mesa 3.5 port + * of the I830 driver. + */ + ctx->shared.SAREASize = SAREA_MAX; + + /* Note that drmOpen will try to load the kernel module, if needed. */ + ctx->drmFD = drmOpen("i915", NULL ); + if (ctx->drmFD < 0) { + fprintf(stderr, "[drm] drmOpen failed\n"); + return 0; + } + + if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) { + fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", + ctx->drmFD, ctx->pciBusID, strerror(-err)); + return 0; + } + + if (drmAddMap( ctx->drmFD, + 0, + ctx->shared.SAREASize, + DRM_SHM, + DRM_CONTAINS_LOCK, + &ctx->shared.hSAREA) < 0) + { + fprintf(stderr, "[drm] drmAddMap failed\n"); + return 0; + } + + fprintf(stderr, "[drm] added %d byte SAREA at 0x%08x\n", + ctx->shared.SAREASize, ctx->shared.hSAREA); + + if (drmMap( ctx->drmFD, + ctx->shared.hSAREA, + ctx->shared.SAREASize, + (drmAddressPtr)(&ctx->pSAREA)) < 0) + { + fprintf(stderr, "[drm] drmMap failed\n"); + return 0; + + } + + memset(ctx->pSAREA, 0, ctx->shared.SAREASize); + fprintf(stderr, "[drm] mapped SAREA 0x%08x to %p, size %d\n", + ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize); + + + if (drmAddMap(ctx->drmFD, + ctx->MMIOStart, + ctx->MMIOSize, + DRM_REGISTERS, + DRM_READ_ONLY, + &pI830->registerHandle) < 0) { + fprintf(stderr, "[drm] drmAddMap mmio failed\n"); + return 0; + } + fprintf(stderr, + "[drm] register handle = 0x%08x\n", pI830->registerHandle); + + + if (!I830CheckDRMVersion(ctx, pI830)) { + return FALSE; + } + + /* Create a 'server' context so we can grab the lock for + * initialization ioctls. + */ + if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) { + fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); + return 0; + } + + DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0); + + /* Initialize the SAREA private data structure */ + pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) + + sizeof(drm_sarea_t)); + memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); + + pI830->StolenMemory.Size = I830DetectMemory(ctx, pI830); + pI830->StolenMemory.Start = 0; + pI830->StolenMemory.End = pI830->StolenMemory.Size; + + pI830->MemoryAperture.Start = pI830->StolenMemory.End; + pI830->MemoryAperture.End = KB(40000); + pI830->MemoryAperture.Size = pI830->MemoryAperture.End - pI830->MemoryAperture.Start; + + pI830->StolenPool.Fixed = pI830->StolenMemory; + pI830->StolenPool.Total = pI830->StolenMemory; + pI830->StolenPool.Free = pI830->StolenPool.Total; + pI830->FreeMemory = pI830->StolenPool.Total.Size; + + if (!AgpInit(ctx, pI830)) + return FALSE; + + if (I830AllocateMemory(ctx, pI830) == FALSE) + { + return FALSE; + } + + if (I830BindMemory(ctx, pI830) == FALSE) + { + return FALSE; + } + + pSAREAPriv->front_offset = pI830->FrontBuffer.Start; + pSAREAPriv->front_size = pI830->FrontBuffer.Size; + pSAREAPriv->width = ctx->shared.virtualWidth; + pSAREAPriv->height = ctx->shared.virtualHeight; + pSAREAPriv->pitch = ctx->shared.virtualWidth; + pSAREAPriv->virtualX = ctx->shared.virtualWidth; + pSAREAPriv->virtualY = ctx->shared.virtualHeight; + pSAREAPriv->back_offset = pI830->BackBuffer.Start; + pSAREAPriv->back_size = pI830->BackBuffer.Size; + pSAREAPriv->depth_offset = pI830->DepthBuffer.Start; + pSAREAPriv->depth_size = pI830->DepthBuffer.Size; + pSAREAPriv->tex_offset = pI830->TexMem.Start; + pSAREAPriv->tex_size = pI830->TexMem.Size; + pSAREAPriv->log_tex_granularity = pI830->TexGranularity; + + ctx->driverClientMsg = malloc(sizeof(I830DRIRec)); + ctx->driverClientMsgSize = sizeof(I830DRIRec); + pI830DRI = (I830DRIPtr)ctx->driverClientMsg; + pI830DRI->deviceID = pI830->Chipset; + pI830DRI->regsSize = I830_REG_SIZE; + pI830DRI->width = ctx->shared.virtualWidth; + pI830DRI->height = ctx->shared.virtualHeight; + pI830DRI->mem = ctx->shared.fbSize; + pI830DRI->cpp = ctx->cpp; + pI830DRI->backOffset = pI830->BackBuffer.Start; + pI830DRI->backPitch = pI830->BackBuffer.Pitch; + + pI830DRI->depthOffset = pI830->DepthBuffer.Start; + pI830DRI->depthPitch = pI830->DepthBuffer.Pitch; + + pI830DRI->fbOffset = pI830->FrontBuffer.Start; + pI830DRI->fbStride = pI830->FrontBuffer.Pitch; + + pI830DRI->bitsPerPixel = ctx->bpp; + pI830DRI->sarea_priv_offset = sizeof(drm_sarea_t); + + err = I830DRIDoMappings(ctx, pI830, pSAREAPriv); + if (err == FALSE) + return FALSE; + + I830SetupMemoryTiling(ctx, pI830); + + /* Quick hack to clear the front & back buffers. Could also use + * the clear ioctl to do this, but would need to setup hw state + * first. + */ + I830ClearScreen(ctx, pI830, pSAREAPriv); + + I830SetRingRegs(ctx, pI830); + + return TRUE; +} + + +/** + * \brief Validate the fbdev mode. + * + * \param ctx display handle. + * + * \return one on success, or zero on failure. + * + * Saves some registers and returns 1. + * + * \sa radeonValidateMode(). + */ +static int i830ValidateMode( const DRIDriverContext *ctx ) +{ + return 1; +} + +/** + * \brief Examine mode returned by fbdev. + * + * \param ctx display handle. + * + * \return one on success, or zero on failure. + * + * Restores registers that fbdev has clobbered and returns 1. + * + * \sa i810ValidateMode(). + */ +static int i830PostValidateMode( const DRIDriverContext *ctx ) +{ + I830Rec *pI830 = ctx->driverPrivate; + + I830SetRingRegs(ctx, pI830); + return 1; +} + + +/** + * \brief Initialize the framebuffer device mode + * + * \param ctx display handle. + * + * \return one on success, or zero on failure. + * + * Fills in \p info with some default values and some information from \p ctx + * and then calls I810ScreenInit() for the screen initialization. + * + * Before exiting clears the framebuffer memory accessing it directly. + */ +static int i830InitFBDev( DRIDriverContext *ctx ) +{ + I830Rec *pI830 = calloc(1, sizeof(I830Rec)); + int i; + + { + int dummy = ctx->shared.virtualWidth; + + switch (ctx->bpp / 8) { + case 1: dummy = (ctx->shared.virtualWidth + 127) & ~127; break; + case 2: dummy = (ctx->shared.virtualWidth + 31) & ~31; break; + case 3: + case 4: dummy = (ctx->shared.virtualWidth + 15) & ~15; break; + } + + ctx->shared.virtualWidth = dummy; + ctx->shared.Width = ctx->shared.virtualWidth; + } + + + for (i = 0; pitches[i] != 0; i++) { + if (pitches[i] >= ctx->shared.virtualWidth) { + ctx->shared.virtualWidth = pitches[i]; + break; + } + } + + ctx->driverPrivate = (void *)pI830; + + pI830->LpRing = calloc(1, sizeof(I830RingBuffer)); + pI830->Chipset = ctx->chipset; + pI830->LinearAddr = ctx->FBStart; + + if (!I830ScreenInit( ctx, pI830 )) + return 0; + + + return 1; +} + + +/** + * \brief The screen is being closed, so clean up any state and free any + * resources used by the DRI. + * + * \param ctx display handle. + * + * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver + * private data. + */ +static void i830HaltFBDev( DRIDriverContext *ctx ) +{ + drmI830Sarea *pSAREAPriv; + I830Rec *pI830 = ctx->driverPrivate; + + if (pI830->irq) { + drmCtlUninstHandler(ctx->drmFD); + pI830->irq = 0; } + + I830CleanupDma(ctx); + + pSAREAPriv = (drmI830Sarea *)(((char*)ctx->pSAREA) + + sizeof(drm_sarea_t)); + + I830DRIUnmapScreenRegions(ctx, pI830, pSAREAPriv); + drmUnmap( ctx->pSAREA, ctx->shared.SAREASize ); + drmClose(ctx->drmFD); + + if (ctx->driverPrivate) { + free(ctx->driverPrivate); + ctx->driverPrivate = 0; + } +} + + +extern void i810NotifyFocus( int ); + +/** + * \brief Exported driver interface for Mini GLX. + * + * \sa DRIDriverRec. + */ +const struct DRIDriverRec __driDriver = { + i830ValidateMode, + i830PostValidateMode, + i830InitFBDev, + i830HaltFBDev, + NULL,//I830EngineShutdown, + NULL, //I830EngineRestore, +#ifndef _EMBEDDED + 0, +#else + i810NotifyFocus, +#endif +}; diff --git a/src/mesa/drivers/dri/i965/intel_blit.c b/src/mesa/drivers/dri/i965/intel_blit.c index e501f5e660..0974f1f80a 100644 --- a/src/mesa/drivers/dri/i965/intel_blit.c +++ b/src/mesa/drivers/dri/i965/intel_blit.c @@ -322,14 +322,14 @@ void intelEmitCopyBlit( struct intel_context *intel, -void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, - GLint cx1, GLint cy1, GLint cw, GLint ch) +void intelClearWithBlit(GLcontext *ctx, GLbitfield flags) { struct intel_context *intel = intel_context( ctx ); intelScreenPrivate *intelScreen = intel->intelScreen; GLuint clear_depth, clear_color; - GLint cx, cy; + GLint cx, cy, cw, ch; GLint cpp = intelScreen->cpp; + GLboolean all; GLint i; struct intel_region *front = intel->front_region; struct intel_region *back = intel->back_region; @@ -376,21 +376,16 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, intelFlush( &intel->ctx ); LOCK_HARDWARE( intel ); { - /* Refresh the cx/y/w/h values as they may have been invalidated - * by a new window position or size picked up when we did - * LOCK_HARDWARE above. The values passed by mesa are not - * reliable. - */ - { - cx = ctx->DrawBuffer->_Xmin; - cy = ctx->DrawBuffer->_Ymin; - ch = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; - cw = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; - } + /* get clear bounds after locking */ + cx = ctx->DrawBuffer->_Xmin; + cy = ctx->DrawBuffer->_Ymin; + ch = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; + cw = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; + all = (cw == ctx->DrawBuffer->Width && ch == ctx->DrawBuffer->Height); /* flip top to bottom */ - cy = intel->driDrawable->h-cy1-ch; - cx = cx1 + intel->drawX; + cy = intel->driDrawable->h - cy - ch; + cx = cx + intel->drawX; cy += intel->drawY; /* adjust for page flipping */ diff --git a/src/mesa/drivers/dri/i965/intel_blit.h b/src/mesa/drivers/dri/i965/intel_blit.h index 71ce830778..b15fb1c2b7 100644 --- a/src/mesa/drivers/dri/i965/intel_blit.h +++ b/src/mesa/drivers/dri/i965/intel_blit.h @@ -35,8 +35,7 @@ struct buffer; extern void intelCopyBuffer( const __DRIdrawablePrivate *dpriv, const drm_clip_rect_t *rect ); -extern void intelClearWithBlit(GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint cx1, GLint cy1, GLint cw, GLint ch); +extern void intelClearWithBlit(GLcontext *ctx, GLbitfield mask); extern void intelEmitCopyBlit( struct intel_context *intel, GLuint cpp, diff --git a/src/mesa/drivers/dri/i965/intel_buffers.c b/src/mesa/drivers/dri/i965/intel_buffers.c index dc5b9c0bc4..d155c039d7 100644 --- a/src/mesa/drivers/dri/i965/intel_buffers.c +++ b/src/mesa/drivers/dri/i965/intel_buffers.c @@ -224,12 +224,11 @@ void intelWindowMoved( struct intel_context *intel ) * machine independent. Maybe we'll get there one day. */ static void intelClearWithTris(struct intel_context *intel, - GLbitfield mask, - GLboolean all, - GLint cx, GLint cy, - GLint cw, GLint ch) + GLbitfield mask) { + GLcontext *ctx = &intel->ctx; drm_clip_rect_t clear; + GLint cx, cy, cw, ch; if (INTEL_DEBUG & DEBUG_DRI) _mesa_printf("%s %x\n", __FUNCTION__, mask); @@ -238,18 +237,11 @@ static void intelClearWithTris(struct intel_context *intel, intel->vtbl.install_meta_state(intel); - /* Refresh the cx/y/w/h values as they may have been invalidated - * by a new window position or size picked up when we did - * LOCK_HARDWARE above. The values passed by mesa are not - * reliable. - */ - { - GLcontext *ctx = &intel->ctx; - cx = ctx->DrawBuffer->_Xmin; - cy = ctx->DrawBuffer->_Ymin; - ch = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; - cw = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; - } + /* Get clear bounds after locking */ + cx = ctx->DrawBuffer->_Xmin; + cy = ctx->DrawBuffer->_Ymin; + cw = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; + ch = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; clear.x1 = cx; clear.y1 = cy; @@ -327,11 +319,7 @@ static void intelClearWithTris(struct intel_context *intel, -static void intelClear(GLcontext *ctx, - GLbitfield mask, - GLboolean all, - GLint cx, GLint cy, - GLint cw, GLint ch) +static void intelClear(GLcontext *ctx, GLbitfield mask) { struct intel_context *intel = intel_context( ctx ); const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); @@ -340,8 +328,7 @@ static void intelClear(GLcontext *ctx, GLbitfield swrast_mask = 0; if (INTEL_DEBUG & DEBUG_DRI) - fprintf(stderr, "%s %x all %d dims %d,%d %dx%d\n", __FUNCTION__, - mask, all, cx, cy, cw, ch); + fprintf(stderr, "%s %x\n", __FUNCTION__, mask); if (mask & BUFFER_BIT_FRONT_LEFT) { @@ -392,13 +379,13 @@ static void intelClear(GLcontext *ctx, intelFlush( ctx ); if (blit_mask) - intelClearWithBlit( ctx, blit_mask, all, cx, cy, cw, ch ); + intelClearWithBlit( ctx, blit_mask ); if (tri_mask) - intelClearWithTris( intel, tri_mask, all, cx, cy, cw, ch); + intelClearWithTris( intel, tri_mask ); if (swrast_mask) - _swrast_Clear( ctx, swrast_mask, all, cx, cy, cw, ch ); + _swrast_Clear( ctx, swrast_mask ); } diff --git a/src/mesa/drivers/dri/mach64/mach64_ioctl.c b/src/mesa/drivers/dri/mach64/mach64_ioctl.c index 30a45ad034..36e7d3c5d3 100644 --- a/src/mesa/drivers/dri/mach64/mach64_ioctl.c +++ b/src/mesa/drivers/dri/mach64/mach64_ioctl.c @@ -665,8 +665,7 @@ void mach64PerformanceBoxesLocked( mach64ContextPtr mmesa ) * Buffer clear */ -static void mach64DDClear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, - GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo ) +static void mach64DDClear( GLcontext *ctx, GLbitfield mask ) { mach64ContextPtr mmesa = MACH64_CONTEXT( ctx ); __DRIdrawablePrivate *dPriv = mmesa->driDrawable; @@ -713,7 +712,7 @@ static void mach64DDClear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, } if ( mask ) - _swrast_Clear( ctx, mask, 0, 0, 0, 0, 0 ); + _swrast_Clear( ctx, mask ); if ( !flags ) return; diff --git a/src/mesa/drivers/dri/mga/mga_xmesa.c b/src/mesa/drivers/dri/mga/mga_xmesa.c index 32cfbc6a1c..f024f73eb6 100644 --- a/src/mesa/drivers/dri/mga/mga_xmesa.c +++ b/src/mesa/drivers/dri/mga/mga_xmesa.c @@ -883,7 +883,6 @@ mgaMakeCurrent(__DRIcontextPrivate *driContextPriv, mmesa->driDrawable = driDrawPriv; mmesa->dirty = ~0; mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK); - mmesa->mesa_drawable = driDrawPriv; } mmesa->driReadable = driReadPriv; diff --git a/src/mesa/drivers/dri/mga/mgacontext.h b/src/mesa/drivers/dri/mga/mgacontext.h index 81348b6c7f..2124006ade 100644 --- a/src/mesa/drivers/dri/mga/mgacontext.h +++ b/src/mesa/drivers/dri/mga/mgacontext.h @@ -303,13 +303,6 @@ struct mga_context_t { __DRIdrawablePrivate *driDrawable; __DRIdrawablePrivate *driReadable; - /** - * Drawable used by Mesa for software fallbacks for reading and - * writing. It is set by Mesa's \c SetBuffer callback, and will always be - * either \c mga_context_t::driDrawable or \c mga_context_t::driReadable. - */ - __DRIdrawablePrivate *mesa_drawable; - __DRIscreenPrivate *driScreen; struct mga_screen_private_s *mgaScreen; drm_mga_sarea_t *sarea; diff --git a/src/mesa/drivers/dri/mga/mgadd.c b/src/mesa/drivers/dri/mga/mgadd.c index faf46f3139..b1d5e0c48f 100644 --- a/src/mesa/drivers/dri/mga/mgadd.c +++ b/src/mesa/drivers/dri/mga/mgadd.c @@ -41,7 +41,7 @@ #include "mga_xmesa.h" #include "utils.h" -#define DRIVER_DATE "20050609" +#define DRIVER_DATE "20061030" /*************************************** @@ -74,24 +74,7 @@ static const GLubyte *mgaGetString( GLcontext *ctx, GLenum name ) } -static void mgaBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height) -{ - GET_CURRENT_CONTEXT(ctx); - mgaContextPtr mmesa = MGA_CONTEXT(ctx); - - /* Need to lock to make sure the driDrawable is uptodate. This - * information is used to resize Mesa's software buffers, so it has - * to be correct. - */ - LOCK_HARDWARE( mmesa ); - *width = mmesa->driDrawable->w; - *height = mmesa->driDrawable->h; - UNLOCK_HARDWARE( mmesa ); -} - - void mgaInitDriverFuncs( struct dd_function_table *functions ) { - functions->GetBufferSize = mgaBufferSize; functions->GetString = mgaGetString; } diff --git a/src/mesa/drivers/dri/mga/mgaioctl.c b/src/mesa/drivers/dri/mga/mgaioctl.c index c9fa9d1294..f8587fc541 100644 --- a/src/mesa/drivers/dri/mga/mgaioctl.c +++ b/src/mesa/drivers/dri/mga/mgaioctl.c @@ -204,8 +204,7 @@ drmBufPtr mga_get_buffer_ioctl( mgaContextPtr mmesa ) static void -mgaClear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, - GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo ) +mgaClear( GLcontext *ctx, GLbitfield mask ) { mgaContextPtr mmesa = MGA_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = mmesa->driDrawable; @@ -334,7 +333,7 @@ mgaClear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, } if (mask) - _swrast_Clear( ctx, mask, 0, 0, 0, 0, 0 ); + _swrast_Clear( ctx, mask ); } diff --git a/src/mesa/drivers/dri/mga/mgaspan.c b/src/mesa/drivers/dri/mga/mgaspan.c index dbc7fc884c..05dcbb8526 100644 --- a/src/mesa/drivers/dri/mga/mgaspan.c +++ b/src/mesa/drivers/dri/mga/mgaspan.c @@ -36,9 +36,9 @@ #define LOCAL_VARS \ mgaContextPtr mmesa = MGA_CONTEXT(ctx); \ - __DRIdrawablePrivate *dPriv = mmesa->mesa_drawable; \ __DRIscreenPrivate *sPriv = mmesa->driScreen; \ driRenderbuffer *drb = (driRenderbuffer *) rb; \ + const __DRIdrawablePrivate *dPriv = drb->dPriv; \ GLuint pitch = drb->pitch; \ GLuint height = dPriv->h; \ char *buf = (char *)(sPriv->pFB + \ @@ -52,9 +52,9 @@ #define LOCAL_DEPTH_VARS \ mgaContextPtr mmesa = MGA_CONTEXT(ctx); \ - __DRIdrawablePrivate *dPriv = mmesa->mesa_drawable; \ __DRIscreenPrivate *sPriv = mmesa->driScreen; \ driRenderbuffer *drb = (driRenderbuffer *) rb; \ + const __DRIdrawablePrivate *dPriv = drb->dPriv; \ GLuint pitch = drb->pitch; \ GLuint height = dPriv->h; \ char *buf = (char *)(sPriv->pFB + \ diff --git a/src/mesa/drivers/dri/mga/mgastate.c b/src/mesa/drivers/dri/mga/mgastate.c index 69f85d62a5..f7e07c330a 100644 --- a/src/mesa/drivers/dri/mga/mgastate.c +++ b/src/mesa/drivers/dri/mga/mgastate.c @@ -744,32 +744,12 @@ static void mgaDDLogicOp( GLcontext *ctx, GLenum opcode ) } -static void mgaXMesaSetFrontClipRects( mgaContextPtr mmesa ) +static void mga_set_cliprects(mgaContextPtr mmesa) { __DRIdrawablePrivate *driDrawable = mmesa->driDrawable; - if (driDrawable->numClipRects == 0) { - static drm_clip_rect_t zeroareacliprect = {0,0,0,0}; - mmesa->numClipRects = 1; - mmesa->pClipRects = &zeroareacliprect; - } else { - mmesa->numClipRects = driDrawable->numClipRects; - mmesa->pClipRects = driDrawable->pClipRects; - } - mmesa->drawX = driDrawable->x; - mmesa->drawY = driDrawable->y; - - mmesa->setup.dstorg = mmesa->drawOffset; - mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_CLIPRECTS; -} - - -static void mgaXMesaSetBackClipRects( mgaContextPtr mmesa ) -{ - __DRIdrawablePrivate *driDrawable = mmesa->driDrawable; - - if (driDrawable->numBackClipRects == 0) - { + if ((mmesa->draw_buffer != MGA_FRONT) + || (driDrawable->numBackClipRects == 0)) { if (driDrawable->numClipRects == 0) { static drm_clip_rect_t zeroareacliprect = {0,0,0,0}; mmesa->numClipRects = 1; @@ -794,25 +774,25 @@ static void mgaXMesaSetBackClipRects( mgaContextPtr mmesa ) void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers ) { - __DRIdrawablePrivate *driDrawable = mmesa->driDrawable; + __DRIdrawablePrivate *const driDrawable = mmesa->driDrawable; + __DRIdrawablePrivate *const driReadable = mmesa->driReadable; drm_mga_sarea_t *sarea = mmesa->sarea; - DRI_VALIDATE_DRAWABLE_INFO(mmesa->driScreen, driDrawable); mmesa->dirty_cliprects = 0; - if (mmesa->draw_buffer == MGA_FRONT) - mgaXMesaSetFrontClipRects( mmesa ); - else - mgaXMesaSetBackClipRects( mmesa ); + driUpdateFramebufferSize(mmesa->glCtx, driDrawable); + if (driDrawable != driReadable) { + driUpdateFramebufferSize(mmesa->glCtx, driReadable); + } + + mga_set_cliprects(mmesa); sarea->req_drawable = driDrawable->draw; sarea->req_draw_buffer = mmesa->draw_buffer; mgaUpdateClipping( mmesa->glCtx ); mgaCalcViewport( mmesa->glCtx ); - - mmesa->dirty |= MGA_UPLOAD_CLIPRECTS; } @@ -828,23 +808,21 @@ static void mgaDDDrawBuffer(GLcontext *ctx, GLenum mode ) switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0] ) { case BUFFER_BIT_FRONT_LEFT: mmesa->setup.dstorg = mmesa->mgaScreen->frontOffset; - mmesa->dirty |= MGA_UPLOAD_CONTEXT; mmesa->draw_buffer = MGA_FRONT; - mgaXMesaSetFrontClipRects( mmesa ); - FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE ); break; case BUFFER_BIT_BACK_LEFT: mmesa->setup.dstorg = mmesa->mgaScreen->backOffset; mmesa->draw_buffer = MGA_BACK; - mmesa->dirty |= MGA_UPLOAD_CONTEXT; - mgaXMesaSetBackClipRects( mmesa ); - FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE ); break; default: /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */ FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_TRUE ); return; } + + mmesa->dirty |= MGA_UPLOAD_CONTEXT; + mga_set_cliprects(mmesa); + FALLBACK(ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE); } diff --git a/src/mesa/drivers/dri/r128/r128_ioctl.c b/src/mesa/drivers/dri/r128/r128_ioctl.c index 7dbb5e5dda..b0dba7d04e 100644 --- a/src/mesa/drivers/dri/r128/r128_ioctl.c +++ b/src/mesa/drivers/dri/r128/r128_ioctl.c @@ -399,8 +399,7 @@ void r128PageFlip( const __DRIdrawablePrivate *dPriv ) * Buffer clear */ -static void r128Clear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, - GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo ) +static void r128Clear( GLcontext *ctx, GLbitfield mask ) { r128ContextPtr rmesa = R128_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = rmesa->driDrawable; @@ -541,7 +540,7 @@ static void r128Clear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, } if ( mask ) - _swrast_Clear( ctx, mask, 0, 0, 0, 0, 0 ); + _swrast_Clear( ctx, mask ); } diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.c b/src/mesa/drivers/dri/r200/r200_ioctl.c index efa0b64ed2..463bd64415 100644 --- a/src/mesa/drivers/dri/r200/r200_ioctl.c +++ b/src/mesa/drivers/dri/r200/r200_ioctl.c @@ -605,8 +605,7 @@ void r200PageFlip( const __DRIdrawablePrivate *dPriv ) /* ================================================================ * Buffer clear */ -static void r200Clear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, - GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo ) +static void r200Clear( GLcontext *ctx, GLbitfield mask ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; @@ -653,7 +652,7 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, if ( mask ) { if (R200_DEBUG & DEBUG_FALLBACKS) fprintf(stderr, "%s: swrast clear, mask: %x\n", __FUNCTION__, mask); - _swrast_Clear( ctx, mask, 0, 0, 0, 0, 0 ); + _swrast_Clear( ctx, mask ); } if ( !flags ) diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c index 2d947dea3a..91ec4f855c 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog.c @@ -82,7 +82,8 @@ static const struct { { "LG2", 1, R300_FPI0_OUTC_REPL_ALPHA, R300_FPI2_OUTA_LG2 }, { "RCP", 1, R300_FPI0_OUTC_REPL_ALPHA, R300_FPI2_OUTA_RCP }, { "RSQ", 1, R300_FPI0_OUTC_REPL_ALPHA, R300_FPI2_OUTA_RSQ }, - { "REPL_ALPHA", 1, R300_FPI0_OUTC_REPL_ALPHA, PFS_INVAL } + { "REPL_ALPHA", 1, R300_FPI0_OUTC_REPL_ALPHA, PFS_INVAL }, + { "CMPH", 3, R300_FPI0_OUTC_CMPH, PFS_INVAL }, }; #define MAKE_SWZ3(x, y, z) (MAKE_SWIZZLE4(SWIZZLE_##x, \ @@ -180,7 +181,7 @@ static const pfs_reg_t undef = { valid: GL_FALSE }; -/* constant zero source */ +/* constant one source */ static const pfs_reg_t pfs_one = { type: REG_TYPE_CONST, index: 0, @@ -189,7 +190,16 @@ static const pfs_reg_t pfs_one = { valid: GL_TRUE }; -/* constant one source */ +/* constant half source */ +static const pfs_reg_t pfs_half = { + type: REG_TYPE_CONST, + index: 0, + v_swz: SWIZZLE_HHH, + s_swz: SWIZZLE_HALF, + valid: GL_TRUE +}; + +/* constant zero source */ static const pfs_reg_t pfs_zero = { type: REG_TYPE_CONST, index: 0, @@ -319,7 +329,6 @@ static pfs_reg_t emit_param4fv(struct r300_fragment_program *rp, return r; } -#if 0 static pfs_reg_t emit_const4fv(struct r300_fragment_program *rp, GLfloat *cp) { pfs_reg_t r = undef; @@ -330,13 +339,11 @@ static pfs_reg_t emit_const4fv(struct r300_fragment_program *rp, GLfloat *cp) ERROR("Out of hw constants!\n"); return r; } - - COPY_4V(rp->constant[r.index], cp); + COPY_4V(rp->constant[r.index], cp); r.valid = GL_TRUE; return r; } -#endif static __inline pfs_reg_t negate(pfs_reg_t r) { @@ -773,13 +780,15 @@ static void emit_tex(struct r300_fragment_program *rp, cs->dest_in_node = 0; } - if (rp->cur_node == 0) rp->first_node_has_tex = 1; + if (rp->cur_node == 0) + rp->first_node_has_tex = 1; - rp->tex.inst[rp->tex.length++] = 0 - | (hwsrc << R300_FPITX_SRC_SHIFT) - | (hwdest << R300_FPITX_DST_SHIFT) - | (unit << R300_FPITX_IMAGE_SHIFT) - | (opcode << R300_FPITX_OPCODE_SHIFT); /* not entirely sure about this */ + rp->tex.inst[rp->tex.length++] = 0 + | (hwsrc << R300_FPITX_SRC_SHIFT) + | (hwdest << R300_FPITX_DST_SHIFT) + | (unit << R300_FPITX_IMAGE_SHIFT) + /* not entirely sure about this */ + | (opcode << R300_FPITX_OPCODE_SHIFT); cs->dest_in_node |= (1 << hwdest); if (coord.type != REG_TYPE_CONST) @@ -884,7 +893,7 @@ static void emit_arith(struct r300_fragment_program *rp, int op, vop = r300_fpop[op].v_op; sop = r300_fpop[op].s_op; - argc = r300_fpop[op].argc; + argc = r300_fpop[op].argc; if ((mask & WRITEMASK_XYZ) || vop == R300_FPI0_OUTC_DP3) emit_vop = GL_TRUE; @@ -1039,7 +1048,9 @@ static GLboolean parse_program(struct r300_fragment_program *rp) const struct prog_instruction *inst = mp->Base.Instructions; struct prog_instruction *fpi; pfs_reg_t src[3], dest, temp; + pfs_reg_t cnst; int flags, mask = 0; + GLfloat cnstv[4] = {0.0, 0.0, 0.0, 0.0}; if (!inst || inst[0].Opcode == OPCODE_END) { ERROR("empty program?\n"); @@ -1179,7 +1190,66 @@ static GLboolean parse_program(struct r300_fragment_program *rp) flags); break; case OPCODE_LIT: - ERROR("LIT not implemented\n"); + /* LIT + * if (s.x < 0) t.x = 0; else t.x = s.x; + * if (s.y < 0) t.y = 0; else t.y = s.y; + * if (s.w > 128.0) t.w = 128.0; else t.w = s.w; + * if (s.w < -128.0) t.w = -128.0; else t.w = s.w; + * r.x = 1.0 + * if (t.x > 0) r.y = pow(t.y, t.w); else r.y = 0; + * Also r.y = 0 if t.y < 0 + * For the t.x > 0 FGLRX use the CMPH opcode which + * change the compare to (t.x + 0.5) > 0.5 we may + * save one instruction by doing CMP -t.x + */ + cnstv[0] = cnstv[1] = cnstv[2] = cnstv[4] = 0.50001; + src[0] = t_src(rp, fpi->SrcReg[0]); + temp = get_temp_reg(rp); + cnst = emit_const4fv(rp, cnstv); + emit_arith(rp, PFS_OP_CMP, temp, + WRITEMASK_X | WRITEMASK_Y, + src[0], pfs_zero, src[0], flags); + emit_arith(rp, PFS_OP_MIN, temp, WRITEMASK_Z, + swizzle(keep(src[0]), W, W, W, W), + cnst, undef, flags); + emit_arith(rp, PFS_OP_LG2, temp, WRITEMASK_W, + swizzle(temp, Y, Y, Y, Y), + undef, undef, flags); + emit_arith(rp, PFS_OP_MAX, temp, WRITEMASK_Z, + temp, negate(cnst), undef, flags); + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_W, + temp, swizzle(temp, Z, Z, Z, Z), + pfs_zero, flags); + emit_arith(rp, PFS_OP_EX2, temp, WRITEMASK_W, + temp, undef, undef, flags); + emit_arith(rp, PFS_OP_MAD, dest, WRITEMASK_Y, + swizzle(keep(temp), X, X, X, X), + pfs_one, pfs_zero, flags); +#if 0 + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, + temp, pfs_one, pfs_half, flags); + emit_arith(rp, PFS_OP_CMPH, temp, WRITEMASK_Z, + swizzle(keep(temp), W, W, W, W), + pfs_zero, swizzle(keep(temp), X, X, X, X), + flags); +#else + emit_arith(rp, PFS_OP_CMP, temp, WRITEMASK_Z, + pfs_zero, + swizzle(keep(temp), W, W, W, W), + negate(swizzle(keep(temp), X, X, X, X)), + flags); +#endif + emit_arith(rp, PFS_OP_CMP, dest, WRITEMASK_Z, + pfs_zero, temp, + negate(swizzle(keep(temp), Y, Y, Y, Y)), + flags); + emit_arith(rp, PFS_OP_MAD, dest, + WRITEMASK_X | WRITEMASK_W, + pfs_one, + pfs_one, + pfs_zero, + flags); + free_temp(rp, temp); break; case OPCODE_LRP: src[0] = t_src(rp, fpi->SrcReg[0]); @@ -1345,7 +1415,7 @@ static GLboolean parse_program(struct r300_fragment_program *rp) return GL_FALSE; } - + return GL_TRUE; } diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.h b/src/mesa/drivers/dri/r300/r300_fragprog.h index e7dbaf973e..4bbaa07e01 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.h +++ b/src/mesa/drivers/dri/r300/r300_fragprog.h @@ -78,7 +78,8 @@ typedef struct r300_fragment_program_swizzle { #define PFS_OP_RCP 9 #define PFS_OP_RSQ 10 #define PFS_OP_REPL_ALPHA 11 -#define MAX_PFS_OP 11 +#define PFS_OP_CMPH 12 +#define MAX_PFS_OP 12 #define PFS_FLAG_SAT (1 << 0) #define PFS_FLAG_ABS (1 << 1) diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c index 7775ca96e4..87276a11ae 100644 --- a/src/mesa/drivers/dri/r300/r300_ioctl.c +++ b/src/mesa/drivers/dri/r300/r300_ioctl.c @@ -477,8 +477,7 @@ static void r300EmitClearState(GLcontext * ctx) /** * Buffer clear */ -static void r300Clear(GLcontext * ctx, GLbitfield mask, GLboolean allFoo, - GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo) +static void r300Clear(GLcontext * ctx, GLbitfield mask) { r300ContextPtr r300 = R300_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable; @@ -520,7 +519,7 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask, GLboolean allFoo, if (RADEON_DEBUG & DEBUG_FALLBACKS) fprintf(stderr, "%s: swrast clear, mask: %x\n", __FUNCTION__, mask); - _swrast_Clear(ctx, mask, 0, 0, 0, 0, 0); + _swrast_Clear(ctx, mask); } swapped = r300->radeon.doPageFlip && (r300->radeon.sarea->pfCurrentPage == 1); diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h index f3d8fa60f5..9f636ec1d2 100644 --- a/src/mesa/drivers/dri/r300/r300_reg.h +++ b/src/mesa/drivers/dri/r300/r300_reg.h @@ -1001,6 +1001,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * - DP4: Use OUTC_DP4, OUTA_DP4 * - DP3: Use OUTC_DP3, OUTA_DP4, appropriate alpha operands * - DPH: Use OUTC_DP4, OUTA_DP4, appropriate alpha operands + * - CMPH: If ARG2 > 0.5, return ARG0, else return ARG1 * - CMP: If ARG2 < 0, return ARG1, else return ARG0 * - FLR: use FRC+MAD * - XPD: use MAD+MAD @@ -1138,6 +1139,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_FPI0_OUTC_DP4 (2 << 23) # define R300_FPI0_OUTC_MIN (4 << 23) # define R300_FPI0_OUTC_MAX (5 << 23) +# define R300_FPI0_OUTC_CMPH (7 << 23) # define R300_FPI0_OUTC_CMP (8 << 23) # define R300_FPI0_OUTC_FRC (9 << 23) # define R300_FPI0_OUTC_REPL_ALPHA (10 << 23) diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 5a98226300..6aff04fd27 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -460,7 +460,6 @@ static void update_depth(GLcontext* ctx) static void r300Enable(GLcontext* ctx, GLenum cap, GLboolean state) { r300ContextPtr r300 = R300_CONTEXT(ctx); - uint32_t newval; if (RADEON_DEBUG & DEBUG_STATE) fprintf(stderr, "%s( %s = %s )\n", __FUNCTION__, diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c index 1d78918a2b..cc356afb23 100644 --- a/src/mesa/drivers/dri/r300/r300_texstate.c +++ b/src/mesa/drivers/dri/r300/r300_texstate.c @@ -171,7 +171,6 @@ static void r300SetTexImages(r300ContextPtr rmesa, GLint i, texelBytes; GLint numLevels; GLint log2Width, log2Height, log2Depth; - const GLuint ui = 1; /* Set the hardware texture format */ diff --git a/src/mesa/drivers/dri/r300/radeon_context.c b/src/mesa/drivers/dri/r300/radeon_context.c index 09321126d6..62a6e1e5f7 100644 --- a/src/mesa/drivers/dri/r300/radeon_context.c +++ b/src/mesa/drivers/dri/r300/radeon_context.c @@ -98,27 +98,11 @@ static const GLubyte *radeonGetString(GLcontext * ctx, GLenum name) } } - -/* Return the width and height of the given buffer. - */ -static void radeonGetBufferSize(GLframebuffer * buffer, - GLuint * width, GLuint * height) -{ - GET_CURRENT_CONTEXT(ctx); - radeonContextPtr radeon = RADEON_CONTEXT(ctx); - - LOCK_HARDWARE(radeon); - *width = radeon->dri.drawable->w; - *height = radeon->dri.drawable->h; - UNLOCK_HARDWARE(radeon); -} - - /* Initialize the driver's misc functions. */ static void radeonInitDriverFuncs(struct dd_function_table *functions) { - functions->GetBufferSize = radeonGetBufferSize; + functions->GetBufferSize = NULL; functions->GetString = radeonGetString; } @@ -158,7 +142,8 @@ GLboolean radeonInitContext(radeonContextPtr radeon, /* DRI fields */ radeon->dri.context = driContextPriv; radeon->dri.screen = sPriv; - radeon->dri.drawable = NULL; /* Set by XMesaMakeCurrent */ + radeon->dri.drawable = NULL; + radeon->dri.readable = NULL; radeon->dri.hwContext = driContextPriv->hHWContext; radeon->dri.hwLock = &sPriv->pSAREA->lock; radeon->dri.fd = sPriv->fd; @@ -282,12 +267,15 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, fprintf(stderr, "%s ctx %p\n", __FUNCTION__, radeon->glCtx); - if (radeon->dri.drawable != driDrawPriv) { + if ( (radeon->dri.drawable != driDrawPriv) + || (radeon->dri.readable != driReadPriv) ) { + driDrawableInitVBlank(driDrawPriv, radeon->vblank_flags, &radeon->vbl_seq); radeon->dri.drawable = driDrawPriv; - + radeon->dri.readable = driReadPriv; + r300UpdateWindow(radeon->glCtx); r300UpdateViewportOffset(radeon->glCtx); } diff --git a/src/mesa/drivers/dri/r300/radeon_context.h b/src/mesa/drivers/dri/r300/radeon_context.h index 0ec6466e44..07a0c7cbd6 100644 --- a/src/mesa/drivers/dri/r300/radeon_context.h +++ b/src/mesa/drivers/dri/r300/radeon_context.h @@ -120,7 +120,15 @@ extern void radeonTclFallback(GLcontext * ctx, GLuint bit, GLboolean mode); struct radeon_dri_mirror { __DRIcontextPrivate *context; /* DRI context */ __DRIscreenPrivate *screen; /* DRI screen */ - __DRIdrawablePrivate *drawable; /* DRI drawable bound to this ctx */ + /** + * DRI drawable bound to this context for drawing. + */ + __DRIdrawablePrivate *drawable; + + /** + * DRI drawable bound to this context for reading. + */ + __DRIdrawablePrivate *readable; drm_context_t hwContext; drm_hw_lock_t *hwLock; diff --git a/src/mesa/drivers/dri/r300/radeon_lock.c b/src/mesa/drivers/dri/r300/radeon_lock.c index 0e1e6512db..a00da6c8bc 100644 --- a/src/mesa/drivers/dri/r300/radeon_lock.c +++ b/src/mesa/drivers/dri/r300/radeon_lock.c @@ -75,34 +75,30 @@ static void radeonUpdatePageFlipping(radeonContextPtr radeon) * Called by radeonGetLock() after the lock has been obtained. */ static void r300RegainedLock(radeonContextPtr radeon) -{ - __DRIdrawablePrivate *dPriv = radeon->dri.drawable; +{ int i; + __DRIdrawablePrivate *const drawable = radeon->dri.drawable; r300ContextPtr r300 = (r300ContextPtr)radeon; + drm_radeon_sarea_t *sarea = radeon->sarea; - if (radeon->lastStamp != dPriv->lastStamp) { - _mesa_resize_framebuffer(radeon->glCtx, - (GLframebuffer*)dPriv->driverPrivate, - dPriv->w, dPriv->h); - + if ( radeon->lastStamp != drawable->lastStamp ) { radeonUpdatePageFlipping(radeon); - - if (radeon->glCtx->DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_BACK_LEFT) - radeonSetCliprects(radeon, GL_BACK_LEFT); - else - radeonSetCliprects(radeon, GL_FRONT_LEFT); - + radeonSetCliprects(radeon); #if 1 r300UpdateViewportOffset( radeon->glCtx ); - driUpdateFramebufferSize(radeon->glCtx, dPriv); + driUpdateFramebufferSize(radeon->glCtx, drawable); #else radeonUpdateScissor(radeon->glCtx); #endif - radeon->lastStamp = dPriv->lastStamp; + radeon->lastStamp = drawable->lastStamp; } - for (i = 0; i < r300->nr_heaps; i++) { - DRI_AGE_TEXTURES(r300->texture_heaps[i]); + if (sarea->ctx_owner != radeon->dri.hwContext) { + sarea->ctx_owner = radeon->dri.hwContext; + + for (i = 0; i < r300->nr_heaps; i++) { + DRI_AGE_TEXTURES(r300->texture_heaps[i]); + } } } @@ -116,11 +112,11 @@ static void r300RegainedLock(radeonContextPtr radeon) */ void radeonGetLock(radeonContextPtr radeon, GLuint flags) { - __DRIdrawablePrivate *dPriv = radeon->dri.drawable; + __DRIdrawablePrivate *const drawable = radeon->dri.drawable; + __DRIdrawablePrivate *const readable = radeon->dri.readable; __DRIscreenPrivate *sPriv = radeon->dri.screen; - drm_radeon_sarea_t *sarea = radeon->sarea; - assert (dPriv != NULL); + assert (drawable != NULL); drmGetLock(radeon->dri.fd, radeon->dri.hwContext, flags); @@ -132,10 +128,10 @@ void radeonGetLock(radeonContextPtr radeon, GLuint flags) * 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); - - if (sarea->ctx_owner != radeon->dri.hwContext) - sarea->ctx_owner = radeon->dri.hwContext; + DRI_VALIDATE_DRAWABLE_INFO( sPriv, drawable ); + if (drawable != readable) { + DRI_VALIDATE_DRAWABLE_INFO( sPriv, readable ); + } if (IS_R300_CLASS(radeon->radeonScreen)) r300RegainedLock(radeon); diff --git a/src/mesa/drivers/dri/r300/radeon_state.c b/src/mesa/drivers/dri/r300/radeon_state.c index 7726c22f42..1b1ec3df3c 100644 --- a/src/mesa/drivers/dri/r300/radeon_state.c +++ b/src/mesa/drivers/dri/r300/radeon_state.c @@ -49,7 +49,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_ioctl.h" #include "radeon_state.h" #include "r300_ioctl.h" - +#include "framebuffer.h" /* ============================================================= * Scissoring @@ -137,7 +137,6 @@ static void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h if (ctx->Scissor.Enabled) { /* We don't pipeline cliprect changes */ r300Flush(ctx); - radeonUpdateScissor(ctx); } } @@ -146,31 +145,46 @@ static void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h /** * Update cliprects and scissors. */ -void radeonSetCliprects(radeonContextPtr radeon, GLenum mode) +void radeonSetCliprects(radeonContextPtr radeon) { - __DRIdrawablePrivate *dPriv = radeon->dri.drawable; - - switch (mode) { - case GL_FRONT_LEFT: - radeon->numClipRects = dPriv->numClipRects; - radeon->pClipRects = dPriv->pClipRects; - break; - case GL_BACK_LEFT: - /* Can't ignore 2d windows if we are page flipping. - */ - if (dPriv->numBackClipRects == 0 || radeon->doPageFlip) { - radeon->numClipRects = dPriv->numClipRects; - radeon->pClipRects = dPriv->pClipRects; + __DRIdrawablePrivate *const drawable = radeon->dri.drawable; + __DRIdrawablePrivate *const readable = radeon->dri.readable; + GLframebuffer *const draw_fb = (GLframebuffer*)drawable->driverPrivate; + GLframebuffer *const read_fb = (GLframebuffer*)readable->driverPrivate; + + if (draw_fb->_ColorDrawBufferMask[0] == BUFFER_BIT_BACK_LEFT) { + /* Can't ignore 2d windows if we are page flipping. */ + if (drawable->numBackClipRects == 0 || radeon->doPageFlip) { + radeon->numClipRects = drawable->numClipRects; + radeon->pClipRects = drawable->pClipRects; } else { - radeon->numClipRects = dPriv->numBackClipRects; - radeon->pClipRects = dPriv->pBackClipRects; + radeon->numClipRects = drawable->numBackClipRects; + radeon->pClipRects = drawable->pBackClipRects; + } + } else { + /* front buffer (or none, or multiple buffers */ + radeon->numClipRects = drawable->numClipRects; + radeon->pClipRects = drawable->pClipRects; + } + + if ((draw_fb->Width != drawable->w) || + (draw_fb->Height != drawable->h)) { + printf("w,h %d %d\n", + radeon->glCtx->DrawBuffer->Width, + radeon->glCtx->DrawBuffer->Height); + + _mesa_resize_framebuffer(radeon->glCtx, draw_fb, + drawable->w, drawable->h); + draw_fb->Initialized = GL_TRUE; + } + + if (drawable != readable) { + if ((read_fb->Width != readable->w) || + (read_fb->Height != readable->h)) { + _mesa_resize_framebuffer(radeon->glCtx, read_fb, + readable->w, readable->h); + read_fb->Initialized = GL_TRUE; } - break; - default: - fprintf(stderr, "bad mode in radeonSetCliprects\n"); - radeon->numClipRects = 0; - radeon->pClipRects = 0; - return; } if (radeon->state.scissor.enabled) diff --git a/src/mesa/drivers/dri/r300/radeon_state.h b/src/mesa/drivers/dri/r300/radeon_state.h index 636bf5d008..c2d041eb4a 100644 --- a/src/mesa/drivers/dri/r300/radeon_state.h +++ b/src/mesa/drivers/dri/r300/radeon_state.h @@ -34,7 +34,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_context.h" extern void radeonRecalcScissorRects(radeonContextPtr radeon); -extern void radeonSetCliprects(radeonContextPtr radeon, GLenum mode); +extern void radeonSetCliprects(radeonContextPtr radeon); extern void radeonUpdateScissor(GLcontext* ctx); extern void radeonEnable(GLcontext* ctx, GLenum cap, GLboolean state); diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c index d9eec622f3..737490fcde 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c @@ -1021,8 +1021,7 @@ void radeonPageFlip( const __DRIdrawablePrivate *dPriv ) */ #define RADEON_MAX_CLEARS 256 -static void radeonClear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, - GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo ) +static void radeonClear( GLcontext *ctx, GLbitfield mask ) { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; @@ -1071,7 +1070,7 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, if ( mask ) { if (RADEON_DEBUG & DEBUG_FALLBACKS) fprintf(stderr, "%s: swrast clear, mask: %x\n", __FUNCTION__, mask); - _swrast_Clear( ctx, mask, 0, 0, 0, 0, 0 ); + _swrast_Clear( ctx, mask ); } if ( !flags ) diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c index f1a1728eaa..e19202fa44 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.c +++ b/src/mesa/drivers/dri/radeon/radeon_state.c @@ -40,6 +40,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "light.h" #include "state.h" #include "context.h" +#include "framebuffer.h" #include "vbo/vbo.h" #include "tnl/tnl.h" @@ -1659,14 +1660,14 @@ void radeonSetCliprects( radeonContextPtr rmesa ) } if ((draw_fb->Width != drawable->w) || (draw_fb->Height != drawable->h)) { - _mesa_resize_framebuffer(&rmesa->glCtx, draw_fb, + _mesa_resize_framebuffer(rmesa->glCtx, draw_fb, drawable->w, drawable->h); draw_fb->Initialized = GL_TRUE; } if (drawable != readable) { if ((read_fb->Width != readable->w) || (read_fb->Height != readable->h)) { - _mesa_resize_framebuffer(&rmesa->glCtx, read_fb, + _mesa_resize_framebuffer(rmesa->glCtx, read_fb, readable->w, readable->h); read_fb->Initialized = GL_TRUE; } diff --git a/src/mesa/drivers/dri/s3v/s3v_state.c b/src/mesa/drivers/dri/s3v/s3v_state.c index 08ce0f565c..b86b618c11 100644 --- a/src/mesa/drivers/dri/s3v/s3v_state.c +++ b/src/mesa/drivers/dri/s3v/s3v_state.c @@ -73,8 +73,7 @@ static void s3vDDBlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor ) * Buffer clear */ -static void s3vDDClear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, - GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo ) +static void s3vDDClear( GLcontext *ctx, GLbitfield mask ) { s3vContextPtr vmesa = S3V_CONTEXT(ctx); unsigned int _stride; @@ -163,7 +162,7 @@ static void s3vDDClear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, if ( mask ) DEBUG(("still masked ;3(\n")); */ /* yes */ #else - _swrast_Clear( ctx, mask, 0, 0, 0, 0, 0 ); + _swrast_Clear( ctx, mask ); #endif } diff --git a/src/mesa/drivers/dri/savage/savageioctl.c b/src/mesa/drivers/dri/savage/savageioctl.c index 7513a07e85..4eac1fb349 100644 --- a/src/mesa/drivers/dri/savage/savageioctl.c +++ b/src/mesa/drivers/dri/savage/savageioctl.c @@ -327,8 +327,7 @@ static GLuint savageIntersectClipRects(drm_clip_rect_t *dest, } -static void savageDDClear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, - GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo ) +static void savageDDClear( GLcontext *ctx, GLbitfield mask ) { savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); GLuint colorMask, depthMask, clearColor, clearDepth, flags; @@ -426,7 +425,7 @@ static void savageDDClear( GLcontext *ctx, GLbitfield mask, GLboolean allFoo, } if (mask) - _swrast_Clear( ctx, mask, 0, 0, 0, 0, 0 ); + _swrast_Clear( ctx, mask ); } /* diff --git a/src/mesa/drivers/dri/sis/sis6326_clear.c b/src/mesa/drivers/dri/sis/sis6326_clear.c index d8f39b31c7..48db19566c 100644 --- a/src/mesa/drivers/dri/sis/sis6326_clear.c +++ b/src/mesa/drivers/dri/sis/sis6326_clear.c @@ -69,8 +69,7 @@ sis6326UpdateZPattern(sisContextPtr smesa, GLclampd z) } void -sis6326DDClear(GLcontext *ctx, GLbitfield mask, GLboolean allFoo, - GLint xFoo, GLint yFoo, GLint widthFoo, GLint heightFoo) +sis6326DDClear(GLcontext *ctx, GLbitfield mask) { sisContextPtr smesa = SIS_CONTEXT(ctx); GLint x1, y1, width1, height1; @@ -110,7 +109,7 @@ sis6326DDClear(GLcontext *ctx, GLbitfield mask, GLboolean allFoo, UNLOCK_HARDWARE(); if (mask != 0) - _swrast_Clear(ctx, mask, 0, 0, 0, 0, 0); + _swrast_Clear(ctx, mask); } diff --git a/src/mesa/drivers/dri/sis/sis_clear.c b/src/mesa/drivers/dri/sis/sis_clear.c index 64b6870871..fb92d06c73 100644 --- a/src/mesa/drivers/dri/sis/sis_clear.c +++ b/src/mesa/drivers/dri/sis/sis_clear.c @@ -95,8 +95,7 @@ sisUpdateZStencilPattern( sisContextPtr smesa, GLclampd z, GLint stencil ) } void -sisDDClear( GLcontext * ctx, GLbitfield mask, GLboolean allFoo, - GLint xFoo, GLint yFoo, GLint widthFoo, GLint heightFoo ) +sisDDClear( GLcontext * ctx, GLbitfield mask ) { sisContextPtr smesa = SIS_CONTEXT(ctx); @@ -145,7 +144,7 @@ sisDDClear( GLcontext * ctx, GLbitfield mask, GLboolean allFoo, UNLOCK_HARDWARE(); if (mask != 0) - _swrast_Clear( ctx, mask, 0, 0, 0, 0, 0); + _swrast_Clear( ctx, mask); } @@ -329,9 +328,7 @@ sis_clear_color_buffer( GLcontext *ctx, GLenum mask, GLint x, GLint y, GLint width, GLint height ) { sisContextPtr smesa = SIS_CONTEXT(ctx); - int count; - GLuint depth = smesa->bytesPerPixel; drm_clip_rect_t *pExtents = NULL; GLint xx, yy; GLint x0, y0, width0, height0; @@ -379,8 +376,6 @@ sis_clear_color_buffer( GLcontext *ctx, GLenum mask, GLint x, GLint y, if (width <= 0 || height <= 0) continue; - int cmd; - mWait3DCmdQueue (8); MMIO(REG_SRC_PITCH, (smesa->bytesPerPixel == 4) ? BLIT_DEPTH_32 : BLIT_DEPTH_16); diff --git a/src/mesa/drivers/dri/sis/sis_screen.c b/src/mesa/drivers/dri/sis/sis_screen.c index 4fd692ec24..8f52cfe098 100644 --- a/src/mesa/drivers/dri/sis/sis_screen.c +++ b/src/mesa/drivers/dri/sis/sis_screen.c @@ -209,7 +209,7 @@ sisCreateBuffer( __DRIscreenPrivate *driScrnPriv, const __GLcontextModes *mesaVis, GLboolean isPixmap ) { - sisScreenPtr screen = (sisScreenPtr) driScrnPriv->private; + /*sisScreenPtr screen = (sisScreenPtr) driScrnPriv->private;*/ struct gl_framebuffer *fb; if (isPixmap) diff --git a/src/mesa/drivers/dri/sis/sis_state.h b/src/mesa/drivers/dri/sis/sis_state.h index 580a522bf3..8f7e2acb92 100644 --- a/src/mesa/drivers/dri/sis/sis_state.h +++ b/src/mesa/drivers/dri/sis/sis_state.h @@ -35,15 +35,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "sis_context.h" /* sis6326_clear.c */ -extern void sis6326DDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height ); +extern void sis6326DDClear( GLcontext *ctx, GLbitfield mask ); extern void sis6326DDClearColor( GLcontext * ctx, const GLfloat color[4] ); extern void sis6326DDClearDepth( GLcontext * ctx, GLclampd d ); extern void sis6326UpdateZPattern(sisContextPtr smesa, GLclampd z); /* sis_clear.c */ -extern void sisDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height ); +extern void sisDDClear( GLcontext *ctx, GLbitfield mask ); extern void sisDDClearColor( GLcontext * ctx, const GLfloat color[4] ); extern void sisDDClearDepth( GLcontext * ctx, GLclampd d ); extern void sisDDClearStencil( GLcontext * ctx, GLint s ); diff --git a/src/mesa/drivers/dri/tdfx/tdfx_render.c b/src/mesa/drivers/dri/tdfx/tdfx_render.c index 3301d948e1..f36c97bfeb 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_render.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_render.c @@ -46,9 +46,7 @@ /* Clear the color and/or depth buffers. */ -static void tdfxClear( GLcontext *ctx, - GLbitfield mask, GLboolean all, - GLint xFoo, GLint yFoo, GLint widthFoo, GLint heightFoo) +static void tdfxClear( GLcontext *ctx, GLbitfield mask ) { tdfxContextPtr fxMesa = (tdfxContextPtr) ctx->DriverCtx; GLbitfield softwareMask = mask & (BUFFER_BIT_ACCUM); @@ -312,7 +310,7 @@ static void tdfxClear( GLcontext *ctx, } if (softwareMask) - _swrast_Clear( ctx, softwareMask, 0, 0, 0, 0, 0); + _swrast_Clear(ctx, softwareMask); } diff --git a/src/mesa/drivers/dri/tdfx/tdfx_tex.c b/src/mesa/drivers/dri/tdfx/tdfx_tex.c index 3e6011a2ac..c3fe7bebd3 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_tex.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_tex.c @@ -1404,7 +1404,6 @@ tdfxTexImage2D(GLcontext *ctx, GLenum target, GLint level, GLint mipWidth, mipHeight; tdfxMipMapLevel *mip; struct gl_texture_image *mipImage; - const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; const GLint maxLevels = _mesa_max_texture_levels(ctx, texObj->Target); assert(!texImage->IsCompressed); @@ -1425,7 +1424,7 @@ tdfxTexImage2D(GLcontext *ctx, GLenum target, GLint level, mipWidth, mipHeight, border, format, type, NULL); - mipImage = _mesa_select_tex_image(ctx, texUnit, target, level); + mipImage = _mesa_select_tex_image(ctx, texObj, target, level); mip = TDFX_TEXIMAGE_DATA(mipImage); _mesa_halve2x2_teximage2d(ctx, texImage, @@ -1514,7 +1513,6 @@ tdfxTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, GLint mipWidth, mipHeight; tdfxMipMapLevel *mip; struct gl_texture_image *mipImage; - const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; const GLint maxLevels = _mesa_max_texture_levels(ctx, texObj->Target); assert(!texImage->IsCompressed); @@ -1534,7 +1532,7 @@ tdfxTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, break; } ++level; - mipImage = _mesa_select_tex_image(ctx, texUnit, target, level); + mipImage = _mesa_select_tex_image(ctx, texObj, target, level); mip = TDFX_TEXIMAGE_DATA(mipImage); _mesa_halve2x2_teximage2d(ctx, texImage, diff --git a/src/mesa/drivers/dri/trident/trident_state.c b/src/mesa/drivers/dri/trident/trident_state.c index 6cdf23092a..5303bd422e 100644 --- a/src/mesa/drivers/dri/trident/trident_state.c +++ b/src/mesa/drivers/dri/trident/trident_state.c @@ -150,8 +150,7 @@ void tridentCopyBuffer( const __DRIdrawablePrivate *dPriv ) } -static void tridentDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo) +static void tridentDDClear( GLcontext *ctx, GLbitfield mask ) { tridentContextPtr tmesa = TRIDENT_CONTEXT(ctx); unsigned char *MMIO = tmesa->tridentScreen->mmio.map; @@ -297,7 +296,7 @@ if (flags & DRM_TRIDENT_FRONT) { UNLOCK_HARDWARE(tmesa); if ( mask ) - _swrast_Clear( ctx, mask, 0, 0, 0, 0, 0); + _swrast_Clear( ctx, mask ); } static void tridentDDShadeModel( GLcontext *ctx, GLenum mode ) diff --git a/src/mesa/drivers/dri/unichrome/via_ioctl.c b/src/mesa/drivers/dri/unichrome/via_ioctl.c index 86077bc4d4..dd2e93b286 100644 --- a/src/mesa/drivers/dri/unichrome/via_ioctl.c +++ b/src/mesa/drivers/dri/unichrome/via_ioctl.c @@ -202,8 +202,7 @@ static void viaFillBuffer(struct via_context *vmesa, -static void viaClear(GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo) +static void viaClear(GLcontext *ctx, GLbitfield mask) { struct via_context *vmesa = VIA_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = vmesa->driDrawable; @@ -262,6 +261,7 @@ static void viaClear(GLcontext *ctx, GLbitfield mask, GLboolean all, drm_clip_rect_t *boxes, *tmp_boxes = 0; int nr = 0; GLint cx, cy, cw, ch; + GLboolean all; LOCK_HARDWARE(vmesa); @@ -270,6 +270,7 @@ static void viaClear(GLcontext *ctx, GLbitfield mask, GLboolean all, cy = ctx->DrawBuffer->_Ymin; cw = ctx->DrawBuffer->_Xmax - cx; ch = ctx->DrawBuffer->_Ymax - cy; + all = (cw == ctx->DrawBuffer->Width && ch == ctx->DrawBuffer->Height); /* flip top to bottom */ cy = dPriv->h - cy - ch; @@ -335,7 +336,7 @@ static void viaClear(GLcontext *ctx, GLbitfield mask, GLboolean all, } if (mask) - _swrast_Clear(ctx, mask, 0, 0, 0, 0, 0); + _swrast_Clear(ctx, mask); } diff --git a/src/mesa/drivers/ggi/ggimesa.c b/src/mesa/drivers/ggi/ggimesa.c index 4fbbe61ab8..47d7f2bdb9 100644 --- a/src/mesa/drivers/ggi/ggimesa.c +++ b/src/mesa/drivers/ggi/ggimesa.c @@ -313,10 +313,14 @@ static void gl_ggiSetClearColor(GLcontext *ctx, const GLfloat color[4]) ggi_ctx->clearcolor = col; } -static void gl_ggiClear(GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height) +static void gl_ggiClear(GLcontext *ctx, GLbitfield mask) { ggi_mesa_context_t ggi_ctx = (ggi_mesa_context_t)ctx->DriverCtx; + int x = ctx->DrawBuffer->_Xmin; + int y = ctx->DrawBuffer->_Ymin; + int w = ctx->DrawBuffer->_Xmax - x; + int h = ctx->DrawBuffer->_Ymax - y; + GLboolean all = (w == ctx->DrawBuffer->Width && h == ctx->DrawBuffer->height) GGIMESADPRINT_CORE("gl_ggiClear() called\n"); @@ -336,7 +340,7 @@ static void gl_ggiClear(GLcontext *ctx, GLbitfield mask, GLboolean all, mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT); } - _swrast_Clear(ctx, mask, all, x, y, width, height); + _swrast_Clear(ctx, mask); } diff --git a/src/mesa/drivers/glide/fxdd.c b/src/mesa/drivers/glide/fxdd.c index e218a316aa..f49c3889f6 100644 --- a/src/mesa/drivers/glide/fxdd.c +++ b/src/mesa/drivers/glide/fxdd.c @@ -162,9 +162,7 @@ fxDDClearColor(GLcontext * ctx, const GLfloat color[4]) /* Clear the color and/or depth buffers */ -static void fxDDClear( GLcontext *ctx, - GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height ) +static void fxDDClear( GLcontext *ctx, GLbitfield mask ) { fxMesaContext fxMesa = FX_CONTEXT(ctx); GLbitfield softwareMask = mask & (BUFFER_BIT_ACCUM); @@ -173,8 +171,7 @@ static void fxDDClear( GLcontext *ctx, const FxU8 clearS = (FxU8) (ctx->Stencil.Clear & 0xff); if ( TDFX_DEBUG & MESA_VERBOSE ) { - fprintf( stderr, "fxDDClear( %d, %d, %d, %d )\n", - (int) x, (int) y, (int) width, (int) height ); + fprintf( stderr, "fxDDClear\n"); } /* we can't clear accum buffers nor stereo */ @@ -389,7 +386,7 @@ static void fxDDClear( GLcontext *ctx, grRenderBuffer(fxMesa->currentFB); if (softwareMask) - _swrast_Clear( ctx, softwareMask, all, x, y, width, height ); + _swrast_Clear( ctx, softwareMask ); } diff --git a/src/mesa/drivers/svga/svgamesa15.c b/src/mesa/drivers/svga/svgamesa15.c index 54b6c977a7..ae5104d0c0 100644 --- a/src/mesa/drivers/svga/svgamesa15.c +++ b/src/mesa/drivers/svga/svgamesa15.c @@ -1,4 +1,4 @@ -/* $Id: svgamesa15.c,v 1.11 2002/11/11 18:42:39 brianp Exp $ */ +/* $Id: svgamesa15.c,v 1.11.36.1 2006/11/02 12:02:17 alanh Exp $ */ /* * Mesa 3-D graphics library @@ -66,10 +66,14 @@ void __clear_color15( GLcontext *ctx, const GLfloat color[4] ) /* SVGAMesa->clear_hicolor=(red)<<10 | (green)<<5 | (blue);*/ } -void __clear15( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height ) +void __clear15( GLcontext *ctx, GLbitfield mask ) { int i, j; + int x = ctx->DrawBuffer->_Xmin; + int y = ctx->DrawBuffer->_Ymin; + int width = ctx->DrawBuffer->_Xmax - x; + int height = ctx->DrawBuffer->_Ymax - y; + GLboolean all = (width == ctx->DrawBuffer->Width && height == ctx->DrawBuffer->height) if (mask & DD_FRONT_LEFT_BIT) { GLshort *shortBuffer=(void *)SVGABuffer.FrontBuffer; @@ -105,7 +109,7 @@ void __clear15( GLcontext *ctx, GLbitfield mask, GLboolean all, } if (mask) - _swrast_Clear( ctx, mask, all, x, y, width, height ); + _swrast_Clear( ctx, mask ); } void __write_rgba_span15( const GLcontext *ctx, GLuint n, GLint x, GLint y, diff --git a/src/mesa/drivers/svga/svgamesa16.c b/src/mesa/drivers/svga/svgamesa16.c index 72ac818329..a59937bfb4 100644 --- a/src/mesa/drivers/svga/svgamesa16.c +++ b/src/mesa/drivers/svga/svgamesa16.c @@ -1,4 +1,4 @@ -/* $Id: svgamesa16.c,v 1.11 2002/11/11 18:42:40 brianp Exp $ */ +/* $Id: svgamesa16.c,v 1.11.36.1 2006/11/02 12:02:17 alanh Exp $ */ /* * Mesa 3-D graphics library @@ -69,10 +69,14 @@ void __clear_color16( GLcontext *ctx, const GLfloat color[4] ) /* SVGAMesa->clear_hicolor=(red)<<11 | (green)<<5 | (blue); */ } -void __clear16( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height ) +void __clear16( GLcontext *ctx, GLbitfield mask ) { int i,j; + int x = ctx->DrawBuffer->_Xmin; + int y = ctx->DrawBuffer->_Ymin; + int width = ctx->DrawBuffer->_Xmax - x; + int height = ctx->DrawBuffer->_Ymax - y; + GLboolean all = (width == ctx->DrawBuffer->Width && height == ctx->DrawBuffer->height) if (mask & DD_FRONT_LEFT_BIT) { if (all) { @@ -108,7 +112,7 @@ void __clear16( GLcontext *ctx, GLbitfield mask, GLboolean all, } if (mask) - _swrast_Clear( ctx, mask, all, x, y, width, height ); + _swrast_Clear( ctx, mask ); } void __write_rgba_span16( const GLcontext *ctx, GLuint n, GLint x, GLint y, diff --git a/src/mesa/drivers/svga/svgamesa24.c b/src/mesa/drivers/svga/svgamesa24.c index 07491cc67a..dd15bf38db 100644 --- a/src/mesa/drivers/svga/svgamesa24.c +++ b/src/mesa/drivers/svga/svgamesa24.c @@ -1,4 +1,4 @@ -/* $Id: svgamesa24.c,v 1.12 2002/11/11 18:42:41 brianp Exp $ */ +/* $Id: svgamesa24.c,v 1.12.36.1 2006/11/02 12:02:17 alanh Exp $ */ /* * Mesa 3-D graphics library @@ -91,10 +91,14 @@ void __clear_color24( GLcontext *ctx, const GLfloat color[4] ) /* SVGAMesa->clear_truecolor = red<<16 | green<<8 | blue; */ } -void __clear24( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height ) +void __clear24( GLcontext *ctx, GLbitfield mask ) { int i,j; + int x = ctx->DrawBuffer->_Xmin; + int y = ctx->DrawBuffer->_Ymin; + int width = ctx->DrawBuffer->_Xmax - x; + int height = ctx->DrawBuffer->_Ymax - y; + GLboolean all = (width == ctx->DrawBuffer->Width && height == ctx->DrawBuffer->height) if (mask & DD_FRONT_LEFT_BIT) { if (all) { @@ -140,7 +144,7 @@ void __clear24( GLcontext *ctx, GLbitfield mask, GLboolean all, } if (mask) - _swrast_Clear( ctx, mask, all, x, y, width, height ); + _swrast_Clear( ctx, mask ); } void __write_rgba_span24( const GLcontext *ctx, GLuint n, GLint x, GLint y, diff --git a/src/mesa/drivers/svga/svgamesa32.c b/src/mesa/drivers/svga/svgamesa32.c index 8a366998d6..4da18795d8 100644 --- a/src/mesa/drivers/svga/svgamesa32.c +++ b/src/mesa/drivers/svga/svgamesa32.c @@ -1,4 +1,4 @@ -/* $Id: svgamesa32.c,v 1.12 2002/11/11 18:42:42 brianp Exp $ */ +/* $Id: svgamesa32.c,v 1.12.36.1 2006/11/02 12:02:17 alanh Exp $ */ /* * Mesa 3-D graphics library @@ -85,10 +85,14 @@ void __clear_color32( GLcontext *ctx, const GLfloat color[4] ) SVGAMesa->clear_truecolor = (col[0] << 16) | (col[1] << 8) | col[2]; } -void __clear32( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height ) +void __clear32( GLcontext *ctx, GLbitfield mask ) { int i,j; + int x = ctx->DrawBuffer->_Xmin; + int y = ctx->DrawBuffer->_Ymin; + int width = ctx->DrawBuffer->_Xmax - x; + int height = ctx->DrawBuffer->_Ymax - y; + GLboolean all = (width == ctx->DrawBuffer->Width && height == ctx->DrawBuffer->height) if (mask & DD_FRONT_LEFT_BIT) { if (all) { @@ -124,7 +128,7 @@ void __clear32( GLcontext *ctx, GLbitfield mask, GLboolean all, } if (mask) - _swrast_Clear( ctx, mask, all, x, y, width, height ); + _swrast_Clear( ctx, mask ); } void __write_rgba_span32( const GLcontext *ctx, GLuint n, GLint x, GLint y, diff --git a/src/mesa/drivers/svga/svgamesa8.c b/src/mesa/drivers/svga/svgamesa8.c index fd880ef85a..4264fcd959 100644 --- a/src/mesa/drivers/svga/svgamesa8.c +++ b/src/mesa/drivers/svga/svgamesa8.c @@ -1,4 +1,4 @@ -/* $Id: svgamesa8.c,v 1.9 2005/05/04 20:11:39 brianp Exp $ */ +/* $Id: svgamesa8.c,v 1.9.10.1 2006/11/02 12:02:17 alanh Exp $ */ /* * Mesa 3-D graphics library @@ -60,10 +60,14 @@ void __clear_index8( GLcontext *ctx, GLuint index ) SVGAMesa->clear_index = index; } -void __clear8( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height ) +void __clear8( GLcontext *ctx, GLbitfield mask ) { int i,j; + int x = ctx->DrawBuffer->_Xmin; + int y = ctx->DrawBuffer->_Ymin; + int width = ctx->DrawBuffer->_Xmax - x; + int height = ctx->DrawBuffer->_Ymax - y; + GLboolean all = (width == ctx->DrawBuffer->Width && height == ctx->DrawBuffer->height) if (mask & DD_FRONT_LEFT_BIT) { if (all) { @@ -95,7 +99,7 @@ void __clear8( GLcontext *ctx, GLbitfield mask, GLboolean all, } if (mask) - _swrast_Clear( ctx, mask, all, x, y, width, height ); + _swrast_Clear( ctx, mask ); } void __write_ci32_span8( const GLcontext *ctx, struct gl_renderbuffer *rb, diff --git a/src/mesa/drivers/windows/gdi/wmesa.c b/src/mesa/drivers/windows/gdi/wmesa.c index 0dfd7a6b39..8c3229ab14 100644 --- a/src/mesa/drivers/windows/gdi/wmesa.c +++ b/src/mesa/drivers/windows/gdi/wmesa.c @@ -281,11 +281,7 @@ static void clear_color(GLcontext *ctx, const GLfloat color[4]) * Clearing of the other non-color buffers is left to the swrast. */ -static void clear(GLcontext *ctx, - GLbitfield mask, - GLboolean all, - GLint xFoo, GLint yFoo, - GLint widthFoo, GLint heightFoo) +static void clear(GLcontext *ctx, GLbitfield mask) { #define FLIP(Y) (ctx->DrawBuffer->Height - (Y) - 1) const GLint x = ctx->DrawBuffer->_Xmin; @@ -303,7 +299,7 @@ static void clear(GLcontext *ctx, ctx->Color.ColorMask[1] != 0xff || ctx->Color.ColorMask[2] != 0xff || ctx->Color.ColorMask[3] != 0xff) { - _swrast_Clear(ctx, mask, all, x, y, width, height); + _swrast_Clear(ctx, mask); return; } @@ -322,7 +318,8 @@ static void clear(GLcontext *ctx, /* Try for a fast clear - clearing entire buffer with a single * byte value. */ - if (all) { /* entire buffer */ + if (width == ctx->DrawBuffer->Width && + height == ctx->DrawBuffer->Height) { /* entire buffer */ /* Now check for an easy clear value */ switch (bytesPerPixel) { case 1: @@ -435,7 +432,7 @@ static void clear(GLcontext *ctx, /* Call swrast if there is anything left to clear (like DEPTH) */ if (mask) - _swrast_Clear(ctx, mask, all, x, y, width, height); + _swrast_Clear(ctx, mask); #undef FLIP } diff --git a/src/mesa/drivers/x11/xm_dd.c b/src/mesa/drivers/x11/xm_dd.c index 87bd5e4a30..dbac3b8cdb 100644 --- a/src/mesa/drivers/x11/xm_dd.c +++ b/src/mesa/drivers/x11/xm_dd.c @@ -382,9 +382,7 @@ clear_nbit_ximage(GLcontext *ctx, struct xmesa_renderbuffer *xrb, static void -clear_buffers( GLcontext *ctx, GLbitfield mask, - GLboolean all, GLint xFoo, GLint yFoo, - GLint widthFoo, GLint heightFoo ) +clear_buffers(GLcontext *ctx, GLbitfield buffers) { if (ctx->DrawBuffer->Name == 0) { /* this is a window system framebuffer */ @@ -397,33 +395,33 @@ clear_buffers( GLcontext *ctx, GLbitfield mask, /* we can't handle color or index masking */ if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) { - if (mask & BUFFER_BIT_FRONT_LEFT) { + if (buffers & BUFFER_BIT_FRONT_LEFT) { /* clear front color buffer */ struct gl_renderbuffer *frontRb = ctx->DrawBuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; if (b->frontxrb == xmesa_renderbuffer(frontRb)) { /* renderbuffer is not wrapped - great! */ b->frontxrb->clearFunc(ctx, b->frontxrb, x, y, width, height); - mask &= ~BUFFER_BIT_FRONT_LEFT; + buffers &= ~BUFFER_BIT_FRONT_LEFT; } else { /* we can't directly clear an alpha-wrapped color buffer */ } } - if (mask & BUFFER_BIT_BACK_LEFT) { + if (buffers & BUFFER_BIT_BACK_LEFT) { /* clear back color buffer */ struct gl_renderbuffer *backRb = ctx->DrawBuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer; if (b->backxrb == xmesa_renderbuffer(backRb)) { /* renderbuffer is not wrapped - great! */ b->backxrb->clearFunc(ctx, b->backxrb, x, y, width, height); - mask &= ~BUFFER_BIT_BACK_LEFT; + buffers &= ~BUFFER_BIT_BACK_LEFT; } } } } - if (mask) - _swrast_Clear( ctx, mask, 0, 0, 0, 0, 0); + if (buffers) + _swrast_Clear(ctx, buffers); } diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index ef970ad9eb..e22edc1bbc 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -337,6 +337,8 @@ _mesa_PushAttrib(GLbitfield mask) if (mask & GL_TEXTURE_BIT) { struct gl_texture_attrib *attr; GLuint u; + + _mesa_lock_context_textures(ctx); /* Bump the texture object reference counts so that they don't * inadvertantly get deleted. */ @@ -362,6 +364,9 @@ _mesa_PushAttrib(GLbitfield mask) _mesa_copy_texture_object(&attr->Unit[u].SavedRect, attr->Unit[u].CurrentRect); } + + _mesa_unlock_context_textures(ctx); + newnode = new_attrib_node( GL_TEXTURE_BIT ); newnode->data = attr; newnode->next = head; diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c index 2710d04454..ece53463b3 100644 --- a/src/mesa/main/buffers.c +++ b/src/mesa/main/buffers.c @@ -141,10 +141,6 @@ _mesa_Clear( GLbitfield mask ) } if (ctx->RenderMode == GL_RENDER) { - const GLint x = ctx->DrawBuffer->_Xmin; - const GLint y = ctx->DrawBuffer->_Ymin; - const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; - const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; GLbitfield bufferMask; /* don't clear depth buffer if depth writing disabled */ @@ -177,8 +173,7 @@ _mesa_Clear( GLbitfield mask ) } ASSERT(ctx->Driver.Clear); - ctx->Driver.Clear( ctx, bufferMask, (GLboolean) !ctx->Scissor.Enabled, - x, y, width, height ); + ctx->Driver.Clear(ctx, bufferMask); } } diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 15b69db595..91f3af3c91 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -735,6 +735,10 @@ alloc_shared_state( GLcontext *ctx ) ss->DefaultCubeMap->RefCount += MAX_TEXTURE_IMAGE_UNITS; ss->DefaultRect->RefCount += MAX_TEXTURE_IMAGE_UNITS; + _glthread_INIT_MUTEX(ss->TexMutex); + ss->TextureStateStamp = 0; + + #if FEATURE_EXT_framebuffer_object ss->FrameBuffers = _mesa_NewHashTable(); if (!ss->FrameBuffers) @@ -1048,6 +1052,7 @@ _mesa_init_constants( GLcontext *ctx ) ctx->Const.VertexProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS; ctx->Const.VertexProgram.MaxEnvParams = MAX_NV_VERTEX_PROGRAM_PARAMS; ctx->Const.VertexProgram.MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS; + ctx->Const.VertexProgram.MaxUniformComponents = MAX_VERTEX_UNIFORM_COMPONENTS; init_natives(&ctx->Const.VertexProgram); #endif #if FEATURE_ARB_fragment_program @@ -1061,6 +1066,7 @@ _mesa_init_constants( GLcontext *ctx ) ctx->Const.FragmentProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS; ctx->Const.FragmentProgram.MaxEnvParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS; ctx->Const.FragmentProgram.MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS; + ctx->Const.FragmentProgram.MaxUniformComponents = MAX_FRAGMENT_UNIFORM_COMPONENTS; init_natives(&ctx->Const.FragmentProgram); #endif ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES; @@ -1087,6 +1093,11 @@ _mesa_init_constants( GLcontext *ctx ) ctx->Const.MaxRenderbufferSize = MAX_WIDTH; #endif +#if FEATURE_ARB_vertex_shader + ctx->Const.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS; + ctx->Const.MaxVaryingFloats = MAX_VARYING_FLOATS; +#endif + /* sanity checks */ ASSERT(ctx->Const.MaxTextureUnits == MIN2(ctx->Const.MaxTextureImageUnits, ctx->Const.MaxTextureCoordUnits)); diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index a1999ac76d..1de2542bee 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -99,39 +99,24 @@ struct dd_function_table { /** * Clear the color/depth/stencil/accum buffer(s). - * - * \param mask a bitmask of the DD_*_BIT values defined above that indicates - * which buffers need to be cleared. - * \param all if true then clear the whole buffer, else clear only the - * region defined by (x, y, width, height). - * - * This function must obey the glColorMask(), glIndexMask() and - * glStencilMask() settings! - * Software Mesa can do masked clears if the device driver can't. + * \param buffers a bitmask of BUFFER_BIT_* flags indicating which + * renderbuffers need to be cleared. */ - void (*Clear)( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height ); - + void (*Clear)( GLcontext *ctx, GLbitfield buffers ); - /** - * \name For hardware accumulation buffer - */ - /*@{*/ /** * Execute glAccum command. */ void (*Accum)( GLcontext *ctx, GLenum op, GLfloat value ); - /*@}*/ /** - * \name glDraw(), glRead(), glCopyPixels() and glBitmap() functions + * \name Image-related functions */ /*@{*/ /** - * This is called by glDrawPixels(). - * + * Called by glDrawPixels(). * \p unpack describes how to unpack the source image data. */ void (*DrawPixels)( GLcontext *ctx, @@ -150,19 +135,14 @@ struct dd_function_table { GLvoid *dest ); /** - * Do a glCopyPixels(). - * - * This function must respect all rasterization state, glPixelTransfer(), - * glPixelZoom(), etc. + * Called by glCopyPixels(). */ void (*CopyPixels)( GLcontext *ctx, GLint srcx, GLint srcy, GLsizei width, GLsizei height, GLint dstx, GLint dsty, GLenum type ); /** - * This is called by glBitmap(). - * - * Works the same as dd_function_table::DrawPixels, above. + * Called by glBitmap(). */ void (*Bitmap)( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c index 5edf9a7dd6..39f8e26f57 100644 --- a/src/mesa/main/extensions.c +++ b/src/mesa/main/extensions.c @@ -135,6 +135,7 @@ static const struct { { OFF, "GL_ATI_texture_env_combine3", F(ATI_texture_env_combine3)}, { OFF, "GL_ATI_texture_mirror_once", F(ATI_texture_mirror_once)}, { OFF, "GL_ATI_fragment_shader", F(ATI_fragment_shader)}, + { OFF, "GL_ATI_separate_stencil", F(ATI_separate_stencil)}, { OFF, "GL_IBM_multimode_draw_arrays", F(IBM_multimode_draw_arrays) }, { ON, "GL_IBM_rasterpos_clip", F(IBM_rasterpos_clip) }, { OFF, "GL_IBM_texture_mirrored_repeat", F(ARB_texture_mirrored_repeat)}, @@ -222,6 +223,7 @@ _mesa_enable_sw_extensions(GLcontext *ctx) #endif ctx->Extensions.ATI_texture_env_combine3 = GL_TRUE; ctx->Extensions.ATI_texture_mirror_once = GL_TRUE; + ctx->Extensions.ATI_separate_stencil = GL_TRUE; ctx->Extensions.EXT_blend_color = GL_TRUE; ctx->Extensions.EXT_blend_equation_separate = GL_TRUE; ctx->Extensions.EXT_blend_func_separate = GL_TRUE; @@ -249,7 +251,7 @@ _mesa_enable_sw_extensions(GLcontext *ctx) ctx->Extensions.EXT_secondary_color = GL_TRUE; ctx->Extensions.EXT_shared_texture_palette = GL_TRUE; ctx->Extensions.EXT_stencil_wrap = GL_TRUE; - ctx->Extensions.EXT_stencil_two_side = GL_TRUE; + ctx->Extensions.EXT_stencil_two_side = GL_FALSE; /* obsolete */ ctx->Extensions.EXT_texture_env_add = GL_TRUE; ctx->Extensions.EXT_texture_env_combine = GL_TRUE; ctx->Extensions.EXT_texture_env_dot3 = GL_TRUE; @@ -388,7 +390,8 @@ _mesa_enable_2_0_extensions(GLcontext *ctx) #if FEATURE_ARB_shading_language_100 ctx->Extensions.ARB_shading_language_100 = GL_TRUE; #endif - ctx->Extensions.EXT_stencil_two_side = GL_FALSE; /* yes, turn it off */ + ctx->Extensions.ATI_separate_stencil = GL_TRUE; + ctx->Extensions.EXT_stencil_two_side = GL_FALSE; /* obsolete */ #if FEATURE_ARB_vertex_shader ctx->Extensions.ARB_vertex_shader = GL_TRUE; #endif diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index 2ca1014631..cf8de1e0cb 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -979,7 +979,9 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer) } FLUSH_VERTICES(ctx, _NEW_BUFFERS); - + if (ctx->Driver.Flush) { + ctx->Driver.Flush(ctx); + } if (framebuffer) { /* Binding a user-created framebuffer object */ newFb = _mesa_lookup_framebuffer(ctx, framebuffer); @@ -1548,7 +1550,9 @@ _mesa_GenerateMipmapEXT(GLenum target) texObj = _mesa_select_tex_object(ctx, texUnit, target); /* XXX this might not handle cube maps correctly */ + _mesa_lock_texture(ctx, texObj); _mesa_generate_mipmap(ctx, target, texUnit, texObj); + _mesa_unlock_texture(ctx, texObj); } diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index 3dd1aa1873..9f3a8d12cf 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -1863,7 +1863,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) break; case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB: CHECK_EXT1(ARB_fragment_shader, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(MAX_FRAGMENT_UNIFORM_COMPONENTS); + params[0] = INT_TO_BOOLEAN(ctx->Const.FragmentProgram.MaxUniformComponents); break; case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB: CHECK_EXT1(ARB_fragment_shader, "GetBooleanv"); @@ -1871,15 +1871,15 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) break; case GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(MAX_VERTEX_UNIFORM_COMPONENTS); + params[0] = INT_TO_BOOLEAN(ctx->Const.VertexProgram.MaxUniformComponents); break; case GL_MAX_VARYING_FLOATS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(MAX_VARYING_FLOATS); + params[0] = INT_TO_BOOLEAN(ctx->Const.MaxVaryingFloats); break; case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(MAX_VERTEX_TEXTURE_IMAGE_UNITS); + params[0] = INT_TO_BOOLEAN(ctx->Const.MaxVertexTextureImageUnits); break; case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetBooleanv"); @@ -3687,7 +3687,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) break; case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB: CHECK_EXT1(ARB_fragment_shader, "GetFloatv"); - params[0] = (GLfloat)(MAX_FRAGMENT_UNIFORM_COMPONENTS); + params[0] = (GLfloat)(ctx->Const.FragmentProgram.MaxUniformComponents); break; case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB: CHECK_EXT1(ARB_fragment_shader, "GetFloatv"); @@ -3695,15 +3695,15 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) break; case GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetFloatv"); - params[0] = (GLfloat)(MAX_VERTEX_UNIFORM_COMPONENTS); + params[0] = (GLfloat)(ctx->Const.VertexProgram.MaxUniformComponents); break; case GL_MAX_VARYING_FLOATS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetFloatv"); - params[0] = (GLfloat)(MAX_VARYING_FLOATS); + params[0] = (GLfloat)(ctx->Const.MaxVaryingFloats); break; case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetFloatv"); - params[0] = (GLfloat)(MAX_VERTEX_TEXTURE_IMAGE_UNITS); + params[0] = (GLfloat)(ctx->Const.MaxVertexTextureImageUnits); break; case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetFloatv"); @@ -5511,7 +5511,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) break; case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB: CHECK_EXT1(ARB_fragment_shader, "GetIntegerv"); - params[0] = MAX_FRAGMENT_UNIFORM_COMPONENTS; + params[0] = ctx->Const.FragmentProgram.MaxUniformComponents; break; case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB: CHECK_EXT1(ARB_fragment_shader, "GetIntegerv"); @@ -5519,15 +5519,15 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) break; case GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetIntegerv"); - params[0] = MAX_VERTEX_UNIFORM_COMPONENTS; + params[0] = ctx->Const.VertexProgram.MaxUniformComponents; break; case GL_MAX_VARYING_FLOATS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetIntegerv"); - params[0] = MAX_VARYING_FLOATS; + params[0] = ctx->Const.MaxVaryingFloats; break; case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetIntegerv"); - params[0] = MAX_VERTEX_TEXTURE_IMAGE_UNITS; + params[0] = ctx->Const.MaxVertexTextureImageUnits; break; case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetIntegerv"); diff --git a/src/mesa/main/get_gen.py b/src/mesa/main/get_gen.py index ec8a192b31..50ff13d2f9 100644 --- a/src/mesa/main/get_gen.py +++ b/src/mesa/main/get_gen.py @@ -978,17 +978,19 @@ StateVars = [ # GL_ARB_fragment_shader ( "GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB", GLint, - ["MAX_FRAGMENT_UNIFORM_COMPONENTS"], "", ["ARB_fragment_shader"] ), + ["ctx->Const.FragmentProgram.MaxUniformComponents"], "", + ["ARB_fragment_shader"] ), ( "GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB", GLenum, ["ctx->Hint.FragmentShaderDerivative"], "", ["ARB_fragment_shader"] ), # GL_ARB_vertex_shader ( "GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB", GLint, - ["MAX_VERTEX_UNIFORM_COMPONENTS"], "", ["ARB_vertex_shader"] ), + ["ctx->Const.VertexProgram.MaxUniformComponents"], "", + ["ARB_vertex_shader"] ), ( "GL_MAX_VARYING_FLOATS_ARB", GLint, - ["MAX_VARYING_FLOATS"], "", ["ARB_vertex_shader"] ), + ["ctx->Const.MaxVaryingFloats"], "", ["ARB_vertex_shader"] ), ( "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB", GLint, - ["MAX_VERTEX_TEXTURE_IMAGE_UNITS"], "", ["ARB_vertex_shader"] ), + ["ctx->Const.MaxVertexTextureImageUnits"], "", ["ARB_vertex_shader"] ), ( "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB", GLint, ["MAX_COMBINED_TEXTURE_IMAGE_UNITS"], "", ["ARB_vertex_shader"] ) ] diff --git a/src/mesa/main/getstring.c b/src/mesa/main/getstring.c index a68bf9ff74..f2989aaefa 100644 --- a/src/mesa/main/getstring.c +++ b/src/mesa/main/getstring.c @@ -54,7 +54,7 @@ _mesa_GetString( GLenum name ) static const char *version_1_3 = "1.3 Mesa " MESA_VERSION_STRING; static const char *version_1_4 = "1.4 Mesa " MESA_VERSION_STRING; static const char *version_1_5 = "1.5 Mesa " MESA_VERSION_STRING; - static const char *version_2_0 = "1.5 Mesa " MESA_VERSION_STRING;/*XXX FIX*/ + static const char *version_2_0 = "1.5 Mesa " MESA_VERSION_STRING; #if FEATURE_ARB_shading_language_100 static const char *sl_version_110 = "1.10 Mesa " MESA_VERSION_STRING; @@ -111,7 +111,7 @@ _mesa_GetString( GLenum name ) if (ctx->Extensions.ARB_draw_buffers && ctx->Extensions.ARB_point_sprite && ctx->Extensions.ARB_texture_non_power_of_two && - ctx->Extensions.EXT_stencil_two_side) { + ctx->Extensions.ATI_separate_stencil) { return (const GLubyte *) version_2_0; } else { diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c index 604dea34e0..f154bd4651 100644 --- a/src/mesa/main/mipmap.c +++ b/src/mesa/main/mipmap.c @@ -883,7 +883,7 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, GLint border, bytesPerTexel; /* get src image parameters */ - srcImage = _mesa_select_tex_image(ctx, texUnit, target, level); + srcImage = _mesa_select_tex_image(ctx, texObj, target, level); ASSERT(srcImage); srcWidth = srcImage->Width; srcHeight = srcImage->Height; @@ -922,7 +922,7 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, } /* get dest gl_texture_image */ - dstImage = _mesa_get_tex_image(ctx, texUnit, target, level + 1); + dstImage = _mesa_get_tex_image(ctx, texObj, target, level + 1); if (!dstImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); return; diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index bc7c6b8026..1d5eb61e06 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1909,20 +1909,6 @@ struct gl_program_state }; -/** - * Virtual vertex program machine state. - * Only used during program execution (may be moved someday): - */ -struct gl_vertex_program_machine -{ - GLfloat Temporaries[MAX_NV_VERTEX_PROGRAM_TEMPS][4]; - GLfloat Inputs[MAX_NV_VERTEX_PROGRAM_INPUTS][4]; - GLuint InputsSize[MAX_NV_VERTEX_PROGRAM_INPUTS]; - GLfloat Outputs[MAX_NV_VERTEX_PROGRAM_OUTPUTS][4]; - GLint AddressReg[4]; -}; - - /** * Context state for vertex programs. */ @@ -1939,8 +1925,6 @@ struct gl_vertex_program_state GLfloat Parameters[MAX_NV_VERTEX_PROGRAM_PARAMS][4]; /**< Env params */ - struct gl_vertex_program_machine Machine; - /* For GL_NV_vertex_program only: */ GLenum TrackMatrix[MAX_NV_VERTEX_PROGRAM_PARAMS / 4]; GLenum TrackMatrixTransform[MAX_NV_VERTEX_PROGRAM_PARAMS / 4]; @@ -2074,6 +2058,19 @@ struct gl_shared_state struct gl_texture_object *DefaultRect; /*@}*/ + /** + * \name Thread safety and statechange notification for texture + * objects. + * + * \todo Improve the granularity of locking. + */ + /*@{*/ + _glthread_Mutex TexMutex; /**< texobj thread safety */ + GLuint TextureStateStamp; /**< state notification for shared tex */ + /*@}*/ + + + /** * \name Vertex/fragment programs */ @@ -2323,6 +2320,8 @@ struct gl_program_constants GLuint MaxNativeTemps; GLuint MaxNativeAddressRegs; /* vertex program only, for now */ GLuint MaxNativeParameters; + /* For shaders */ + GLuint MaxUniformComponents; }; @@ -2372,6 +2371,9 @@ struct gl_constants /* GL_EXT_framebuffer_object */ GLuint MaxColorAttachments; GLuint MaxRenderbufferSize; + /* GL_ARB_vertex_shader */ + GLuint MaxVertexTextureImageUnits; + GLuint MaxVaryingFloats; }; @@ -2471,6 +2473,7 @@ struct gl_extensions GLboolean ATI_texture_mirror_once; GLboolean ATI_texture_env_combine3; GLboolean ATI_fragment_shader; + GLboolean ATI_separate_stencil; GLboolean IBM_rasterpos_clip; GLboolean IBM_multimode_draw_arrays; GLboolean MESA_pack_invert; @@ -2938,6 +2941,8 @@ struct __GLcontextRec GLboolean _ForceEyeCoords; GLenum _CurrentProgram; /* currently executing program */ + GLuint TextureStateTimestamp; /* detect changes to shared state */ + struct gl_shine_tab *_ShineTable[2]; /**< Active shine tables */ struct gl_shine_tab *_ShineTabList; /**< MRU list of inactive shine tables */ /**@}*/ diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index d57217d9c4..06cf5f8698 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -1003,7 +1003,7 @@ update_color(GLcontext *ctx) * _mesa_update_lighting() and _mesa_update_tnl_spaces(). */ void -_mesa_update_state( GLcontext *ctx ) +_mesa_update_state_locked( GLcontext *ctx ) { GLbitfield new_state = ctx->NewState; @@ -1084,4 +1084,17 @@ _mesa_update_state( GLcontext *ctx ) ctx->Array.NewState = 0; } + +/* This is the usual entrypoint for state updates: + */ +void +_mesa_update_state( GLcontext *ctx ) +{ + _mesa_lock_context_textures(ctx); + _mesa_update_state_locked(ctx); + _mesa_unlock_context_textures(ctx); +} + + + /*@}*/ diff --git a/src/mesa/main/state.h b/src/mesa/main/state.h index 58cfcc4146..5240d4bf93 100644 --- a/src/mesa/main/state.h +++ b/src/mesa/main/state.h @@ -39,5 +39,11 @@ _mesa_init_exec_table(struct _glapi_table *exec); extern void _mesa_update_state( GLcontext *ctx ); +/* As above but can only be called between _mesa_lock_context_textures() and + * _mesa_unlock_context_textures(). + */ +extern void +_mesa_update_state_locked( GLcontext *ctx ); + #endif diff --git a/src/mesa/main/stencil.c b/src/mesa/main/stencil.c index 9992ec9b6e..d6be410e76 100644 --- a/src/mesa/main/stencil.c +++ b/src/mesa/main/stencil.c @@ -115,23 +115,7 @@ _mesa_StencilFunc( GLenum func, GLint ref, GLuint mask ) ref = CLAMP( ref, 0, stencilMax ); - if (ctx->Extensions.EXT_stencil_two_side) { - /* only set active face state */ - const GLint face = ctx->Stencil.ActiveFace; - if (ctx->Stencil.Function[face] == func && - ctx->Stencil.ValueMask[face] == mask && - ctx->Stencil.Ref[face] == ref) - return; - FLUSH_VERTICES(ctx, _NEW_STENCIL); - ctx->Stencil.Function[face] = func; - ctx->Stencil.Ref[face] = ref; - ctx->Stencil.ValueMask[face] = mask; - if (ctx->Driver.StencilFuncSeparate) { - ctx->Driver.StencilFuncSeparate(ctx, face ? GL_BACK : GL_FRONT, - func, ref, mask); - } - } - else { + if (ctx->Extensions.ATI_separate_stencil) { /* set both front and back state */ if (ctx->Stencil.Function[0] == func && ctx->Stencil.Function[1] == func && @@ -149,6 +133,22 @@ _mesa_StencilFunc( GLenum func, GLint ref, GLuint mask ) func, ref, mask); } } + else { + /* only set active face state */ + const GLint face = ctx->Stencil.ActiveFace; + if (ctx->Stencil.Function[face] == func && + ctx->Stencil.ValueMask[face] == mask && + ctx->Stencil.Ref[face] == ref) + return; + FLUSH_VERTICES(ctx, _NEW_STENCIL); + ctx->Stencil.Function[face] = func; + ctx->Stencil.Ref[face] = ref; + ctx->Stencil.ValueMask[face] = mask; + if (ctx->Driver.StencilFuncSeparate) { + ctx->Driver.StencilFuncSeparate(ctx, face ? GL_BACK : GL_FRONT, + func, ref, mask); + } + } } @@ -169,26 +169,26 @@ _mesa_StencilMask( GLuint mask ) GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); - if (ctx->Extensions.EXT_stencil_two_side) { - /* only set active face state */ - const GLint face = ctx->Stencil.ActiveFace; - if (ctx->Stencil.WriteMask[face] == mask) + if (ctx->Extensions.ATI_separate_stencil) { + /* set both front and back state */ + if (ctx->Stencil.WriteMask[0] == mask && + ctx->Stencil.WriteMask[1] == mask) return; FLUSH_VERTICES(ctx, _NEW_STENCIL); - ctx->Stencil.WriteMask[face] = mask; + ctx->Stencil.WriteMask[0] = ctx->Stencil.WriteMask[1] = mask; if (ctx->Driver.StencilMaskSeparate) { - ctx->Driver.StencilMaskSeparate(ctx, face ? GL_BACK : GL_FRONT, mask); + ctx->Driver.StencilMaskSeparate(ctx, GL_FRONT_AND_BACK, mask); } } else { - /* set both front and back state */ - if (ctx->Stencil.WriteMask[0] == mask && - ctx->Stencil.WriteMask[1] == mask) + /* only set active face state */ + const GLint face = ctx->Stencil.ActiveFace; + if (ctx->Stencil.WriteMask[face] == mask) return; FLUSH_VERTICES(ctx, _NEW_STENCIL); - ctx->Stencil.WriteMask[0] = ctx->Stencil.WriteMask[1] = mask; + ctx->Stencil.WriteMask[face] = mask; if (ctx->Driver.StencilMaskSeparate) { - ctx->Driver.StencilMaskSeparate(ctx, GL_FRONT_AND_BACK, mask); + ctx->Driver.StencilMaskSeparate(ctx, face ? GL_BACK : GL_FRONT, mask); } } } @@ -269,23 +269,7 @@ _mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass) return; } - if (ctx->Extensions.EXT_stencil_two_side) { - /* only set active face state */ - const GLint face = ctx->Stencil.ActiveFace; - if (ctx->Stencil.ZFailFunc[face] == zfail && - ctx->Stencil.ZPassFunc[face] == zpass && - ctx->Stencil.FailFunc[face] == fail) - return; - FLUSH_VERTICES(ctx, _NEW_STENCIL); - ctx->Stencil.ZFailFunc[face] = zfail; - ctx->Stencil.ZPassFunc[face] = zpass; - ctx->Stencil.FailFunc[face] = fail; - if (ctx->Driver.StencilOpSeparate) { - ctx->Driver.StencilOpSeparate(ctx, face ? GL_BACK : GL_FRONT, - fail, zfail, zpass); - } - } - else { + if (ctx->Extensions.ATI_separate_stencil) { /* set both front and back state */ if (ctx->Stencil.ZFailFunc[0] == zfail && ctx->Stencil.ZFailFunc[1] == zfail && @@ -303,6 +287,22 @@ _mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass) fail, zfail, zpass); } } + else { + /* only set active face state */ + const GLint face = ctx->Stencil.ActiveFace; + if (ctx->Stencil.ZFailFunc[face] == zfail && + ctx->Stencil.ZPassFunc[face] == zpass && + ctx->Stencil.FailFunc[face] == fail) + return; + FLUSH_VERTICES(ctx, _NEW_STENCIL); + ctx->Stencil.ZFailFunc[face] = zfail; + ctx->Stencil.ZPassFunc[face] = zpass; + ctx->Stencil.FailFunc[face] = fail; + if (ctx->Driver.StencilOpSeparate) { + ctx->Driver.StencilOpSeparate(ctx, face ? GL_BACK : GL_FRONT, + fail, zfail, zpass); + } + } } @@ -406,17 +406,16 @@ _mesa_StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) FLUSH_VERTICES(ctx, _NEW_STENCIL); - if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + if (face != GL_BACK) { ctx->Stencil.FailFunc[0] = fail; ctx->Stencil.ZFailFunc[0] = zfail; ctx->Stencil.ZPassFunc[0] = zpass; } - if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + if (face != GL_FRONT) { ctx->Stencil.FailFunc[1] = fail; ctx->Stencil.ZFailFunc[1] = zfail; ctx->Stencil.ZPassFunc[1] = zpass; } - if (ctx->Driver.StencilOpSeparate) { ctx->Driver.StencilOpSeparate(ctx, face, fail, zfail, zpass); } @@ -465,7 +464,6 @@ _mesa_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) ctx->Stencil.Ref[1] = ref; ctx->Stencil.ValueMask[1] = mask; } - if (ctx->Driver.StencilFuncSeparate) { ctx->Driver.StencilFuncSeparate(ctx, face, func, ref, mask); } @@ -486,13 +484,12 @@ _mesa_StencilMaskSeparate(GLenum face, GLuint mask) FLUSH_VERTICES(ctx, _NEW_STENCIL); - if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + if (face != GL_BACK) { ctx->Stencil.WriteMask[0] = mask; } - if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + if (face != GL_FRONT) { ctx->Stencil.WriteMask[1] = mask; } - if (ctx->Driver.StencilMaskSeparate) { ctx->Driver.StencilMaskSeparate(ctx, face, mask); } diff --git a/src/mesa/main/texcompress_s3tc.c b/src/mesa/main/texcompress_s3tc.c index 65ecaba3a3..c71501c5e6 100644 --- a/src/mesa/main/texcompress_s3tc.c +++ b/src/mesa/main/texcompress_s3tc.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5.1 + * Version: 6.5.2 * * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * @@ -48,6 +48,8 @@ #ifdef __MINGW32__ #define DXTN_LIBNAME "dxtn.dll" +#define RTLD_LAZY 0 +#define RTLD_GLOBAL 0 #elif defined(__DJGPP__) #define DXTN_LIBNAME "dxtn.dxe" #else @@ -104,7 +106,7 @@ _mesa_dlsym(void *handle, const char *fname) { #if USE_EXTERNAL_DXTN_LIB #ifdef __MINGW32__ - return (GenericFunc) GetProcAddress(handle, fname) + return (GenericFunc) GetProcAddress(handle, fname); #elif defined(__DJGPP__) /* need '_' prefix on symbol names */ char fname2[1000]; diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index 5f798cc7df..c99ff5cdc4 100644 --- a/src/mesa/main/texenvprogram.c +++ b/src/mesa/main/texenvprogram.c @@ -33,7 +33,11 @@ #include "shader/program.h" #include "shader/program_instruction.h" -#define MAX_INSTRUCTIONS 100 +/** + * According to Glean's texCombine test, no more than 21 instructions + * are needed. Allow a few extra just in case. + */ +#define MAX_INSTRUCTIONS 24 #define DISASSEM (MESA_VERBOSE & VERBOSE_DISASSEM) @@ -474,7 +478,7 @@ emit_op(struct texenv_fragment_program *p, GLuint nr = p->program->Base.NumInstructions++; struct prog_instruction *inst = &p->program->Base.Instructions[nr]; - _mesa_init_instruction(inst); + _mesa_init_instructions(inst, 1); inst->Opcode = op; emit_arg( &inst->SrcReg[0], src0 ); @@ -988,9 +992,10 @@ load_texunit_sources( struct texenv_fragment_program *p, int unit ) * current texture env/combine mode. */ static void -create_new_program(struct state_key *key, GLcontext *ctx, +create_new_program(GLcontext *ctx, struct state_key *key, struct gl_fragment_program *program) { + struct prog_instruction instBuffer[MAX_INSTRUCTIONS]; struct texenv_fragment_program p; GLuint unit; struct ureg cf, out; @@ -1000,18 +1005,19 @@ create_new_program(struct state_key *key, GLcontext *ctx, p.state = key; p.program = program; - p.program->Base.Instructions = - (struct prog_instruction*) _mesa_malloc(sizeof(struct prog_instruction) * MAX_INSTRUCTIONS); - p.program->Base.NumInstructions = 0; + /* During code generation, use locally-allocated instruction buffer, + * then alloc dynamic storage below. + */ + p.program->Base.Instructions = instBuffer; p.program->Base.Target = GL_FRAGMENT_PROGRAM_ARB; p.program->NumTexIndirections = 1; /* correct? */ p.program->NumTexInstructions = 0; p.program->NumAluInstructions = 0; p.program->Base.String = 0; p.program->Base.NumInstructions = - p.program->Base.NumTemporaries = - p.program->Base.NumParameters = - p.program->Base.NumAttributes = p.program->Base.NumAddressRegs = 0; + p.program->Base.NumTemporaries = + p.program->Base.NumParameters = + p.program->Base.NumAttributes = p.program->Base.NumAddressRegs = 0; p.program->Base.Parameters = _mesa_new_parameter_list(); p.program->Base.InputsRead = 0; @@ -1088,17 +1094,28 @@ create_new_program(struct state_key *key, GLcontext *ctx, ASSERT(p.program->Base.NumInstructions <= MAX_INSTRUCTIONS); + /* Allocate final instruction array */ + program->Base.Instructions + = _mesa_alloc_instructions(program->Base.NumInstructions); + if (!program->Base.Instructions) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, + "generating tex env program"); + return; + } + _mesa_memcpy(program->Base.Instructions, instBuffer, + sizeof(struct prog_instruction) + * program->Base.NumInstructions); + /* Notify driver the fragment program has (actually) changed. */ - if (ctx->Driver.ProgramStringNotify || DISASSEM) { - if (ctx->Driver.ProgramStringNotify) - ctx->Driver.ProgramStringNotify( ctx, GL_FRAGMENT_PROGRAM_ARB, - &p.program->Base ); - - if (DISASSEM) { - _mesa_print_program(&p.program->Base); - _mesa_printf("\n"); - } + if (ctx->Driver.ProgramStringNotify) { + ctx->Driver.ProgramStringNotify( ctx, GL_FRAGMENT_PROGRAM_ARB, + &p.program->Base ); + } + + if (DISASSEM) { + _mesa_print_program(&p.program->Base); + _mesa_printf("\n"); } } @@ -1225,7 +1242,7 @@ void _mesa_UpdateTexEnvProgram( GLcontext *ctx ) (struct gl_fragment_program *) ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); - create_new_program(&key, ctx, ctx->_TexEnvProgram); + create_new_program(ctx, &key, ctx->_TexEnvProgram); cache_item(&ctx->Texture.env_fp_cache, hash, &key, ctx->_TexEnvProgram); } else { diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index c2ba450cb3..662f697147 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -706,9 +706,12 @@ _mesa_free_texture_image_data(GLcontext *ctx, void _mesa_delete_texture_image( GLcontext *ctx, struct gl_texture_image *texImage ) { - if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } + /* Free texImage->Data and/or any other driver-specific texture + * image storage. + */ + ASSERT(ctx->Driver.FreeTexImageData); + ctx->Driver.FreeTexImageData( ctx, texImage ); + ASSERT(texImage->Data == NULL); if (texImage->ImageOffsets) _mesa_free(texImage->ImageOffsets); @@ -801,24 +804,23 @@ _mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit, * \sa gl_texture_unit. */ struct gl_texture_image * -_mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit, - GLenum target, GLint level) +_mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_object *texObj, + GLenum target, GLint level) { - ASSERT(texUnit); - ASSERT(level < MAX_TEXTURE_LEVELS); + ASSERT(texObj); + + if (level < 0 || level >= MAX_TEXTURE_LEVELS) + return NULL; + switch (target) { case GL_TEXTURE_1D: - return texUnit->Current1D->Image[0][level]; case GL_PROXY_TEXTURE_1D: - return ctx->Texture.Proxy1D->Image[0][level]; case GL_TEXTURE_2D: - return texUnit->Current2D->Image[0][level]; case GL_PROXY_TEXTURE_2D: - return ctx->Texture.Proxy2D->Image[0][level]; case GL_TEXTURE_3D: - return texUnit->Current3D->Image[0][level]; case GL_PROXY_TEXTURE_3D: - return ctx->Texture.Proxy3D->Image[0][level]; + return texObj->Image[0][level]; + case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: @@ -828,33 +830,25 @@ _mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit, if (ctx->Extensions.ARB_texture_cube_map) { GLuint face = ((GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X); - return texUnit->CurrentCubeMap->Image[face][level]; + return texObj->Image[face][level]; } else return NULL; + case GL_PROXY_TEXTURE_CUBE_MAP_ARB: if (ctx->Extensions.ARB_texture_cube_map) - return ctx->Texture.ProxyCubeMap->Image[0][level]; + return texObj->Image[0][level]; else return NULL; + case GL_TEXTURE_RECTANGLE_NV: - if (ctx->Extensions.NV_texture_rectangle) { - ASSERT(level == 0); - return texUnit->CurrentRect->Image[0][level]; - } - else { - return NULL; - } case GL_PROXY_TEXTURE_RECTANGLE_NV: - if (ctx->Extensions.NV_texture_rectangle) { - ASSERT(level == 0); - return ctx->Texture.ProxyRect->Image[0][level]; - } - else { + if (ctx->Extensions.NV_texture_rectangle && level == 0) + return texObj->Image[0][level]; + else return NULL; - } + default: - _mesa_problem(ctx, "bad target in _mesa_select_tex_image()"); return NULL; } } @@ -866,22 +860,25 @@ _mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit, * out of memory. */ struct gl_texture_image * -_mesa_get_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit, +_mesa_get_tex_image(GLcontext *ctx, struct gl_texture_object *texObj, GLenum target, GLint level) { struct gl_texture_image *texImage; - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + + if (!texObj) + return NULL; + + texImage = _mesa_select_tex_image(ctx, texObj, target, level); if (!texImage) { - struct gl_texture_object *texObj; texImage = ctx->Driver.NewTextureImage(ctx); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture image allocation"); return NULL; } - texObj = _mesa_select_tex_object(ctx, texUnit, target); - ASSERT(texObj); + _mesa_set_tex_image(texObj, target, level, texImage); } + return texImage; } @@ -1584,9 +1581,6 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions, GLint width, GLint height, GLint depth, GLenum format, GLenum type ) { - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - struct gl_texture_image *destTex; - /* Check target */ if (dimensions == 1) { if (target != GL_TEXTURE_1D) { @@ -1602,8 +1596,7 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions, return GL_TRUE; } } - else if (ctx->Extensions.NV_texture_rectangle && - target == GL_TEXTURE_RECTANGLE_NV) { + else if (target == GL_TEXTURE_RECTANGLE_NV) { if (!ctx->Extensions.NV_texture_rectangle) { _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" ); return GL_TRUE; @@ -1647,8 +1640,23 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions, return GL_TRUE; } - destTex = _mesa_select_tex_image(ctx, texUnit, target, level); + if (!_mesa_is_legal_format_and_type(ctx, format, type)) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glTexSubImage%dD(format or type)", dimensions); + return GL_TRUE; + } + + return GL_FALSE; +} +static GLboolean +subtexture_error_check2( GLcontext *ctx, GLuint dimensions, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint width, GLint height, GLint depth, + GLenum format, GLenum type, + const struct gl_texture_image *destTex ) +{ if (!destTex) { /* undefined image level */ _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage%dD", dimensions); @@ -1688,12 +1696,6 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions, } } - if (!_mesa_is_legal_format_and_type(ctx, format, type)) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glTexSubImage%dD(format or type)", dimensions); - return GL_TRUE; - } - #if FEATURE_EXT_texture_sRGB if (destTex->InternalFormat == GL_COMPRESSED_SRGB_S3TC_DXT1_EXT || destTex->InternalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT || @@ -1709,11 +1711,6 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions, #endif if (destTex->IsCompressed) { - const struct gl_texture_unit *texUnit; - const struct gl_texture_image *texImage; - texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) { /* OK */ } @@ -1735,12 +1732,12 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions, return GL_TRUE; } /* size must be multiple of 4 or equal to whole texture size */ - if ((width & 3) && (GLuint) width != texImage->Width) { + if ((width & 3) && (GLuint) width != destTex->Width) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage%D(width)", dimensions); return GL_TRUE; } - if ((height & 3) && (GLuint) height != texImage->Height) { + if ((height & 3) && (GLuint) height != destTex->Height) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage%D(width)", dimensions); return GL_TRUE; @@ -1781,6 +1778,11 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions, /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */ if (level < 0 || level >= MAX_TEXTURE_LEVELS) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyTexImage%dD(level=%d)", dimensions, level); + return GL_TRUE; + } + /* Check that the source buffer is complete */ if (ctx->ReadBuffer->Name) { _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer); @@ -1791,11 +1793,6 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions, } } - _mesa_error(ctx, GL_INVALID_VALUE, - "glCopyTexImage%dD(level=%d)", dimensions, level); - return GL_TRUE; - } - /* Check border */ if (border < 0 || border > 1 || ((target == GL_TEXTURE_RECTANGLE_NV || @@ -1945,11 +1942,8 @@ static GLboolean copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height ) + GLsizei width, GLsizei height) { - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - struct gl_texture_image *teximage; - /* Check target */ /* Check that the source buffer is complete */ if (ctx->ReadBuffer->Name) { @@ -2012,7 +2006,16 @@ copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions, return GL_TRUE; } - teximage = _mesa_select_tex_image(ctx, texUnit, target, level); + return GL_FALSE; +} + +static GLboolean +copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, + const struct gl_texture_image *teximage ) +{ if (!teximage) { _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexSubImage%dD(undefined texture level: %d)", @@ -2186,59 +2189,66 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format, if (!pixels) return; - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - if (!texImage) { - /* invalid mipmap level, not an error */ - return; - } + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); + if (!texImage) { + /* invalid mipmap level, not an error */ + goto out; + } - /* Make sure the requested image format is compatible with the - * texture's format. Note that a color index texture can be converted - * to RGBA so that combo is allowed. - */ - if (is_color_format(format) - && !is_color_format(texImage->TexFormat->BaseFormat) - && !is_index_format(texImage->TexFormat->BaseFormat)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); - return; - } - else if (is_index_format(format) - && !is_index_format(texImage->TexFormat->BaseFormat)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); - return; - } - else if (is_depth_format(format) - && !is_depth_format(texImage->TexFormat->BaseFormat) - && !is_depthstencil_format(texImage->TexFormat->BaseFormat)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); - return; - } - else if (is_ycbcr_format(format) - && !is_ycbcr_format(texImage->TexFormat->BaseFormat)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); - return; - } - else if (is_depthstencil_format(format) - && !is_depthstencil_format(texImage->TexFormat->BaseFormat)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); - return; - } - if (ctx->Pack.BufferObj->Name) { - /* packing texture image into a PBO */ - const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2; - if (!_mesa_validate_pbo_access(dimensions, &ctx->Pack, texImage->Width, - texImage->Height, texImage->Depth, - format, type, pixels)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetTexImage(invalid PBO access)"); - return; + /* Make sure the requested image format is compatible with the + * texture's format. Note that a color index texture can be converted + * to RGBA so that combo is allowed. + */ + if (is_color_format(format) + && !is_color_format(texImage->TexFormat->BaseFormat) + && !is_index_format(texImage->TexFormat->BaseFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); + goto out; + } + else if (is_index_format(format) + && !is_index_format(texImage->TexFormat->BaseFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); + goto out; + } + else if (is_depth_format(format) + && !is_depth_format(texImage->TexFormat->BaseFormat) + && !is_depthstencil_format(texImage->TexFormat->BaseFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); + goto out; + } + else if (is_ycbcr_format(format) + && !is_ycbcr_format(texImage->TexFormat->BaseFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); + goto out; + } + else if (is_depthstencil_format(format) + && !is_depthstencil_format(texImage->TexFormat->BaseFormat)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)"); + goto out; + } + + if (ctx->Pack.BufferObj->Name) { + /* packing texture image into a PBO */ + const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2; + if (!_mesa_validate_pbo_access(dimensions, &ctx->Pack, texImage->Width, + texImage->Height, texImage->Depth, + format, type, pixels)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTexImage(invalid PBO access)"); + goto out; + } } - } - /* typically, this will call _mesa_get_teximage() */ - ctx->Driver.GetTexImage(ctx, target, level, format, type, pixels, - texObj, texImage); + /* typically, this will call _mesa_get_teximage() */ + ctx->Driver.GetTexImage(ctx, target, level, format, type, pixels, + texObj, texImage); + + } + out: + _mesa_unlock_texture(ctx, texObj); } @@ -2301,40 +2311,47 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, return; /* error was recorded */ } - texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_get_tex_image(ctx, texUnit, target, level); - - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); - return; - } - else if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } - ASSERT(texImage->Data == NULL); - clear_teximage_fields(texImage); /* not really needed, but helpful */ - _mesa_init_teximage_fields(ctx, target, texImage, - postConvWidth, 1, 1, - border, internalFormat); - if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) - _mesa_update_state(ctx); + _mesa_update_state(ctx); - ASSERT(ctx->Driver.TexImage1D); + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_get_tex_image(ctx, texObj, target, level); + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); + goto out; + } + + if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); + } - /* Give the texture to the driver! may be null! */ - (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat, - width, border, format, type, pixels, - &ctx->Unpack, texObj, texImage); + ASSERT(texImage->Data == NULL); - ASSERT(texImage->TexFormat); + clear_teximage_fields(texImage); /* not really needed, but helpful */ + _mesa_init_teximage_fields(ctx, target, texImage, + postConvWidth, 1, 1, + border, internalFormat); + + ASSERT(ctx->Driver.TexImage1D); - update_fbo_texture(ctx, texObj, face, level); + /* Give the texture to the driver! may be null! */ + (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat, + width, border, format, type, pixels, + &ctx->Unpack, texObj, texImage); + + ASSERT(texImage->TexFormat); - /* state update */ - texObj->Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + update_fbo_texture(ctx, texObj, face, level); + + /* state update */ + texObj->Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } else if (target == GL_PROXY_TEXTURE_1D) { /* Proxy texture: check for errors and update proxy state */ @@ -2396,39 +2413,46 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, return; /* error was recorded */ } - texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_get_tex_image(ctx, texUnit, target, level); - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); - return; - } - else if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } - ASSERT(texImage->Data == NULL); - clear_teximage_fields(texImage); /* not really needed, but helpful */ - _mesa_init_teximage_fields(ctx, target, texImage, - postConvWidth, postConvHeight, 1, - border, internalFormat); - if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) - _mesa_update_state(ctx); + _mesa_update_state(ctx); - ASSERT(ctx->Driver.TexImage2D); - - /* Give the texture to the driver! may be null! */ - (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat, - width, height, border, format, type, pixels, - &ctx->Unpack, texObj, texImage); - - ASSERT(texImage->TexFormat); - - update_fbo_texture(ctx, texObj, face, level); - - /* state update */ - texObj->Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_get_tex_image(ctx, texObj, target, level); + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + goto out; + } + + if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); + } + + ASSERT(texImage->Data == NULL); + clear_teximage_fields(texImage); /* not really needed, but helpful */ + _mesa_init_teximage_fields(ctx, target, texImage, + postConvWidth, postConvHeight, 1, + border, internalFormat); + + ASSERT(ctx->Driver.TexImage2D); + + /* Give the texture to the driver! may be null! */ + (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat, + width, height, border, format, type, pixels, + &ctx->Unpack, texObj, texImage); + + ASSERT(texImage->TexFormat); + + update_fbo_texture(ctx, texObj, face, level); + + /* state update */ + texObj->Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } else if (target == GL_PROXY_TEXTURE_2D || (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB && @@ -2486,39 +2510,46 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, return; /* error was recorded */ } + if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) + _mesa_update_state(ctx); + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_get_tex_image(ctx, texUnit, target, level); - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); - return; - } - else if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } - ASSERT(texImage->Data == NULL); - clear_teximage_fields(texImage); /* not really needed, but helpful */ - _mesa_init_teximage_fields(ctx, target, texImage, - width, height, depth, - border, internalFormat); - - if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) - _mesa_update_state(ctx); + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_get_tex_image(ctx, texObj, target, level); + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); + goto out; + } + + if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); + } + + ASSERT(texImage->Data == NULL); + clear_teximage_fields(texImage); /* not really needed, but helpful */ + _mesa_init_teximage_fields(ctx, target, texImage, + width, height, depth, + border, internalFormat); - ASSERT(ctx->Driver.TexImage3D); + ASSERT(ctx->Driver.TexImage3D); - /* Give the texture to the driver! may be null! */ - (*ctx->Driver.TexImage3D)(ctx, target, level, internalFormat, - width, height, depth, border, format, type, - pixels, &ctx->Unpack, texObj, texImage); + /* Give the texture to the driver! may be null! */ + (*ctx->Driver.TexImage3D)(ctx, target, level, internalFormat, + width, height, depth, border, format, type, + pixels, &ctx->Unpack, texObj, texImage); - ASSERT(texImage->TexFormat); + ASSERT(texImage->TexFormat); - update_fbo_texture(ctx, texObj, face, level); + update_fbo_texture(ctx, texObj, face, level); - /* state update */ - texObj->Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + /* state update */ + texObj->Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } else if (target == GL_PROXY_TEXTURE_3D) { /* Proxy texture: check for errors and update proxy state */ @@ -2566,7 +2597,7 @@ _mesa_TexSubImage1D( GLenum target, GLint level, GLsizei postConvWidth = width; struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; - struct gl_texture_image *texImage; + struct gl_texture_image *texImage = NULL; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); @@ -2579,26 +2610,38 @@ _mesa_TexSubImage1D( GLenum target, GLint level, } if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0, - postConvWidth, 1, 1, format, type)) { + postConvWidth, 1, 1, format, type)) { return; /* error was detected */ } + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - assert(texImage); + assert(texObj); - if (width == 0) - return; /* no-op, not an error */ + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); - /* If we have a border, xoffset=-1 is legal. Bias by border width */ - xoffset += texImage->Border; + if (subtexture_error_check2(ctx, 1, target, level, xoffset, 0, 0, + postConvWidth, 1, 1, format, type, texImage)) { + goto out; /* error was detected */ + } + + if (width == 0) + goto out; /* no-op, not an error */ + + /* If we have a border, xoffset=-1 is legal. Bias by border width */ + xoffset += texImage->Border; - ASSERT(ctx->Driver.TexSubImage1D); - (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width, - format, type, pixels, &ctx->Unpack, - texObj, texImage); - ctx->NewState |= _NEW_TEXTURE; + ASSERT(ctx->Driver.TexSubImage1D); + (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width, + format, type, pixels, &ctx->Unpack, + texObj, texImage); + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } @@ -2626,27 +2669,37 @@ _mesa_TexSubImage2D( GLenum target, GLint level, } if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0, - postConvWidth, postConvHeight, 1, format, type)) { + postConvWidth, postConvHeight, 1, format, type)) { return; /* error was detected */ } texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - assert(texImage); + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); - if (width == 0 || height == 0) - return; /* no-op, not an error */ + if (subtexture_error_check2(ctx, 2, target, level, xoffset, yoffset, 0, + postConvWidth, postConvHeight, 1, format, type, + texImage)) { + goto out; /* error was detected */ + } - /* If we have a border, xoffset=-1 is legal. Bias by border width */ - xoffset += texImage->Border; - yoffset += texImage->Border; + if (width == 0 || height == 0) + goto out; /* no-op, not an error */ - ASSERT(ctx->Driver.TexSubImage2D); - (*ctx->Driver.TexSubImage2D)(ctx, target, level, xoffset, yoffset, - width, height, format, type, pixels, - &ctx->Unpack, texObj, texImage); - ctx->NewState |= _NEW_TEXTURE; + /* If we have a border, xoffset=-1 is legal. Bias by border width */ + xoffset += texImage->Border; + yoffset += texImage->Border; + + ASSERT(ctx->Driver.TexSubImage2D); + (*ctx->Driver.TexSubImage2D)(ctx, target, level, xoffset, yoffset, + width, height, format, type, pixels, + &ctx->Unpack, texObj, texImage); + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } @@ -2674,24 +2727,34 @@ _mesa_TexSubImage3D( GLenum target, GLint level, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - assert(texImage); - - if (width == 0 || height == 0 || height == 0) - return; /* no-op, not an error */ - - /* If we have a border, xoffset=-1 is legal. Bias by border width */ - xoffset += texImage->Border; - yoffset += texImage->Border; - zoffset += texImage->Border; - - ASSERT(ctx->Driver.TexSubImage3D); - (*ctx->Driver.TexSubImage3D)(ctx, target, level, - xoffset, yoffset, zoffset, - width, height, depth, - format, type, pixels, - &ctx->Unpack, texObj, texImage ); - ctx->NewState |= _NEW_TEXTURE; + + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); + + if (subtexture_error_check2(ctx, 3, target, level, xoffset, yoffset, zoffset, + width, height, depth, format, type, texImage)) { + goto out; /* error was detected */ + } + + if (width == 0 || height == 0 || height == 0) + goto out; /* no-op, not an error */ + + /* If we have a border, xoffset=-1 is legal. Bias by border width */ + xoffset += texImage->Border; + yoffset += texImage->Border; + zoffset += texImage->Border; + + ASSERT(ctx->Driver.TexSubImage3D); + (*ctx->Driver.TexSubImage3D)(ctx, target, level, + xoffset, yoffset, zoffset, + width, height, depth, + format, type, pixels, + &ctx->Unpack, texObj, texImage ); + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } @@ -2723,32 +2786,39 @@ _mesa_CopyTexImage1D( GLenum target, GLint level, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_get_tex_image(ctx, texUnit, target, level); - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D"); - return; - } - else if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } - ASSERT(texImage->Data == NULL); + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_get_tex_image(ctx, texObj, target, level); + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D"); + goto out; + } + + if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); + } + + ASSERT(texImage->Data == NULL); - clear_teximage_fields(texImage); /* not really needed, but helpful */ - _mesa_init_teximage_fields(ctx, target, texImage, postConvWidth, 1, 1, - border, internalFormat); + clear_teximage_fields(texImage); /* not really needed, but helpful */ + _mesa_init_teximage_fields(ctx, target, texImage, postConvWidth, 1, 1, + border, internalFormat); - ASSERT(ctx->Driver.CopyTexImage1D); - (*ctx->Driver.CopyTexImage1D)(ctx, target, level, internalFormat, - x, y, width, border); + ASSERT(ctx->Driver.CopyTexImage1D); + (*ctx->Driver.CopyTexImage1D)(ctx, target, level, internalFormat, + x, y, width, border); - ASSERT(texImage->TexFormat); + ASSERT(texImage->TexFormat); - update_fbo_texture(ctx, texObj, face, level); + update_fbo_texture(ctx, texObj, face, level); - /* state update */ - texObj->Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + /* state update */ + texObj->Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } @@ -2780,41 +2850,50 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_get_tex_image(ctx, texUnit, target, level); - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D"); - return; - } - else if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } - ASSERT(texImage->Data == NULL); - clear_teximage_fields(texImage); /* not really needed, but helpful */ - _mesa_init_teximage_fields(ctx, target, texImage, - postConvWidth, postConvHeight, 1, - border, internalFormat); + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_get_tex_image(ctx, texObj, target, level); - ASSERT(ctx->Driver.CopyTexImage2D); - (*ctx->Driver.CopyTexImage2D)(ctx, target, level, internalFormat, - x, y, width, height, border); + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D"); + goto out; + } + + if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); + } + + ASSERT(texImage->Data == NULL); - ASSERT(texImage->TexFormat); + clear_teximage_fields(texImage); /* not really needed, but helpful */ + _mesa_init_teximage_fields(ctx, target, texImage, + postConvWidth, postConvHeight, 1, + border, internalFormat); + + ASSERT(ctx->Driver.CopyTexImage2D); + (*ctx->Driver.CopyTexImage2D)(ctx, target, level, internalFormat, + x, y, width, height, border); + + ASSERT(texImage->TexFormat); - update_fbo_texture(ctx, texObj, face, level); + update_fbo_texture(ctx, texObj, face, level); - /* state update */ - texObj->Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + /* state update */ + texObj->Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } - void GLAPIENTRY _mesa_CopyTexSubImage1D( GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width ) { struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; struct gl_texture_image *texImage; GLsizei postConvWidth = width; GET_CURRENT_CONTEXT(ctx); @@ -2831,15 +2910,27 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level, return; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - ASSERT(texImage); + texObj = _mesa_select_tex_object(ctx, texUnit, target); + + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); + + if (copytexsubimage_error_check2(ctx, 1, target, level, + xoffset, 0, 0, postConvWidth, 1, + texImage)) + goto out; + - /* If we have a border, xoffset=-1 is legal. Bias by border width */ - xoffset += texImage->Border; + /* If we have a border, xoffset=-1 is legal. Bias by border width */ + xoffset += texImage->Border; - ASSERT(ctx->Driver.CopyTexSubImage1D); - (*ctx->Driver.CopyTexSubImage1D)(ctx, target, level, xoffset, x, y, width); - ctx->NewState |= _NEW_TEXTURE; + ASSERT(ctx->Driver.CopyTexSubImage1D); + (*ctx->Driver.CopyTexSubImage1D)(ctx, target, level, xoffset, x, y, width); + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } @@ -2850,6 +2941,7 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level, GLint x, GLint y, GLsizei width, GLsizei height ) { struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; struct gl_texture_image *texImage; GLsizei postConvWidth = width, postConvHeight = height; GET_CURRENT_CONTEXT(ctx); @@ -2866,17 +2958,27 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level, return; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - ASSERT(texImage); + texObj = _mesa_select_tex_object(ctx, texUnit, target); + + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); - /* If we have a border, xoffset=-1 is legal. Bias by border width */ - xoffset += texImage->Border; - yoffset += texImage->Border; + if (copytexsubimage_error_check2(ctx, 2, target, level, xoffset, yoffset, 0, + postConvWidth, postConvHeight, texImage)) + goto out; - ASSERT(ctx->Driver.CopyTexSubImage2D); - (*ctx->Driver.CopyTexSubImage2D)(ctx, target, level, - xoffset, yoffset, x, y, width, height); - ctx->NewState |= _NEW_TEXTURE; + /* If we have a border, xoffset=-1 is legal. Bias by border width */ + xoffset += texImage->Border; + yoffset += texImage->Border; + + ASSERT(ctx->Driver.CopyTexSubImage2D); + (*ctx->Driver.CopyTexSubImage2D)(ctx, target, level, + xoffset, yoffset, x, y, width, height); + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } @@ -2887,6 +2989,7 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level, GLint x, GLint y, GLsizei width, GLsizei height ) { struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; struct gl_texture_image *texImage; GLsizei postConvWidth = width, postConvHeight = height; GET_CURRENT_CONTEXT(ctx); @@ -2903,19 +3006,30 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level, return; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - ASSERT(texImage); + texObj = _mesa_select_tex_object(ctx, texUnit, target); - /* If we have a border, xoffset=-1 is legal. Bias by border width */ - xoffset += texImage->Border; - yoffset += texImage->Border; - zoffset += texImage->Border; + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); - ASSERT(ctx->Driver.CopyTexSubImage3D); - (*ctx->Driver.CopyTexSubImage3D)(ctx, target, level, - xoffset, yoffset, zoffset, - x, y, width, height); - ctx->NewState |= _NEW_TEXTURE; + if (copytexsubimage_error_check2(ctx, 3, target, level, xoffset, yoffset, + zoffset, postConvWidth, postConvHeight, + texImage)) + goto out; + + /* If we have a border, xoffset=-1 is legal. Bias by border width */ + xoffset += texImage->Border; + yoffset += texImage->Border; + zoffset += texImage->Border; + + ASSERT(ctx->Driver.CopyTexSubImage3D); + (*ctx->Driver.CopyTexSubImage3D)(ctx, target, level, + xoffset, yoffset, zoffset, + x, y, width, height); + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } @@ -3136,28 +3250,35 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_get_tex_image(ctx, texUnit, target, level); - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1D"); - return; - } - else if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } - ASSERT(texImage->Data == NULL); - _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, - border, internalFormat); + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_get_tex_image(ctx, texObj, target, level); + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1D"); + goto out; + } + + if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); + } + ASSERT(texImage->Data == NULL); + + _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, + border, internalFormat); - ASSERT(ctx->Driver.CompressedTexImage1D); - (*ctx->Driver.CompressedTexImage1D)(ctx, target, level, - internalFormat, width, border, - imageSize, data, - texObj, texImage); + ASSERT(ctx->Driver.CompressedTexImage1D); + (*ctx->Driver.CompressedTexImage1D)(ctx, target, level, + internalFormat, width, border, + imageSize, data, + texObj, texImage); - /* state update */ - texObj->Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + /* state update */ + texObj->Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } else if (target == GL_PROXY_TEXTURE_1D) { /* Proxy texture: check for errors and update proxy state */ @@ -3179,11 +3300,18 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level, else { /* store the teximage parameters */ struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; struct gl_texture_image *texImage; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, - border, internalFormat); + texObj = _mesa_select_tex_object(ctx, texUnit, target); + + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); + _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, + border, internalFormat); + } + _mesa_unlock_texture(ctx, texObj); } } else { @@ -3219,28 +3347,35 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_get_tex_image(ctx, texUnit, target, level); - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); - return; - } - else if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } - ASSERT(texImage->Data == NULL); - _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, - border, internalFormat); + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_get_tex_image(ctx, texObj, target, level); + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); + goto out; + } + + if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); + } + ASSERT(texImage->Data == NULL); - ASSERT(ctx->Driver.CompressedTexImage2D); - (*ctx->Driver.CompressedTexImage2D)(ctx, target, level, - internalFormat, width, height, - border, imageSize, data, - texObj, texImage); + _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, + border, internalFormat); - /* state update */ - texObj->Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + ASSERT(ctx->Driver.CompressedTexImage2D); + (*ctx->Driver.CompressedTexImage2D)(ctx, target, level, + internalFormat, width, height, + border, imageSize, data, + texObj, texImage); + + /* state update */ + texObj->Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } else if (target == GL_PROXY_TEXTURE_2D || (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB && @@ -3264,11 +3399,18 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level, else { /* store the teximage parameters */ struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; struct gl_texture_image *texImage; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, - border, internalFormat); + texObj = _mesa_select_tex_object(ctx, texUnit, target); + + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); + _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, + border, internalFormat); + } + _mesa_unlock_texture(ctx, texObj); } } else { @@ -3301,29 +3443,35 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_get_tex_image(ctx, texUnit, target, level); - if (!texImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3D"); - return; - } - else if (texImage->Data) { - ctx->Driver.FreeTexImageData( ctx, texImage ); - } - ASSERT(texImage->Data == NULL); - - _mesa_init_teximage_fields(ctx, target, texImage, width, height, depth, - border, internalFormat); + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_get_tex_image(ctx, texObj, target, level); + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3D"); + goto out; + } + + if (texImage->Data) { + ctx->Driver.FreeTexImageData( ctx, texImage ); + } + ASSERT(texImage->Data == NULL); - ASSERT(ctx->Driver.CompressedTexImage3D); - (*ctx->Driver.CompressedTexImage3D)(ctx, target, level, - internalFormat, - width, height, depth, - border, imageSize, data, - texObj, texImage); + _mesa_init_teximage_fields(ctx, target, texImage, width, height, depth, + border, internalFormat); - /* state update */ - texObj->Complete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + ASSERT(ctx->Driver.CompressedTexImage3D); + (*ctx->Driver.CompressedTexImage3D)(ctx, target, level, + internalFormat, + width, height, depth, + border, imageSize, data, + texObj, texImage); + + /* state update */ + texObj->Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + out: + _mesa_unlock_texture(ctx, texObj); } else if (target == GL_PROXY_TEXTURE_3D) { /* Proxy texture: check for errors and update proxy state */ @@ -3345,11 +3493,17 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level, else { /* store the teximage parameters */ struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; struct gl_texture_image *texImage; texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - _mesa_init_teximage_fields(ctx, target, texImage, width, height, - depth, border, internalFormat); + texObj = _mesa_select_tex_object(ctx, texUnit, target); + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); + _mesa_init_teximage_fields(ctx, target, texImage, width, height, + depth, border, internalFormat); + } + _mesa_unlock_texture(ctx, texObj); } } else { @@ -3382,30 +3536,35 @@ _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - assert(texImage); + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); + assert(texImage); - if ((GLint) format != texImage->InternalFormat) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glCompressedTexSubImage1D(format)"); - return; - } + if ((GLint) format != texImage->InternalFormat) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCompressedTexSubImage1D(format)"); + goto out; + } - if ((width == 1 || width == 2) && (GLuint) width != texImage->Width) { - _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage1D(width)"); - return; - } + if ((width == 1 || width == 2) && (GLuint) width != texImage->Width) { + _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage1D(width)"); + goto out; + } - if (width == 0) - return; /* no-op, not an error */ + if (width == 0) + goto out; /* no-op, not an error */ - if (ctx->Driver.CompressedTexSubImage1D) { - (*ctx->Driver.CompressedTexSubImage1D)(ctx, target, level, - xoffset, width, - format, imageSize, data, - texObj, texImage); + if (ctx->Driver.CompressedTexSubImage1D) { + (*ctx->Driver.CompressedTexSubImage1D)(ctx, target, level, + xoffset, width, + format, imageSize, data, + texObj, texImage); + } + ctx->NewState |= _NEW_TEXTURE; } - ctx->NewState |= _NEW_TEXTURE; + out: + _mesa_unlock_texture(ctx, texObj); } @@ -3434,31 +3593,36 @@ _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - assert(texImage); + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); + assert(texImage); - if ((GLint) format != texImage->InternalFormat) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glCompressedTexSubImage2D(format)"); - return; - } + if ((GLint) format != texImage->InternalFormat) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCompressedTexSubImage2D(format)"); + goto out; + } - if (((width == 1 || width == 2) && (GLuint) width != texImage->Width) || - ((height == 1 || height == 2) && (GLuint) height != texImage->Height)) { - _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage2D(size)"); - return; - } + if (((width == 1 || width == 2) && (GLuint) width != texImage->Width) || + ((height == 1 || height == 2) && (GLuint) height != texImage->Height)) { + _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage2D(size)"); + goto out; + } - if (width == 0 || height == 0) - return; /* no-op, not an error */ + if (width == 0 || height == 0) + goto out; /* no-op, not an error */ - if (ctx->Driver.CompressedTexSubImage2D) { - (*ctx->Driver.CompressedTexSubImage2D)(ctx, target, level, - xoffset, yoffset, width, height, - format, imageSize, data, - texObj, texImage); + if (ctx->Driver.CompressedTexSubImage2D) { + (*ctx->Driver.CompressedTexSubImage2D)(ctx, target, level, + xoffset, yoffset, width, height, + format, imageSize, data, + texObj, texImage); + } + ctx->NewState |= _NEW_TEXTURE; } - ctx->NewState |= _NEW_TEXTURE; + out: + _mesa_unlock_texture(ctx, texObj); } @@ -3486,33 +3650,38 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - assert(texImage); + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); + assert(texImage); - if ((GLint) format != texImage->InternalFormat) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glCompressedTexSubImage3D(format)"); - return; - } + if ((GLint) format != texImage->InternalFormat) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCompressedTexSubImage3D(format)"); + goto out; + } - if (((width == 1 || width == 2) && (GLuint) width != texImage->Width) || - ((height == 1 || height == 2) && (GLuint) height != texImage->Height) || - ((depth == 1 || depth == 2) && (GLuint) depth != texImage->Depth)) { - _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage3D(size)"); - return; - } + if (((width == 1 || width == 2) && (GLuint) width != texImage->Width) || + ((height == 1 || height == 2) && (GLuint) height != texImage->Height) || + ((depth == 1 || depth == 2) && (GLuint) depth != texImage->Depth)) { + _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage3D(size)"); + goto out; + } - if (width == 0 || height == 0 || depth == 0) - return; /* no-op, not an error */ + if (width == 0 || height == 0 || depth == 0) + goto out; /* no-op, not an error */ - if (ctx->Driver.CompressedTexSubImage3D) { - (*ctx->Driver.CompressedTexSubImage3D)(ctx, target, level, - xoffset, yoffset, zoffset, - width, height, depth, - format, imageSize, data, - texObj, texImage); + if (ctx->Driver.CompressedTexSubImage3D) { + (*ctx->Driver.CompressedTexSubImage3D)(ctx, target, level, + xoffset, yoffset, zoffset, + width, height, depth, + format, imageSize, data, + texObj, texImage); + } + ctx->NewState |= _NEW_TEXTURE; } - ctx->NewState |= _NEW_TEXTURE; + out: + _mesa_unlock_texture(ctx, texObj); } @@ -3520,12 +3689,13 @@ void GLAPIENTRY _mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img) { const struct gl_texture_unit *texUnit; - const struct gl_texture_object *texObj; + struct gl_texture_object *texObj; struct gl_texture_image *texImage; GLint maxLevels; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); if (!texObj) { @@ -3546,18 +3716,24 @@ _mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img) return; } - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); - if (!texImage) { - /* probably invalid mipmap level */ - _mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)"); - return; - } - if (!texImage->IsCompressed) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetCompressedTexImageARB"); - return; - } + _mesa_lock_texture(ctx, texObj); + { + texImage = _mesa_select_tex_image(ctx, texObj, target, level); + if (!texImage) { + /* probably invalid mipmap level */ + _mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)"); + goto out; + } + + if (!texImage->IsCompressed) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetCompressedTexImageARB"); + goto out; + } - /* this typically calls _mesa_get_compressed_teximage() */ - ctx->Driver.GetCompressedTexImage(ctx, target, level, img, texObj,texImage); + /* this typically calls _mesa_get_compressed_teximage() */ + ctx->Driver.GetCompressedTexImage(ctx, target, level, img, texObj,texImage); + } + out: + _mesa_unlock_texture(ctx, texObj); } diff --git a/src/mesa/main/teximage.h b/src/mesa/main/teximage.h index 410789fe04..68457f4728 100644 --- a/src/mesa/main/teximage.h +++ b/src/mesa/main/teximage.h @@ -84,12 +84,12 @@ _mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit, extern struct gl_texture_image * -_mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit, +_mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_object *texObj, GLenum target, GLint level); extern struct gl_texture_image * -_mesa_get_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit, +_mesa_get_tex_image(GLcontext *ctx, struct gl_texture_object *texObj, GLenum target, GLint level); @@ -106,6 +106,23 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level, GLint internalFormat, GLenum format, GLenum type, GLint width, GLint height, GLint depth, GLint border); + +/* Lock a texture for updating. See also _mesa_lock_context_textures(). + */ +static INLINE void _mesa_lock_texture(GLcontext *ctx, + struct gl_texture_object *texObj) +{ + _glthread_LOCK_MUTEX(ctx->Shared->TexMutex); + ctx->Shared->TextureStateStamp++; + (void) texObj; +} + +static INLINE void _mesa_unlock_texture(GLcontext *ctx, + struct gl_texture_object *texObj) +{ + _glthread_UNLOCK_MUTEX(ctx->Shared->TexMutex); +} + /*@}*/ diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c index 8b42c2a712..1d27cd3f7c 100644 --- a/src/mesa/main/texobj.c +++ b/src/mesa/main/texobj.c @@ -697,7 +697,11 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) if (textures[i] > 0) { struct gl_texture_object *delObj = _mesa_lookup_texture(ctx, textures[i]); + if (delObj) { + GLboolean delete; + + _mesa_lock_texture(ctx, delObj); /* Check if texture is bound to any framebuffer objects. * If so, unbind. @@ -724,7 +728,14 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) * XXX all RefCount accesses should be protected by a mutex. */ delObj->RefCount--; - if (delObj->RefCount == 0) { + delete = (delObj->RefCount == 0); + _mesa_unlock_texture(ctx, delObj); + + /* We know that refcount went to zero above, so this is + * the only pointer left to delObj, so we don't have to + * worry about locking any more: + */ + if (delete) { ASSERT(delObj->Name != 0); /* Never delete default tex objs */ ASSERT(ctx->Driver.DeleteTexture); (*ctx->Driver.DeleteTexture)(ctx, delObj); @@ -1052,4 +1063,30 @@ _mesa_IsTexture( GLuint texture ) return t && t->Target; } +/* Simplest implementation of texture locking: Grab the a new mutex in + * the shared context. Examine the shared context state timestamp and + * if there has been a change, set the appropriate bits in + * ctx->NewState. + * + * See also _mesa_lock/unlock_texture in texobj.h + */ +void _mesa_lock_context_textures( GLcontext *ctx ) +{ + _glthread_LOCK_MUTEX(ctx->Shared->TexMutex); + + if (ctx->Shared->TextureStateStamp != ctx->TextureStateTimestamp) { + ctx->NewState |= _NEW_TEXTURE; + ctx->TextureStateTimestamp = ctx->Shared->TextureStateStamp; + } +} + + +void _mesa_unlock_context_textures( GLcontext *ctx ) +{ + assert(ctx->Shared->TextureStateStamp == ctx->TextureStateTimestamp); + _glthread_UNLOCK_MUTEX(ctx->Shared->TexMutex); +} + /*@}*/ + + diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h index ac66ac69d3..ec7cf8cd86 100644 --- a/src/mesa/main/texobj.h +++ b/src/mesa/main/texobj.h @@ -61,6 +61,9 @@ extern void _mesa_test_texobj_completeness( const GLcontext *ctx, struct gl_texture_object *obj ); +extern void _mesa_unlock_context_textures( GLcontext *ctx ); +extern void _mesa_lock_context_textures( GLcontext *ctx ); + /*@}*/ @@ -95,4 +98,5 @@ _mesa_IsTexture( GLuint texture ); /*@}*/ + #endif diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 0687e5760c..bcedcafe19 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -144,6 +144,8 @@ _mesa_copy_texture_state( const GLcontext *src, GLcontext *dst ) dst->Texture.Unit[i].Combine.ScaleShiftA = src->Texture.Unit[i].Combine.ScaleShiftA; /* copy texture object bindings, not contents of texture objects */ + _mesa_lock_context_textures(dst); + copy_texture_binding(src, &dst->Texture.Unit[i].Current1D, src->Texture.Unit[i].Current1D); copy_texture_binding(src, &dst->Texture.Unit[i].Current2D, @@ -154,6 +156,8 @@ _mesa_copy_texture_state( const GLcontext *src, GLcontext *dst ) src->Texture.Unit[i].CurrentCubeMap); copy_texture_binding(src, &dst->Texture.Unit[i].CurrentRect, src->Texture.Unit[i].CurrentRect); + + _mesa_unlock_context_textures(dst); } } @@ -1700,6 +1704,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, GLenum pname, GLint *params ) { const struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; const struct gl_texture_image *img = NULL; GLuint dimensions; GLboolean isProxy; @@ -1734,14 +1739,17 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, return; } - img = _mesa_select_tex_image(ctx, texUnit, target, level); + texObj = _mesa_select_tex_object(ctx, texUnit, target); + _mesa_lock_texture(ctx, texObj); + + img = _mesa_select_tex_image(ctx, texObj, target, level); if (!img || !img->TexFormat) { /* undefined texture image */ if (pname == GL_TEXTURE_COMPONENTS) *params = 1; else *params = 0; - return; + goto out; } isProxy = _mesa_is_proxy_texture(target); @@ -1749,37 +1757,37 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, switch (pname) { case GL_TEXTURE_WIDTH: *params = img->Width; - return; + break; case GL_TEXTURE_HEIGHT: *params = img->Height; - return; + break; case GL_TEXTURE_DEPTH: *params = img->Depth; - return; + break; case GL_TEXTURE_INTERNAL_FORMAT: *params = img->InternalFormat; - return; + break; case GL_TEXTURE_BORDER: *params = img->Border; - return; + break; case GL_TEXTURE_RED_SIZE: if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA) *params = img->TexFormat->RedBits; else *params = 0; - return; + break; case GL_TEXTURE_GREEN_SIZE: if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA) *params = img->TexFormat->GreenBits; else *params = 0; - return; + break; case GL_TEXTURE_BLUE_SIZE: if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA) *params = img->TexFormat->BlueBits; else *params = 0; - return; + break; case GL_TEXTURE_ALPHA_SIZE: if (img->_BaseFormat == GL_ALPHA || img->_BaseFormat == GL_LUMINANCE_ALPHA || @@ -1787,7 +1795,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, *params = img->TexFormat->AlphaBits; else *params = 0; - return; + break; case GL_TEXTURE_INTENSITY_SIZE: if (img->_BaseFormat != GL_INTENSITY) *params = 0; @@ -1795,7 +1803,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, *params = img->TexFormat->IntensityBits; else /* intensity probably stored as rgb texture */ *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits); - return; + break; case GL_TEXTURE_LUMINANCE_SIZE: if (img->_BaseFormat != GL_LUMINANCE && img->_BaseFormat != GL_LUMINANCE_ALPHA) @@ -1804,13 +1812,13 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, *params = img->TexFormat->LuminanceBits; else /* luminance probably stored as rgb texture */ *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits); - return; + break; case GL_TEXTURE_INDEX_SIZE_EXT: if (img->_BaseFormat == GL_COLOR_INDEX) *params = img->TexFormat->IndexBits; else *params = 0; - return; + break; case GL_TEXTURE_DEPTH_SIZE_ARB: if (ctx->Extensions.SGIX_depth_texture || ctx->Extensions.ARB_depth_texture) @@ -1818,7 +1826,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, else _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); - return; + break; case GL_TEXTURE_STENCIL_SIZE_EXT: if (ctx->Extensions.EXT_packed_depth_stencil) { *params = img->TexFormat->StencilBits; @@ -1827,7 +1835,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } - return; + break; /* GL_ARB_texture_compression */ case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: @@ -1849,7 +1857,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } - return; + break; case GL_TEXTURE_COMPRESSED: if (ctx->Extensions.ARB_texture_compression) { *params = (GLint) img->IsCompressed; @@ -1858,7 +1866,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } - return; + break; /* GL_ARB_texture_float */ case GL_TEXTURE_RED_TYPE_ARB: @@ -1869,7 +1877,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } - return; + break; case GL_TEXTURE_GREEN_TYPE_ARB: if (ctx->Extensions.ARB_texture_float) { *params = img->TexFormat->GreenBits ? img->TexFormat->DataType : GL_NONE; @@ -1878,7 +1886,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } - return; + break; case GL_TEXTURE_BLUE_TYPE_ARB: if (ctx->Extensions.ARB_texture_float) { *params = img->TexFormat->BlueBits ? img->TexFormat->DataType : GL_NONE; @@ -1887,7 +1895,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } - return; + break; case GL_TEXTURE_ALPHA_TYPE_ARB: if (ctx->Extensions.ARB_texture_float) { *params = img->TexFormat->AlphaBits ? img->TexFormat->DataType : GL_NONE; @@ -1896,7 +1904,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } - return; + break; case GL_TEXTURE_LUMINANCE_TYPE_ARB: if (ctx->Extensions.ARB_texture_float) { *params = img->TexFormat->LuminanceBits ? img->TexFormat->DataType : GL_NONE; @@ -1905,7 +1913,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } - return; + break; case GL_TEXTURE_INTENSITY_TYPE_ARB: if (ctx->Extensions.ARB_texture_float) { *params = img->TexFormat->IntensityBits ? img->TexFormat->DataType : GL_NONE; @@ -1914,7 +1922,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } - return; + break; case GL_TEXTURE_DEPTH_TYPE_ARB: if (ctx->Extensions.ARB_texture_float) { *params = img->TexFormat->DepthBits ? img->TexFormat->DataType : GL_NONE; @@ -1923,12 +1931,15 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } - return; + break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); } + + out: + _mesa_unlock_texture(ctx, texObj); } @@ -1938,6 +1949,7 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) { struct gl_texture_unit *texUnit; struct gl_texture_object *obj; + GLboolean error = GL_FALSE; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -1955,28 +1967,29 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) return; } + _mesa_lock_texture(ctx, obj); switch (pname) { case GL_TEXTURE_MAG_FILTER: *params = ENUM_TO_FLOAT(obj->MagFilter); - return; + break; case GL_TEXTURE_MIN_FILTER: *params = ENUM_TO_FLOAT(obj->MinFilter); - return; + break; case GL_TEXTURE_WRAP_S: *params = ENUM_TO_FLOAT(obj->WrapS); - return; + break; case GL_TEXTURE_WRAP_T: *params = ENUM_TO_FLOAT(obj->WrapT); - return; + break; case GL_TEXTURE_WRAP_R: *params = ENUM_TO_FLOAT(obj->WrapR); - return; + break; case GL_TEXTURE_BORDER_COLOR: params[0] = CLAMP(obj->BorderColor[0], 0.0F, 1.0F); params[1] = CLAMP(obj->BorderColor[1], 0.0F, 1.0F); params[2] = CLAMP(obj->BorderColor[2], 0.0F, 1.0F); params[3] = CLAMP(obj->BorderColor[3], 0.0F, 1.0F); - return; + break; case GL_TEXTURE_RESIDENT: { GLboolean resident; @@ -1986,82 +1999,94 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) resident = GL_TRUE; *params = ENUM_TO_FLOAT(resident); } - return; + break; case GL_TEXTURE_PRIORITY: *params = obj->Priority; - return; + break; case GL_TEXTURE_MIN_LOD: *params = obj->MinLod; - return; + break; case GL_TEXTURE_MAX_LOD: *params = obj->MaxLod; - return; + break; case GL_TEXTURE_BASE_LEVEL: *params = (GLfloat) obj->BaseLevel; - return; + break; case GL_TEXTURE_MAX_LEVEL: *params = (GLfloat) obj->MaxLevel; - return; + break; case GL_TEXTURE_MAX_ANISOTROPY_EXT: if (ctx->Extensions.EXT_texture_filter_anisotropic) { *params = obj->MaxAnisotropy; - return; } + else + error = 1; break; case GL_TEXTURE_COMPARE_SGIX: if (ctx->Extensions.SGIX_shadow) { *params = (GLfloat) obj->CompareFlag; - return; } + else + error = 1; break; case GL_TEXTURE_COMPARE_OPERATOR_SGIX: if (ctx->Extensions.SGIX_shadow) { *params = (GLfloat) obj->CompareOperator; - return; } + else + error = 1; break; case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */ if (ctx->Extensions.SGIX_shadow_ambient) { *params = obj->ShadowAmbient; - return; } + else + error = 1; break; case GL_GENERATE_MIPMAP_SGIS: if (ctx->Extensions.SGIS_generate_mipmap) { *params = (GLfloat) obj->GenerateMipmap; - return; } + else + error = 1; break; case GL_TEXTURE_COMPARE_MODE_ARB: if (ctx->Extensions.ARB_shadow) { *params = (GLfloat) obj->CompareMode; - return; } + else + error = 1; break; case GL_TEXTURE_COMPARE_FUNC_ARB: if (ctx->Extensions.ARB_shadow) { *params = (GLfloat) obj->CompareFunc; - return; } + else + error = 1; break; case GL_DEPTH_TEXTURE_MODE_ARB: if (ctx->Extensions.ARB_depth_texture) { *params = (GLfloat) obj->DepthMode; - return; } + else + error = 1; break; case GL_TEXTURE_LOD_BIAS: if (ctx->Extensions.EXT_texture_lod_bias) { *params = obj->LodBias; - return; } + else + error = 1; break; default: - ; /* silence warnings */ + error = 1; + break; } - /* If we get here, pname was an unrecognized enum */ - _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)", - pname); + if (error) + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)", + pname); + + _mesa_unlock_texture(ctx, obj); } diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c index b8e5e4bd8a..43e3bc183d 100644 --- a/src/mesa/shader/arbprogparse.c +++ b/src/mesa/shader/arbprogparse.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5.1 + * Version: 6.5.2 * * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * @@ -2571,8 +2571,6 @@ parse_fp_vector_src_reg(GLcontext * ctx, const GLubyte ** inst, reg->File = file; reg->Index = index; - reg->Abs = 0; /* NV only */ - reg->NegateAbs = 0; /* NV only */ reg->NegateBase = negate; reg->Swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], swizzle[2], swizzle[3]); return 0; @@ -2595,8 +2593,6 @@ parse_fp_dst_reg(GLcontext * ctx, const GLubyte ** inst, if (parse_masked_dst_reg (ctx, inst, vc_head, Program, &file, &idx, &mask)) return 1; - reg->CondMask = 0; /* NV only */ - reg->CondSwizzle = 0; /* NV only */ reg->File = file; reg->Index = idx; reg->WriteMask = mask; @@ -2632,8 +2628,6 @@ parse_fp_scalar_src_reg (GLcontext * ctx, const GLubyte ** inst, reg->File = File; reg->Index = Index; - reg->Abs = 0; /* NV only */ - reg->NegateAbs = 0; /* NV only */ reg->NegateBase = Negate; reg->Swizzle = (Swizzle[0] << 0); @@ -2656,7 +2650,7 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst, GLubyte instClass, type, code; GLboolean rel; - _mesa_init_instruction(fp); + _mesa_init_instructions(fp, 1); /* Record the position in the program string for debugging */ fp->StringPos = Program->Position; @@ -3148,7 +3142,7 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst, /* The actual opcode name */ code = *(*inst)++; - _mesa_init_instruction(vp); + _mesa_init_instructions(vp, 1); /* Record the position in the program string for debugging */ vp->StringPos = Program->Position; @@ -3690,7 +3684,7 @@ parse_instructions(GLcontext * ctx, const GLubyte * inst, /* Finally, tag on an OPCODE_END instruction */ { const GLuint numInst = Program->Base.NumInstructions; - _mesa_init_instruction(Program->Base.Instructions + numInst); + _mesa_init_instructions(Program->Base.Instructions + numInst, 1); Program->Base.Instructions[numInst].Opcode = OPCODE_END; /* YYY Wrong Position in program, whatever, at least not random -> crash Program->Position = parse_position (&inst); diff --git a/src/mesa/shader/nvfragparse.c b/src/mesa/shader/nvfragparse.c index 49ce220944..5f3a30b741 100644 --- a/src/mesa/shader/nvfragparse.c +++ b/src/mesa/shader/nvfragparse.c @@ -1273,7 +1273,7 @@ Parse_InstructionSequence(struct parse_state *parseState, GLubyte token[100]; /* Initialize the instruction */ - _mesa_init_instruction(inst); + _mesa_init_instructions(inst, 1); /* special instructions */ if (Parse_String(parseState, "DEFINE")) { diff --git a/src/mesa/shader/nvprogram.c b/src/mesa/shader/nvprogram.c index 47d2b61a62..0e9a01dcab 100644 --- a/src/mesa/shader/nvprogram.c +++ b/src/mesa/shader/nvprogram.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5.1 + * Version: 6.5.2 * * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * @@ -77,10 +77,7 @@ _mesa_ExecuteProgramNV(GLenum target, GLuint id, const GLfloat *params) return; } - _mesa_init_vp_per_vertex_registers(ctx); - _mesa_init_vp_per_primitive_registers(ctx); - COPY_4V(ctx->VertexProgram.Machine.Inputs[VERT_ATTRIB_POS], params); - _mesa_exec_vertex_program(ctx, vprog); + _mesa_exec_vertex_state_program(ctx, vprog, params); } diff --git a/src/mesa/shader/nvvertexec.c b/src/mesa/shader/nvvertexec.c index 1985593659..10962d7e14 100644 --- a/src/mesa/shader/nvvertexec.c +++ b/src/mesa/shader/nvvertexec.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.2 * * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * @@ -47,23 +47,23 @@ static const GLfloat ZeroVec[4] = { 0.0F, 0.0F, 0.0F, 0.0F }; * per-vertex. */ void -_mesa_init_vp_per_vertex_registers(GLcontext *ctx) +_mesa_init_vp_per_vertex_registers(GLcontext *ctx, struct vp_machine *machine) { /* Input registers get initialized from the current vertex attribs */ - MEMCPY(ctx->VertexProgram.Machine.Inputs, ctx->Current.Attrib, + MEMCPY(machine->Inputs, ctx->Current.Attrib, MAX_VERTEX_PROGRAM_ATTRIBS * 4 * sizeof(GLfloat)); if (ctx->VertexProgram.Current->IsNVProgram) { GLuint i; /* Output/result regs are initialized to [0,0,0,1] */ for (i = 0; i < MAX_NV_VERTEX_PROGRAM_OUTPUTS; i++) { - ASSIGN_4V(ctx->VertexProgram.Machine.Outputs[i], 0.0F, 0.0F, 0.0F, 1.0F); + ASSIGN_4V(machine->Outputs[i], 0.0F, 0.0F, 0.0F, 1.0F); } /* Temp regs are initialized to [0,0,0,0] */ for (i = 0; i < MAX_NV_VERTEX_PROGRAM_TEMPS; i++) { - ASSIGN_4V(ctx->VertexProgram.Machine.Temporaries[i], 0.0F, 0.0F, 0.0F, 0.0F); + ASSIGN_4V(machine->Temporaries[i], 0.0F, 0.0F, 0.0F, 0.0F); } - ASSIGN_4V(ctx->VertexProgram.Machine.AddressReg, 0, 0, 0, 0); + ASSIGN_4V(machine->AddressReg, 0, 0, 0, 0); } } @@ -139,7 +139,7 @@ _mesa_init_vp_per_primitive_registers(GLcontext *ctx) continue; } - /* load the matrix */ + /* load the matrix values into sequential registers */ if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_IDENTITY_NV) { load_matrix(ctx->VertexProgram.Parameters, i*4, mat->m); } @@ -176,36 +176,37 @@ _mesa_init_vp_per_primitive_registers(GLcontext *ctx) * For debugging. Dump the current vertex program machine registers. */ void -_mesa_dump_vp_state( const struct gl_vertex_program_state *state ) +_mesa_dump_vp_state( const struct gl_vertex_program_state *state, + const struct vp_machine *machine) { int i; _mesa_printf("VertexIn:\n"); for (i = 0; i < MAX_NV_VERTEX_PROGRAM_INPUTS; i++) { _mesa_printf("%d: %f %f %f %f ", i, - state->Machine.Inputs[i][0], - state->Machine.Inputs[i][1], - state->Machine.Inputs[i][2], - state->Machine.Inputs[i][3]); + machine->Inputs[i][0], + machine->Inputs[i][1], + machine->Inputs[i][2], + machine->Inputs[i][3]); } _mesa_printf("\n"); _mesa_printf("VertexOut:\n"); for (i = 0; i < MAX_NV_VERTEX_PROGRAM_OUTPUTS; i++) { _mesa_printf("%d: %f %f %f %f ", i, - state->Machine.Outputs[i][0], - state->Machine.Outputs[i][1], - state->Machine.Outputs[i][2], - state->Machine.Outputs[i][3]); + machine->Outputs[i][0], + machine->Outputs[i][1], + machine->Outputs[i][2], + machine->Outputs[i][3]); } _mesa_printf("\n"); _mesa_printf("Registers:\n"); for (i = 0; i < MAX_NV_VERTEX_PROGRAM_TEMPS; i++) { _mesa_printf("%d: %f %f %f %f ", i, - state->Machine.Temporaries[i][0], - state->Machine.Temporaries[i][1], - state->Machine.Temporaries[i][2], - state->Machine.Temporaries[i][3]); + machine->Temporaries[i][0], + machine->Temporaries[i][1], + machine->Temporaries[i][2], + machine->Temporaries[i][3]); } _mesa_printf("\n"); @@ -227,41 +228,45 @@ _mesa_dump_vp_state( const struct gl_vertex_program_state *state ) * source register. */ static INLINE const GLfloat * -get_register_pointer( const struct prog_src_register *source, - const struct gl_vertex_program_state *state ) +get_register_pointer( GLcontext *ctx, + const struct prog_src_register *source, + struct vp_machine *machine, + const struct gl_vertex_program *program ) { if (source->RelAddr) { - const GLint reg = source->Index + state->Machine.AddressReg[0]; + const GLint reg = source->Index + machine->AddressReg[0]; ASSERT( (source->File == PROGRAM_ENV_PARAM) || (source->File == PROGRAM_STATE_VAR) ); if (reg < 0 || reg > MAX_NV_VERTEX_PROGRAM_PARAMS) return ZeroVec; else if (source->File == PROGRAM_ENV_PARAM) - return state->Parameters[reg]; - else - return state->Current->Base.Parameters->ParameterValues[reg]; + return ctx->VertexProgram.Parameters[reg]; + else { + ASSERT(source->File == PROGRAM_LOCAL_PARAM); + return program->Base.Parameters->ParameterValues[reg]; + } } else { switch (source->File) { case PROGRAM_TEMPORARY: ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_TEMPS); - return state->Machine.Temporaries[source->Index]; + return machine->Temporaries[source->Index]; case PROGRAM_INPUT: ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_INPUTS); - return state->Machine.Inputs[source->Index]; + return machine->Inputs[source->Index]; case PROGRAM_OUTPUT: /* This is only needed for the PRINT instruction */ ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_OUTPUTS); - return state->Machine.Outputs[source->Index]; + return machine->Outputs[source->Index]; case PROGRAM_LOCAL_PARAM: ASSERT(source->Index < MAX_PROGRAM_LOCAL_PARAMS); - return state->Current->Base.LocalParams[source->Index]; + return program->Base.LocalParams[source->Index]; case PROGRAM_ENV_PARAM: ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_PARAMS); - return state->Parameters[source->Index]; + return ctx->VertexProgram.Parameters[source->Index]; case PROGRAM_STATE_VAR: - ASSERT(source->Index < state->Current->Base.Parameters->NumParameters); - return state->Current->Base.Parameters->ParameterValues[source->Index]; + ASSERT(source->Index < program->Base.Parameters->NumParameters); + return program->Base.Parameters->ParameterValues[source->Index]; default: _mesa_problem(NULL, "Bad source register file in get_register_pointer"); @@ -277,23 +282,23 @@ get_register_pointer( const struct prog_src_register *source, * Apply swizzling and negating as needed. */ static INLINE void -fetch_vector4( const struct prog_src_register *source, - const struct gl_vertex_program_state *state, +fetch_vector4( GLcontext *ctx, + const struct prog_src_register *source, + struct vp_machine *machine, + const struct gl_vertex_program *program, GLfloat result[4] ) { - const GLfloat *src = get_register_pointer(source, state); - + const GLfloat *src = get_register_pointer(ctx, source, machine, program); + ASSERT(src); + result[0] = src[GET_SWZ(source->Swizzle, 0)]; + result[1] = src[GET_SWZ(source->Swizzle, 1)]; + result[2] = src[GET_SWZ(source->Swizzle, 2)]; + result[3] = src[GET_SWZ(source->Swizzle, 3)]; if (source->NegateBase) { - result[0] = -src[GET_SWZ(source->Swizzle, 0)]; - result[1] = -src[GET_SWZ(source->Swizzle, 1)]; - result[2] = -src[GET_SWZ(source->Swizzle, 2)]; - result[3] = -src[GET_SWZ(source->Swizzle, 3)]; - } - else { - result[0] = src[GET_SWZ(source->Swizzle, 0)]; - result[1] = src[GET_SWZ(source->Swizzle, 1)]; - result[2] = src[GET_SWZ(source->Swizzle, 2)]; - result[3] = src[GET_SWZ(source->Swizzle, 3)]; + result[0] = -result[0]; + result[1] = -result[1]; + result[2] = -result[2]; + result[3] = -result[3]; } } @@ -303,17 +308,17 @@ fetch_vector4( const struct prog_src_register *source, * As above, but only return result[0] element. */ static INLINE void -fetch_vector1( const struct prog_src_register *source, - const struct gl_vertex_program_state *state, +fetch_vector1( GLcontext *ctx, + const struct prog_src_register *source, + struct vp_machine *machine, + const struct gl_vertex_program *program, GLfloat result[4] ) { - const GLfloat *src = get_register_pointer(source, state); - + const GLfloat *src = get_register_pointer(ctx, source, machine, program); + ASSERT(src); + result[0] = src[GET_SWZ(source->Swizzle, 0)]; if (source->NegateBase) { - result[0] = -src[GET_SWZ(source->Swizzle, 0)]; - } - else { - result[0] = src[GET_SWZ(source->Swizzle, 0)]; + result[0] = -result[0]; } } @@ -322,19 +327,21 @@ fetch_vector1( const struct prog_src_register *source, * Store 4 floats into a register. */ static void -store_vector4( const struct prog_dst_register *dest, - struct gl_vertex_program_state *state, +store_vector4( const struct prog_instruction *inst, + struct vp_machine *machine, const GLfloat value[4] ) { + const struct prog_dst_register *dest = &(inst->DstReg); GLfloat *dst; switch (dest->File) { - case PROGRAM_TEMPORARY: - dst = state->Machine.Temporaries[dest->Index]; - break; case PROGRAM_OUTPUT: - dst = state->Machine.Outputs[dest->Index]; + dst = machine->Outputs[dest->Index]; + break; + case PROGRAM_TEMPORARY: + dst = machine->Temporaries[dest->Index]; break; case PROGRAM_ENV_PARAM: + /* Only for VP state programs */ { /* a slight hack */ GET_CURRENT_CONTEXT(ctx); @@ -379,9 +386,10 @@ store_vector4( const struct prog_dst_register *dest, * Execute the given vertex program */ void -_mesa_exec_vertex_program(GLcontext *ctx, const struct gl_vertex_program *program) +_mesa_exec_vertex_program(GLcontext *ctx, + struct vp_machine *machine, + const struct gl_vertex_program *program) { - struct gl_vertex_program_state *state = &ctx->VertexProgram; const struct prog_instruction *inst; ctx->_CurrentProgram = GL_VERTEX_PROGRAM_ARB; /* or NV, doesn't matter */ @@ -390,9 +398,9 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct gl_vertex_program *progra * by the MVP matrix and store in the vertex position result register. */ if (ctx->VertexProgram.Current->IsPositionInvariant) { - TRANSFORM_POINT( ctx->VertexProgram.Machine.Outputs[VERT_RESULT_HPOS], + TRANSFORM_POINT( machine->Outputs[VERT_RESULT_HPOS], ctx->_ModelProjectMatrix.m, - ctx->VertexProgram.Machine.Inputs[VERT_ATTRIB_POS]); + machine->Inputs[VERT_ATTRIB_POS]); /* XXX: This could go elsewhere */ ctx->VertexProgram.Current->Base.OutputsWritten |= VERT_BIT_POS; @@ -411,15 +419,15 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct gl_vertex_program *progra case OPCODE_MOV: { GLfloat t[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - store_vector4( &inst->DstReg, state, t ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + store_vector4( inst, machine, t ); } break; case OPCODE_LIT: { const GLfloat epsilon = 1.0F / 256.0F; /* per NV spec */ GLfloat t[4], lit[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); t[0] = MAX2(t[0], 0.0F); t[1] = MAX2(t[1], 0.0F); t[3] = CLAMP(t[3], -(128.0F - epsilon), (128.0F - epsilon)); @@ -427,32 +435,32 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct gl_vertex_program *progra lit[1] = t[0]; lit[2] = (t[0] > 0.0) ? (GLfloat) _mesa_pow(t[1], t[3]) : 0.0F; lit[3] = 1.0; - store_vector4( &inst->DstReg, state, lit ); + store_vector4( inst, machine, lit ); } break; case OPCODE_RCP: { GLfloat t[4]; - fetch_vector1( &inst->SrcReg[0], state, t ); + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t ); if (t[0] != 1.0F) t[0] = 1.0F / t[0]; /* div by zero is infinity! */ t[1] = t[2] = t[3] = t[0]; - store_vector4( &inst->DstReg, state, t ); + store_vector4( inst, machine, t ); } break; case OPCODE_RSQ: { GLfloat t[4]; - fetch_vector1( &inst->SrcReg[0], state, t ); + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t ); t[0] = INV_SQRTF(FABSF(t[0])); t[1] = t[2] = t[3] = t[0]; - store_vector4( &inst->DstReg, state, t ); + store_vector4( inst, machine, t ); } break; case OPCODE_EXP: { GLfloat t[4], q[4], floor_t0; - fetch_vector1( &inst->SrcReg[0], state, t ); + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t ); floor_t0 = FLOORF(t[0]); if (floor_t0 > FLT_MAX_EXP) { SET_POS_INFINITY(q[0]); @@ -475,13 +483,13 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct gl_vertex_program *progra } q[1] = t[0] - floor_t0; q[3] = 1.0F; - store_vector4( &inst->DstReg, state, q ); + store_vector4( inst, machine, q ); } break; case OPCODE_LOG: { GLfloat t[4], q[4], abs_t0; - fetch_vector1( &inst->SrcReg[0], state, t ); + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t ); abs_t0 = FABSF(t[0]); if (abs_t0 != 0.0F) { /* Since we really can't handle infinite values on VMS @@ -512,147 +520,147 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct gl_vertex_program *progra SET_NEG_INFINITY(q[2]); } q[3] = 1.0; - store_vector4( &inst->DstReg, state, q ); + store_vector4( inst, machine, q ); } break; case OPCODE_MUL: { GLfloat t[4], u[4], prod[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - fetch_vector4( &inst->SrcReg[1], state, u ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); prod[0] = t[0] * u[0]; prod[1] = t[1] * u[1]; prod[2] = t[2] * u[2]; prod[3] = t[3] * u[3]; - store_vector4( &inst->DstReg, state, prod ); + store_vector4( inst, machine, prod ); } break; case OPCODE_ADD: { GLfloat t[4], u[4], sum[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - fetch_vector4( &inst->SrcReg[1], state, u ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); sum[0] = t[0] + u[0]; sum[1] = t[1] + u[1]; sum[2] = t[2] + u[2]; sum[3] = t[3] + u[3]; - store_vector4( &inst->DstReg, state, sum ); + store_vector4( inst, machine, sum ); } break; case OPCODE_DP3: { GLfloat t[4], u[4], dot[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - fetch_vector4( &inst->SrcReg[1], state, u ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2]; dot[1] = dot[2] = dot[3] = dot[0]; - store_vector4( &inst->DstReg, state, dot ); + store_vector4( inst, machine, dot ); } break; case OPCODE_DP4: { GLfloat t[4], u[4], dot[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - fetch_vector4( &inst->SrcReg[1], state, u ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2] + t[3] * u[3]; dot[1] = dot[2] = dot[3] = dot[0]; - store_vector4( &inst->DstReg, state, dot ); + store_vector4( inst, machine, dot ); } break; case OPCODE_DST: { GLfloat t[4], u[4], dst[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - fetch_vector4( &inst->SrcReg[1], state, u ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); dst[0] = 1.0F; dst[1] = t[1] * u[1]; dst[2] = t[2]; dst[3] = u[3]; - store_vector4( &inst->DstReg, state, dst ); + store_vector4( inst, machine, dst ); } break; case OPCODE_MIN: { GLfloat t[4], u[4], min[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - fetch_vector4( &inst->SrcReg[1], state, u ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); min[0] = (t[0] < u[0]) ? t[0] : u[0]; min[1] = (t[1] < u[1]) ? t[1] : u[1]; min[2] = (t[2] < u[2]) ? t[2] : u[2]; min[3] = (t[3] < u[3]) ? t[3] : u[3]; - store_vector4( &inst->DstReg, state, min ); + store_vector4( inst, machine, min ); } break; case OPCODE_MAX: { GLfloat t[4], u[4], max[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - fetch_vector4( &inst->SrcReg[1], state, u ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); max[0] = (t[0] > u[0]) ? t[0] : u[0]; max[1] = (t[1] > u[1]) ? t[1] : u[1]; max[2] = (t[2] > u[2]) ? t[2] : u[2]; max[3] = (t[3] > u[3]) ? t[3] : u[3]; - store_vector4( &inst->DstReg, state, max ); + store_vector4( inst, machine, max ); } break; case OPCODE_SLT: { GLfloat t[4], u[4], slt[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - fetch_vector4( &inst->SrcReg[1], state, u ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); slt[0] = (t[0] < u[0]) ? 1.0F : 0.0F; slt[1] = (t[1] < u[1]) ? 1.0F : 0.0F; slt[2] = (t[2] < u[2]) ? 1.0F : 0.0F; slt[3] = (t[3] < u[3]) ? 1.0F : 0.0F; - store_vector4( &inst->DstReg, state, slt ); + store_vector4( inst, machine, slt ); } break; case OPCODE_SGE: { GLfloat t[4], u[4], sge[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - fetch_vector4( &inst->SrcReg[1], state, u ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); sge[0] = (t[0] >= u[0]) ? 1.0F : 0.0F; sge[1] = (t[1] >= u[1]) ? 1.0F : 0.0F; sge[2] = (t[2] >= u[2]) ? 1.0F : 0.0F; sge[3] = (t[3] >= u[3]) ? 1.0F : 0.0F; - store_vector4( &inst->DstReg, state, sge ); + store_vector4( inst, machine, sge ); } break; case OPCODE_MAD: { GLfloat t[4], u[4], v[4], sum[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - fetch_vector4( &inst->SrcReg[1], state, u ); - fetch_vector4( &inst->SrcReg[2], state, v ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); + fetch_vector4( ctx, &inst->SrcReg[2], machine, program, v ); sum[0] = t[0] * u[0] + v[0]; sum[1] = t[1] * u[1] + v[1]; sum[2] = t[2] * u[2] + v[2]; sum[3] = t[3] * u[3] + v[3]; - store_vector4( &inst->DstReg, state, sum ); + store_vector4( inst, machine, sum ); } break; case OPCODE_ARL: { GLfloat t[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - state->Machine.AddressReg[0] = (GLint) FLOORF(t[0]); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + machine->AddressReg[0] = (GLint) FLOORF(t[0]); } break; case OPCODE_DPH: { GLfloat t[4], u[4], dot[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - fetch_vector4( &inst->SrcReg[1], state, u ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2] + u[3]; dot[1] = dot[2] = dot[3] = dot[0]; - store_vector4( &inst->DstReg, state, dot ); + store_vector4( inst, machine, dot ); } break; case OPCODE_RCC: { GLfloat t[4], u; - fetch_vector1( &inst->SrcReg[0], state, t ); + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t ); if (t[0] == 1.0F) u = 1.0F; else @@ -674,115 +682,120 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct gl_vertex_program *progra } } t[0] = t[1] = t[2] = t[3] = u; - store_vector4( &inst->DstReg, state, t ); + store_vector4( inst, machine, t ); } break; case OPCODE_SUB: /* GL_NV_vertex_program1_1 */ { GLfloat t[4], u[4], sum[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - fetch_vector4( &inst->SrcReg[1], state, u ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); sum[0] = t[0] - u[0]; sum[1] = t[1] - u[1]; sum[2] = t[2] - u[2]; sum[3] = t[3] - u[3]; - store_vector4( &inst->DstReg, state, sum ); + store_vector4( inst, machine, sum ); } break; case OPCODE_ABS: /* GL_NV_vertex_program1_1 */ { GLfloat t[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); if (t[0] < 0.0) t[0] = -t[0]; if (t[1] < 0.0) t[1] = -t[1]; if (t[2] < 0.0) t[2] = -t[2]; if (t[3] < 0.0) t[3] = -t[3]; - store_vector4( &inst->DstReg, state, t ); + store_vector4( inst, machine, t ); } break; case OPCODE_FLR: /* GL_ARB_vertex_program */ { GLfloat t[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); t[0] = FLOORF(t[0]); t[1] = FLOORF(t[1]); t[2] = FLOORF(t[2]); t[3] = FLOORF(t[3]); - store_vector4( &inst->DstReg, state, t ); + store_vector4( inst, machine, t ); } break; case OPCODE_FRC: /* GL_ARB_vertex_program */ { GLfloat t[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); t[0] = t[0] - FLOORF(t[0]); t[1] = t[1] - FLOORF(t[1]); t[2] = t[2] - FLOORF(t[2]); t[3] = t[3] - FLOORF(t[3]); - store_vector4( &inst->DstReg, state, t ); + store_vector4( inst, machine, t ); } break; case OPCODE_EX2: /* GL_ARB_vertex_program */ { GLfloat t[4]; - fetch_vector1( &inst->SrcReg[0], state, t ); + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t ); t[0] = t[1] = t[2] = t[3] = (GLfloat)_mesa_pow(2.0, t[0]); - store_vector4( &inst->DstReg, state, t ); + store_vector4( inst, machine, t ); } break; case OPCODE_LG2: /* GL_ARB_vertex_program */ { GLfloat t[4]; - fetch_vector1( &inst->SrcReg[0], state, t ); + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t ); t[0] = t[1] = t[2] = t[3] = LOG2(t[0]); - store_vector4( &inst->DstReg, state, t ); + store_vector4( inst, machine, t ); } break; case OPCODE_POW: /* GL_ARB_vertex_program */ { GLfloat t[4], u[4]; - fetch_vector1( &inst->SrcReg[0], state, t ); - fetch_vector1( &inst->SrcReg[1], state, u ); + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector1( ctx, &inst->SrcReg[1], machine, program, u ); t[0] = t[1] = t[2] = t[3] = (GLfloat)_mesa_pow(t[0], u[0]); - store_vector4( &inst->DstReg, state, t ); + store_vector4( inst, machine, t ); } break; case OPCODE_XPD: /* GL_ARB_vertex_program */ { GLfloat t[4], u[4], cross[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); - fetch_vector4( &inst->SrcReg[1], state, u ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); cross[0] = t[1] * u[2] - t[2] * u[1]; cross[1] = t[2] * u[0] - t[0] * u[2]; cross[2] = t[0] * u[1] - t[1] * u[0]; - store_vector4( &inst->DstReg, state, cross ); + store_vector4( inst, machine, cross ); } break; case OPCODE_SWZ: /* GL_ARB_vertex_program */ { const struct prog_src_register *source = &inst->SrcReg[0]; - const GLfloat *src = get_register_pointer(source, state); + const GLfloat *src = get_register_pointer(ctx, source, + machine, program); GLfloat result[4]; GLuint i; /* do extended swizzling here */ for (i = 0; i < 4; i++) { - if (GET_SWZ(source->Swizzle, i) == SWIZZLE_ZERO) + const GLuint swz = GET_SWZ(source->Swizzle, i); + if (swz == SWIZZLE_ZERO) result[i] = 0.0; - else if (GET_SWZ(source->Swizzle, i) == SWIZZLE_ONE) + else if (swz == SWIZZLE_ONE) result[i] = 1.0; - else - result[i] = src[GET_SWZ(source->Swizzle, i)]; + else { + ASSERT(swz >= 0); + ASSERT(swz <= 3); + result[i] = src[swz]; + } if (source->NegateBase & (1 << i)) result[i] = -result[i]; } - store_vector4( &inst->DstReg, state, result ); + store_vector4( inst, machine, result ); } break; case OPCODE_PRINT: if (inst->SrcReg[0].File) { GLfloat t[4]; - fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); _mesa_printf("%s%g, %g, %g, %g\n", (char *) inst->Data, t[0], t[1], t[2], t[3]); } @@ -805,48 +818,18 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct gl_vertex_program *progra } - /** -Thoughts on vertex program optimization: - -The obvious thing to do is to compile the vertex program into X86/SSE/3DNow! -assembly code. That will probably be a lot of work. - -Another approach might be to replace the vp_instruction->Opcode field with -a pointer to a specialized C function which executes the instruction. -In particular we can write functions which skip swizzling, negating, -masking, relative addressing, etc. when they're not needed. - -For example: - -void simple_add( struct prog_instruction *inst ) + * Execute a vertex state program. + * \sa _mesa_ExecuteProgramNV + */ +void +_mesa_exec_vertex_state_program(GLcontext *ctx, + struct gl_vertex_program *vprog, + const GLfloat *params) { - GLfloat *sum = machine->Registers[inst->DstReg.Register]; - GLfloat *a = machine->Registers[inst->SrcReg[0].Register]; - GLfloat *b = machine->Registers[inst->SrcReg[1].Register]; - sum[0] = a[0] + b[0]; - sum[1] = a[1] + b[1]; - sum[2] = a[2] + b[2]; - sum[3] = a[3] + b[3]; + struct vp_machine machine; + _mesa_init_vp_per_vertex_registers(ctx, &machine); + _mesa_init_vp_per_primitive_registers(ctx); + COPY_4V(machine.Inputs[VERT_ATTRIB_POS], params); + _mesa_exec_vertex_program(ctx, &machine, vprog); } - -*/ - -/* - -KW: - -A first step would be to 'vectorize' the programs in the same way as -the normal transformation code in the tnl module. Thus each opcode -takes zero or more input vectors (registers) and produces one or more -output vectors. - -These operations would intially be coded in C, with machine-specific -assembly following, as is currently the case for matrix -transformations in the math/ directory. The preprocessing scheme for -selecting simpler operations Brian describes above would also work -here. - -This should give reasonable performance without excessive effort. - -*/ diff --git a/src/mesa/shader/nvvertexec.h b/src/mesa/shader/nvvertexec.h index e0fd46a766..b1cf31bd3c 100644 --- a/src/mesa/shader/nvvertexec.h +++ b/src/mesa/shader/nvvertexec.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.1 + * Version: 6.5.2 * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2006 Brian Paul 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"), @@ -28,16 +28,40 @@ #ifndef NVVERTEXEC_H #define NVVERTEXEC_H + +/** + * Virtual vertex program machine state. + * Only used during program execution. + */ +struct vp_machine +{ + GLfloat Temporaries[MAX_NV_VERTEX_PROGRAM_TEMPS][4]; + GLfloat Inputs[MAX_NV_VERTEX_PROGRAM_INPUTS][4]; + GLuint InputsSize[MAX_NV_VERTEX_PROGRAM_INPUTS]; + GLfloat Outputs[MAX_NV_VERTEX_PROGRAM_OUTPUTS][4]; + GLint AddressReg[4]; +}; + + + extern void -_mesa_init_vp_per_vertex_registers(GLcontext *ctx); +_mesa_init_vp_per_vertex_registers(GLcontext *ctx, struct vp_machine *machine); extern void _mesa_init_vp_per_primitive_registers(GLcontext *ctx); extern void -_mesa_exec_vertex_program(GLcontext *ctx, const struct gl_vertex_program *program); +_mesa_exec_vertex_program(GLcontext *ctx, + struct vp_machine *machine, + const struct gl_vertex_program *program); + +extern void +_mesa_exec_vertex_state_program(GLcontext *ctx, + struct gl_vertex_program *vprog, + const GLfloat *params); extern void -_mesa_dump_vp_state( const struct gl_vertex_program_state *state ); +_mesa_dump_vp_state( const struct gl_vertex_program_state *state, + const struct vp_machine *machine); #endif diff --git a/src/mesa/shader/nvvertparse.c b/src/mesa/shader/nvvertparse.c index f3821d7f43..ecfe8ec334 100644 --- a/src/mesa/shader/nvvertparse.c +++ b/src/mesa/shader/nvvertparse.c @@ -1143,7 +1143,7 @@ Parse_InstructionSequence(struct parse_state *parseState, struct prog_instruction *inst = program + parseState->numInst; /* Initialize the instruction */ - _mesa_init_instruction(inst); + _mesa_init_instructions(inst, 1); if (Parse_String(parseState, "MOV")) { if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_MOV)) diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index 8ac38ae119..681584941e 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5.1 + * Version: 6.5.2 * * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * @@ -45,7 +45,7 @@ static const char * make_state_string(const GLint stateTokens[6]); -static GLuint +static GLbitfield make_state_flags(const GLint state[]); @@ -485,8 +485,7 @@ _mesa_add_state_reference(struct gl_program_parameter_list *paramList, paramList->Parameters[index].StateIndexes[i] = (enum state_index) stateTokens[i]; } - paramList->StateFlags |= - make_state_flags(stateTokens); + paramList->StateFlags |= make_state_flags(stateTokens); } /* free name string here since we duplicated it in add_parameter() */ @@ -580,37 +579,29 @@ _mesa_fetch_state(GLcontext *ctx, const enum state_index state[], { /* state[1] is either 0=front or 1=back side */ const GLuint face = (GLuint) state[1]; + const struct gl_material *mat = &ctx->Light.Material; + ASSERT(face == 0 || face == 1); + /* we rely on tokens numbered so that _BACK_ == _FRONT_+ 1 */ + ASSERT(MAT_ATTRIB_FRONT_AMBIENT + 1 == MAT_ATTRIB_BACK_AMBIENT); + /* XXX we could get rid of this switch entirely with a little + * work in arbprogparse.c's parse_state_single_item(). + */ /* state[2] is the material attribute */ switch (state[2]) { case STATE_AMBIENT: - if (face == 0) - COPY_4V(value, ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT]); - else - COPY_4V(value, ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_AMBIENT]); + COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_AMBIENT + face]); return; case STATE_DIFFUSE: - if (face == 0) - COPY_4V(value, ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE]); - else - COPY_4V(value, ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE]); + COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_DIFFUSE + face]); return; case STATE_SPECULAR: - if (face == 0) - COPY_4V(value, ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR]); - else - COPY_4V(value, ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_SPECULAR]); + COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_SPECULAR + face]); return; case STATE_EMISSION: - if (face == 0) - COPY_4V(value, ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION]); - else - COPY_4V(value, ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_EMISSION]); + COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_EMISSION + face]); return; case STATE_SHININESS: - if (face == 0) - value[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SHININESS][0]; - else - value[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_SHININESS][0]; + value[0] = mat->Attrib[MAT_ATTRIB_FRONT_SHININESS + face][0]; value[1] = 0.0F; value[2] = 0.0F; value[3] = 1.0F; @@ -941,10 +932,14 @@ _mesa_fetch_state(GLcontext *ctx, const enum state_index state[], /** - * Return a bit mask of the Mesa state flags under which a parameter's - * value might change. + * Return a bitmask of the Mesa state flags (_NEW_* values) which would + * indicate that the given context state may have changed. + * The bitmask is used during validation to determine if we need to update + * vertex/fragment program parameters (like "state.material.color") when + * some GL state has changed. */ -static GLuint make_state_flags(const GLint state[]) +static GLbitfield +make_state_flags(const GLint state[]) { switch (state[0]) { case STATE_MATERIAL: @@ -1307,26 +1302,32 @@ _mesa_load_state_parameters(GLcontext *ctx, /** * Initialize program instruction fields to defaults. + * \param inst first instruction to initialize + * \param count number of instructions to initialize */ void -_mesa_init_instruction(struct prog_instruction *inst) +_mesa_init_instructions(struct prog_instruction *inst, GLuint count) { - _mesa_bzero(inst, sizeof(struct prog_instruction)); - - inst->SrcReg[0].File = PROGRAM_UNDEFINED; - inst->SrcReg[0].Swizzle = SWIZZLE_NOOP; - inst->SrcReg[1].File = PROGRAM_UNDEFINED; - inst->SrcReg[1].Swizzle = SWIZZLE_NOOP; - inst->SrcReg[2].File = PROGRAM_UNDEFINED; - inst->SrcReg[2].Swizzle = SWIZZLE_NOOP; - - inst->DstReg.File = PROGRAM_UNDEFINED; - inst->DstReg.WriteMask = WRITEMASK_XYZW; - inst->DstReg.CondMask = COND_TR; - inst->DstReg.CondSwizzle = SWIZZLE_NOOP; - - inst->SaturateMode = SATURATE_OFF; - inst->Precision = FLOAT32; + GLuint i; + + _mesa_bzero(inst, count * sizeof(struct prog_instruction)); + + for (i = 0; i < count; i++) { + inst[i].SrcReg[0].File = PROGRAM_UNDEFINED; + inst[i].SrcReg[0].Swizzle = SWIZZLE_NOOP; + inst[i].SrcReg[1].File = PROGRAM_UNDEFINED; + inst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP; + inst[i].SrcReg[2].File = PROGRAM_UNDEFINED; + inst[i].SrcReg[2].Swizzle = SWIZZLE_NOOP; + + inst[i].DstReg.File = PROGRAM_UNDEFINED; + inst[i].DstReg.WriteMask = WRITEMASK_XYZW; + inst[i].DstReg.CondMask = COND_TR; + inst[i].DstReg.CondSwizzle = SWIZZLE_NOOP; + + inst[i].SaturateMode = SATURATE_OFF; + inst[i].Precision = FLOAT32; + } } @@ -2102,7 +2103,9 @@ _mesa_GetProgramRegisterfvMESA(GLenum target, "glGetProgramRegisterfvMESA(registerName)"); return; } - COPY_4V(v, ctx->VertexProgram.Machine.Temporaries[i]); +#if 0 /* FIX ME */ + ctx->Driver.GetVertexProgramRegister(ctx, PROGRAM_TEMPORARY, i, v); +#endif } else if (reg[0] == 'v' && reg[1] == '[') { /* Vertex Input attribute */ @@ -2113,7 +2116,10 @@ _mesa_GetProgramRegisterfvMESA(GLenum target, _mesa_sprintf(number, "%d", i); if (_mesa_strncmp(reg + 2, name, 4) == 0 || _mesa_strncmp(reg + 2, number, _mesa_strlen(number)) == 0) { - COPY_4V(v, ctx->VertexProgram.Machine.Inputs[i]); +#if 0 /* FIX ME */ + ctx->Driver.GetVertexProgramRegister(ctx, PROGRAM_INPUT, + i, v); +#endif return; } } diff --git a/src/mesa/shader/program_instruction.h b/src/mesa/shader/program_instruction.h index 93bcfc240a..cdec0ceb2a 100644 --- a/src/mesa/shader/program_instruction.h +++ b/src/mesa/shader/program_instruction.h @@ -343,7 +343,7 @@ struct prog_instruction extern void -_mesa_init_instruction(struct prog_instruction *inst); +_mesa_init_instructions(struct prog_instruction *inst, GLuint count); extern GLuint _mesa_num_inst_src_regs(enum prog_opcode opcode); diff --git a/src/mesa/shader/programopt.c b/src/mesa/shader/programopt.c index 55991dcce3..172d373b57 100644 --- a/src/mesa/shader/programopt.c +++ b/src/mesa/shader/programopt.c @@ -85,8 +85,8 @@ _mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog) * newInst[2] = DP4 result.position.z, mvp.row[2], vertex.position; * newInst[3] = DP4 result.position.w, mvp.row[3], vertex.position; */ + _mesa_init_instructions(newInst, 4); for (i = 0; i < 4; i++) { - _mesa_init_instruction(newInst + i); newInst[i].Opcode = OPCODE_DP4; newInst[i].DstReg.File = PROGRAM_OUTPUT; newInst[i].DstReg.Index = VERT_RESULT_HPOS; @@ -137,7 +137,7 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) GLfloat fogVals[4]; GLuint fogConsts; /* constant values for EXP, EXP2 mode */ - if (fprog->FogOption != GL_NONE) { + if (fprog->FogOption == GL_NONE) { _mesa_problem(ctx, "_mesa_append_fog_code() called for fragment program" " with FogOption == GL_NONE"); return; @@ -191,8 +191,7 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) } assert(inst->Opcode == OPCODE_END); /* we'll overwrite this inst */ - for (i = 0; i < 6; i++) - _mesa_init_instruction(inst + i); + _mesa_init_instructions(inst, 6); /* emit instructions to compute fog blending factor */ if (fprog->FogOption == GL_LINEAR) { diff --git a/src/mesa/swrast/s_arbshader.c b/src/mesa/swrast/s_arbshader.c index 9e41d7c673..ee971a36ec 100644 --- a/src/mesa/swrast/s_arbshader.c +++ b/src/mesa/swrast/s_arbshader.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.6 * * Copyright (C) 2006 Brian Paul All Rights Reserved. * @@ -106,6 +106,15 @@ _swrast_exec_arbshader(GLcontext *ctx, SWspan *span) (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_FRAGCOLOR, vec, 0, 4 * sizeof(GLfloat), GL_FALSE); COPY_4V(span->array->color.sz4.rgba[i], vec); + + (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_FRAGDEPTH, vec, 0, + sizeof (GLfloat), GL_FALSE); + if (vec[0] <= 0.0f) + span->array->z[i] = 0; + else if (vec[0] >= 1.0f) + span->array->z[i] = ctx->DrawBuffer->_DepthMax; + else + span->array->z[i] = IROUND(vec[0] * ctx->DrawBuffer->_DepthMaxF); } } } diff --git a/src/mesa/swrast/s_buffers.c b/src/mesa/swrast/s_buffers.c index bb85ee5777..284ea2b517 100644 --- a/src/mesa/swrast/s_buffers.c +++ b/src/mesa/swrast/s_buffers.c @@ -293,18 +293,15 @@ clear_color_buffers(GLcontext *ctx) /** * Called via the device driver's ctx->Driver.Clear() function if the * device driver can't clear one or more of the buffers itself. - * \param mask bitfield of BUFER_BIT_* values indicating which renderbuffers - * are to be cleared. + * \param buffers bitfield of BUFFER_BIT_* values indicating which + * renderbuffers are to be cleared. * \param all if GL_TRUE, clear whole buffer, else clear specified region. */ void -_swrast_Clear(GLcontext *ctx, GLbitfield mask, - GLboolean all, GLint x, GLint y, GLint width, GLint height) +_swrast_Clear(GLcontext *ctx, GLbitfield buffers) { SWcontext *swrast = SWRAST_CONTEXT(ctx); - (void) all; (void) x; (void) y; (void) width; (void) height; - #ifdef DEBUG_FOO { const GLbitfield legalBits = @@ -319,25 +316,25 @@ _swrast_Clear(GLcontext *ctx, GLbitfield mask, BUFFER_BIT_AUX1 | BUFFER_BIT_AUX2 | BUFFER_BIT_AUX3; - assert((mask & (~legalBits)) == 0); + assert((buffers & (~legalBits)) == 0); } #endif RENDER_START(swrast,ctx); /* do software clearing here */ - if (mask) { - if (mask & ctx->DrawBuffer->_ColorDrawBufferMask[0]) { + if (buffers) { + if (buffers & ctx->DrawBuffer->_ColorDrawBufferMask[0]) { clear_color_buffers(ctx); } - if (mask & BUFFER_BIT_DEPTH) { + if (buffers & BUFFER_BIT_DEPTH) { _swrast_clear_depth_buffer(ctx, ctx->DrawBuffer->_DepthBuffer); } - if (mask & BUFFER_BIT_ACCUM) { + if (buffers & BUFFER_BIT_ACCUM) { _swrast_clear_accum_buffer(ctx, ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer); } - if (mask & BUFFER_BIT_STENCIL) { + if (buffers & BUFFER_BIT_STENCIL) { _swrast_clear_stencil_buffer(ctx, ctx->DrawBuffer->_StencilBuffer); } } diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c index 18f5fe497b..62cf6f2f5a 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -223,11 +223,12 @@ _swrast_update_fog_state( GLcontext *ctx ) * program parameters with current state values. */ static void -_swrast_update_fragment_program( GLcontext *ctx ) +_swrast_update_fragment_program(GLcontext *ctx, GLbitfield newState) { if (ctx->FragmentProgram._Enabled) { const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; - _mesa_load_state_parameters(ctx, fp->Base.Parameters); + if (fp->Base.Parameters->StateFlags & newState) + _mesa_load_state_parameters(ctx, fp->Base.Parameters); } } @@ -521,8 +522,18 @@ _swrast_validate_derived( GLcontext *ctx ) if (swrast->NewState & (_NEW_FOG | _NEW_PROGRAM)) _swrast_update_fog_state( ctx ); - if (swrast->NewState & _NEW_PROGRAM) - _swrast_update_fragment_program( ctx ); + if (swrast->NewState & (_NEW_MODELVIEW | + _NEW_PROJECTION | + _NEW_TEXTURE_MATRIX | + _NEW_FOG | + _NEW_LIGHT | + _NEW_LINE | + _NEW_TEXTURE | + _NEW_TRANSFORM | + _NEW_POINT | + _NEW_VIEWPORT | + _NEW_PROGRAM)) + _swrast_update_fragment_program( ctx, swrast->NewState ); if (swrast->NewState & _NEW_TEXTURE) _swrast_update_texture_samplers( ctx ); diff --git a/src/mesa/swrast/s_nvfragprog.c b/src/mesa/swrast/s_nvfragprog.c index dfca960005..7a6785b1d2 100644 --- a/src/mesa/swrast/s_nvfragprog.c +++ b/src/mesa/swrast/s_nvfragprog.c @@ -41,7 +41,10 @@ #include "s_span.h" -/* if 1, print some debugging info */ +/* See comments below for info about this */ +#define LAMBDA_ZERO 1 + +/* debug predicate */ #define DEBUG_FRAG 0 @@ -178,8 +181,8 @@ get_register_pointer( GLcontext *ctx, ASSERT(source->Index < (GLint) program->Base.Parameters->NumParameters); return program->Base.Parameters->ParameterValues[source->Index]; default: - _mesa_problem(ctx, "Invalid input register file %d in fetch_vector4", - source->File); + _mesa_problem(ctx, "Invalid input register file %d in fp " + "get_register_pointer", source->File); return NULL; } } @@ -458,7 +461,7 @@ store_vector4( const struct prog_instruction *inst, return; } -#if DEBUG_FRAG +#if 0 if (value[0] > 1.0e10 || IS_INF_OR_NAN(value[0]) || IS_INF_OR_NAN(value[1]) || @@ -646,9 +649,9 @@ execute_program( GLcontext *ctx, { GLuint pc; -#if DEBUG_FRAG - printf("execute fragment program --------------------\n"); -#endif + if (DEBUG_FRAG) { + printf("execute fragment program --------------------\n"); + } for (pc = 0; pc < maxInst; pc++) { const struct prog_instruction *inst = program->Base.Instructions + pc; @@ -660,6 +663,10 @@ execute_program( GLcontext *ctx, ctx->FragmentProgram.CallbackData); } + if (DEBUG_FRAG) { + _mesa_print_instruction(inst); + } + switch (inst->Opcode) { case OPCODE_ABS: { @@ -682,6 +689,12 @@ execute_program( GLcontext *ctx, result[2] = a[2] + b[2]; result[3] = a[3] + b[3]; store_vector4( inst, machine, result ); + if (DEBUG_FRAG) { + printf("ADD (%g %g %g %g) = (%g %g %g %g) + (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3]); + } } break; case OPCODE_CMP: @@ -758,10 +771,10 @@ execute_program( GLcontext *ctx, fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); result[0] = result[1] = result[2] = result[3] = DOT3(a, b); store_vector4( inst, machine, result ); -#if DEBUG_FRAG - printf("DP3 %g = (%g %g %g) . (%g %g %g)\n", - result[0], a[0], a[1], a[2], b[0], b[1], b[2]); -#endif + if (DEBUG_FRAG) { + printf("DP3 %g = (%g %g %g) . (%g %g %g)\n", + result[0], a[0], a[1], a[2], b[0], b[1], b[2]); + } } break; case OPCODE_DP4: @@ -771,10 +784,11 @@ execute_program( GLcontext *ctx, fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); result[0] = result[1] = result[2] = result[3] = DOT4(a,b); store_vector4( inst, machine, result ); -#if DEBUG_FRAG - printf("DP4 %g = (%g, %g %g %g) . (%g, %g %g %g)\n", - result[0], a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]); -#endif + if (DEBUG_FRAG) { + printf("DP4 %g = (%g, %g %g %g) . (%g, %g %g %g)\n", + result[0], a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3]); + } } break; case OPCODE_DPH: @@ -882,6 +896,11 @@ execute_program( GLcontext *ctx, } result[3] = 1.0F; store_vector4( inst, machine, result ); + if (DEBUG_FRAG) { + printf("LIT (%g %g %g %g) : (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3]); + } } break; case OPCODE_LRP: @@ -895,14 +914,14 @@ execute_program( GLcontext *ctx, result[2] = a[2] * b[2] + (1.0F - a[2]) * c[2]; result[3] = a[3] * b[3] + (1.0F - a[3]) * c[3]; store_vector4( inst, machine, result ); -#if DEBUG_FRAG - printf("LRP (%g %g %g %g) = (%g %g %g %g), " - "(%g %g %g %g), (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3], - b[0], b[1], b[2], b[3], - c[0], c[1], c[2], c[3]); -#endif + if (DEBUG_FRAG) { + printf("LRP (%g %g %g %g) = (%g %g %g %g), " + "(%g %g %g %g), (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3], + c[0], c[1], c[2], c[3]); + } } break; case OPCODE_MAD: @@ -916,6 +935,14 @@ execute_program( GLcontext *ctx, result[2] = a[2] * b[2] + c[2]; result[3] = a[3] * b[3] + c[3]; store_vector4( inst, machine, result ); + if (DEBUG_FRAG) { + printf("MAD (%g %g %g %g) = (%g %g %g %g) * " + "(%g %g %g %g) + (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3], + c[0], c[1], c[2], c[3]); + } } break; case OPCODE_MAX: @@ -928,12 +955,12 @@ execute_program( GLcontext *ctx, result[2] = MAX2(a[2], b[2]); result[3] = MAX2(a[3], b[3]); store_vector4( inst, machine, result ); -#if DEBUG_FRAG - printf("MAX (%g %g %g %g) = (%g %g %g %g), (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3], - b[0], b[1], b[2], b[3]); -#endif + if (DEBUG_FRAG) { + printf("MAX (%g %g %g %g) = (%g %g %g %g), (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3]); + } } break; case OPCODE_MIN: @@ -953,10 +980,10 @@ execute_program( GLcontext *ctx, GLfloat result[4]; fetch_vector4( ctx, &inst->SrcReg[0], machine, program, result ); store_vector4( inst, machine, result ); -#if DEBUG_FRAG - printf("MOV (%g %g %g %g)\n", - result[0], result[1], result[2], result[3]); -#endif + if (DEBUG_FRAG) { + printf("MOV (%g %g %g %g)\n", + result[0], result[1], result[2], result[3]); + } } break; case OPCODE_MUL: @@ -969,12 +996,12 @@ execute_program( GLcontext *ctx, result[2] = a[2] * b[2]; result[3] = a[3] * b[3]; store_vector4( inst, machine, result ); -#if DEBUG_FRAG - printf("MUL (%g %g %g %g) = (%g %g %g %g) * (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3], - b[0], b[1], b[2], b[3]); -#endif + if (DEBUG_FRAG) { + printf("MUL (%g %g %g %g) = (%g %g %g %g) * (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3]); + } } break; case OPCODE_PK2H: /* pack two 16-bit floats in one 32-bit float */ @@ -1056,12 +1083,12 @@ execute_program( GLcontext *ctx, { GLfloat a[4], result[4]; fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); -#if DEBUG_FRAG - if (a[0] == 0) - printf("RCP(0)\n"); - else if (IS_INF_OR_NAN(a[0])) - printf("RCP(inf)\n"); -#endif + if (DEBUG_FRAG) { + if (a[0] == 0) + printf("RCP(0)\n"); + else if (IS_INF_OR_NAN(a[0])) + printf("RCP(inf)\n"); + } result[0] = result[1] = result[2] = result[3] = 1.0F / a[0]; store_vector4( inst, machine, result ); } @@ -1087,9 +1114,9 @@ execute_program( GLcontext *ctx, a[0] = FABSF(a[0]); result[0] = result[1] = result[2] = result[3] = INV_SQRTF(a[0]); store_vector4( inst, machine, result ); -#if DEBUG_FRAG - printf("RSQ %g = 1/sqrt(|%g|)\n", result[0], a[0]); -#endif + if (DEBUG_FRAG) { + printf("RSQ %g = 1/sqrt(|%g|)\n", result[0], a[0]); + } } break; case OPCODE_SCS: /* sine and cos */ @@ -1206,11 +1233,11 @@ execute_program( GLcontext *ctx, result[2] = a[2] - b[2]; result[3] = a[3] - b[3]; store_vector4( inst, machine, result ); -#if DEBUG_FRAG - printf("SUB (%g %g %g %g) = (%g %g %g %g) - (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]); -#endif + if (DEBUG_FRAG) { + printf("SUB (%g %g %g %g) = (%g %g %g %g) - (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]); + } } break; case OPCODE_SWZ: /* extended swizzle */ @@ -1240,44 +1267,47 @@ execute_program( GLcontext *ctx, case OPCODE_TEX: /* Both ARB and NV frag prog */ /* Texel lookup */ { - GLfloat texcoord[4], color[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, texcoord ); - /* Note: we pass 0 for LOD. The ARB extension requires it - * while the NV extension says it's implementation dependant. + /* Note: only use the precomputed lambda value when we're + * sampling texture unit [K] with texcoord[K]. + * Otherwise, the lambda value may have no relation to the + * instruction's texcoord or texture image. Using the wrong + * lambda is usually bad news. + * The rest of the time, just use zero (until we get a more + * sophisticated way of computing lambda). */ - /* KW: Previously lambda was passed as zero, but I - * believe this is incorrect, the spec seems to - * indicate rather that lambda should not be - * changed/biased, unlike TXB where texcoord[3] is - * added to the lambda calculations. The lambda should - * still be calculated normally for TEX & TXP though, - * not set to zero. Otherwise it's very difficult to - * implement normal GL semantics through the fragment - * shader. - */ - fetch_texel( ctx, texcoord, - span->array->lambda[inst->TexSrcUnit][column], - inst->TexSrcUnit, color ); -#if DEBUG_FRAG - if (color[3]) - printf("color[3] = %f\n", color[3]); -#endif + GLfloat coord[4], color[4], lambda; + if (inst->SrcReg[0].File == PROGRAM_INPUT && + inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) + lambda = span->array->lambda[inst->TexSrcUnit][column]; + else + lambda = 0.0; + fetch_vector4(ctx, &inst->SrcReg[0], machine, program, coord); + fetch_texel( ctx, coord, lambda, inst->TexSrcUnit, color ); + if (DEBUG_FRAG) { + printf("TEX (%g, %g, %g, %g) = texture[%d][%g, %g, %g, %g], " + "lod %f\n", + color[0], color[1], color[2], color[3], + inst->TexSrcUnit, + coord[0], coord[1], coord[2], coord[3], lambda); + } store_vector4( inst, machine, color ); } break; case OPCODE_TXB: /* GL_ARB_fragment_program only */ /* Texel lookup with LOD bias */ { - GLfloat texcoord[4], color[4], bias, lambda; - - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, texcoord ); - /* texcoord[3] is the bias to add to lambda */ + GLfloat coord[4], color[4], lambda, bias; + if (inst->SrcReg[0].File == PROGRAM_INPUT && + inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) + lambda = span->array->lambda[inst->TexSrcUnit][column]; + else + lambda = 0.0; + fetch_vector4(ctx, &inst->SrcReg[0], machine, program, coord); + /* coord[3] is the bias to add to lambda */ bias = ctx->Texture.Unit[inst->TexSrcUnit].LodBias + ctx->Texture.Unit[inst->TexSrcUnit]._Current->LodBias - + texcoord[3]; - lambda = span->array->lambda[inst->TexSrcUnit][column] + bias; - fetch_texel( ctx, texcoord, lambda, - inst->TexSrcUnit, color ); + + coord[3]; + fetch_texel(ctx, coord, lambda + bias, inst->TexSrcUnit, color); store_vector4( inst, machine, color ); } break; @@ -1296,8 +1326,13 @@ execute_program( GLcontext *ctx, case OPCODE_TXP: /* GL_ARB_fragment_program only */ /* Texture lookup w/ projective divide */ { - GLfloat texcoord[4], color[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, texcoord ); + GLfloat texcoord[4], color[4], lambda; + if (inst->SrcReg[0].File == PROGRAM_INPUT && + inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) + lambda = span->array->lambda[inst->TexSrcUnit][column]; + else + lambda = 0.0; + fetch_vector4(ctx, &inst->SrcReg[0], machine, program,texcoord); /* Not so sure about this test - if texcoord[3] is * zero, we'd probably be fine except for an ASSERT in * IROUND_POS() which gets triggered by the inf values created. @@ -1307,34 +1342,27 @@ execute_program( GLcontext *ctx, texcoord[1] /= texcoord[3]; texcoord[2] /= texcoord[3]; } - /* KW: Previously lambda was passed as zero, but I - * believe this is incorrect, the spec seems to - * indicate rather that lambda should not be - * changed/biased, unlike TXB where texcoord[3] is - * added to the lambda calculations. The lambda should - * still be calculated normally for TEX & TXP though, - * not set to zero. - */ - fetch_texel( ctx, texcoord, - span->array->lambda[inst->TexSrcUnit][column], - inst->TexSrcUnit, color ); + fetch_texel( ctx, texcoord, lambda, inst->TexSrcUnit, color ); store_vector4( inst, machine, color ); } break; case OPCODE_TXP_NV: /* GL_NV_fragment_program only */ /* Texture lookup w/ projective divide */ { - GLfloat texcoord[4], color[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, texcoord ); + GLfloat texcoord[4], color[4], lambda; + if (inst->SrcReg[0].File == PROGRAM_INPUT && + inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) + lambda = span->array->lambda[inst->TexSrcUnit][column]; + else + lambda = 0.0; + fetch_vector4(ctx, &inst->SrcReg[0], machine, program,texcoord); if (inst->TexSrcTarget != TEXTURE_CUBE_INDEX && texcoord[3] != 0.0) { texcoord[0] /= texcoord[3]; texcoord[1] /= texcoord[3]; texcoord[2] /= texcoord[3]; } - fetch_texel( ctx, texcoord, - span->array->lambda[inst->TexSrcUnit][column], - inst->TexSrcUnit, color ); + fetch_texel( ctx, texcoord, lambda, inst->TexSrcUnit, color ); store_vector4( inst, machine, color ); } break; @@ -1572,10 +1600,6 @@ _swrast_exec_fragment_program( GLcontext *ctx, SWspan *span ) ctx->_CurrentProgram = GL_FRAGMENT_PROGRAM_ARB; /* or NV, doesn't matter */ - if (program->Base.Parameters) { - _mesa_load_state_parameters(ctx, program->Base.Parameters); - } - run_program(ctx, span, 0, span->end); if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) { diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 2e20f7a296..c74b98facf 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -353,32 +353,38 @@ interpolate_specular(SWspan *span) case GL_FLOAT: { GLfloat (*spec)[4] = span->array->color.sz4.spec; +#if CHAN_BITS <= 16 + GLfloat r = CHAN_TO_FLOAT(FixedToChan(span->specRed)); + GLfloat g = CHAN_TO_FLOAT(FixedToChan(span->specGreen)); + GLfloat b = CHAN_TO_FLOAT(FixedToChan(span->specBlue)); +#else + GLfloat r = span->specRed; + GLfloat g = span->specGreen; + GLfloat b = span->specBlue; +#endif + GLfloat dr, dg, db; if (span->interpMask & SPAN_FLAT) { - GLfloat color[4]; - color[RCOMP] = span->specRed; - color[GCOMP] = span->specGreen; - color[BCOMP] = span->specBlue; - color[ACOMP] = 0.0F; - for (i = 0; i < n; i++) { - COPY_4V(spec[i], color); - } + dr = dg = db = 0.0; } else { - GLfloat r = span->specRed; - GLfloat g = span->specGreen; - GLfloat b = span->specBlue; - GLfloat dr = span->specRedStep; - GLfloat dg = span->specGreenStep; - GLfloat db = span->specBlueStep; - for (i = 0; i < n; i++) { - spec[i][RCOMP] = r; - spec[i][GCOMP] = g; - spec[i][BCOMP] = b; - spec[i][ACOMP] = 0.0F; - r += dr; - g += dg; - b += db; - } +#if CHAN_BITS <= 16 + dr = CHAN_TO_FLOAT(FixedToChan(span->specRedStep)); + dg = CHAN_TO_FLOAT(FixedToChan(span->specGreenStep)); + db = CHAN_TO_FLOAT(FixedToChan(span->specBlueStep)); +#else + dr = span->specRedStep; + dg = span->specGreenStep; + db = span->specBlueStep; +#endif + } + for (i = 0; i < n; i++) { + spec[i][RCOMP] = r; + spec[i][GCOMP] = g; + spec[i][BCOMP] = b; + spec[i][ACOMP] = 0.0F; + r += dr; + g += dg; + b += db; } } break; diff --git a/src/mesa/swrast/s_texstore.c b/src/mesa/swrast/s_texstore.c index ddaf7471f5..3f49b40d9c 100644 --- a/src/mesa/swrast/s_texstore.c +++ b/src/mesa/swrast/s_texstore.c @@ -254,7 +254,7 @@ _swrast_copy_teximage1d( GLcontext *ctx, GLenum target, GLint level, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); ASSERT(texObj); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + texImage = _mesa_select_tex_image(ctx, texObj, target, level); ASSERT(texImage); ASSERT(ctx->Driver.TexImage1D); @@ -331,7 +331,7 @@ _swrast_copy_teximage2d( GLcontext *ctx, GLenum target, GLint level, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); ASSERT(texObj); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + texImage = _mesa_select_tex_image(ctx, texObj, target, level); ASSERT(texImage); ASSERT(ctx->Driver.TexImage2D); @@ -400,7 +400,7 @@ _swrast_copy_texsubimage1d( GLcontext *ctx, GLenum target, GLint level, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); ASSERT(texObj); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + texImage = _mesa_select_tex_image(ctx, texObj, target, level); ASSERT(texImage); ASSERT(ctx->Driver.TexImage1D); @@ -474,7 +474,7 @@ _swrast_copy_texsubimage2d( GLcontext *ctx, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); ASSERT(texObj); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + texImage = _mesa_select_tex_image(ctx, texObj, target, level); ASSERT(texImage); ASSERT(ctx->Driver.TexImage2D); @@ -547,7 +547,7 @@ _swrast_copy_texsubimage3d( GLcontext *ctx, texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; texObj = _mesa_select_tex_object(ctx, texUnit, target); ASSERT(texObj); - texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + texImage = _mesa_select_tex_image(ctx, texObj, target, level); ASSERT(texImage); ASSERT(ctx->Driver.TexImage3D); diff --git a/src/mesa/swrast/swrast.h b/src/mesa/swrast/swrast.h index 04bd01a0cd..09686c8380 100644 --- a/src/mesa/swrast/swrast.h +++ b/src/mesa/swrast/swrast.h @@ -130,8 +130,7 @@ _swrast_BlitFramebuffer(GLcontext *ctx, GLbitfield mask, GLenum filter); extern void -_swrast_Clear( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint x, GLint y, GLint width, GLint height ); +_swrast_Clear(GLcontext *ctx, GLbitfield buffers); extern void _swrast_Accum(GLcontext *ctx, GLenum op, GLfloat value); diff --git a/src/mesa/tnl/t_context.c b/src/mesa/tnl/t_context.c index 5d6b6dd97d..bd459a7747 100644 --- a/src/mesa/tnl/t_context.c +++ b/src/mesa/tnl/t_context.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.2 * * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * @@ -135,7 +135,8 @@ _tnl_InvalidateState( GLcontext *ctx, GLuint new_state ) if (ctx->Fog.Enabled || (ctx->FragmentProgram._Active && - ctx->FragmentProgram._Current->FogOption != GL_NONE)) + (ctx->FragmentProgram._Current->FogOption != GL_NONE || + ctx->FragmentProgram._Current->Base.InputsRead & FRAG_BIT_FOGC))) RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_FOG ); if (ctx->Polygon.FrontMode != GL_FILL || diff --git a/src/mesa/tnl/t_vb_program.c b/src/mesa/tnl/t_vb_program.c index b8828ec36a..f11ac616f1 100644 --- a/src/mesa/tnl/t_vb_program.c +++ b/src/mesa/tnl/t_vb_program.c @@ -76,6 +76,7 @@ run_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage ) struct vp_stage_data *store = VP_STAGE_DATA(stage); struct vertex_buffer *VB = &tnl->vb; struct gl_vertex_program *program = ctx->VertexProgram.Current; + struct vp_machine machine; GLuint i; if (ctx->ShaderObjects._VertexShaderPresent) @@ -91,7 +92,7 @@ run_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage ) for (i = 0; i < VB->Count; i++) { GLuint attr; - _mesa_init_vp_per_vertex_registers(ctx); + _mesa_init_vp_per_vertex_registers(ctx, &machine); #if 0 printf("Input %d: %f, %f, %f, %f\n", i, @@ -118,30 +119,29 @@ run_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage ) const GLuint size = VB->AttribPtr[attr]->size; const GLuint stride = VB->AttribPtr[attr]->stride; const GLfloat *data = (GLfloat *) (ptr + stride * i); - COPY_CLEAN_4V(ctx->VertexProgram.Machine.Inputs[attr], size, data); + COPY_CLEAN_4V(machine.Inputs[attr], size, data); } } /* execute the program */ ASSERT(program); - _mesa_exec_vertex_program(ctx, program); + _mesa_exec_vertex_program(ctx, &machine, program); /* Fixup fog an point size results if needed */ if (ctx->Fog.Enabled && (program->Base.OutputsWritten & (1 << VERT_RESULT_FOGC)) == 0) { - ctx->VertexProgram.Machine.Outputs[VERT_RESULT_FOGC][0] = 1.0; + machine.Outputs[VERT_RESULT_FOGC][0] = 1.0; } if (ctx->VertexProgram.PointSizeEnabled && (program->Base.OutputsWritten & (1 << VERT_RESULT_PSIZ)) == 0) { - ctx->VertexProgram.Machine.Outputs[VERT_RESULT_PSIZ][0] = ctx->Point.Size; + machine.Outputs[VERT_RESULT_PSIZ][0] = ctx->Point.Size; } /* copy the output registers into the VB->attribs arrays */ /* XXX (optimize) could use a conditional and smaller loop limit here */ for (attr = 0; attr < 15; attr++) { - COPY_4V(store->attribs[attr].data[i], - ctx->VertexProgram.Machine.Outputs[attr]); + COPY_4V(store->attribs[attr].data[i], machine.Outputs[attr]); } } -- cgit v1.2.3 From a93f4a73100f00d8114ee9931fd80eaa8f6f0375 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Thu, 2 Nov 2006 20:44:03 +0000 Subject: Move r300 to new fbo interface based on Keith Whithwell. Tested with progs/redbook/varray. --- src/mesa/drivers/dri/r300/radeon_vtxfmt_a.c | 304 ++++++++-------------------- 1 file changed, 86 insertions(+), 218 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/r300/radeon_vtxfmt_a.c b/src/mesa/drivers/dri/r300/radeon_vtxfmt_a.c index 72c03c53ad..0625e5bc57 100644 --- a/src/mesa/drivers/dri/r300/radeon_vtxfmt_a.c +++ b/src/mesa/drivers/dri/r300/radeon_vtxfmt_a.c @@ -46,6 +46,8 @@ #include "state.h" #include "image.h" +#include "vbo/vbo_context.h" + #define CONV_VB(a, b) rvb->AttribPtr[(a)].size = vb->b->size, \ rvb->AttribPtr[(a)].type = GL_FLOAT, \ rvb->AttribPtr[(a)].stride = vb->b->stride, \ @@ -129,15 +131,7 @@ static int setup_arrays(r300ContextPtr rmesa, GLint start) CONV(i, VertexAttrib[i]); for (i=0; i < VERT_ATTRIB_MAX; i++) { - if (enabled & (1 << i)) { - rmesa->state.VB.AttribPtr[i].data += rmesa->state.VB.AttribPtr[i].stride * start; - } else { - def.data = ctx->Current.Attrib[i]; - memcpy(&rmesa->state.VB.AttribPtr[i], &def, sizeof(struct dt)); - } - - /*if(rmesa->state.VB.AttribPtr[i].data == ctx->Current.Attrib[i]) - fprintf(stderr, "%d is default coord\n", i);*/ + rmesa->state.VB.AttribPtr[i].data += rmesa->state.VB.AttribPtr[i].stride * start; } for(i=0; i < VERT_ATTRIB_MAX; i++){ @@ -177,177 +171,18 @@ static int setup_arrays(r300ContextPtr rmesa, GLint start) void radeon_init_vtxfmt_a(r300ContextPtr rmesa); -static void radeonDrawElements( GLenum mode, GLsizei count, GLenum type, const GLvoid *c_indices ) -{ - GET_CURRENT_CONTEXT(ctx); - r300ContextPtr rmesa = R300_CONTEXT(ctx); - int elt_size; - int i; - unsigned int min = ~0, max = 0; - struct tnl_prim prim; - static void *ptr = NULL; - struct r300_dma_region rvb; - const GLvoid *indices = c_indices; - - if (count > 65535) { - WARN_ONCE("Too many verts!\n"); - goto fallback; - } - - if (ctx->Array.ElementArrayBufferObj->Name) { - /* use indices in the buffer object */ - if (!ctx->Array.ElementArrayBufferObj->Data) { - _mesa_warning(ctx, "DrawRangeElements with empty vertex elements buffer!"); - return; - } - /* actual address is the sum of pointers */ - indices = (GLvoid *) - ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Data, (const GLubyte *) c_indices); - } - - if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) - return; - - FLUSH_CURRENT( ctx, 0 ); - - memset(&rvb, 0, sizeof(rvb)); - switch (type) { - case GL_UNSIGNED_BYTE: - for (i=0; i < count; i++) { - if(((unsigned char *)indices)[i] < min) - min = ((unsigned char *)indices)[i]; - if(((unsigned char *)indices)[i] > max) - max = ((unsigned char *)indices)[i]; - } - -#ifdef FORCE_32BITS_ELTS - elt_size = 4; -#else - elt_size = 2; -#endif - r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size); - rvb.aos_offset = GET_START(&rvb); - ptr = rvb.address + rvb.start; - -#ifdef FORCE_32BITS_ELTS - for (i=0; i < count; i++) - ((unsigned int *)ptr)[i] = ((unsigned char *)indices)[i] - min; -#else - for (i=0; i < count; i++) - ((unsigned short int *)ptr)[i] = ((unsigned char *)indices)[i] - min; -#endif - break; - - case GL_UNSIGNED_SHORT: - for (i=0; i < count; i++) { - if(((unsigned short int *)indices)[i] < min) - min = ((unsigned short int *)indices)[i]; - if(((unsigned short int *)indices)[i] > max) - max = ((unsigned short int *)indices)[i]; - } - -#ifdef FORCE_32BITS_ELTS - elt_size = 4; -#else - elt_size = 2; -#endif - - r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size); - rvb.aos_offset = GET_START(&rvb); - ptr = rvb.address + rvb.start; - -#ifdef FORCE_32BITS_ELTS - for (i=0; i < count; i++) - ((unsigned int *)ptr)[i] = ((unsigned short int *)indices)[i] - min; -#else - for (i=0; i < count; i++) - ((unsigned short int *)ptr)[i] = ((unsigned short int *)indices)[i] - min; -#endif - break; - - case GL_UNSIGNED_INT: - for (i=0; i < count; i++) { - if(((unsigned int *)indices)[i] < min) - min = ((unsigned int *)indices)[i]; - if(((unsigned int *)indices)[i] > max) - max = ((unsigned int *)indices)[i]; - } - -#ifdef FORCE_32BITS_ELTS - elt_size = 4; -#else - if (max - min <= 65535) - elt_size = 2; - else - elt_size = 4; -#endif - r300AllocDmaRegion(rmesa, &rvb, count * elt_size, elt_size); - rvb.aos_offset = GET_START(&rvb); - ptr = rvb.address + rvb.start; - - - if (elt_size == 2) - for (i=0; i < count; i++) - ((unsigned short int *)ptr)[i] = ((unsigned int *)indices)[i] - min; - else - for (i=0; i < count; i++) - ((unsigned int *)ptr)[i] = ((unsigned int *)indices)[i] - min; - break; - - default: - WARN_ONCE("Unknown elt type!\n"); - goto fallback; - } - - if (ctx->NewState) - _mesa_update_state( ctx ); - - r300UpdateShaders(rmesa); - - if (setup_arrays(rmesa, min) >= R300_FALLBACK_TCL) { - r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__); - goto fallback; - } - - rmesa->state.VB.Count = max - min + 1; - - r300UpdateShaderStates(rmesa); - - rmesa->state.VB.Primitive = &prim; - rmesa->state.VB.PrimitiveCount = 1; - - prim.mode = mode | PRIM_BEGIN | PRIM_END; - if (rmesa->state.VB.LockCount) - prim.start = min - rmesa->state.VB.LockFirst; - else - prim.start = 0; - prim.count = count; - - rmesa->state.VB.Elts = ptr; - rmesa->state.VB.elt_size = elt_size; - - if (r300_run_vb_render(ctx, NULL)) { - r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__); - goto fallback; - } - - if(rvb.buf) - radeon_mm_use(rmesa, rvb.buf->id); - - r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__); - return; - - fallback: - _tnl_array_init(ctx); - _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt ); - CALL_DrawElements(GET_DISPATCH(), (mode, count, type, c_indices)); - radeon_init_vtxfmt_a(rmesa); - _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt ); -} -static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei count, GLenum type, const GLvoid *c_indices) +static void radeonDrawRangeElements(GLcontext *ctx, + GLenum mode, + GLuint min, + GLuint max, + GLsizei count, + GLenum type, + const GLvoid *c_indices) { - GET_CURRENT_CONTEXT(ctx); +#if 1 + return GL_FALSE; +#else r300ContextPtr rmesa = R300_CONTEXT(ctx); struct tnl_prim prim; int elt_size; @@ -371,26 +206,23 @@ static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei indices += i * _mesa_sizeof_type(type); count -= i; } - return ; + return GL_TRUE; } WARN_ONCE("Too many verts!\n"); - goto fallback; + return GL_FALSE; } if (ctx->Array.ElementArrayBufferObj->Name) { /* use indices in the buffer object */ if (!ctx->Array.ElementArrayBufferObj->Data) { _mesa_warning(ctx, "DrawRangeElements with empty vertex elements buffer!"); - return; + return GL_TRUE; } /* actual address is the sum of pointers */ indices = (GLvoid *) ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Data, (const GLubyte *) c_indices); } - if (!_mesa_validate_DrawRangeElements( ctx, mode, min, max, count, type, indices )) - return; - FLUSH_CURRENT( ctx, 0 ); #ifdef OPTIMIZE_ELTS min = 0; @@ -465,7 +297,7 @@ static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei default: WARN_ONCE("Unknown elt type!\n"); - goto fallback; + return GL_FALSE; } /* XXX: setup_arrays before state update? */ @@ -477,7 +309,7 @@ static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei if (setup_arrays(rmesa, min) >= R300_FALLBACK_TCL) { r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__); - goto fallback; + return GL_FALSE; } rmesa->state.VB.Count = max - min + 1; @@ -501,37 +333,34 @@ static void radeonDrawRangeElements(GLenum mode, GLuint min, GLuint max, GLsizei if (r300_run_vb_render(ctx, NULL)) { r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__); - goto fallback; + return GL_FALSE; } if(rvb.buf) radeon_mm_use(rmesa, rvb.buf->id); r300ReleaseDmaRegion(rmesa, &rvb, __FUNCTION__); - return ; - - fallback: - _tnl_array_init(ctx); - _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt ); - CALL_DrawRangeElements(GET_DISPATCH(), (mode, min, max, count, type, c_indices)); - radeon_init_vtxfmt_a(rmesa); - _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt ); + return GL_TRUE; +#endif } -static void radeonDrawArrays( GLenum mode, GLint start, GLsizei count ) +static GLboolean radeonDrawArrays( GLcontext *ctx, + GLenum mode, GLint start, GLsizei count ) { +#if 1 + return GL_FALSE; +#else GET_CURRENT_CONTEXT(ctx); r300ContextPtr rmesa = R300_CONTEXT(ctx); struct tnl_prim prim; if (count > 65535) { + /* TODO: split into multiple draws. + */ WARN_ONCE("Too many verts!\n"); - goto fallback; + return GL_FALSE; } - if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) - return; - FLUSH_CURRENT( ctx, 0 ); if (ctx->NewState) @@ -542,7 +371,7 @@ static void radeonDrawArrays( GLenum mode, GLint start, GLsizei count ) r300UpdateShaders(rmesa); if (setup_arrays(rmesa, start) >= R300_FALLBACK_TCL) - goto fallback; + return GL_FALSE; rmesa->state.VB.Count = count; @@ -564,31 +393,70 @@ static void radeonDrawArrays( GLenum mode, GLint start, GLsizei count ) rmesa->state.VB.elt_max = 0; if (r300_run_vb_render(ctx, NULL)) - goto fallback; + return GL_FALSE; - return ; - - fallback: - _tnl_array_init(ctx); - _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt ); - CALL_DrawArrays(GET_DISPATCH(), (mode, start, count)); - radeon_init_vtxfmt_a(rmesa); - _mesa_install_exec_vtxfmt( ctx, &TNL_CONTEXT(ctx)->exec_vtxfmt ); + return GL_TRUE; +#endif } +static void radeon_draw_prims( GLcontext *ctx, + const struct gl_client_array *arrays[], + const struct _mesa_prim *prim, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLuint min_index, + GLuint max_index) +{ + if (ib == NULL) { + for (i = 0; i < nr_prims; i++) { + if (!radeonDrawArrays(ctx, + prim->mode, + prim->start, + prim->count)) { + /* Fallback + */ + _tnl_draw_prims(ctx, + arrays, + prim + i, + nr_prims - i, + ib, + min_index, + max_index); + return; + } + } + } else { + for (i = 0; i < nr_prims; i++) { + if (!radeonDrawRangeElements(ctx, + prim->mode, + min_index, + max_index, + prim->count, + ib->types, + ib->ptr)) { + /* Fallback + */ + _tnl_draw_prims(ctx, + arrays, + prim + i, + nr_prims - i, + ib, + min_index, + max_index); + return; + } + } + } +} + void radeon_init_vtxfmt_a(r300ContextPtr rmesa) { GLcontext *ctx; - GLvertexformat *vfmt; - - ctx = rmesa->radeon.glCtx; - vfmt = (GLvertexformat *)ctx->TnlModule.Current; - - vfmt->DrawElements = radeonDrawElements; - vfmt->DrawArrays = radeonDrawArrays; - vfmt->DrawRangeElements = radeonDrawRangeElements; + struct vbo_context *vbo = vbo_context(ctx); + vbo->draw_prims = radeon_draw_prims; } + #endif #ifdef HW_VBOS -- cgit v1.2.3 From 25b2e50229592ecd4cc3d058471bdee1cb8a0c55 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Fri, 3 Nov 2006 12:30:55 +0000 Subject: remove remaining traces of r200FlushVertices... --- src/mesa/drivers/dri/r200/r200_context.c | 1 - src/mesa/drivers/dri/r200/r200_swtcl.h | 1 - 2 files changed, 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c index 02651587a6..a1533d7f3e 100644 --- a/src/mesa/drivers/dri/r200/r200_context.c +++ b/src/mesa/drivers/dri/r200/r200_context.c @@ -442,7 +442,6 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, */ _tnl_destroy_pipeline( ctx ); _tnl_install_pipeline( ctx, r200_pipeline ); - ctx->Driver.FlushVertices = r200FlushVertices; /* Try and keep materials and vertices separate: */ diff --git a/src/mesa/drivers/dri/r200/r200_swtcl.h b/src/mesa/drivers/dri/r200/r200_swtcl.h index ce2b6b5f06..ccf817988c 100644 --- a/src/mesa/drivers/dri/r200/r200_swtcl.h +++ b/src/mesa/drivers/dri/r200/r200_swtcl.h @@ -42,7 +42,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. extern void r200InitSwtcl( GLcontext *ctx ); extern void r200DestroySwtcl( GLcontext *ctx ); -extern void r200FlushVertices( GLcontext *ctx, GLuint flags ); extern void r200ChooseRenderState( GLcontext *ctx ); extern void r200ChooseVertexState( GLcontext *ctx ); -- cgit v1.2.3 From e2b4d9b317104ff3c56a9bf108aa79084d49eba5 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sun, 5 Nov 2006 13:46:48 +0000 Subject: Architect the DRI : - make use of the autogenerated nouveau_reg.h file - add object creation to the DRI - some work on screen and context creation --- src/mesa/drivers/dri/nouveau/Makefile | 6 +- src/mesa/drivers/dri/nouveau/nouveau_card.c | 50 + src/mesa/drivers/dri/nouveau/nouveau_card.h | 49 + src/mesa/drivers/dri/nouveau/nouveau_context.c | 12 +- src/mesa/drivers/dri/nouveau/nouveau_context.h | 5 +- src/mesa/drivers/dri/nouveau/nouveau_ctrlreg.h | 42 + src/mesa/drivers/dri/nouveau/nouveau_dri.h | 28 + src/mesa/drivers/dri/nouveau/nouveau_driver.c | 31 +- src/mesa/drivers/dri/nouveau/nouveau_fifo.c | 38 +- src/mesa/drivers/dri/nouveau/nouveau_fifo.h | 8 +- src/mesa/drivers/dri/nouveau/nouveau_ioctl.c | 60 - src/mesa/drivers/dri/nouveau/nouveau_ioctl.h | 36 - src/mesa/drivers/dri/nouveau/nouveau_object.c | 36 + src/mesa/drivers/dri/nouveau/nouveau_object.h | 13 + src/mesa/drivers/dri/nouveau/nouveau_reg.h | 1484 ++++++++++++++++++++++-- src/mesa/drivers/dri/nouveau/nouveau_screen.c | 49 + src/mesa/drivers/dri/nouveau/nouveau_screen.h | 5 +- src/mesa/drivers/dri/nouveau/nouveau_state.c | 1 - src/mesa/drivers/dri/nouveau/nouveau_swtcl.c | 4 +- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 59 +- 20 files changed, 1768 insertions(+), 248 deletions(-) create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_card.c create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_card.h create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_ctrlreg.h create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_dri.h delete mode 100644 src/mesa/drivers/dri/nouveau/nouveau_ioctl.c delete mode 100644 src/mesa/drivers/dri/nouveau/nouveau_ioctl.h create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_object.c create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_object.h create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_screen.c (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile index ee7bc5d317..08240ad032 100644 --- a/src/mesa/drivers/dri/nouveau/Makefile +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -8,13 +8,15 @@ LIBNAME = nouveau_dri.so MINIGLX_SOURCES = DRIVER_SOURCES = \ + nouveau_card.c \ nouveau_context.c \ nouveau_driver.c \ nouveau_fifo.c \ - nouveau_ioctl.c \ nouveau_lock.c \ + nouveau_object.c \ + nouveau_screen.c \ nouveau_span.c \ - nouveau_state.c \ + nouveau_state.c \ nouveau_tex.c \ nouveau_swtcl.c \ nv10_swtcl.c diff --git a/src/mesa/drivers/dri/nouveau/nouveau_card.c b/src/mesa/drivers/dri/nouveau/nouveau_card.c new file mode 100644 index 0000000000..c36f62aff6 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_card.c @@ -0,0 +1,50 @@ + +#include "nouveau_card.h" +#include "nouveau_reg.h" + +static nouveau_card nouveau_card_list[]={ +//x0010, "Riva 128", ????, NV_03, 0}, +{0x0020, "TNT/TNT2", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, +{0x00A0, "TNT2", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, +{0x0100, "GeForce", NV10_TCL_PRIMITIVE_3D, NV_10, 0}, +{0x0110, "GeForce 2 MX", NV15_TCL_PRIMITIVE_3D|0x1100, NV_10, 0}, +{0x01A0, "NForce", NV15_TCL_PRIMITIVE_3D|0x1100, NV_10, 0}, +{0x0150, "GeForce 2", NV15_TCL_PRIMITIVE_3D, NV_10, 0}, +{0x0170, "GeForce 4 MX", NV15_TCL_PRIMITIVE_3D|0x1700, NV_10, NV_HAS_LMA}, +{0x0180, "GeForce 4 MX", NV15_TCL_PRIMITIVE_3D|0x1700, NV_10, NV_HAS_LMA}, +{0x01F0, "NForce 2", NV15_TCL_PRIMITIVE_3D|0x1700, NV_10, NV_HAS_LMA}, +{0x0200, "GeForce 3", NV20_TCL_PRIMITIVE_3D|0x2000, NV_20, NV_HAS_LMA}, +{0x0250, "GeForce 4 Ti", NV20_TCL_PRIMITIVE_3D|0x2500, NV_20, NV_HAS_LMA}, +{0x0280, "GeForce 4 Ti", NV20_TCL_PRIMITIVE_3D|0x2500, NV_20, NV_HAS_LMA}, +{0x0320, "GeForce FX 5200/5500", NV30_TCL_PRIMITIVE_3D|0x3400, NV_30, NV_HAS_LMA}, +{0x0310, "GeForce FX 5600", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, NV_HAS_LMA}, +{0x0340, "GeForce FX 5700", NV30_TCL_PRIMITIVE_3D|0x3500, NV_30, NV_HAS_LMA}, +{0x0300, "GeForce FX 5800", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, NV_HAS_LMA}, +{0x0330, "GeForce FX 5900", NV30_TCL_PRIMITIVE_3D|0x3500, NV_30, NV_HAS_LMA}, +{0x0240, "GeForce 6100", NV30_TCL_PRIMITIVE_3D|0x4400, NV_40, NV_HAS_LMA}, +{0x0160, "GeForce 6200", NV30_TCL_PRIMITIVE_3D|0x4400, NV_40, NV_HAS_LMA}, +{0x0220, "GeForce 6200", NV30_TCL_PRIMITIVE_3D|0x4400, NV_40, NV_HAS_LMA}, +{0x0140, "GeForce 6200/6600", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, NV_HAS_LMA}, +{0x0040, "GeForce 6800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, NV_HAS_LMA}, +{0x00C0, "GeForce 6800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, NV_HAS_LMA}, +{0x0210, "GeForce 6800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, NV_HAS_LMA}, +{0x01D0, "GeForce 7200/7300/7400", NV30_TCL_PRIMITIVE_3D|0x4400, NV_40, NV_HAS_LMA}, +{0x0390, "GeForce 7300/7600", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, NV_HAS_LMA}, +{0x02E0, "GeForce 7300/7600", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, NV_HAS_LMA}, +{0x0090, "GeForce 7800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, NV_HAS_LMA}, +{0x0290, "GeForce 7900", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, NV_HAS_LMA}, +/* catchall */ +{0x0000, "Unknown card", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, NV_HAS_LMA}, +}; + + +nouveau_card* nouveau_card_lookup(uint32_t device_id) +{ + int i; + for(i=0;iscreen->card_type) + switch(nmesa->screen->card->type) { case NV_03: //nv03TriInitFunctions( ctx ); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 21aa1a6313..be0785f453 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -36,13 +36,13 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #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* mmio; u_int32_t current; u_int32_t put; u_int32_t free; @@ -80,9 +80,6 @@ typedef struct nouveau_context { /* The per-context fifo */ nouveau_fifo fifo; - /* The fifo control regs */ - volatile unsigned char* fifo_mmio; - /* The read-only regs */ volatile unsigned char* mmio; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_ctrlreg.h b/src/mesa/drivers/dri/nouveau/nouveau_ctrlreg.h new file mode 100644 index 0000000000..2f4c3f6d5d --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_ctrlreg.h @@ -0,0 +1,42 @@ +/************************************************************************** + +Copyright 2006 Stephane Marchesin, Sylvain Munaut +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_STATUS 0x004006b0 +#define NV04_STATUS 0x00400700 + +#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_dri.h b/src/mesa/drivers/dri/nouveau/nouveau_dri.h new file mode 100644 index 0000000000..ce3c3fb9cc --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_dri.h @@ -0,0 +1,28 @@ +#ifndef _NOUVEAU_DRI_ +#define _NOUVEAU_DRI_ + +#include "xf86drm.h" +#include "drm.h" +#include "nouveau_drm.h" + +typedef struct { + uint32_t device_id; /**< \brief PCI device ID */ + uint32_t width; /**< \brief width in pixels of display */ + uint32_t height; /**< \brief height in scanlines of display */ + uint32_t depth; /**< \brief depth of display (8, 15, 16, 24) */ + uint32_t bpp; /**< \brief bit depth of display (8, 16, 24, 32) */ + + uint32_t bus_type; /**< \brief ths bus type */ + uint32_t bus_mode; /**< \brief bus mode (used for AGP, maybe also for PCI-E ?) */ + + uint32_t front_offset; /**< \brief front buffer offset */ + uint32_t front_pitch; /**< \brief front buffer pitch */ + uint32_t back_offset; /**< \brief private back buffer offset */ + uint32_t back_pitch; /**< \brief private back buffer pitch */ + uint32_t depth_offset; /**< \brief private depth buffer offset */ + uint32_t depth_pitch; /**< \brief private depth buffer pitch */ + +} NOUVEAUDRIRec, *NOUVEAUDRIPtr; + +#endif + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_driver.c b/src/mesa/drivers/dri/nouveau/nouveau_driver.c index cb996acd89..a45530e451 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_driver.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_driver.c @@ -25,7 +25,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ #include "nouveau_context.h" -#include "nouveau_ioctl.h" //#include "nouveau_state.h" #include "nouveau_lock.h" #include "nouveau_fifo.h" @@ -64,35 +63,7 @@ static const GLubyte *nouveauGetString( GLcontext *ctx, GLenum name ) 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; - } + card_name=nmesa->screen->card->name; switch(nmesa->screen->bus_type) { diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c index cc77b577ca..5793909705 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c @@ -25,14 +25,25 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +#include "vblank.h" +#include +#include "mtypes.h" +#include "macros.h" +#include "dd.h" +#include "swrast/swrast.h" +#include "nouveau_context.h" +#include "nouveau_msg.h" #include "nouveau_fifo.h" #include "nouveau_lock.h" -#include "vblank.h" + #define RING_SKIPS 8 void WAIT_RING(nouveauContextPtr nmesa,u_int32_t size) { +#ifdef NOUVEAU_RING_DEBUG + return; +#endif u_int32_t fifo_get; while(nmesa->fifo.free < size+1) { fifo_get = NV_FIFO_READ(NV03_FIFO_REGS_DMAGET); @@ -58,15 +69,17 @@ void WAIT_RING(nouveauContextPtr nmesa,u_int32_t size) /* * Wait for the card to be idle - * XXX we should also wait for an empty fifo */ void nouveauWaitForIdleLocked(nouveauContextPtr nmesa) { int i,status; + FIRE_RING(); + while(RING_AHEAD()>0); + for(i=0;i<1000000;i++) /* 1 second */ { - switch(nmesa->screen->card_type) + switch(nmesa->screen->card->type) { case NV_03: status=NV_READ(NV03_STATUS); @@ -95,3 +108,22 @@ void nouveauWaitForIdle(nouveauContextPtr nmesa) UNLOCK_HARDWARE(nmesa); } +// here we call the fifo initialization ioctl and fill in stuff accordingly +void nouveauFifoInit(nouveauContextPtr nmesa) +{ + drm_nouveau_fifo_alloc_t fifo_init; + + int ret; + ret=drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_FIFO_ALLOC, &fifo_init, sizeof(fifo_init)); + if (ret) + FATAL("Fifo initialization ioctl failed (returned %d)\n",ret); + + if (drmMap(nmesa->driFd, fifo_init.cmdbuf, fifo_init.cmdbuf_size, &nmesa->fifo.buffer)) + FATAL("Unable to map the fifo\n",ret); + if (drmMap(nmesa->driFd, fifo_init.ctrl, fifo_init.ctrl_size, &nmesa->fifo.mmio)) + FATAL("Unable to map the control regs\n",ret); + + MESSAGE("Fifo init ok. Using context %d\n", fifo_init.channel); +} + + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h index 95c78b5675..c2f8633dcc 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h @@ -30,11 +30,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define __NOUVEAU_FIFO_H__ #include "nouveau_context.h" +#include "nouveau_ctrlreg.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; +#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 @@ -44,7 +45,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * - 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 + * - FIRE_RING fires whatever we have that wasn't fired before * - WAIT_RING waits for size (in uint32_ts) to be available in the fifo */ @@ -112,6 +113,7 @@ extern void WAIT_RING(nouveauContextPtr nmesa,u_int32_t size); }while(0) extern void nouveauWaitForIdle(nouveauContextPtr nmesa); +extern void nouveauFifoInit(nouveauContextPtr nmesa); #endif /* __NOUVEAU_FIFO_H__ */ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_ioctl.c b/src/mesa/drivers/dri/nouveau/nouveau_ioctl.c deleted file mode 100644 index 3f6e3076e2..0000000000 --- a/src/mesa/drivers/dri/nouveau/nouveau_ioctl.c +++ /dev/null @@ -1,60 +0,0 @@ -/************************************************************************** - -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 -#include "mtypes.h" -#include "macros.h" -#include "dd.h" -#include "swrast/swrast.h" - - -#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(nouveauContextPtr nmesa) -{ - int ret; - drm_nouveau_fifo_alloc_t fifo_init; - - ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_FIFO_ALLOC, &fifo_init, sizeof(fifo_init)); - if (ret) - FATAL("Fifo initialization ioctl failed (returned %d)\n",ret); - MESSAGE("Fifo init ok. Using context %d\n", fifo_init.channel); - - // XXX needs more stuff : - // - map the command buffer - // - map the fifo control regs - // - create the 3D object - -} - -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 deleted file mode 100644 index ce77d3d11e..0000000000 --- a/src/mesa/drivers/dri/nouveau/nouveau_ioctl.h +++ /dev/null @@ -1,36 +0,0 @@ -/************************************************************************** - -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__ - -#include "nouveau_context.h" - -extern void nouveauIoctlInitFifo(nouveauContextPtr nmesa); -extern void nouveauIoctlInitFunctions(struct dd_function_table *functions); - -#endif /* __NOUVEAU_IOCTL_H__ */ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.c b/src/mesa/drivers/dri/nouveau/nouveau_object.c new file mode 100644 index 0000000000..9003fb1eae --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.c @@ -0,0 +1,36 @@ + +#include "nouveau_fifo.h" +#include "nouveau_object.h" + + +static GLboolean NVDmaCreateContextObject(nouveauContextPtr nmesa, int handle, int class, uint32_t flags, + uint32_t dma_in, uint32_t dma_out, uint32_t dma_notifier) +{ + drm_nouveau_object_init_t cto; + int ret; + + cto.handle = handle; + cto.class = class; + cto.flags = flags; + cto.dma0= dma_in; + cto.dma1= dma_out; + cto.dma_notifier = dma_notifier; + ret = drmCommandWrite(nmesa->driFd, DRM_NOUVEAU_OBJECT_INIT, &cto, sizeof(cto)); + + return ret == 0; +} + +static void nouveauObjectOnSubchannel(nouveauContextPtr nmesa, int handle, int subchannel) +{ + BEGIN_RING_SIZE(subchannel, 0, 1); + OUT_RING(handle); +} + +void nouveauObjectInit(nouveauContextPtr nmesa) +{ + NVDmaCreateContextObject(nmesa, Nv3D, nmesa->screen->card->class_3d, 0, 0, 0, 0); + nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); +} + + + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.h b/src/mesa/drivers/dri/nouveau/nouveau_object.h new file mode 100644 index 0000000000..5fe7487c47 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.h @@ -0,0 +1,13 @@ + +#include "nouveau_context.h" + +void nouveauObjectInit(nouveauContextPtr nmesa); + +enum DMAObjects { + Nv3D = 0x80000019, +}; + +enum DMASubchannel { + NvSub3D = 1, +}; + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_reg.h b/src/mesa/drivers/dri/nouveau/nouveau_reg.h index 583a2b82cb..359f36cec8 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_reg.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_reg.h @@ -1,79 +1,1417 @@ -/************************************************************************** +/* + Autogenerated file, do not edit ! + +************************************************************************** + + Copyright (C) 2006 : + Dmitry Baryshkov, + Laurent Carlier, + Matthieu Castet, + Dawid Gajownik, + Jeremy Kolb, + Stephane Loeuillet, + Patrice Mandin, + Stephane Marchesin, + Serge Martin, + Sylvain Munaut, + Ben Skeggs, + Erik Waling, + koala_br, + sturmflut. -Copyright 2006 Stephane Marchesin, Sylvain Munaut 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)) - -/* Vertex attributes */ -#define NV30_UNKNOWN_0 0x00001718 -#define NV30_VERTEX_ATTRIBUTES 0x00001740 -#define NV20_VERTEX_ATTRIBUTE(i) (0x00001760+i*4) -#define NV20_VERTEX_ATTRIBUTE_TYPE_MASK 0x0000000f -#define NV20_VERTEX_ATTRIBUTE_TYPE_FLOAT 0x00000002 -#define NV20_VERTEX_ATTRIBUTE_SIZE_MASK 0x000000f0 -#define NV10_VERTEX_ATTRIBUTE(i) (0x00000d04+i*8) -#define NV10_VERTEX_SET_FORMAT 0x00000cf0 - -/* Rendering commands */ -#define NV10_PRIMITIVE 0x00000dfc -#define NV20_PRIMITIVE 0x000017fc -#define NV30_PRIMITIVE 0x00001808 -#define NV10_BEGIN_VERTICES 0x00001800 -#define NV20_BEGIN_VERTICES 0x00001818 +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. + +************************************************************************** + + Created from objects.c rev. 1.332 +*/ + +#ifndef _NOUVEAU_REG_H +#define _NOUVEAU_REG_H + +/****************************************** +Object NV01_CONTEXT_CLIP_RECTANGLE used on: NV03 NV04 NV10 NV15 NV20 NV40 G70 +*/ +#define NV01_CONTEXT_CLIP_RECTANGLE 0x00000019 +# define NV01_CONTEXT_CLIP_RECTANGLE_SET_POINT 0x00000300 /* Parameters: x y */ +# define NV01_CONTEXT_CLIP_RECTANGLE_SET_SIZE 0x00000304 /* Parameters: width height */ + +/****************************************** +Object NV_MEMORY_TO_MEMORY_FORMAT used on: NV04 NV10 NV15 NV20 NV30 NV40 G70 +*/ +#define NV_MEMORY_TO_MEMORY_FORMAT 0x00000039 +# define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x00000104 +# define NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY 0x00000180 +# define NV_MEMORY_TO_MEMORY_FORMAT_OBJECT_IN 0x00000184 +# define NV_MEMORY_TO_MEMORY_FORMAT_OBJECT_OUT 0x00000188 +# define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN 0x0000030c +# define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_OUT 0x00000310 +# define NV_MEMORY_TO_MEMORY_FORMAT_PITCH_IN 0x00000314 +# define NV_MEMORY_TO_MEMORY_FORMAT_PITCH_OUT 0x00000318 +# define NV_MEMORY_TO_MEMORY_FORMAT_LINE_LENGTH_IN 0x0000031c +# define NV_MEMORY_TO_MEMORY_FORMAT_LINE_COUNT 0x00000320 + +/****************************************** +Object NV03_PRIMITIVE_RASTER_OP used on: NV03 NV04 NV10 NV15 NV20 NV30 NV40 G70 +*/ +#define NV03_PRIMITIVE_RASTER_OP 0x00000043 +# define NV03_PRIMITIVE_RASTER_OP_NOTIFY 0x00000100 +# define NV03_PRIMITIVE_RASTER_OP_DMA_NOTIFY 0x00000180 +# define NV03_PRIMITIVE_RASTER_OP_LOGIC_OP 0x00000300 /* Parameters: logic_op */ + +/****************************************** +Object NV04_GDI_RECTANGLE_TEXT used on: NV04 NV10 NV15 NV20 NV30 NV40 G70 +*/ +#define NV04_GDI_RECTANGLE_TEXT 0x0000004a +# define NV04_GDI_RECTANGLE_TEXT_SET_DMA_NOTIFY 0x00000180 +# define NV04_GDI_RECTANGLE_TEXT_PATTERN 0x00000188 +# define NV04_GDI_RECTANGLE_TEXT_ROP5 0x0000018c +# define NV04_GDI_RECTANGLE_TEXT_SURFACE 0x00000198 +# define NV04_GDI_RECTANGLE_TEXT_OPERATION 0x000002fc +# define NV04_GDI_RECTANGLE_TEXT_FORMAT 0x00000300 +# define NV04_GDI_RECTANGLE_TEXT_BLOCK_LEVEL1_TL 0x000005f4 /* Parameters: left top */ +# define NV04_GDI_RECTANGLE_TEXT_BLOCK_LEVEL1_BR 0x000005f8 /* Parameters: right bottom */ +# define NV04_GDI_RECTANGLE_TEXT_FILL_VALUE 0x000005fc +# define NV04_GDI_RECTANGLE_TEXT_BLOCK_LEVEL2_TL 0x00000600 /* Parameters: left top */ +# define NV04_GDI_RECTANGLE_TEXT_BLOCK_LEVEL2_BR 0x00000604 /* Parameters: right bottom */ + +/****************************************** +Object NV04_SWIZZLED_SURFACE used on: NV04 NV10 NV15 +*/ +#define NV04_SWIZZLED_SURFACE 0x00000052 +# define NV04_SWIZZLED_SURFACE_DMA_NOTIFY 0x00000180 +# define NV04_SWIZZLED_SURFACE_DMA_IMAGE 0x00000184 +# define NV04_SWIZZLED_SURFACE_FORMAT 0x00000300 /* Parameters: log2(height) log2(width) color */ +# define NV04_SWIZZLED_SURFACE_OFFSET 0x00000304 + +/****************************************** +Object NV04_CONTEXT_SURFACES_3D used on: NV04 +*/ +#define NV04_CONTEXT_SURFACES_3D 0x00000053 +# define NV04_CONTEXT_SURFACES_3D_DMA_NOTIFY 0x00000180 +# define NV04_CONTEXT_SURFACES_3D_DMA_COLOR 0x00000184 +# define NV04_CONTEXT_SURFACES_3D_DMA_ZETA 0x00000188 +# define NV04_CONTEXT_SURFACES_3D_CLIP_HORIZONTAL 0x000002f8 /* Parameters: x width */ +# define NV04_CONTEXT_SURFACES_3D_CLIP_VERTICAL 0x000002fc /* Parameters: y height */ +# define NV04_CONTEXT_SURFACES_3D_FORMAT 0x00000300 /* Parameters: color type width height */ +# define NV04_CONTEXT_SURFACES_3D_CLIP_SIZE 0x00000304 /* Parameters: width height */ +# define NV04_CONTEXT_SURFACES_3D_PITCH 0x00000308 /* Parameters: color zeta */ +# define NV04_CONTEXT_SURFACES_3D_OFFSET_COLOR 0x0000030c +# define NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA 0x00000310 + +/****************************************** +Object NV04_DX5_TEXTURED_TRIANGLE used on: NV04 +*/ +#define NV04_DX5_TEXTURED_TRIANGLE 0x00000054 +# define NV04_DX5_TEXTURED_TRIANGLE_NOP 0x00000100 +# define NV04_DX5_TEXTURED_TRIANGLE_NOTIFY 0x00000104 +# define NV04_DX5_TEXTURED_TRIANGLE_DMA_NOTIFY 0x00000180 +# define NV04_DX5_TEXTURED_TRIANGLE_DMA_1 0x00000184 +# define NV04_DX5_TEXTURED_TRIANGLE_DMA_2 0x00000188 +# define NV04_DX5_TEXTURED_TRIANGLE_SURFACE 0x0000018c +# define NV04_DX5_TEXTURED_TRIANGLE_COLOR_KEY 0x00000300 +# define NV04_DX5_TEXTURED_TRIANGLE_TEXTURE_OFFSET 0x00000304 +# define NV04_DX5_TEXTURED_TRIANGLE_TEXTURE_FORMAT 0x00000308 /* Parameters: color mipmaps log(u) log(v) wrap_s wrap_t */ +# define NV04_DX5_TEXTURED_TRIANGLE_TEXTURE_FILTER 0x0000030c /* Parameters: magfilter minfilter lodbias */ +# define NV04_DX5_TEXTURED_TRIANGLE_BLEND 0x00000310 /* Parameters: texture benable dst src */ +# define NV04_DX5_TEXTURED_TRIANGLE_CONTROL 0x00000314 /* Parameters: alpharef alphafunc alphaenable zenable zwrite zfunc cullmode */ +# define NV04_DX5_TEXTURED_TRIANGLE_FOG_COLOR 0x00000318 +# define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX( d) (0x00000400 + d * 0x0020) +# define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SY( d) (0x00000404 + d * 0x0020) +# define NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SZ( d) (0x00000408 + d * 0x0020) +# define NV04_DX5_TEXTURED_TRIANGLE_INV_W( d) (0x0000040c + d * 0x0020) +# define NV04_DX5_TEXTURED_TRIANGLE_COLOR( d) (0x00000410 + d * 0x0020) +# define NV04_DX5_TEXTURED_TRIANGLE_SPECULAR( d) (0x00000414 + d * 0x0020) +# define NV04_DX5_TEXTURED_TRIANGLE_TEXTURE_S( d) (0x00000418 + d * 0x0020) +# define NV04_DX5_TEXTURED_TRIANGLE_TEXTURE_T( d) (0x0000041c + d * 0x0020) +# define NV04_DX5_TEXTURED_TRIANGLE_DRAW 0x00000600 /* Parameters: v0 v1 v2 v3 v4 v5 */ + +/****************************************** +Object NV04_DX6_MULTITEX_TRIANGLE used on: NV04 NV10 NV15 +*/ +#define NV04_DX6_MULTITEX_TRIANGLE 0x00000055 +# define NV04_DX6_MULTITEX_TRIANGLE_NOP 0x00000100 +# define NV04_DX6_MULTITEX_TRIANGLE_NOTIFY 0x00000104 +# define NV04_DX6_MULTITEX_TRIANGLE_DMA_NOTIFY 0x00000180 +# define NV04_DX6_MULTITEX_TRIANGLE_DMA_1 0x00000184 +# define NV04_DX6_MULTITEX_TRIANGLE_DMA_2 0x00000188 +# define NV04_DX6_MULTITEX_TRIANGLE_SURFACE 0x0000018c +# define NV04_DX6_MULTITEX_TRIANGLE_OFFSET0 0x00000308 +# define NV04_DX6_MULTITEX_TRIANGLE_OFFSET1 0x0000030c +# define NV04_DX6_MULTITEX_TRIANGLE_FORMAT0 0x00000310 /* Parameters: color mipmaps log(u) log(v) wrap_s wrap_t */ +# define NV04_DX6_MULTITEX_TRIANGLE_FORMAT1 0x00000314 /* Parameters: color mipmaps log(u) log(v) wrap_s wrap_t */ +# define NV04_DX6_MULTITEX_TRIANGLE_FILTER0 0x00000318 /* Parameters: magfilter minfilter lodbias */ +# define NV04_DX6_MULTITEX_TRIANGLE_FILTER1 0x0000031c /* Parameters: magfilter minfilter lodbias */ +# define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_ALPHA 0x00000320 +# define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_0_COLOR 0x00000324 +# define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_ALPHA 0x0000032c +# define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_1_COLOR 0x00000330 +# define NV04_DX6_MULTITEX_TRIANGLE_COMBINE_FACTOR 0x00000334 +# define NV04_DX6_MULTITEX_TRIANGLE_BLEND 0x00000338 /* Parameters: benable dst src */ +# define NV04_DX6_MULTITEX_TRIANGLE_CONTROL0 0x0000033c /* Parameters: red_write green_write blue_write alpha_write alpha_write stencil_write alpharef alphafunc alphaenable zenable zwrite zfunc cullmode */ +# define NV04_DX6_MULTITEX_TRIANGLE_CONTROL1 0x00000340 /* Parameters: stencil_enable stencil_mask_write stencil_mask_read stencilref stencilfunc */ +# define NV04_DX6_MULTITEX_TRIANGLE_CONTROL2 0x00000344 /* Parameters: stencil_fail stencil_zfail stencil_zpass */ +# define NV04_DX6_MULTITEX_TRIANGLE_FOG_COLOR 0x00000348 +# define NV04_DX6_MULTITEX_TRIANGLE_TLVERTEX_SX( d) (0x00000400 + d * 0x0028) +# define NV04_DX6_MULTITEX_TRIANGLE_TLVERTEX_SY( d) (0x00000404 + d * 0x0028) +# define NV04_DX6_MULTITEX_TRIANGLE_TLVERTEX_SZ( d) (0x00000408 + d * 0x0028) +# define NV04_DX6_MULTITEX_TRIANGLE_INV_W( d) (0x0000040c + d * 0x0028) +# define NV04_DX6_MULTITEX_TRIANGLE_COLOR( d) (0x00000410 + d * 0x0028) +# define NV04_DX6_MULTITEX_TRIANGLE_SPECULAR( d) (0x00000414 + d * 0x0028) +# define NV04_DX6_MULTITEX_TRIANGLE_TEXTURE0_S( d) (0x00000418 + d * 0x0028) +# define NV04_DX6_MULTITEX_TRIANGLE_TEXTURE0_T( d) (0x0000041c + d * 0x0028) +# define NV04_DX6_MULTITEX_TRIANGLE_TEXTURE1_S( d) (0x00000420 + d * 0x0028) +# define NV04_DX6_MULTITEX_TRIANGLE_TEXTURE1_T( d) (0x00000424 + d * 0x0028) +# define NV04_DX6_MULTITEX_TRIANGLE_DRAW 0x00000540 /* Parameters: v0 v1 v2 v3 v4 v5 */ + +/****************************************** +Object NV04_COLOR_KEY used on: NV04 NV10 NV15 NV20 +*/ +#define NV04_COLOR_KEY 0x00000057 +# define NV04_COLOR_KEY_SET_DMA_NOTIFY 0x00000180 +# define NV04_COLOR_KEY_FORMAT 0x00000300 +# define NV04_COLOR_KEY_VALUE 0x00000304 + +/****************************************** +Object NV04_SOLID_LINE used on: NV04 +*/ +#define NV04_SOLID_LINE 0x0000005c +# define NV04_SOLID_LINE_CLIP_RECTANGLE 0x00000184 +# define NV04_SOLID_LINE_PATTERN 0x00000188 +# define NV04_SOLID_LINE_ROP 0x0000018c +# define NV04_SOLID_LINE_SURFACE 0x00000198 +# define NV04_SOLID_LINE_OPERATION 0x000002fc +# define NV04_SOLID_LINE_COLOR_FORMAT 0x00000300 +# define NV04_SOLID_LINE_COLOR_VALUE 0x00000304 +# define NV04_SOLID_LINE_START 0x00000400 /* Parameters: x y */ +# define NV04_SOLID_LINE_END 0x00000400 /* Parameters: x y */ + +/****************************************** +Object NV04_UNK005E used on: NV04 +*/ +#define NV04_UNK005E 0x0000005e +# define NV04_UNK005E_SET_SURFACE 0x00000198 +# define NV04_UNK005E_UNK02fc 0x000002fc +# define NV04_UNK005E_UNK0300 0x00000300 +# define NV04_UNK005E_COUNTER 0x00000304 + +/****************************************** +Object NV05_SCALED_IMAGE_FROM_MEMORY used on: NV04 +*/ +#define NV05_SCALED_IMAGE_FROM_MEMORY 0x00000063 +# define NV05_SCALED_IMAGE_FROM_MEMORY_SURFACE 0x00000198 +# define NV05_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION 0x000002fc +# define NV05_SCALED_IMAGE_FROM_MEMORY_OPERATION 0x00000304 + +/****************************************** +Object NV04_SCALED_IMAGE_FROM_MEMORY used on: NV04 +*/ +#define NV04_SCALED_IMAGE_FROM_MEMORY 0x00000077 +# define NV04_SCALED_IMAGE_FROM_MEMORY_DMA_NOTIFY 0x00000180 +# define NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE 0x00000184 +# define NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE 0x00000198 +# define NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT 0x00000300 +# define NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION 0x00000304 +# define NV04_SCALED_IMAGE_FROM_MEMORY_CLIP_POS 0x00000308 /* Parameters: x y */ +# define NV04_SCALED_IMAGE_FROM_MEMORY_CLIP_SIZE 0x0000030c /* Parameters: width height */ +# define NV04_SCALED_IMAGE_FROM_MEMORY_OUT_POS 0x00000310 /* Parameters: x y */ +# define NV04_SCALED_IMAGE_FROM_MEMORY_OUT_SIZE 0x00000314 /* Parameters: width height */ +# define NV04_SCALED_IMAGE_FROM_MEMORY_DU_DX 0x00000318 /* Parameters: int frac*0x100000 */ +# define NV04_SCALED_IMAGE_FROM_MEMORY_DV_DY 0x0000031c /* Parameters: int frac*0x100000 */ +# define NV04_SCALED_IMAGE_FROM_MEMORY_SIZE 0x00000400 /* Parameters: width height */ +# define NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT 0x00000404 /* Parameters: pitch */ +# define NV04_SCALED_IMAGE_FROM_MEMORY_OFFSET 0x00000408 +# define NV04_SCALED_IMAGE_FROM_MEMORY_POINT 0x0000040c /* Parameters: u_int u_frac*0x10 v_int v_frac*0x10 */ + +/****************************************** +Object NV_IMAGE_FROM_CPU used on: NV04 +*/ +#define NV_IMAGE_FROM_CPU 0x00000061 +# define NV_IMAGE_FROM_CPU_DMA_NOTIFY 0x00000180 +# define NV_IMAGE_FROM_CPU_CLIP_RECTANGLE 0x00000188 +# define NV_IMAGE_FROM_CPU_PATTERN 0x0000018c +# define NV_IMAGE_FROM_CPU_ROP 0x00000190 +# define NV_IMAGE_FROM_CPU_SURFACE 0x0000019c +# define NV_IMAGE_FROM_CPU_OPERATION 0x000002fc +# define NV_IMAGE_FROM_CPU_FORMAT 0x00000300 + +/****************************************** +Object NV05_IMAGE_FROM_CPU used on: NV04 +*/ +#define NV05_IMAGE_FROM_CPU 0x00000065 +# define NV05_IMAGE_FROM_CPU_DMA_NOTIFY 0x00000180 +# define NV05_IMAGE_FROM_CPU_CLIP_RECTANGLE 0x00000188 +# define NV05_IMAGE_FROM_CPU_PATTERN 0x0000018c +# define NV05_IMAGE_FROM_CPU_ROP 0x00000190 +# define NV05_IMAGE_FROM_CPU_SURFACE 0x0000019c +# define NV05_IMAGE_FROM_CPU_OPERATION 0x000002fc +# define NV05_IMAGE_FROM_CPU_FORMAT 0x00000300 +# define NV05_IMAGE_FROM_CPU_POINT 0x00000304 /* Parameters: x y */ +# define NV05_IMAGE_FROM_CPU_SIZE_OUT 0x00000308 /* Parameters: x y */ +# define NV05_IMAGE_FROM_CPU_SIZE_IN 0x0000030c /* Parameters: x y */ +# define NV05_IMAGE_FROM_CPU_COLOR( d) (0x00000400 + d * 0x0004) + +/****************************************** +Object NV_IMAGE_BLIT used on: NV04 NV10 NV15 NV20 +*/ +#define NV_IMAGE_BLIT 0x0000005f +# define NV_IMAGE_BLIT_DMA_NOTIFY 0x00000180 +# define NV_IMAGE_BLIT_COLOR_KEY 0x00000184 +# define NV_IMAGE_BLIT_CLIP_RECTANGLE 0x00000188 +# define NV_IMAGE_BLIT_PATTERN 0x0000018c +# define NV_IMAGE_BLIT_ROP5 0x00000190 +# define NV_IMAGE_BLIT_SURFACE 0x0000019c +# define NV_IMAGE_BLIT_OPERATION 0x000002fc +# define NV_IMAGE_BLIT_POINT_IN 0x00000300 /* Parameters: x y */ +# define NV_IMAGE_BLIT_POINT_OUT 0x00000304 /* Parameters: x y */ +# define NV_IMAGE_BLIT_SIZE 0x00000308 /* Parameters: width height */ + +/****************************************** +Object NV10_TCL_PRIMITIVE_3D used on: NV10 +*/ +#define NV10_TCL_PRIMITIVE_3D 0x00000056 +# define NV10_TCL_PRIMITIVE_3D_NOP 0x00000100 +# define NV10_TCL_PRIMITIVE_3D_NOTIFY 0x00000104 +# define NV10_TCL_PRIMITIVE_3D_SET_DMA_NOTIFY 0x00000180 +# define NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY0 0x00000184 +# define NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY1 0x00000188 +# define NV10_TCL_PRIMITIVE_3D_SET_DISPLAY_LIST 0x0000018c +# define NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY2 0x00000194 +# define NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY3 0x00000198 +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ 0x00000200 /* Parameters: width x */ +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_VERT 0x00000204 /* Parameters: height y */ +# define NV10_TCL_PRIMITIVE_3D_BUFFER_FORMAT 0x00000208 /* Parameters: type color */ +# define NV10_TCL_PRIMITIVE_3D_BUFFER_PITCH 0x0000020c /* Parameters: depth/stencil buffer pitch color buffer pitch */ +# define NV10_TCL_PRIMITIVE_3D_COLOR_OFFSET 0x00000210 +# define NV10_TCL_PRIMITIVE_3D_DEPTH_OFFSET 0x00000214 +# define NV10_TCL_PRIMITIVE_3D_TX_OFFSET(d) (0x00000218 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_TX_FORMAT(d) (0x00000220 + d * 0x0004) /* Parameters: wrap_t wrap_s log2(height) log2(width) lod npot format cube_map */ +# define NV10_TCL_PRIMITIVE_3D_TX_ENABLE(d) (0x00000228 + d * 0x0004) /* Parameters: enable anisotropy */ +# define NV10_TCL_PRIMITIVE_3D_TX_NPOT_PITCH(d) (0x00000230 + d * 0x0004) /* Parameters: pitch */ +# define NV10_TCL_PRIMITIVE_3D_TX_NPOT_SIZE(d) (0x00000240 + d * 0x0004) /* Parameters: width height */ +# define NV10_TCL_PRIMITIVE_3D_TX_FILTER(d) (0x00000248 + d * 0x0004) /* Parameters: mag_filter min_filter */ +# define NV10_TCL_PRIMITIVE_3D_RC_IN_ALPHA(d) (0x00000260 + d * 0x0004) /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ +# define NV10_TCL_PRIMITIVE_3D_RC_IN_RGB(d) (0x00000268 + d * 0x0004) /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ +# define NV10_TCL_PRIMITIVE_3D_RC_OUT_ALPHA(d) (0x00000278 + d * 0x0004) /* Parameters: scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ +# define NV10_TCL_PRIMITIVE_3D_RC_OUT_RGB(d) (0x00000280 + d * 0x0004) /* Parameters: rc1_tx_units_enabled rc1_rc_enabled scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ +# define NV10_TCL_PRIMITIVE_3D_TX_MATRIX_ENABLE(d) (0x000003e0 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_TX_MATRIX(x,y) (0x00000540 + y * 0x0010 + x * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_RC_COLOR0 0x00000270 /* Parameters: a r g b */ +# define NV10_TCL_PRIMITIVE_3D_RC_COLOR1 0x00000274 /* Parameters: a r g b */ +# define NV10_TCL_PRIMITIVE_3D_RC_FINAL0 0x00000288 /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ +# define NV10_TCL_PRIMITIVE_3D_RC_FINAL1 0x0000028c /* Parameters: vare_mapping vare_component_usage vare_input varf_mapping varf_component_usage varf_input varg_mapping varg_component_usage varg_input color_sum_clamp */ +# define NV10_TCL_PRIMITIVE_3D_LIGHT_MODEL 0x00000294 /* Parameters: local_viewer color_control */ +# define NV10_TCL_PRIMITIVE_3D_COLOR_MATERIAL 0x00000298 /* Parameters: specular diffuse ambient emission */ +# define NV10_TCL_PRIMITIVE_3D_FOG_MODE 0x0000029c +# define NV10_TCL_PRIMITIVE_3D_FOG_COORD_DIST 0x000002a0 +# define NV10_TCL_PRIMITIVE_3D_FOG_ENABLE 0x000002a4 +# define NV10_TCL_PRIMITIVE_3D_FOG_COLOR 0x000002a8 /* Parameters: a b g r */ +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(d) (0x000002c0 + d * 0x0004) /* Parameters: x2 x1 */ +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(d) (0x000002e0 + d * 0x0004) /* Parameters: y2 y1 */ +# define NV10_TCL_PRIMITIVE_3D_ALPHA_TEST_ENABLE 0x00000300 +# define NV10_TCL_PRIMITIVE_3D_BLEND_ENABLE 0x00000304 +# define NV10_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE 0x00000308 +# define NV10_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE 0x0000030c +# define NV10_TCL_PRIMITIVE_3D_DITHER_ENABLE 0x00000310 +# define NV10_TCL_PRIMITIVE_3D_LIGHTING_ENABLE 0x00000314 +# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETERS_ENABLE 0x00000318 +# define NV10_TCL_PRIMITIVE_3D_POINT_SMOOTH_ENABLE 0x0000031c +# define NV10_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE 0x00000320 +# define NV10_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE 0x00000324 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_WEIGHT_ENABLE 0x00000328 +# define NV10_TCL_PRIMITIVE_3D_STENCIL_TEST_ENABLE 0x0000032c +# define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE 0x00000330 +# define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE 0x00000334 +# define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE 0x00000338 +# define NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC 0x0000033c +# define NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF 0x00000340 +# define NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC 0x00000344 +# define NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_DST 0x00000348 +# define NV10_TCL_PRIMITIVE_3D_BLEND_COLOR 0x0000034c /* Parameters: a r g b */ +# define NV10_TCL_PRIMITIVE_3D_BLEND_EQUATION 0x00000350 +# define NV10_TCL_PRIMITIVE_3D_DEPTH_FUNC 0x00000354 +# define NV10_TCL_PRIMITIVE_3D_COLOR_MASK 0x00000358 /* Parameters: r g b */ +# define NV10_TCL_PRIMITIVE_3D_DEPTH_MASK 0x0000035c +# define NV10_TCL_PRIMITIVE_3D_STENCIL_MASK 0x00000360 +# define NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC 0x00000364 +# define NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_REF 0x00000368 +# define NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_MASK 0x0000036c +# define NV10_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL 0x00000370 +# define NV10_TCL_PRIMITIVE_3D_STENCIL_OP_ZFAIL 0x00000374 +# define NV10_TCL_PRIMITIVE_3D_STENCIL_OP_ZPASS 0x00000378 +# define NV10_TCL_PRIMITIVE_3D_SHADE_MODEL 0x0000037c +# define NV10_TCL_PRIMITIVE_3D_LINE_WIDTH 0x00000380 +# define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR 0x00000384 +# define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_UNITS 0x00000388 +# define NV10_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT 0x0000038c +# define NV10_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK 0x00000390 +# define NV10_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR 0x00000394 +# define NV10_TCL_PRIMITIVE_3D_DEPTH_RANGE_FAR 0x00000398 +# define NV10_TCL_PRIMITIVE_3D_CULL_FACE 0x0000039c +# define NV10_TCL_PRIMITIVE_3D_FRONT_FACE 0x000003a0 +# define NV10_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE 0x000003a4 +# define NV10_TCL_PRIMITIVE_3D_MATERIAL_DIFFUSE_ALPHA 0x000003b4 +# define NV10_TCL_PRIMITIVE_3D_COLOR_CONTROL 0x000003b8 /* Parameters: color_control */ +# define NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS 0x000003bc /* Parameters: light 7 light 6 light 5 light 4 light 3 light 2 light 1 light 0 */ +# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE( d) (0x000003c0 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_VIEW_MATRIX_ENABLE 0x000003e8 /* Parameters: projection modelview0 modelview1 */ +# define NV10_TCL_PRIMITIVE_3D_POINT_SIZE 0x000003ec +# define NV10_TCL_PRIMITIVE_3D_MODELVIEW0_MATRIX( d) (0x00000400 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_MODELVIEW1_MATRIX( d) (0x00000440 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_INVERSE_MODELVIEW0_MATRIX( d) (0x00000480 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_INVERSE_MODELVIEW1_MATRIX( d) (0x000004c0 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_PROJECTION_MATRIX( d) (0x00000500 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_A(d) (0x00000600 + d * 0x0010) +# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_B(d) (0x00000604 + d * 0x0010) +# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_C(d) (0x00000608 + d * 0x0010) +# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_D(d) (0x0000060c + d * 0x0010) +# define NV10_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT 0x00000680 +# define NV10_TCL_PRIMITIVE_3D_FOG_EQUATION_LINEAR 0x00000684 +# define NV10_TCL_PRIMITIVE_3D_FOG_EQUATION_QUADRATIC 0x00000688 +# define NV10_TCL_PRIMITIVE_3D_SHININESS_A 0x000006a0 +# define NV10_TCL_PRIMITIVE_3D_SHININESS_B 0x000006a4 +# define NV10_TCL_PRIMITIVE_3D_SHININESS_C 0x000006a8 +# define NV10_TCL_PRIMITIVE_3D_SHININESS_D 0x000006ac +# define NV10_TCL_PRIMITIVE_3D_SHININESS_E 0x000006b0 +# define NV10_TCL_PRIMITIVE_3D_SHININESS_F 0x000006b4 +# define NV10_TCL_PRIMITIVE_3D_MATERIAL_AMBIENT_EMISSION 0x000006c4 +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X 0x000006e8 +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_Y 0x000006ec +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_Z 0x000006f0 +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_W 0x000006f4 +# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_A 0x000006f8 +# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_B 0x000006fc +# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_C 0x00000700 +# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_D 0x00000704 +# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_E 0x00000708 +# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_F 0x0000070c +# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_G 0x00000710 +# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_H 0x00000714 +# define NV10_TCL_PRIMITIVE_3D_LIGHT_AMBIENT(d) (0x00000800 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_DIFFUSE(d) (0x0000080c + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPECULAR(d) (0x00000818 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR(d) (0x00000828 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION0(d) (0x00000834 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_LIGHT(d) (0x00000840 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION1(d) (0x0000085c + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_NORMAL(d) (0x00000868 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_X 0x00000c00 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_Y 0x00000c04 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_Z 0x00000c08 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_4F_X 0x00000c18 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_4F_Y 0x00000c1c +# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_4F_Z 0x00000c20 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_4F_W 0x00000c24 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_X 0x00000c30 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_Y 0x00000c34 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_Z 0x00000c38 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_XY 0x00000c40 /* Parameters: y x */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_Z 0x00000c44 /* Parameters: z */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4F_R 0x00000c50 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4F_G 0x00000c54 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4F_B 0x00000c58 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4F_A 0x00000c5c +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_3F_R 0x00000c60 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_3F_G 0x00000c64 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_3F_B 0x00000c68 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4I 0x00000c6c /* Parameters: a b g r */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_R 0x00000c80 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_G 0x00000c84 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_B 0x00000c88 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL2_3I 0x00000c8c /* Parameters: a b g r */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_S 0x00000c90 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_T 0x00000c94 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_2I 0x00000c98 /* Parameters: t s */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_S 0x00000ca0 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_T 0x00000ca4 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_R 0x00000ca8 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_Q 0x00000cac +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_ST 0x00000cb0 /* Parameters: t s */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_RQ 0x00000cb4 /* Parameters: q r */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_S 0x00000cb8 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_T 0x00000cbc +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_2I 0x00000cc0 /* Parameters: t s */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_S 0x00000cc8 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_T 0x00000ccc +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_R 0x00000cd0 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_Q 0x00000cd4 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_ST 0x00000cd8 /* Parameters: t s */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_RQ 0x00000cdc /* Parameters: q r */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_FOG_1F 0x00000ce0 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_WGH_1F 0x00000ce4 +# define NV10_TCL_PRIMITIVE_3D_EDGEFLAG_ENABLE 0x00000cec +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_VALIDATE 0x00000cf0 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_POS 0x00000d00 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_POS 0x00000d04 /* Parameters: stride fields type */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_COL 0x00000d08 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_COL 0x00000d0c /* Parameters: stride fields type */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_COL2 0x00000d10 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_COL2 0x00000d14 /* Parameters: stride fields type */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_TX0 0x00000d18 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_TX0 0x00000d1c /* Parameters: stride fields type */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_TX1 0x00000d20 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_TX1 0x00000d24 /* Parameters: stride fields type */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_NOR 0x00000d28 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_NOR 0x00000d2c /* Parameters: stride fields type */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_WGH 0x00000d30 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_WGH 0x00000d34 /* Parameters: stride fields type */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_FOG 0x00000d38 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_FOG 0x00000d3c /* Parameters: stride fields type */ +# define NV10_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE 0x00000d40 +# define NV10_TCL_PRIMITIVE_3D_LOGIC_OP 0x00000d44 +# define NV10_TCL_PRIMITIVE_3D_BEGIN_END 0x00000dfc +# define NV10_TCL_PRIMITIVE_3D_INDEX_DATA 0x00000e00 /* Parameters: index1 index0 */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_BUFFER_BEGIN_END 0x000013fc +# define NV10_TCL_PRIMITIVE_3D_VERTEX_BUFFER_DRAW_ARRAYS 0x00001400 /* Parameters: count-1 first */ +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X 0x00001638 +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_Y 0x0000163c +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_Z 0x00001640 +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_W 0x00001644 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_DATA 0x00001800 + +/****************************************** +Object NV15_TCL_PRIMITIVE_3D used on: NV15 +*/ +#define NV15_TCL_PRIMITIVE_3D 0x00000096 +# define NV10_TCL_PRIMITIVE_3D_NOP 0x00000100 +# define NV10_TCL_PRIMITIVE_3D_NOTIFY 0x00000104 +# define NV10_TCL_PRIMITIVE_3D_SET_DMA_NOTIFY 0x00000180 +# define NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY0 0x00000184 +# define NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY1 0x00000188 +# define NV10_TCL_PRIMITIVE_3D_SET_DISPLAY_LIST 0x0000018c +# define NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY2 0x00000194 +# define NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY3 0x00000198 +# define NV17_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY4 0x000001ac +# define NV17_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY5 0x000001b0 +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ 0x00000200 /* Parameters: width x */ +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_VERT 0x00000204 /* Parameters: height y */ +# define NV10_TCL_PRIMITIVE_3D_BUFFER_FORMAT 0x00000208 /* Parameters: type color */ +# define NV10_TCL_PRIMITIVE_3D_BUFFER_PITCH 0x0000020c /* Parameters: depth/stencil buffer pitch color buffer pitch */ +# define NV10_TCL_PRIMITIVE_3D_COLOR_OFFSET 0x00000210 +# define NV10_TCL_PRIMITIVE_3D_DEPTH_OFFSET 0x00000214 +# define NV10_TCL_PRIMITIVE_3D_TX_OFFSET(d) (0x00000218 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_TX_FORMAT(d) (0x00000220 + d * 0x0004) /* Parameters: wrap_t wrap_s log2(height) log2(width) lod npot format cube_map */ +# define NV10_TCL_PRIMITIVE_3D_TX_ENABLE(d) (0x00000228 + d * 0x0004) /* Parameters: enable anisotropy */ +# define NV10_TCL_PRIMITIVE_3D_TX_NPOT_PITCH(d) (0x00000230 + d * 0x0004) /* Parameters: pitch */ +# define NV10_TCL_PRIMITIVE_3D_TX_NPOT_SIZE(d) (0x00000240 + d * 0x0004) /* Parameters: width height */ +# define NV10_TCL_PRIMITIVE_3D_TX_FILTER(d) (0x00000248 + d * 0x0004) /* Parameters: mag_filter min_filter */ +# define NV10_TCL_PRIMITIVE_3D_RC_IN_ALPHA(d) (0x00000260 + d * 0x0004) /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ +# define NV10_TCL_PRIMITIVE_3D_RC_IN_RGB(d) (0x00000268 + d * 0x0004) /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ +# define NV10_TCL_PRIMITIVE_3D_RC_OUT_ALPHA(d) (0x00000278 + d * 0x0004) /* Parameters: scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ +# define NV10_TCL_PRIMITIVE_3D_RC_OUT_RGB(d) (0x00000280 + d * 0x0004) /* Parameters: rc1_tx_units_enabled rc1_rc_enabled scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ +# define NV10_TCL_PRIMITIVE_3D_TX_MATRIX_ENABLE(d) (0x000003e0 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_TX_MATRIX(x,y) (0x00000540 + y * 0x0010 + x * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_RC_COLOR0 0x00000270 /* Parameters: a r g b */ +# define NV10_TCL_PRIMITIVE_3D_RC_COLOR1 0x00000274 /* Parameters: a r g b */ +# define NV10_TCL_PRIMITIVE_3D_RC_FINAL0 0x00000288 /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ +# define NV10_TCL_PRIMITIVE_3D_RC_FINAL1 0x0000028c /* Parameters: vare_mapping vare_component_usage vare_input varf_mapping varf_component_usage varf_input varg_mapping varg_component_usage varg_input color_sum_clamp */ +# define NV10_TCL_PRIMITIVE_3D_LIGHT_MODEL 0x00000294 /* Parameters: local_viewer color_control */ +# define NV10_TCL_PRIMITIVE_3D_COLOR_MATERIAL 0x00000298 /* Parameters: specular diffuse ambient emission */ +# define NV10_TCL_PRIMITIVE_3D_FOG_MODE 0x0000029c +# define NV10_TCL_PRIMITIVE_3D_FOG_COORD_DIST 0x000002a0 +# define NV10_TCL_PRIMITIVE_3D_FOG_ENABLE 0x000002a4 +# define NV10_TCL_PRIMITIVE_3D_FOG_COLOR 0x000002a8 /* Parameters: a b g r */ +# define NV17_TCL_PRIMITIVE_3D_COLOR_MASK_ENABLE 0x000002bc +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(d) (0x000002c0 + d * 0x0004) /* Parameters: x2 x1 */ +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(d) (0x000002e0 + d * 0x0004) /* Parameters: y2 y1 */ +# define NV10_TCL_PRIMITIVE_3D_ALPHA_TEST_ENABLE 0x00000300 +# define NV10_TCL_PRIMITIVE_3D_BLEND_ENABLE 0x00000304 +# define NV10_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE 0x00000308 +# define NV10_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE 0x0000030c +# define NV10_TCL_PRIMITIVE_3D_DITHER_ENABLE 0x00000310 +# define NV10_TCL_PRIMITIVE_3D_LIGHTING_ENABLE 0x00000314 +# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETERS_ENABLE 0x00000318 +# define NV10_TCL_PRIMITIVE_3D_POINT_SMOOTH_ENABLE 0x0000031c +# define NV10_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE 0x00000320 +# define NV10_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE 0x00000324 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_WEIGHT_ENABLE 0x00000328 +# define NV10_TCL_PRIMITIVE_3D_STENCIL_TEST_ENABLE 0x0000032c +# define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE 0x00000330 +# define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE 0x00000334 +# define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE 0x00000338 +# define NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC 0x0000033c +# define NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF 0x00000340 +# define NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC 0x00000344 +# define NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_DST 0x00000348 +# define NV10_TCL_PRIMITIVE_3D_BLEND_COLOR 0x0000034c /* Parameters: a r g b */ +# define NV10_TCL_PRIMITIVE_3D_BLEND_EQUATION 0x00000350 +# define NV10_TCL_PRIMITIVE_3D_DEPTH_FUNC 0x00000354 +# define NV10_TCL_PRIMITIVE_3D_COLOR_MASK 0x00000358 /* Parameters: r g b */ +# define NV10_TCL_PRIMITIVE_3D_DEPTH_MASK 0x0000035c +# define NV10_TCL_PRIMITIVE_3D_STENCIL_MASK 0x00000360 +# define NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC 0x00000364 +# define NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_REF 0x00000368 +# define NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_MASK 0x0000036c +# define NV10_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL 0x00000370 +# define NV10_TCL_PRIMITIVE_3D_STENCIL_OP_ZFAIL 0x00000374 +# define NV10_TCL_PRIMITIVE_3D_STENCIL_OP_ZPASS 0x00000378 +# define NV10_TCL_PRIMITIVE_3D_SHADE_MODEL 0x0000037c +# define NV10_TCL_PRIMITIVE_3D_LINE_WIDTH 0x00000380 +# define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR 0x00000384 +# define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_UNITS 0x00000388 +# define NV10_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT 0x0000038c +# define NV10_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK 0x00000390 +# define NV10_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR 0x00000394 +# define NV10_TCL_PRIMITIVE_3D_DEPTH_RANGE_FAR 0x00000398 +# define NV10_TCL_PRIMITIVE_3D_CULL_FACE 0x0000039c +# define NV10_TCL_PRIMITIVE_3D_FRONT_FACE 0x000003a0 +# define NV10_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE 0x000003a4 +# define NV10_TCL_PRIMITIVE_3D_MATERIAL_DIFFUSE_ALPHA 0x000003b4 +# define NV10_TCL_PRIMITIVE_3D_COLOR_CONTROL 0x000003b8 /* Parameters: color_control */ +# define NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS 0x000003bc /* Parameters: light 7 light 6 light 5 light 4 light 3 light 2 light 1 light 0 */ +# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE( d) (0x000003c0 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_VIEW_MATRIX_ENABLE 0x000003e8 /* Parameters: projection modelview0 modelview1 */ +# define NV10_TCL_PRIMITIVE_3D_POINT_SIZE 0x000003ec +# define NV10_TCL_PRIMITIVE_3D_MODELVIEW0_MATRIX( d) (0x00000400 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_MODELVIEW1_MATRIX( d) (0x00000440 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_INVERSE_MODELVIEW0_MATRIX( d) (0x00000480 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_INVERSE_MODELVIEW1_MATRIX( d) (0x000004c0 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_PROJECTION_MATRIX( d) (0x00000500 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_A(d) (0x00000600 + d * 0x0010) +# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_B(d) (0x00000604 + d * 0x0010) +# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_C(d) (0x00000608 + d * 0x0010) +# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_D(d) (0x0000060c + d * 0x0010) +# define NV10_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT 0x00000680 +# define NV10_TCL_PRIMITIVE_3D_FOG_EQUATION_LINEAR 0x00000684 +# define NV10_TCL_PRIMITIVE_3D_FOG_EQUATION_QUADRATIC 0x00000688 +# define NV10_TCL_PRIMITIVE_3D_SHININESS_A 0x000006a0 +# define NV10_TCL_PRIMITIVE_3D_SHININESS_B 0x000006a4 +# define NV10_TCL_PRIMITIVE_3D_SHININESS_C 0x000006a8 +# define NV10_TCL_PRIMITIVE_3D_SHININESS_D 0x000006ac +# define NV10_TCL_PRIMITIVE_3D_SHININESS_E 0x000006b0 +# define NV10_TCL_PRIMITIVE_3D_SHININESS_F 0x000006b4 +# define NV10_TCL_PRIMITIVE_3D_MATERIAL_AMBIENT_EMISSION 0x000006c4 +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X 0x000006e8 +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_Y 0x000006ec +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_Z 0x000006f0 +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_W 0x000006f4 +# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_A 0x000006f8 +# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_B 0x000006fc +# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_C 0x00000700 +# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_D 0x00000704 +# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_E 0x00000708 +# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_F 0x0000070c +# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_G 0x00000710 +# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_H 0x00000714 +# define NV10_TCL_PRIMITIVE_3D_LIGHT_AMBIENT(d) (0x00000800 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_DIFFUSE(d) (0x0000080c + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPECULAR(d) (0x00000818 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR(d) (0x00000828 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION0(d) (0x00000834 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_LIGHT(d) (0x00000840 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION1(d) (0x0000085c + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_NORMAL(d) (0x00000868 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_X 0x00000c00 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_Y 0x00000c04 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_Z 0x00000c08 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_4F_X 0x00000c18 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_4F_Y 0x00000c1c +# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_4F_Z 0x00000c20 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_4F_W 0x00000c24 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_X 0x00000c30 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_Y 0x00000c34 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_Z 0x00000c38 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_XY 0x00000c40 /* Parameters: y x */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_Z 0x00000c44 /* Parameters: z */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4F_R 0x00000c50 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4F_G 0x00000c54 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4F_B 0x00000c58 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4F_A 0x00000c5c +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_3F_R 0x00000c60 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_3F_G 0x00000c64 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_3F_B 0x00000c68 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4I 0x00000c6c /* Parameters: a b g r */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_R 0x00000c80 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_G 0x00000c84 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_B 0x00000c88 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL2_3I 0x00000c8c /* Parameters: a b g r */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_S 0x00000c90 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_T 0x00000c94 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_2I 0x00000c98 /* Parameters: t s */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_S 0x00000ca0 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_T 0x00000ca4 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_R 0x00000ca8 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_Q 0x00000cac +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_ST 0x00000cb0 /* Parameters: t s */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_RQ 0x00000cb4 /* Parameters: q r */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_S 0x00000cb8 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_T 0x00000cbc +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_2I 0x00000cc0 /* Parameters: t s */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_S 0x00000cc8 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_T 0x00000ccc +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_R 0x00000cd0 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_Q 0x00000cd4 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_ST 0x00000cd8 /* Parameters: t s */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_RQ 0x00000cdc /* Parameters: q r */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_FOG_1F 0x00000ce0 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_WGH_1F 0x00000ce4 +# define NV10_TCL_PRIMITIVE_3D_EDGEFLAG_ENABLE 0x00000cec +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ATTR( d) (0x00000d04 + d * 0x0008) +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_VALIDATE 0x00000cf0 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_POS 0x00000d00 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_POS 0x00000d04 /* Parameters: stride fields type */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_COL 0x00000d08 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_COL 0x00000d0c /* Parameters: stride fields type */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_COL2 0x00000d10 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_COL2 0x00000d14 /* Parameters: stride fields type */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_TX0 0x00000d18 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_TX0 0x00000d1c /* Parameters: stride fields type */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_TX1 0x00000d20 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_TX1 0x00000d24 /* Parameters: stride fields type */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_NOR 0x00000d28 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_NOR 0x00000d2c /* Parameters: stride fields type */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_WGH 0x00000d30 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_WGH 0x00000d34 /* Parameters: stride fields type */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_FOG 0x00000d38 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_FOG 0x00000d3c /* Parameters: stride fields type */ +# define NV10_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE 0x00000d40 +# define NV10_TCL_PRIMITIVE_3D_LOGIC_OP 0x00000d44 +# define NV17_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH 0x00000d5c /* Parameters: pitch */ +# define NV17_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_OFFSET 0x00000d60 +# define NV17_TCL_PRIMITIVE_3D_LMA_DEPTH_FILL_VALUE 0x00000d68 +# define NV17_TCL_PRIMITIVE_3D_LMA_DEPTH_CLEAR_ENABLE 0x00000d6c +# define NV10_TCL_PRIMITIVE_3D_BEGIN_END 0x00000dfc +# define NV10_TCL_PRIMITIVE_3D_INDEX_DATA 0x00000e00 /* Parameters: index1 index0 */ +# define NV10_TCL_PRIMITIVE_3D_VERTEX_BUFFER_BEGIN_END 0x000013fc +# define NV10_TCL_PRIMITIVE_3D_VERTEX_BUFFER_DRAW_ARRAYS 0x00001400 /* Parameters: count-1 first */ +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X 0x00001638 +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_Y 0x0000163c +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_Z 0x00001640 +# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_W 0x00001644 +# define NV17_TCL_PRIMITIVE_3D_LMA_DEPTH_ENABLE 0x00001658 +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_DATA 0x00001800 + +/****************************************** +Object NV10_IMAGE_FROM_CPU used on: NV10 NV15 NV20 NV30 NV40 G70 +*/ +#define NV10_IMAGE_FROM_CPU 0x0000008a +# define NV10_IMAGE_FROM_CPU_SET_DMA_NOTIFY 0x00000180 +# define NV10_IMAGE_FROM_CPU_SET_CONTEXT_CLIP_RECTANGLE 0x00000188 +# define NV10_IMAGE_FROM_CPU_SET_IMAGE_PATTERN 0x0000018c +# define NV10_IMAGE_FROM_CPU_SET_RASTER_OP 0x00000190 +# define NV10_IMAGE_FROM_CPU_SET_CONTEXT_SURFACES_2D 0x0000019c +# define NV10_IMAGE_FROM_CPU_OPERATION 0x000002fc +# define NV10_IMAGE_FROM_CPU_FORMAT 0x00000300 +# define NV10_IMAGE_FROM_CPU_POINT 0x00000304 /* Parameters: x y */ +# define NV10_IMAGE_FROM_CPU_SIZE_OUT 0x00000308 /* Parameters: width height */ +# define NV10_IMAGE_FROM_CPU_SIZE_IN 0x0000030c /* Parameters: width height */ +# define NV10_IMAGE_FROM_CPU_HLINE 0x00000400 + +/****************************************** +Object NV10_PRIMITIVE_2D used on: NV10 NV15 NV20 NV30 NV40 G70 +*/ +#define NV10_PRIMITIVE_2D 0x0000007b +# define NV10_PRIMITIVE_2D_SET_DMA_NOTIFY 0x00000180 +# define NV10_PRIMITIVE_2D_SET_SURFACE 0x00000184 +# define NV10_PRIMITIVE_2D_SET_FORMAT 0x00000300 +# define NV10_PRIMITIVE_2D_SET_POINT 0x00000304 /* Parameters: x y */ +# define NV10_PRIMITIVE_2D_SET_SIZE 0x00000308 /* Parameters: width height */ +# define NV10_PRIMITIVE_2D_SET_CLIP_HORIZ 0x0000030c /* Parameters: width x */ +# define NV10_PRIMITIVE_2D_SET_CLIP_VERT 0x00000310 /* Parameters: height y */ +# define NV10_PRIMITIVE_2D_SET_DATA( d) (0x00000400 + d * 0x0004) + +/****************************************** +Object NV10_IMAGE_BLIT used on: NV10 NV15 NV20 NV30 NV40 G70 +*/ +#define NV10_IMAGE_BLIT 0x0000009f +# define NV10_IMAGE_BLIT_NOP 0x00000100 +# define NV10_IMAGE_BLIT_NOTIFY 0x00000104 +# define NV10_IMAGE_BLIT_SET_DMA_NOTIFY 0x00000180 +# define NV10_IMAGE_BLIT_SET_CONTEXT_CLIP_RECTANGLE 0x00000188 +# define NV10_IMAGE_BLIT_SET_IMAGE_PATTERN 0x0000018c +# define NV10_IMAGE_BLIT_SET_RASTER_OP 0x00000190 +# define NV10_IMAGE_BLIT_SET_CONTEXT_SURFACES_2D 0x0000019c +# define NV10_IMAGE_BLIT_SET_OPERATION 0x000002fc +# define NV10_IMAGE_BLIT_SET_POINT 0x00000300 /* Parameters: x y */ +# define NV10_IMAGE_BLIT_SET_PITCH 0x00000304 /* Parameters: skip */ +# define NV10_IMAGE_BLIT_SET_SIZE 0x00000308 /* Parameters: width height */ + +/****************************************** +Object NV10_VIDEO_DISPLAY used on: NV10 NV15 NV20 NV30 NV40 G70 +*/ +#define NV10_VIDEO_DISPLAY 0x0000007c +# define NV10_VIDEO_DISPLAY_COUNTER 0x00000050 +# define NV10_VIDEO_DISPLAY_SET_DMA_FROM_MEMORY 0x00000180 +# define NV10_VIDEO_DISPLAY_SET_DMA_IN_MEMORY0 0x00000184 +# define NV10_VIDEO_DISPLAY_SET_DMA_IN_MEMORY1 0x00000188 +# define NV10_VIDEO_DISPLAY_SET_OBJECT3 0x0000019c +# define NV10_VIDEO_DISPLAY_SIZE 0x000002f8 /* Parameters: height width */ +# define NV10_VIDEO_DISPLAY_OFFSET 0x00000300 + +/****************************************** +Object NV10_UNK0072 used on: NV10 NV15 NV20 NV40 G70 +*/ +#define NV10_UNK0072 0x00000072 +# define NV10_UNK0072_COUNTER 0x00000050 +# define NV10_UNK0072_SET_DMA_NOTIFY 0x00000180 + +/****************************************** +Object NV10_SCALED_IMAGE_FROM_MEMORY used on: NV10 NV15 NV20 NV30 NV40 G70 +*/ +#define NV10_SCALED_IMAGE_FROM_MEMORY 0x00000089 +# define NV10_SCALED_IMAGE_FROM_MEMORY_COUNTER 0x00000050 +# define NV10_SCALED_IMAGE_FROM_MEMORY_SET_DMA_IN_MEMORY 0x00000184 +# define NV10_SCALED_IMAGE_FROM_MEMORY_SET_RASTER_OP 0x0000018c +# define NV10_SCALED_IMAGE_FROM_MEMORY_SET_IMAGE_PATTERN 0x00000188 +# define NV10_SCALED_IMAGE_FROM_MEMORY_SET_SURFACE 0x00000198 +# define NV10_SCALED_IMAGE_FROM_MEMORY_OPERATION 0x00000304 +# define NV10_SCALED_IMAGE_FROM_MEMORY_CLIP_POS 0x00000308 /* Parameters: x y */ +# define NV10_SCALED_IMAGE_FROM_MEMORY_CLIP_SIZE 0x0000030c /* Parameters: width height */ +# define NV10_SCALED_IMAGE_FROM_MEMORY_OUT_POS 0x00000310 /* Parameters: x y */ +# define NV10_SCALED_IMAGE_FROM_MEMORY_OUT_SIZE 0x00000314 /* Parameters: width height */ +# define NV10_SCALED_IMAGE_FROM_MEMORY_SIZE 0x00000400 /* Parameters: width height */ +# define NV10_SCALED_IMAGE_FROM_MEMORY_FORMAT 0x00000404 /* Parameters: pitch */ +# define NV10_SCALED_IMAGE_FROM_MEMORY_OFFSET 0x00000408 +# define NV10_SCALED_IMAGE_FROM_MEMORY_POINT 0x0000040c /* Parameters: u_int u_frac*0x10 v_int v_frac*0x10 */ + +/****************************************** +Object NV10_CONTEXT_SURFACES_2D used on: NV10 NV15 NV20 NV30 NV40 G70 +*/ +#define NV10_CONTEXT_SURFACES_2D 0x00000062 +# define NV10_CONTEXT_SURFACES_2D_SET_DMA_NOTIFY 0x00000180 +# define NV10_CONTEXT_SURFACES_2D_SET_DMA_IN_MEMORY0 0x00000184 +# define NV10_CONTEXT_SURFACES_2D_SET_DMA_IN_MEMORY1 0x00000188 +# define NV10_CONTEXT_SURFACES_2D_FORMAT 0x00000300 /* Parameters: color type width height */ +# define NV10_CONTEXT_SURFACES_2D_PITCH 0x00000304 /* Parameters: src dst */ +# define NV10_CONTEXT_SURFACES_2D_OFFSET_SRC 0x00000308 +# define NV10_CONTEXT_SURFACES_2D_OFFSET_DST 0x0000030c + +/****************************************** +Object NV04_SURFACE used on: NV04 NV10 NV15 +*/ +#define NV04_SURFACE 0x00000042 +# define NV04_SURFACE_NOTIFY 0x00000104 +# define NV04_SURFACE_DMA_NOTIFY 0x00000180 +# define NV04_SURFACE_DMA_IMAGE_SOURCE 0x00000184 +# define NV04_SURFACE_DMA_IMAGE_DESTIN 0x00000188 +# define NV04_SURFACE_FORMAT 0x00000300 +# define NV04_SURFACE_PITCH 0x00000304 /* Parameters: source destin */ +# define NV04_SURFACE_OFFSET_SOURCE 0x00000308 +# define NV04_SURFACE_OFFSET_DESTIN 0x0000030c + +/****************************************** +Object NV04_IMAGE_PATTERN used on: NV04 NV10 NV15 NV20 NV30 NV40 G70 +*/ +#define NV04_IMAGE_PATTERN 0x00000044 +# define NV04_IMAGE_PATTERN_COLOR_FORMAT 0x00000300 +# define NV04_IMAGE_PATTERN_MONO_FORMAT 0x00000304 +# define NV04_IMAGE_PATTERN_SELECT 0x0000030c +# define NV04_IMAGE_PATTERN_MONOCHROME_SHAPE 0x00000308 +# define NV04_IMAGE_PATTERN_MONOCHROME_COLOR0 0x00000310 +# define NV04_IMAGE_PATTERN_MONOCHROME_COLOR1 0x00000314 +# define NV04_IMAGE_PATTERN_MONOCHROME_PATTERN0 0x00000318 +# define NV04_IMAGE_PATTERN_MONOCHROME_PATTERN1 0x0000031c + +/****************************************** +Object NV20_SWIZZLED_SURFACE used on: NV20 NV30 NV40 G70 +*/ +#define NV20_SWIZZLED_SURFACE 0x0000009e +# define NV20_SWIZZLED_SURFACE_SET_OBJECT0 0x00000180 +# define NV20_SWIZZLED_SURFACE_SET_OBJECT1 0x00000184 +# define NV20_SWIZZLED_SURFACE_FORMAT 0x00000300 /* Parameters: log2(height) log2(width) color */ +# define NV20_SWIZZLED_SURFACE_OFFSET 0x00000304 + +/****************************************** +Object NV20_TCL_PRIMITIVE_3D used on: NV20 +*/ +#define NV20_TCL_PRIMITIVE_3D 0x00000097 +# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT0 0x00000180 +# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT1 0x00000184 +# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT2 0x00000188 +# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT3 0x00000194 +# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT4 0x00000198 +# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT5 0x0000019c +# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT6 0x000001a0 +# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT7 0x000001a4 +# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT8 0x000001a8 +# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT9 0x000001ac +# define NV20_TCL_PRIMITIVE_3D_SET_OBJECT10 0x000001b0 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ 0x00000200 /* Parameters: width x */ +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_VERT 0x00000204 /* Parameters: height y */ +# define NV20_TCL_PRIMITIVE_3D_BUFFER_FORMAT 0x00000208 /* Parameters: type color */ +# define NV20_TCL_PRIMITIVE_3D_BUFFER_PITCH 0x0000020c /* Parameters: depth/stencil buffer pitch color buffer pitch */ +# define NV20_TCL_PRIMITIVE_3D_COLOR_OFFSET 0x00000210 +# define NV20_TCL_PRIMITIVE_3D_DEPTH_OFFSET 0x00000214 +# define NV20_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH 0x0000022c /* Parameters: pitch */ +# define NV20_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_OFFSET 0x00000230 +# define NV20_TCL_PRIMITIVE_3D_LIGHT_CONTROL 0x00000294 +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_CONTROL 0x00000298 /* Parameters: back_specular back_ambient back_diffuse back_emission front_specular front_ambient front_diffuse front_emission */ +# define NV20_TCL_PRIMITIVE_3D_FOG_MODE 0x0000029c +# define NV20_TCL_PRIMITIVE_3D_FOG_COORD_DIST 0x000002a0 +# define NV20_TCL_PRIMITIVE_3D_ALPHA_TEST_ENABLE 0x00000300 +# define NV20_TCL_PRIMITIVE_3D_BLEND_ENABLE 0x00000304 +# define NV20_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE 0x00000308 +# define NV20_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE 0x0000030c +# define NV20_TCL_PRIMITIVE_3D_DITHER_ENABLE 0x00000310 +# define NV20_TCL_PRIMITIVE_3D_LIGHTING_ENABLE 0x00000314 +# define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETERS_ENABLE 0x00000318 +# define NV20_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE 0x00000320 +# define NV20_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE 0x00000324 +# define NV20_TCL_PRIMITIVE_3D_STENCIL_TEST_ENABLE 0x0000032c +# define NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE 0x00000330 +# define NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE 0x00000334 +# define NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE 0x00000338 +# define NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC 0x0000033c +# define NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF 0x00000340 +# define NV20_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC 0x00000344 +# define NV20_TCL_PRIMITIVE_3D_BLEND_FUNC_DST 0x00000348 +# define NV20_TCL_PRIMITIVE_3D_BLEND_COLOR 0x0000034c /* Parameters: a r g b */ +# define NV20_TCL_PRIMITIVE_3D_BLEND_EQUATION 0x00000350 +# define NV20_TCL_PRIMITIVE_3D_DEPTH_FUNC 0x00000354 +# define NV20_TCL_PRIMITIVE_3D_COLOR_MASK 0x00000358 /* Parameters: a r g b */ +# define NV20_TCL_PRIMITIVE_3D_DEPTH_MASK 0x0000035c +# define NV20_TCL_PRIMITIVE_3D_STENCIL_MASK 0x00000360 +# define NV20_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC 0x00000364 +# define NV20_TCL_PRIMITIVE_3D_STENCIL_FUNC_REF 0x00000368 +# define NV20_TCL_PRIMITIVE_3D_STENCIL_FUNC_MASK 0x0000036c +# define NV20_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL 0x00000370 +# define NV20_TCL_PRIMITIVE_3D_STENCIL_OP_ZFAIL 0x00000374 +# define NV20_TCL_PRIMITIVE_3D_STENCIL_OP_ZPASS 0x00000378 +# define NV20_TCL_PRIMITIVE_3D_SHADE_MODEL 0x0000037c +# define NV20_TCL_PRIMITIVE_3D_LINE_WIDTH 0x00000380 +# define NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR 0x00000384 +# define NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_UNITS 0x00000388 +# define NV20_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT 0x0000038c +# define NV20_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK 0x00000390 +# define NV20_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR 0x00000394 +# define NV20_TCL_PRIMITIVE_3D_DEPTH_RANGE_FAR 0x00000398 +# define NV20_TCL_PRIMITIVE_3D_CULL_FACE 0x0000039c +# define NV20_TCL_PRIMITIVE_3D_FRONT_FACE 0x000003a0 +# define NV20_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE 0x000003a4 +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT 0x000003a8 +# define NV20_TCL_PRIMITIVE_3D_SEPARATE_SPECULAR_ENABLE 0x000003b8 +# define NV20_TCL_PRIMITIVE_3D_ENABLED_LIGHTS 0x000003bc /* Parameters: light 7 light 6 light 5 light 4 light 3 light 2 light 1 light 0 */ +# define NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(d) (0x000003c0 + d * 0x0004) +# define NV20_TCL_PRIMITIVE_3D_TX_MATRIX_ENABLE(d) (0x00000420 + d * 0x0004) +# define NV20_TCL_PRIMITIVE_3D_POINT_SIZE 0x0000043c +# define NV20_TCL_PRIMITIVE_3D_MODELVIEW_MATRIX( d) (0x00000480 + d * 0x0004) +# define NV20_TCL_PRIMITIVE_3D_INVERSE_MODELVIEW_MATRIX( d) (0x00000580 + d * 0x0004) +# define NV20_TCL_PRIMITIVE_3D_PROJECTION_MATRIX( d) (0x00000680 + d * 0x0004) +# define NV20_TCL_PRIMITIVE_3D_TX_MATRIX(x,y) (0x000006c0 + y * 0x0010 + x * 0x0004) +# define NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_A(d) (0x00000840 + d * 0x0010) +# define NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_B(d) (0x00000844 + d * 0x0010) +# define NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_C(d) (0x00000848 + d * 0x0010) +# define NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_D(d) (0x0000084c + d * 0x0010) +# define NV20_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT 0x000009c0 +# define NV20_TCL_PRIMITIVE_3D_FOG_EQUATION_LINEAR 0x000009c4 +# define NV20_TCL_PRIMITIVE_3D_FOG_EQUATION_QUADRATIC 0x000009c8 +# define NV20_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS 0x000009e0 +# define NV20_TCL_PRIMITIVE_3D_POINT_SPRITE 0x00000a1c /* Parameters: coord_replace r_mode enable */ +# define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_A 0x00000a30 +# define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_B 0x00000a34 +# define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_C 0x00000a38 +# define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_D 0x00000a3c +# define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_E 0x00000a40 +# define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_F 0x00000a44 +# define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_G 0x00000a48 +# define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_H 0x00000a4c +# define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_INST0 0x00000b00 +# define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_INST1 0x00000b04 +# define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_INST2 0x00000b08 +# define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_INST3 0x00000b0c +# define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_X 0x00000b80 +# define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_Y 0x00000b84 +# define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_Z 0x00000b88 +# define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_W 0x00000b8c +# define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_ID 0x00001ea4 +# define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION 0x00000a10 +# define NV20_TCL_PRIMITIVE_3D_TX_OFFSET(d) (0x00001b00 + d * 0x0040) +# define NV20_TCL_PRIMITIVE_3D_TX_FORMAT(d) (0x00001b04 + d * 0x0040) /* Parameters: log2(height) log2(width) lod format cube_map */ +# define NV20_TCL_PRIMITIVE_3D_TX_ENABLE(d) (0x00001b0c + d * 0x0040) /* Parameters: enable anisotropy */ +# define NV20_TCL_PRIMITIVE_3D_TX_NPOT_PITCH(d) (0x00001b10 + d * 0x0040) /* Parameters: pitch */ +# define NV20_TCL_PRIMITIVE_3D_TX_FILTER(d) (0x00001b14 + d * 0x0040) /* Parameters: mag_filter min_filter */ +# define NV20_TCL_PRIMITIVE_3D_TX_NPOT_SIZE(d) (0x00001b1c + d * 0x0040) /* Parameters: width height */ +# define NV20_TCL_PRIMITIVE_3D_TX_SHADER_OP 0x00001e70 /* Parameters: op0 op1 op2 op3 */ +# define NV20_TCL_PRIMITIVE_3D_TX_SHADER_CULL_MODE 0x000017f8 /* Parameters: cull0 cull1 cull2 cull3 */ +# define NV20_TCL_PRIMITIVE_3D_TX_SHADER_PREVIOUS 0x00001e78 /* Parameters: prev2 prev3 */ +# define NV20_TCL_PRIMITIVE_3D_RC_COLOR0 0x00001e20 /* Parameters: a r g b */ +# define NV20_TCL_PRIMITIVE_3D_RC_COLOR1 0x00001e24 /* Parameters: a r g b */ +# define NV20_TCL_PRIMITIVE_3D_RC_FINAL0 0x00000288 /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ +# define NV20_TCL_PRIMITIVE_3D_RC_FINAL1 0x0000028c /* Parameters: vare_mapping vare_component_usage vare_input varf_mapping varf_component_usage varf_input varg_mapping varg_component_usage varg_input color_sum_clamp */ +# define NV20_TCL_PRIMITIVE_3D_RC_IN_ALPHA(d) (0x00000260 + d * 0x0004) /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ +# define NV20_TCL_PRIMITIVE_3D_RC_IN_RGB(d) (0x00000ac0 + d * 0x0004) /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ +# define NV20_TCL_PRIMITIVE_3D_RC_OUT_ALPHA(d) (0x00000aa0 + d * 0x0004) /* Parameters: scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ +# define NV20_TCL_PRIMITIVE_3D_RC_OUT_RGB(d) (0x00001e40 + d * 0x0004) /* Parameters: scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ +# define NV20_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(d) (0x0000105c + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_POSITION_Y(d) (0x00001060 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_POSITION_Z(d) (0x00001064 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_HVEC_AND_DIR(d) (0x00001028 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_A(d) (0x00001000 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_B(d) (0x00001004 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_C(d) (0x00001008 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_A(d) (0x0000100c + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_B(d) (0x00001010 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_C(d) (0x00001014 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_A(d) (0x00001018 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_B(d) (0x0000101c + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_C(d) (0x00001020 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_BACK_SIDE_PRODUCT_AMBIENT(d) (0x00000c00 + d * 0x0040) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_BACK_SIDE_PRODUCT_DIFFUSE(d) (0x00000c0c + d * 0x0040) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_BACK_SIDE_PRODUCT_SPECULAR(d) (0x00000c18 + d * 0x0040) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(d) (0x00001068 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(d) (0x0000106c + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(d) (0x00001070 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(d) (0x00001040 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(d) (0x00001044 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(d) (0x00001048 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(d) (0x0000104c + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_Y(d) (0x00001050 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_Z(d) (0x00001054 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(d) (0x00001058 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS 0x00001e28 +# define NV20_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE 0x0000147c +# define NV20_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(d) (0x00001480 + d * 0x0004) +# define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_3F_X 0x00001500 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_3F_Y 0x00001504 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_3F_Z 0x00001508 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_4F_X 0x00001518 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_4F_Y 0x0000151c +# define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_4F_Z 0x00001520 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_4F_W 0x00001524 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_4I_XY 0x00001528 /* Parameters: y x */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_4I_ZW 0x0000152c /* Parameters: w z */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_X 0x00001530 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_Y 0x00001534 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_Z 0x00001538 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_XY 0x00001540 /* Parameters: y x */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_Z 0x00001544 /* Parameters: z */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL_4F_R 0x00001550 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL_4F_G 0x00001554 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL_4F_B 0x00001558 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL_4F_A 0x0000155c +# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL_3F_R 0x00001560 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL_3F_G 0x00001564 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL_3F_B 0x00001568 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL_4I 0x0000156c /* Parameters: a b g r */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_R 0x00001580 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_G 0x00001584 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_B 0x00001588 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_COL2_3I 0x0000158c /* Parameters: a b g r */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_S 0x00001590 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_T 0x00001594 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX0_2I 0x00001598 /* Parameters: t s */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_S 0x000015a0 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_T 0x000015a4 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_R 0x000015a8 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_Q 0x000015ac +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_ST 0x000015b0 /* Parameters: t s */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_RQ 0x000015b4 /* Parameters: q r */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_S 0x000015b8 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_T 0x000015bc +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX1_2I 0x000015c0 /* Parameters: t s */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_S 0x000015c8 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_T 0x000015cc +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_R 0x000015d0 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_Q 0x000015d4 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_ST 0x000015d8 /* Parameters: t s */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_RQ 0x000015dc /* Parameters: q r */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX2_2F_S 0x000015e0 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX2_2F_T 0x000015e4 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX2_2I 0x000015e8 /* Parameters: t s */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX2_4F_S 0x000015f0 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX2_4F_T 0x000015f4 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX2_4F_R 0x000015f8 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX2_4F_Q 0x000015fc +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX2_4I_ST 0x00001600 /* Parameters: t s */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX2_4I_RQ 0x00001604 /* Parameters: q r */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX3_2F_S 0x00001608 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX3_2F_T 0x0000160c +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX3_2I 0x00001610 /* Parameters: t s */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX3_4F_S 0x00001620 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX3_4F_T 0x00001624 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX3_4F_R 0x00001628 +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX3_4F_Q 0x0000162c +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX3_4I_ST 0x00001630 /* Parameters: t s */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_TX3_4I_RQ 0x00001634 /* Parameters: q r */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_FOG_1F 0x00001698 +# define NV20_TCL_PRIMITIVE_3D_EDGE_FLAG 0x000016bc +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR0_POS 0x00001720 /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR1_WGH 0x00001724 /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR2_NOR 0x00001728 /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR3_COL 0x0000172c /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR4_COL2 0x00001730 /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR5_FOG 0x00001734 /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR6 0x00001738 /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR7 0x0000173c /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR8_TX0 0x00001740 /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR9_TX1 0x00001744 /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR10_TX2 0x00001748 /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR11_TX3 0x0000174c /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR12_TX4 0x00001750 /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR13_TX5 0x00001754 /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR14_TX6 0x00001758 /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VB_POINTER_ATTR15_TX7 0x0000175c /* Parameters: enabled? offset */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR( d) (0x00001760 + d * 0x0004) +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR0_POS 0x00001760 /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR1_WGH 0x00001764 /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR2_NOR 0x00001768 /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR3_COL 0x0000176c /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR4_COL2 0x00001770 /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR5_FOG 0x00001774 /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR6 0x00001778 /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR7 0x0000177c /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR8_TX0 0x00001780 /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR9_TX1 0x00001784 /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR10_TX2 0x00001788 /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR11_TX3 0x0000178c /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR12_TX4 0x00001790 /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR13_TX5 0x00001794 /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR14_TX6 0x00001798 /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR15_TX7 0x0000179c /* Parameters: stride fields type */ +# define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION 0x000017a0 +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK 0x000017b0 +# define NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE 0x000017bc +# define NV20_TCL_PRIMITIVE_3D_LOGIC_OP 0x000017c0 +# define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_TWO_SIDE_ENABLE 0x000017c4 +# define NV20_TCL_PRIMITIVE_3D_BEGIN_END 0x000017fc +# define NV20_TCL_PRIMITIVE_3D_CLEAR_COLOR 0x00001d90 +# define NV20_TCL_PRIMITIVE_3D_CLEAR_MASK 0x00001d94 /* Parameters: clear color a clear color b clear color g clear color r clear depth clear stencil */ +# define NV20_TCL_PRIMITIVE_3D_INDEX_DATA 0x00001800 /* Parameters: index1 index0 */ +# define NV20_TCL_PRIMITIVE_3D_VB_VERTEX_BATCH 0x00001810 /* Parameters: count_vertices offset_vertices */ +# define NV20_TCL_PRIMITIVE_3D_VERTEX_DATA 0x00001818 + +/****************************************** +Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 +*/ +#define NV30_TCL_PRIMITIVE_3D 0x00000097 +# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT0 0x00000180 +# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT1 0x00000184 +# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT2 0x00000188 +# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT3 0x0000018c +# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT4 0x00000194 +# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT5 0x00000198 +# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT6 0x000001a4 +# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT7 0x000001a8 +# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT8 0x000001ac +# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT9 0x000001b4 +# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT10 0x000001b8 +# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT11 0x0000019c +# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT12 0x000001a0 +# define NV30_TCL_PRIMITIVE_3D_BUFFER0_PITCH 0x0000020c /* Parameters: depth/stencil buffer pitch color0 buffer pitch */ +# define NV30_TCL_PRIMITIVE_3D_COLOR0_OFFSET 0x00000210 +# define NV30_TCL_PRIMITIVE_3D_DEPTH_OFFSET 0x00000214 +# define NV30_TCL_PRIMITIVE_3D_COLOR1_OFFSET 0x00000218 +# define NV30_TCL_PRIMITIVE_3D_BUFFER1_PITCH 0x0000021c /* Parameters: color1 buffer pitch */ +# define NV30_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH 0x0000022c /* Parameters: pitch */ +# define NV30_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_OFFSET 0x00000230 +# define NV30_TCL_PRIMITIVE_3D_TX_MATRIX_ENABLE(d) (0x00000240 + d * 0x0004) +# define NV30_TCL_PRIMITIVE_3D_BUFFER2_PITCH 0x00000280 +# define NV30_TCL_PRIMITIVE_3D_BUFFER3_PITCH 0x00000284 +# define NV30_TCL_PRIMITIVE_3D_BUFFER2_OFFSET 0x00000288 +# define NV30_TCL_PRIMITIVE_3D_BUFFER3_OFFSET 0x0000028c +# define NV30_TCL_PRIMITIVE_3D_DITHER_ENABLE 0x00000300 +# define NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE 0x00000304 +# define NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC 0x00000308 +# define NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF 0x0000030c +# define NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE 0x00000310 +# define NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC 0x00000314 +# define NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_DST 0x00000318 +# define NV30_TCL_PRIMITIVE_3D_BLEND_COLOR 0x0000031c /* Parameters: a r g b */ +# define NV30_TCL_PRIMITIVE_3D_BLEND_EQUATION 0x00000320 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MASK 0x00000324 /* Parameters: a r g b */ +# define NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_ENABLE 0x00000328 +# define NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_MASK 0x0000032c +# define NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_FUNC 0x00000330 +# define NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_REF 0x00000334 +# define NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_MASK 0x00000338 +# define NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_FAIL 0x0000033c +# define NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_ZFAIL 0x00000340 +# define NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_ZPASS 0x00000344 +# define NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_ENABLE 0x00000348 +# define NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_MASK 0x0000034c +# define NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_FUNC 0x00000350 +# define NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_REF 0x00000354 +# define NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_MASK 0x00000358 +# define NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_FAIL 0x0000035c +# define NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_ZFAIL 0x00000360 +# define NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_ZPASS 0x00000364 +# define NV30_TCL_PRIMITIVE_3D_SHADE_MODEL 0x00000368 +# define NV30_TCL_PRIMITIVE_3D_FOG_ENABLE 0x0000036c +# define NV40_TCL_PRIMITIVE_3D_COLOR_MASK_BUFFER123 0x00000370 /* Parameters: buffer3 b buffer3 g buffer3 r buffer3 a buffer2 b buffer2 g buffer2 r buffer2 a buffer1 b buffer1 g buffer1 r buffer1 a */ +# define NV30_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE 0x0000037c +# define NV30_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR 0x00000394 +# define NV30_TCL_PRIMITIVE_3D_DEPTH_RANGE_FAR 0x00000398 +# define NV30_TCL_PRIMITIVE_3D_LINE_WIDTH_SMOOTH 0x000003b8 +# define NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(d) (0x00000400 + d * 0x0004) +# define NV30_TCL_PRIMITIVE_3D_MODELVIEW_MATRIX( d) (0x00000480 + d * 0x0004) +# define NV30_TCL_PRIMITIVE_3D_INVERSE_MODELVIEW_MATRIX( d) (0x00000580 + d * 0x0004) +# define NV30_TCL_PRIMITIVE_3D_PROJECTION_MATRIX( d) (0x00000680 + d * 0x0004) +# define NV30_TCL_PRIMITIVE_3D_TX_MATRIX(x,y) (0x000006c0 + y * 0x0010 + x * 0x0004) +# define NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM 0x000008e4 +# define NV30_TCL_PRIMITIVE_3D_FOG_COORD_DIST 0x000008c8 +# define NV30_TCL_PRIMITIVE_3D_FOG_MODE 0x000008cc +# define NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT 0x000008d0 +# define NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_LINEAR 0x000008d4 +# define NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_QUADRATIC 0x000008d8 +# define NV30_TCL_PRIMITIVE_3D_RC_FINAL0 0x000008f4 /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ +# define NV30_TCL_PRIMITIVE_3D_RC_FINAL1 0x000008f8 /* Parameters: vare_mapping vare_component_usage vare_input varf_mapping varf_component_usage varf_input varg_mapping varg_component_usage varg_input color_sum_clamp */ +# define NV30_TCL_PRIMITIVE_3D_RC_IN_ALPHA 0x00000900 /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ +# define NV30_TCL_PRIMITIVE_3D_RC_IN_RGB 0x00000904 /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ +# define NV30_TCL_PRIMITIVE_3D_RC_OUT_ALPHA 0x00000910 /* Parameters: scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ +# define NV30_TCL_PRIMITIVE_3D_RC_OUT_RGB 0x00000914 /* Parameters: scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_DIM0 0x00000200 /* Parameters: width x_offset */ +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_DIM1 0x00000204 /* Parameters: height y_offset */ +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_OFS0 0x000002c0 /* Parameters: width x_offset */ +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_OFS1 0x000002c4 /* Parameters: height y_offset */ +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_0 0x00000a00 /* Parameters: width x_offset */ +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_1 0x00000a04 /* Parameters: height y_offset */ +# define NV30_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS 0x000008c0 /* Parameters: width x_offset */ +# define NV30_TCL_PRIMITIVE_3D_SCISSOR_HEIGHT_YPOS 0x000008c4 /* Parameters: height y_offset */ +# define NV30_TCL_PRIMITIVE_3D_POINT_SPRITE 0x00001ee8 /* Parameters: coord_replace r_mode enable */ +# define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_A 0x00001ec0 +# define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_B 0x00001ec4 +# define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_C 0x00001ec8 +# define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_D 0x00001ecc +# define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_E 0x00001ed0 +# define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_F 0x00001ed4 +# define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_G 0x00001ed8 +# define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_H 0x00001edc +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_OX 0x00000a20 +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_OY 0x00000a24 +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_NPF_DIV2 0x00000a28 +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_UNK0_0x0 0x00000a2c +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_PX_DIV2 0x00000a30 +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_PY_DIV2 0x00000a34 +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_FMN_DIV2 0x00000a38 +# define NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_UNK1_0x0 0x00000a3c +# define NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE 0x00000a60 +# define NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE 0x00000a64 +# define NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE 0x00000a68 +# define NV30_TCL_PRIMITIVE_3D_DEPTH_FUNC 0x00000a6c +# define NV30_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE 0x00000a70 +# define NV30_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE 0x00000a74 +# define NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR 0x00000a78 +# define NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_UNITS 0x00000a7c +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_INST0 0x00000b80 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_INST1 0x00000b84 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_INST2 0x00000b88 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_INST3 0x00000b8c +# define NV30_TCL_PRIMITIVE_3D_OCC_QUERY_OR_COLOR_BUFF_ENABLE 0x000017c8 +# define NV30_TCL_PRIMITIVE_3D_STORE_RESULT 0x00001800 +# define NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_A(d) (0x00000e00 + d * 0x0010) +# define NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_B(d) (0x00000e04 + d * 0x0010) +# define NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_C(d) (0x00000e08 + d * 0x0010) +# define NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_D(d) (0x00000e0c + d * 0x0010) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_A(d) (0x00001000 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_B(d) (0x00001004 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_C(d) (0x00001008 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_A(d) (0x0000100c + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_B(d) (0x00001010 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_C(d) (0x00001014 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_A(d) (0x00001018 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_B(d) (0x0000101c + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_C(d) (0x00001020 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(d) (0x00001228 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(d) (0x0000122c + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(d) (0x00001230 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(d) (0x00001200 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(d) (0x00001204 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(d) (0x00001208 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(d) (0x0000120c + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_Y(d) (0x00001210 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_Z(d) (0x00001214 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(d) (0x00001218 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(d) (0x0000121c + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_Y(d) (0x00001220 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_Z(d) (0x00001224 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_ENABLED_LIGHTS 0x00001420 /* Parameters: light 7 light 6 light 5 light 4 light 3 light 2 light 1 light 0 */ +# define NV30_TCL_PRIMITIVE_3D_LINE_STIPPLE 0x00001db4 +# define NV30_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN 0x00001db8 /* Parameters: factor pattern */ +# define NV30_TCL_PRIMITIVE_3D_BEGIN_END 0x00001808 +# define NV30_TCL_PRIMITIVE_3D_CULL_FACE 0x00001830 +# define NV30_TCL_PRIMITIVE_3D_FRONT_FACE 0x00001834 +# define NV30_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE 0x00001838 +# define NV30_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE 0x0000183c +# define NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH 0x00001d8c +# define NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB 0x00001d90 /* Parameters: a r g b */ +# define NV30_TCL_PRIMITIVE_3D_CLEAR_WHICH_BUFFERS 0x00001d94 +# define NV30_TCL_PRIMITIVE_3D_DO_VERTICES 0x00001dac +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_FROM_ID 0x00001e9c +# define NV30_TCL_PRIMITIVE_3D_VP_PROGRAM_START_ID 0x00001ea0 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_ID 0x00001efc +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P0_X 0x00001f00 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P0_Y 0x00001f04 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P0_Z 0x00001f08 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P0_W 0x00001f0c +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P1_X 0x00001f10 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P1_Y 0x00001f14 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P1_Z 0x00001f18 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P1_W 0x00001f1c +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P2_X 0x00001f20 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P2_Y 0x00001f24 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P2_Z 0x00001f28 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P2_W 0x00001f2c +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P3_X 0x00001f30 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P3_Y 0x00001f34 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P3_Z 0x00001f38 +# define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_P3_W 0x00001f3c +# define NV30_TCL_PRIMITIVE_3D_VTX_ATTR_3X(d) (0x00001500 + d * 0x0010) +# define NV30_TCL_PRIMITIVE_3D_VTX_ATTR_3Y(d) (0x00001504 + d * 0x0010) +# define NV30_TCL_PRIMITIVE_3D_VTX_ATTR_3Z(d) (0x00001508 + d * 0x0010) +# define NV30_TCL_PRIMITIVE_3D_VTX_ATTR_3W(d) (0x0000150c + d * 0x0010) +# define NV30_TCL_PRIMITIVE_3D_VTX_ATTR_4X(d) (0x00001c00 + d * 0x0010) +# define NV30_TCL_PRIMITIVE_3D_VTX_ATTR_4Y(d) (0x00001c04 + d * 0x0010) +# define NV30_TCL_PRIMITIVE_3D_VTX_ATTR_4Z(d) (0x00001c08 + d * 0x0010) +# define NV30_TCL_PRIMITIVE_3D_VTX_ATTR_4W(d) (0x00001c0c + d * 0x0010) +# define NV30_TCL_PRIMITIVE_3D_VB_POINTER_ATTR(d) (0x00001680 + d * 0x0004) /* Parameters: enabled? offset */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_XY 0x00000a90 /* Parameters: y x */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_Z 0x00000a94 /* Parameters: z */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_S 0x000018c0 +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_T 0x000018c4 +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_S 0x000018c8 +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_T 0x000018cc +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX2_2F_S 0x000018d0 +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX2_2F_T 0x000018d4 +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX3_2F_S 0x000018d8 +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX3_2F_T 0x000018dc +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX0_2I 0x00001920 /* Parameters: t s */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX1_2I 0x00001924 /* Parameters: t s */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX2_2I 0x00001928 /* Parameters: t s */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX3_2I 0x0000192c /* Parameters: t s */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_COL_4I 0x0000194c /* Parameters: a b g r */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_COL2_3I 0x00001950 /* Parameters: a b g r */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_ST 0x000019c0 /* Parameters: t s */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_RQ 0x000019c4 /* Parameters: q r */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_ST 0x000019c8 /* Parameters: t s */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_RQ 0x000019cc /* Parameters: q r */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX2_4I_ST 0x000019d0 /* Parameters: t s */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX2_4I_RQ 0x000019d4 /* Parameters: q r */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX3_4I_ST 0x000019d8 /* Parameters: t s */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_TX3_4I_RQ 0x000019dc /* Parameters: q r */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_FOG_1F 0x00001e54 +# define NV30_TCL_PRIMITIVE_3D_VERTEX_UNK_0 0x00001718 +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR( d) (0x00001740 + d * 0x0004) +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR0_POS 0x00001740 /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR1_WGH 0x00001744 /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR2_NOR 0x00001748 /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR3_COL 0x0000174c /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR4_COL2 0x00001750 /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR5_FOG 0x00001754 /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR6 0x00001758 /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR7 0x0000175c /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR8_TX0 0x00001760 /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR9_TX1 0x00001764 /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR10_TX2 0x00001768 /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR11_TX3 0x0000176c /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR12_TX4 0x00001770 /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR13_TX5 0x00001774 /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR14_TX6 0x00001778 /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR15_TX7 0x0000177c /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM 0x000008e4 +# define NV30_TCL_PRIMITIVE_3D_TX_ADDRESS_UNIT(d) (0x00001a00 + d * 0x0020) +# define NV30_TCL_PRIMITIVE_3D_TX_FORMAT_UNIT(d) (0x00001a04 + d * 0x0020) /* Parameters: mipmap type format ncomp cubic */ +# define NV30_TCL_PRIMITIVE_3D_TX_WRAP_UNIT(d) (0x00001a08 + d * 0x0020) /* Parameters: wrap_s wrap_t wrap_r */ +# define NV30_TCL_PRIMITIVE_3D_TX_ENABLE_UNIT(d) (0x00001a0c + d * 0x0020) /* Parameters: nv40_enable nv30_enable anisotropy */ +# define NV30_TCL_PRIMITIVE_3D_TX_SWIZZLE_UNIT(d) (0x00001a10 + d * 0x0020) +# define NV30_TCL_PRIMITIVE_3D_TX_FILTER_UNIT(d) (0x00001a14 + d * 0x0020) /* Parameters: filter_min filter_mag */ +# define NV30_TCL_PRIMITIVE_3D_TX_XY_DIM_UNIT(d) (0x00001a18 + d * 0x0020) /* Parameters: width height */ +# define NV30_TCL_PRIMITIVE_3D_TX_UNK07_UNIT(d) (0x00001a1c + d * 0x0020) +# define NV30_TCL_PRIMITIVE_3D_TX_DEPTH_UNIT(d) (0x00001840 + d * 0x0004) /* Parameters: depth NPOT pitch */ +# define NV30_TCL_PRIMITIVE_3D_VB_VERTEX_BATCH 0x00001814 /* Parameters: count_vertices offset_vertices */ +# define NV30_TCL_PRIMITIVE_3D_VERTEX_DATA 0x00001818 +# define NV30_TCL_PRIMITIVE_3D_LOGIC_OP_ENABLE 0x00000374 +# define NV30_TCL_PRIMITIVE_3D_LOGIC_OP_OP 0x00000378 +# define NV30_TCL_PRIMITIVE_3D_SET_DISPLAY_LIST_MEM_OFFSET 0x0000181c +# define NV30_TCL_PRIMITIVE_3D_EXECUTE_DISPLAY_LIST 0x00001824 /* Parameters: length start offset */ +# define NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT 0x00001828 +# define NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK 0x0000182c +# define NV30_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE 0x0000147c +# define NV30_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN( d) (0x00001480 + d * 0x0004) +# define NV30_TCL_PRIMITIVE_3D_SET_CLIPPING_PLANES 0x00001478 +# define NV30_TCL_PRIMITIVE_3D_VP_IN_REG 0x00001ff0 /* Parameters: vertex pos weight normal primary color secondary color fogcoord texture coords 0 texture ccords 1 texture coords 2 texture coords 3 texture coords 4 texture coords 5 texture coords 6 texture coords 7 */ +# define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG 0x00001ff4 /* Parameters: primary color secondary color backface primary color backface secondary color fogcoord pointsize clip plane 0 clip plane 1 clip plane 2 clip plane 3 clip plane 4 clip plane 5 texture coords 0 texture coords 1 texture coords 2 texture coords 3 texture coords 4 texture coords 5 texture coords 6 texture coords 7 */ + +/****************************************** +Object NV30_CLEAR_BUFFER used on: NV30 NV40 G70 +*/ +#define NV30_CLEAR_BUFFER 0x00000066 +# define NV30_CLEAR_BUFFER_SET_DMA_NOTIFY 0x00000180 +# define NV30_CLEAR_BUFFER_SET_IMAGE_PATTERN 0x00000188 +# define NV30_CLEAR_BUFFER_SET_RASTER_OP 0x0000018c +# define NV30_CLEAR_BUFFER_SET_CONTEXT_SURFACE_2D 0x00000198 +# define NV30_CLEAR_BUFFER_UNK002fc 0x000002fc + +/****************************************** +Object NV_DMA_FROM_MEMORY used on: NV03 NV04 NV10 NV15 NV20 NV30 NV40 G70 +*/ +#define NV_DMA_FROM_MEMORY 0x00000002 + +/****************************************** +Object NV_DMA_TO_MEMORY used on: NV03 NV04 NV10 NV15 NV20 NV30 NV40 G70 +*/ +#define NV_DMA_TO_MEMORY 0x00000003 + +/****************************************** +Object NV_DMA_IN_MEMORY used on: NV03 NV04 NV10 NV15 NV20 NV30 NV40 G70 +*/ +#define NV_DMA_IN_MEMORY 0x0000003d + +/****************************************** +Object NvType0046 used on: NV04 +*/ +#define NvType0046 0x00000046 +# define NvType0046_DMA_NOTIFY 0x00000180 +# define NvType0046_DMA_MEM_1 0x00000184 +# define NvType0046_DMA_MEM_2 0x00000188 +# define NvType0046_DMA_3 0x0000018c +# define NvType0046_DMA_4 0x00000190 +# define NvType0046_OBJ_5 0x00000194 +# define NvType0046_OBJ_6 0x00000198 +# define NvType0046_PITCH1 0x00000304 +# define NvType0046_PITCH2 0x0000030c +# define NvType0046_SIZE 0x00000340 /* Parameters: width height */ +# define NvType0046_WIDTH 0x00000344 /* Parameters: visible_width blank_width */ +# define NvType0046_HSYNC 0x00000348 /* Parameters: hsync_start hsync_len */ +# define NvType0046_HEIGHT 0x0000034c /* Parameters: visible_height blank_height */ +# define NvType0046_VSYNC 0x00000350 /* Parameters: vsync_start vsync_len */ +# define NvType0046_FULL_SIZE 0x00000354 /* Parameters: full_width full_height */ +# define NvType0046_PIXEL_CLK 0x00000358 +# define NvType0046_FLAGS 0x0000035c /* Parameters: doublescan -hsync -vsync depth */ + +/****************************************** +Object NvType0047 used on: NV04 +*/ +#define NvType0047 0x00000047 +# define NvType0047_DMA_NOTIFY 0x00000180 +# define NvType0047_UNK19C 0x0000019c +# define NvType0047_UNK1A0 0x000001a0 +/****************************************** +Object NvType0049 used on: NV04 +*/ +#define NvType0049 0x00000049 +# define NvType0049_DMA_NOTIFY 0x00000180 +# define NvType0049_DMA_MEM_1 0x00000184 +# define NvType0049_DMA_MEM_2 0x00000188 +/****************************************** +Object NvType004D used on: NV04 +*/ +#define NvType004D 0x0000004d +# define NvType004D_DMA_NOTIFY 0x00000180 +# define NvType004D_DMA_MEM_1 0x00000184 +# define NvType004D_DMA_MEM_2 0x00000188 +# define NvType004D_DMA_MEM_3 0x0000018c +# define NvType004D_DMA_MEM_4 0x00000190 +#endif /* _NOUVEAU_REG_H */ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c new file mode 100644 index 0000000000..a2a29fe431 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.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_context.h" +#include "nouveau_screen.h" +#include "nouveau_object.h" + +static nouveauScreenPtr nouveauCreateScreen(__DRIscreenPrivate *sPriv) +{ + nouveauScreenPtr screen; + NOUVEAUDRIPtr dri_priv=(NOUVEAUDRIPtr)sPriv->pDevPriv; + + screen->card=nouveau_card_lookup(dri_priv->device_id); +} + +static GLboolean nouveauInitDriver(__DRIscreenPrivate *sPriv) +{ + sPriv->private = (void *) nouveauCreateScreen( sPriv ); + if ( !sPriv->private ) { + nouveauDestroyScreen( sPriv ); + return GL_FALSE; + } + + return GL_TRUE; +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.h b/src/mesa/drivers/dri/nouveau/nouveau_screen.h index f6959419c5..decdafa86d 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.h @@ -30,8 +30,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "xmlconfig.h" +#include "nouveau_dri.h" +#include "nouveau_card.h" + typedef struct { - u_int32_t card_type; + nouveau_card* card; u_int32_t bus_type; u_int32_t agp_mode; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c index 417fd9fbcc..85b5eae49e 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -26,7 +26,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_context.h" #include "nouveau_state.h" -#include "nouveau_ioctl.h" #include "nouveau_swtcl.h" #include "nouveau_fifo.h" diff --git a/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c b/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c index 7c7ba7374b..746b0fac8c 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c @@ -81,7 +81,7 @@ void nouveauFallback(struct nouveau_context *nmesa, GLuint bit, GLboolean mode) if (mode) { nmesa->Fallback |= bit; if (oldfallback == 0) { - if (nmesa->screen->card_typescreen->card->typescreen->card_typescreen->card->typescreen->card_type==NV_10) - BEGIN_RING_SIZE(channel,NV10_PRIMITIVE,1); - else if (nmesa->screen->card_type==NV_20) - BEGIN_RING_SIZE(channel,NV20_PRIMITIVE,1); + if (nmesa->screen->card->type==NV_10) + BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_BEGIN_END,1); + else if (nmesa->screen->card->type==NV_20) + BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_BEGIN_END,1); else - BEGIN_RING_SIZE(channel,NV30_PRIMITIVE,1); + BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_BEGIN_END,1); OUT_RING(nmesa->current_primitive); - if (nmesa->screen->card_type==NV_10) - BEGIN_RING_PRIM(channel,NV10_BEGIN_VERTICES,NOUVEAU_MIN_PRIM_SIZE); + if (nmesa->screen->card->type==NV_10) + BEGIN_RING_PRIM(NvSub3D,NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_DATA,NOUVEAU_MIN_PRIM_SIZE); + else if (nmesa->screen->card->type==NV_20) + BEGIN_RING_PRIM(NvSub3D,NV20_TCL_PRIMITIVE_3D_VERTEX_DATA,NOUVEAU_MIN_PRIM_SIZE); else - BEGIN_RING_PRIM(channel,NV20_BEGIN_VERTICES,NOUVEAU_MIN_PRIM_SIZE); + BEGIN_RING_PRIM(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_DATA,NOUVEAU_MIN_PRIM_SIZE); } inline void nv10FinishPrimitive(struct nouveau_context *nmesa) { FINISH_RING_PRIM(); - if (nmesa->screen->card_type==NV_10) - BEGIN_RING_SIZE(channel,NV10_PRIMITIVE,1); - else if (nmesa->screen->card_type==NV_20) - BEGIN_RING_SIZE(channel,NV20_PRIMITIVE,1); + if (nmesa->screen->card->type==NV_10) + BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_BEGIN_END,1); + else if (nmesa->screen->card->type==NV_20) + BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_BEGIN_END,1); else - BEGIN_RING_SIZE(channel,NV30_PRIMITIVE,1); + BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_BEGIN_END,1); OUT_RING(0x0); FIRE_RING(); } @@ -700,15 +699,17 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa, GLuint /* * Tell the hardware about the vertex format */ - if (nmesa->screen->card_type==NV_10) { + if (nmesa->screen->card->type==NV_10) { int size; +#define NV_VERTEX_ATTRIBUTE_TYPE_FLOAT 2 + #define NV10_SET_VERTEX_ATTRIB(i,j) \ do { \ size = attr_size[j] << 4; \ size |= (attr_size[j]*4) << 8; \ - size |= NV20_VERTEX_ATTRIBUTE_TYPE_FLOAT; \ - BEGIN_RING_SIZE(channel, NV10_VERTEX_ATTRIBUTE(i),1); \ + size |= NV_VERTEX_ATTRIBUTE_TYPE_FLOAT; \ + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_ATTR(i),1); \ OUT_RING(size); \ } while (0) @@ -721,27 +722,27 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa, GLuint NV10_SET_VERTEX_ATTRIB(6, _TNL_ATTRIB_WEIGHT); NV10_SET_VERTEX_ATTRIB(7, _TNL_ATTRIB_FOG); - BEGIN_RING_SIZE(channel, NV10_VERTEX_SET_FORMAT,1); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_VALIDATE,1); OUT_RING(0); - } else if (nmesa->screen->card_type==NV_20) { + } else if (nmesa->screen->card->type==NV_20) { for(i=0;i<16;i++) { int size=attr_size[i]; - BEGIN_RING_SIZE(channel,NV20_VERTEX_ATTRIBUTE(i),1); - OUT_RING(NV20_VERTEX_ATTRIBUTE_TYPE_FLOAT|(size*0x10)); + BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR(i),1); + OUT_RING(NV_VERTEX_ATTRIBUTE_TYPE_FLOAT|(size*0x10)); } } else { - BEGIN_RING_SIZE(channel,NV30_VERTEX_ATTRIBUTES,slots); + BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR0_POS,slots); for(i=0;i Date: Tue, 7 Nov 2006 17:37:22 +0000 Subject: Commit a small nitpick --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 79ee29cfa5..510704f7d4 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -664,7 +664,7 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa, GLuint if (index&(1< Date: Sat, 11 Nov 2006 00:00:45 +0000 Subject: Some work on nv30 state, heavily based on jkolb's work --- src/mesa/drivers/dri/nouveau/Makefile | 3 +- src/mesa/drivers/dri/nouveau/nouveau_context.h | 10 +- src/mesa/drivers/dri/nouveau/nouveau_state.c | 14 - src/mesa/drivers/dri/nouveau/nv30_state.c | 462 +++++++++++++++++++++++++ 4 files changed, 470 insertions(+), 19 deletions(-) create mode 100644 src/mesa/drivers/dri/nouveau/nv30_state.c (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile index 08240ad032..ed700a7085 100644 --- a/src/mesa/drivers/dri/nouveau/Makefile +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -19,7 +19,8 @@ DRIVER_SOURCES = \ nouveau_state.c \ nouveau_tex.c \ nouveau_swtcl.c \ - nv10_swtcl.c + nv10_swtcl.c \ + nv30_state.c C_SOURCES = \ $(COMMON_SOURCES) \ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index be0785f453..d1abde6856 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -83,6 +83,7 @@ typedef struct nouveau_context { /* The read-only regs */ volatile unsigned char* mmio; + /* FIXME : do we want to put all state into a separate struct ? */ /* State for tris */ GLuint color_offset; GLuint specular_offset; @@ -93,10 +94,11 @@ typedef struct nouveau_context { struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; GLuint vertex_attr_count; - /* Clear state */ - GLuint clear_color; - GLuint clear_depth; - GLuint clear_stencil; + /* Depth/stencil clear state */ + uint32_t clear_value; + + /* Light state */ + uint32_t enabled_lights; /* The drawing fallbacks */ GLuint Fallback; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c index 85b5eae49e..94c92aeb8a 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -54,20 +54,6 @@ static __inline__ GLuint nouveauPackColor(GLuint format, } } -static void nouveauDDClearColor(GLcontext *ctx, const GLfloat color[4]) -{ - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - GLubyte c[4]; - - CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]); - CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]); - CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]); - CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]); - - nmesa->clear_color = nouveauPackColor( nmesa->screen->fbFormat, - c[0], c[1], c[2], c[3] ); -} - static void nouveauCalcViewport(GLcontext *ctx) { /* Calculate the Viewport Matrix */ diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c new file mode 100644 index 0000000000..71a44085ae --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -0,0 +1,462 @@ +/************************************************************************** + +Copyright 2006 Nouveau +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_object.h" +#include "nouveau_fifo.h" +#include "nouveau_reg.h" + +#include "tnl/t_pipeline.h" + +#include "mtypes.h" +#include "colormac.h" + +void nv30AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte ubRef; + CLAMPED_FLOAT_TO_UBYTE(ubRef, ref); + + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2); + OUT_RING(func); /* NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC */ + OUT_RING(ubRef); /* NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF */ +} + +void nv30BlendColor(GLcontext *ctx, const GLfloat color[4]) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte cf[4]; + + CLAMPED_FLOAT_TO_UBYTE(cf[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(cf[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(cf[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(cf[3], color[3]); + + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_COLOR, 1); + OUT_RING(PACK_COLOR_8888(cf[3], cf[1], cf[2], cf[0])); +} + +void nv30BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_EQUATION, 1); + OUT_RING((modeA<<16) | modeRGB); +} + + +void nv30BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2); + OUT_RING((sfactorA<<16) | sfactorRGB); + OUT_RING((dfactorA<<16) | dfactorRGB); +} + +void nv30ClearColor(GLcontext *ctx, const GLfloat color[4]) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte c[4]; + UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,color); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB, 1); + OUT_RING(PACK_COLOR_8888(c[3],c[0],c[1],c[2])); +} + +void nv30ClearDepth(GLcontext *ctx, GLclampd d) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nmesa->clear_value=((nmesa->clear_value&0x000000FF)|(((uint32_t)(d*0xFFFFFF))<<8)); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1); + OUT_RING(nmesa->clear_value); +} + +/* we're don't support indexed buffers + void (*ClearIndex)(GLcontext *ctx, GLuint index) + */ + +void nv30ClearStencil(GLcontext *ctx, GLint s) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nmesa->clear_value=((nmesa->clear_value&0xFFFFFF00)|(s&0x000000FF)); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1); + OUT_RING(nmesa->clear_value); +} + +void nv30ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4); + OUT_RINGf(equation[0]); + OUT_RINGf(equation[1]); + OUT_RINGf(equation[2]); + OUT_RINGf(equation[3]); +} + +void nv30ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, + GLboolean bmask, GLboolean amask ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_MASK, 1); + OUT_RING(((amask && 0x01) << 24) | ((rmask && 0x01) << 16) | ((gmask && 0x01)<< 8) | ((bmask && 0x01) << 0)); +} + +void nv30ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode) +{ + // TODO I need love +} + +void nv30CullFace(GLcontext *ctx, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CULL_FACE, 1); + OUT_RING(mode); +} + +void nv30FrontFace(GLcontext *ctx, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FRONT_FACE, 1); + OUT_RING(mode); +} + +void nv30DepthFunc(GLcontext *ctx, GLenum func) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1); + OUT_RING(func); +} + +void nv30DepthMask(GLcontext *ctx, GLboolean flag) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1); + OUT_RING(flag); +} + +void nv30DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2); + OUT_RINGf(nearval); + OUT_RINGf(farval); +} + +/** Specify the current buffer for writing */ +//void (*DrawBuffer)( GLcontext *ctx, GLenum buffer ); +/** Specify the buffers for writing for fragment programs*/ +//void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers ); + +void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + switch(cap) + { + case GL_ALPHA_TEST: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1); + OUT_RING(state); + break; +// case GL_AUTO_NORMAL: + case GL_BLEND: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1); + OUT_RING(state); + break; + case GL_CLIP_PLANE0: + case GL_CLIP_PLANE1: + case GL_CLIP_PLANE2: + case GL_CLIP_PLANE3: + case GL_CLIP_PLANE4: + case GL_CLIP_PLANE5: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1); + OUT_RING(state); + break; + case GL_COLOR_LOGIC_OP: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LOGIC_OP_ENABLE, 1); + OUT_RING(state); + break; +// case GL_COLOR_MATERIAL: +// case GL_COLOR_SUM_EXT: +// case GL_COLOR_TABLE: +// case GL_CONVOLUTION_1D: +// case GL_CONVOLUTION_2D: + case GL_CULL_FACE: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1); + OUT_RING(state); + break; + case GL_DEPTH_TEST: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1); + OUT_RING(state); + break; + case GL_DITHER: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DITHER_ENABLE, 1); + OUT_RING(state); + break; + case GL_FOG: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_ENABLE, 1); + OUT_RING(state); + break; +// case GL_HISTOGRAM: +// case GL_INDEX_LOGIC_OP: + case GL_LIGHT0: + case GL_LIGHT1: + case GL_LIGHT2: + case GL_LIGHT3: + case GL_LIGHT4: + case GL_LIGHT5: + case GL_LIGHT6: + case GL_LIGHT7: + { + uint32_t mask=0x11<<(2*(cap-GL_LIGHT0)); + nmesa->enabled_lights=((nmesa->enabled_lights&mask)|(mask*state)); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); + OUT_RING(nmesa->enabled_lights); + break; + } +// case GL_LIGHTING: +// case GL_LINE_SMOOTH: +// case GL_LINE_STIPPLE: +// case GL_MAP1_COLOR_4: +// case GL_MAP1_INDEX: +// case GL_MAP1_NORMAL: +// case GL_MAP1_TEXTURE_COORD_1: +// case GL_MAP1_TEXTURE_COORD_2: +// case GL_MAP1_TEXTURE_COORD_3: +// case GL_MAP1_TEXTURE_COORD_4: +// case GL_MAP1_VERTEX_3: +// case GL_MAP1_VERTEX_4: +// case GL_MAP2_COLOR_4: +// case GL_MAP2_INDEX: +// case GL_MAP2_NORMAL: +// case GL_MAP2_TEXTURE_COORD_1: +// case GL_MAP2_TEXTURE_COORD_2: +// case GL_MAP2_TEXTURE_COORD_3: +// case GL_MAP2_TEXTURE_COORD_4: +// case GL_MAP2_VERTEX_3: +// case GL_MAP2_VERTEX_4: +// case GL_MINMAX: + case GL_NORMALIZE: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1); + OUT_RING(state); + break; +// case GL_POINT_SMOOTH: + case GL_POLYGON_OFFSET_POINT: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 1); + OUT_RING(state); + break; + case GL_POLYGON_OFFSET_LINE: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE, 1); + OUT_RING(state); + break; + case GL_POLYGON_OFFSET_FILL: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE, 1); + OUT_RING(state); + break; + case GL_POLYGON_SMOOTH: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1); + OUT_RING(state); + break; + case GL_POLYGON_STIPPLE: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE, 1); + OUT_RING(state); + break; +// case GL_POST_COLOR_MATRIX_COLOR_TABLE: +// case GL_POST_CONVOLUTION_COLOR_TABLE: +// case GL_RESCALE_NORMAL: +// case GL_SCISSOR_TEST: +// case GL_SEPARABLE_2D: + case GL_STENCIL_TEST: + // TODO BACK and FRONT ? + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_ENABLE, 1); + OUT_RING(state); + break; +// case GL_TEXTURE_GEN_Q: +// case GL_TEXTURE_GEN_R: +// case GL_TEXTURE_GEN_S: +// case GL_TEXTURE_GEN_T: +// case GL_TEXTURE_1D: +// case GL_TEXTURE_2D: +// case GL_TEXTURE_3D: + } +} + +void nv30Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + switch(pname) + { + case GL_FOG_MODE: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_MODE, 1); + //OUT_RING (params); + break; + /* TODO: unsure about the rest.*/ + default: + break; + } + +} + +void nv30Hint(GLcontext *ctx, GLenum target, GLenum mode) +{ + // TODO I need love (fog and line_smooth hints) +} + +// void (*IndexMask)(GLcontext *ctx, GLuint mask); + +void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + /* not sure where the fourth param value goes...*/ + switch(pname) + { + case GL_AMBIENT: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_A(light), 3); + OUT_RINGf(params[0]); + OUT_RINGf(params[1]); + OUT_RINGf(params[2]); + break; + case GL_DIFFUSE: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_A(light), 3); + OUT_RINGf(params[0]); + OUT_RINGf(params[1]); + OUT_RINGf(params[2]); + break; + case GL_SPECULAR: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_A(light), 3); + OUT_RINGf(params[0]); + OUT_RINGf(params[1]); + OUT_RINGf(params[2]); + break; + case GL_SPOT_DIRECTION: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(light), 3); + OUT_RINGf(params[0]); + OUT_RINGf(params[1]); + OUT_RINGf(params[2]); + break; + case GL_POSITION: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(light), 3); + OUT_RINGf(params[0]); + OUT_RINGf(params[1]); + OUT_RINGf(params[2]); + break; + case GL_SPOT_EXPONENT: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(light), 1); + OUT_RINGf(*params); + break; + case GL_SPOT_CUTOFF: + /* you can't factor these */ + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(light), 1); + OUT_RINGf(params[0]); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(light), 1); + OUT_RINGf(params[1]); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(light), 1); + OUT_RINGf(params[2]); + break; + case GL_CONSTANT_ATTENUATION: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(light), 1); + OUT_RINGf(*params); + break; + case GL_LINEAR_ATTENUATION: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(light), 1); + OUT_RINGf(*params); + break; + case GL_QUADRATIC_ATTENUATION: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(light), 1); + OUT_RINGf(*params); + break; + default: + break; + } +} + +/** Set the lighting model parameters */ +void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params); + + +void nv30LineStipple(GLcontext *ctx, GLint factor, GLushort pattern ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN, 1); + OUT_RING((pattern << 16) | factor); +} + +void nv30LineWidth(GLcontext *ctx, GLfloat width) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_WIDTH_SMOOTH, 1); + OUT_RINGf(width); +} + +void nv30LogicOpcode(GLcontext *ctx, GLenum opcode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LOGIC_OP_OP, 1); + OUT_RING(opcode); +} + +void nv30PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + /*TODO: not sure what goes here. */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + +} + +/** Specify the diameter of rasterized points */ +void (*PointSize)(GLcontext *ctx, GLfloat size); +/** Select a polygon rasterization mode */ +void (*PolygonMode)(GLcontext *ctx, GLenum face, GLenum mode); +/** Set the scale and units used to calculate depth values */ +void (*PolygonOffset)(GLcontext *ctx, GLfloat factor, GLfloat units); +/** Set the polygon stippling pattern */ +void (*PolygonStipple)(GLcontext *ctx, const GLubyte *mask ); +/* Specifies the current buffer for reading */ +void (*ReadBuffer)( GLcontext *ctx, GLenum buffer ); +/** Set rasterization mode */ +void (*RenderMode)(GLcontext *ctx, GLenum mode ); +/** Define the scissor box */ +void (*Scissor)(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h); +/** Select flat or smooth shading */ +void (*ShadeModel)(GLcontext *ctx, GLenum mode); +/** OpenGL 2.0 two-sided StencilFunc */ +void (*StencilFuncSeparate)(GLcontext *ctx, GLenum face, GLenum func, + GLint ref, GLuint mask); +/** OpenGL 2.0 two-sided StencilMask */ +void (*StencilMaskSeparate)(GLcontext *ctx, GLenum face, GLuint mask); +/** OpenGL 2.0 two-sided StencilOp */ +void (*StencilOpSeparate)(GLcontext *ctx, GLenum face, GLenum fail, + GLenum zfail, GLenum zpass); +/** Control the generation of texture coordinates */ +void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname, + const GLfloat *params); +/** Set texture environment parameters */ +void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname, + const GLfloat *param); +/** Set texture parameters */ +void (*TexParameter)(GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj, + GLenum pname, const GLfloat *params); +void (*TextureMatrix)(GLcontext *ctx, GLuint unit, const GLmatrix *mat); +/** Set the viewport */ +void (*Viewport)(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h); + -- cgit v1.2.3 From 0850289d8c66f75ac72347b1bf4bf6d15fb60139 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sat, 11 Nov 2006 11:25:08 +0000 Subject: Add the GL_LIGHING enable --- src/mesa/drivers/dri/nouveau/nouveau_context.h | 1 + src/mesa/drivers/dri/nouveau/nv30_state.c | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index d1abde6856..257d09f8b2 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -98,6 +98,7 @@ typedef struct nouveau_context { uint32_t clear_value; /* Light state */ + GLboolean lighting_enabled; uint32_t enabled_lights; /* The drawing fallbacks */ diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 71a44085ae..b1914b462f 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -230,11 +230,21 @@ void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) { uint32_t mask=0x11<<(2*(cap-GL_LIGHT0)); nmesa->enabled_lights=((nmesa->enabled_lights&mask)|(mask*state)); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); - OUT_RING(nmesa->enabled_lights); + if (nmesa->lighting_enabled) + { + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); + OUT_RING(nmesa->enabled_lights); + } break; } -// case GL_LIGHTING: + case GL_LIGHTING: + nmesa->lighting_enabled=state; + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); + if (nmesa->lighting_enabled) + OUT_RING(nmesa->enabled_lights); + else + OUT_RING(0x0); + break; // case GL_LINE_SMOOTH: // case GL_LINE_STIPPLE: // case GL_MAP1_COLOR_4: -- cgit v1.2.3 From 994ea9556f7fb55546c6426639ebb4cc3970a5d5 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sat, 11 Nov 2006 12:01:48 +0000 Subject: Fix the texture init function name --- src/mesa/drivers/dri/nouveau/nouveau_tex.c | 2 +- src/mesa/drivers/dri/nouveau/nouveau_tex.h | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_tex.c b/src/mesa/drivers/dri/nouveau/nouveau_tex.c index e3160b2d3d..0a8d279669 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_tex.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_tex.c @@ -28,7 +28,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_tex.h" // XXX needs some love -void nouveauInitTextureFuncs( struct dd_function_table *functions ) +void nouveauTexInitFunctions( struct dd_function_table *functions ) { /* functions->TexEnv = nouveauTexEnv; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_tex.h b/src/mesa/drivers/dri/nouveau/nouveau_tex.h index c415dc2a6b..7ac71f8300 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_tex.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_tex.h @@ -28,6 +28,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef __NOUVEAU_TEX_H__ #define __NOUVEAU_TEX_H__ +#include +#include "mtypes.h" +#include "macros.h" +#include "dd.h" + extern void nouveauTexInitFunctions( struct dd_function_table *functions ); #endif /* __NOUVEAU_TEX_H__ */ -- cgit v1.2.3 From 4f61fd18b2ba2dae38c68f4facb80ac2016d50ac Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Sat, 11 Nov 2006 16:48:14 +0000 Subject: Fill in nv30PointSize and nv30Viewport. --- src/mesa/drivers/dri/nouveau/nouveau_reg.h | 1 + src/mesa/drivers/dri/nouveau/nv30_state.c | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_reg.h b/src/mesa/drivers/dri/nouveau/nouveau_reg.h index 359f36cec8..c5052d7c4b 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_reg.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_reg.h @@ -1178,6 +1178,7 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS 0x000008c0 /* Parameters: width x_offset */ # define NV30_TCL_PRIMITIVE_3D_SCISSOR_HEIGHT_YPOS 0x000008c4 /* Parameters: height y_offset */ # define NV30_TCL_PRIMITIVE_3D_POINT_SPRITE 0x00001ee8 /* Parameters: coord_replace r_mode enable */ +# define NV30_TCL_PRIMITIVE_3D_POINT_SIZE 0x00001ee0 # define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_A 0x00001ec0 # define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_B 0x00001ec4 # define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_C 0x00001ec8 diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index b1914b462f..c3670580a2 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -433,7 +433,13 @@ void nv30PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params) } /** Specify the diameter of rasterized points */ -void (*PointSize)(GLcontext *ctx, GLfloat size); +void nv30PointSize(GLcontext *ctx, GLfloat size) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POINT_SIZE, 1); + OUT_RINFf(size); +} + /** Select a polygon rasterization mode */ void (*PolygonMode)(GLcontext *ctx, GLenum face, GLenum mode); /** Set the scale and units used to calculate depth values */ @@ -467,6 +473,14 @@ void (*TexParameter)(GLcontext *ctx, GLenum target, struct gl_texture_object *texObj, GLenum pname, const GLfloat *params); void (*TextureMatrix)(GLcontext *ctx, GLuint unit, const GLmatrix *mat); + /** Set the viewport */ -void (*Viewport)(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h); +void nv30Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + /* TODO: Where do the VIEWPORT_XFRM_* regs come in? */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_0, 2); + OUT_RING((w << 16) | x); + OUT_RING((h << 16) | y); +} -- cgit v1.2.3 From f65a4b8a8dd9f2dfb7f9fb0ce2b1a3ef3382aa84 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sat, 11 Nov 2006 18:25:00 +0000 Subject: Some nouveau_screen work for darktama --- src/mesa/drivers/dri/nouveau/nouveau_screen.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index a2a29fe431..d1beafe40e 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -28,11 +28,32 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_screen.h" #include "nouveau_object.h" +#include "xmlpool.h" + +PUBLIC const char __driConfigOptions[] = +DRI_CONF_BEGIN + DRI_CONF_SECTION_DEBUG + DRI_CONF_NO_RAST(false) + DRI_CONF_SECTION_END +DRI_CONF_END; +static const GLuint __driNConfigOptions = 1; + static nouveauScreenPtr nouveauCreateScreen(__DRIscreenPrivate *sPriv) { nouveauScreenPtr screen; NOUVEAUDRIPtr dri_priv=(NOUVEAUDRIPtr)sPriv->pDevPriv; + /* allocate screen */ + screen = (nouveauScreenPtr) CALLOC( sizeof(*screen) ); + if ( !screen ) { + __driUtilMessage("%s: Could not allocate memory for screen structure",__FUNCTION__); + return NULL; + } + + + /* parse information in __driConfigOptions */ + driParseOptionInfo (&screen->optionCache,__driConfigOptions, __driNConfigOptions); + screen->card=nouveau_card_lookup(dri_priv->device_id); } -- cgit v1.2.3 From d037c84c33d6a164dc8f76dab4e352054a01f32f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 11 Nov 2006 20:00:29 +0000 Subject: fix typo --- src/mesa/drivers/dri/nouveau/nv30_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index c3670580a2..e6e5fdbd15 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -437,7 +437,7 @@ void nv30PointSize(GLcontext *ctx, GLfloat size) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POINT_SIZE, 1); - OUT_RINFf(size); + OUT_RINGf(size); } /** Select a polygon rasterization mode */ -- cgit v1.2.3 From 6464787bfd1888ea93ebfe53528ceac3c27c993f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 12 Nov 2006 02:05:40 +0000 Subject: Dont call exit() from the DRI driver, with AIGLX this is particularly nasty --- src/mesa/drivers/dri/nouveau/nouveau_context.c | 3 ++- src/mesa/drivers/dri/nouveau/nouveau_fifo.c | 14 ++++++++++---- src/mesa/drivers/dri/nouveau/nouveau_fifo.h | 2 +- src/mesa/drivers/dri/nouveau/nouveau_msg.h | 2 -- 4 files changed, 13 insertions(+), 8 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 00f0646b1b..ff00782c99 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -79,7 +79,8 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, return GL_FALSE; /* Create the hardware context */ - nouveauFifoInit(nmesa); + if (!nouveauFifoInit(nmesa)) + return GL_FALSE; nouveauObjectInit(nmesa); /* Init default driver functions then plug in our nouveau-specific functions diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c index 5793909705..94d6773d33 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c @@ -109,19 +109,25 @@ void nouveauWaitForIdle(nouveauContextPtr nmesa) } // here we call the fifo initialization ioctl and fill in stuff accordingly -void nouveauFifoInit(nouveauContextPtr nmesa) +GLboolean nouveauFifoInit(nouveauContextPtr nmesa) { drm_nouveau_fifo_alloc_t fifo_init; int ret; ret=drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_FIFO_ALLOC, &fifo_init, sizeof(fifo_init)); - if (ret) + if (ret) { FATAL("Fifo initialization ioctl failed (returned %d)\n",ret); + return GL_FALSE; + } - if (drmMap(nmesa->driFd, fifo_init.cmdbuf, fifo_init.cmdbuf_size, &nmesa->fifo.buffer)) + if (drmMap(nmesa->driFd, fifo_init.cmdbuf, fifo_init.cmdbuf_size, &nmesa->fifo.buffer)) { FATAL("Unable to map the fifo\n",ret); - if (drmMap(nmesa->driFd, fifo_init.ctrl, fifo_init.ctrl_size, &nmesa->fifo.mmio)) + return GL_FALSE; + } + if (drmMap(nmesa->driFd, fifo_init.ctrl, fifo_init.ctrl_size, &nmesa->fifo.mmio)) { FATAL("Unable to map the control regs\n",ret); + return GL_FALSE; + } MESSAGE("Fifo init ok. Using context %d\n", fifo_init.channel); } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h index c2f8633dcc..afe4017d60 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h @@ -113,7 +113,7 @@ extern void WAIT_RING(nouveauContextPtr nmesa,u_int32_t size); }while(0) extern void nouveauWaitForIdle(nouveauContextPtr nmesa); -extern void nouveauFifoInit(nouveauContextPtr nmesa); +extern GLboolean nouveauFifoInit(nouveauContextPtr nmesa); #endif /* __NOUVEAU_FIFO_H__ */ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_msg.h b/src/mesa/drivers/dri/nouveau/nouveau_msg.h index 7b8f89e774..5dea2189c7 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_msg.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_msg.h @@ -54,7 +54,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 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{\ @@ -62,7 +61,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 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__ */ -- cgit v1.2.3 From b8e05366e192ab4ebaf69dc8a4a18da4e65cbf80 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 12 Nov 2006 02:06:30 +0000 Subject: We need nmesa->driFd and friends setup before we call nouveauFifoInit --- src/mesa/drivers/dri/nouveau/nouveau_context.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index ff00782c99..37582f3583 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -78,6 +78,16 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, if ( !nmesa ) return GL_FALSE; + 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; + /* Create the hardware context */ if (!nouveauFifoInit(nmesa)) return GL_FALSE; @@ -104,16 +114,6 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, 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"); -- cgit v1.2.3 From 2af374716f351421b978050b113e93abae0e2dc8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 12 Nov 2006 08:38:44 +0000 Subject: Some more nouveau_screen.c setup, not sure how correct it is yet though.. --- src/mesa/drivers/dri/nouveau/nouveau_context.c | 15 ++ src/mesa/drivers/dri/nouveau/nouveau_context.h | 4 + src/mesa/drivers/dri/nouveau/nouveau_fifo.c | 8 + src/mesa/drivers/dri/nouveau/nouveau_fifo.h | 2 + src/mesa/drivers/dri/nouveau/nouveau_screen.c | 309 ++++++++++++++++++++++++- 5 files changed, 337 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 37582f3583..f815ace31c 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -61,6 +61,11 @@ static const struct dri_debug_control debug_control[] = { NULL, 0 } }; +const struct dri_extension common_extensions[] = +{ + { NULL, 0 } +}; + /* Create the device specific context. */ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, @@ -214,3 +219,13 @@ GLboolean nouveauUnbindContext( __DRIcontextPrivate *driContextPriv ) { return GL_TRUE; } + +void nouveauSwapBuffers(__DRIdrawablePrivate *dPriv) +{ +} + +void nouveauCopySubBuffer(__DRIdrawablePrivate *dPriv, + int x, int y, int w, int h) +{ +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 257d09f8b2..1da5b6d61d 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -182,6 +182,10 @@ extern GLboolean nouveauMakeCurrent( __DRIcontextPrivate *driContextPriv, extern GLboolean nouveauUnbindContext( __DRIcontextPrivate *driContextPriv ); +extern void nouveauSwapBuffers(__DRIdrawablePrivate *dPriv); + +extern void nouveauCopySubBuffer(__DRIdrawablePrivate *dPriv, + int x, int y, int w, int h); #endif /* __NOUVEAU_CONTEXT_H__ */ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c index 94d6773d33..52c227cccc 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c @@ -113,6 +113,10 @@ GLboolean nouveauFifoInit(nouveauContextPtr nmesa) { drm_nouveau_fifo_alloc_t fifo_init; +#ifdef NOUVEAU_RING_DEBUG + return GL_TRUE; +#endif + int ret; ret=drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_FIFO_ALLOC, &fifo_init, sizeof(fifo_init)); if (ret) { @@ -129,7 +133,11 @@ GLboolean nouveauFifoInit(nouveauContextPtr nmesa) return GL_FALSE; } + /* Setup our initial FIFO tracking params */ + nmesa->fifo.free = fifo_init.cmdbuf_size >> 2; + MESSAGE("Fifo init ok. Using context %d\n", fifo_init.channel); + return GL_TRUE; } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h index afe4017d60..0edb083388 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h @@ -32,6 +32,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_context.h" #include "nouveau_ctrlreg.h" +//#define NOUVEAU_RING_DEBUG + #define NV_READ(reg) *(volatile u_int32_t *)(nmesa->mmio + (reg)) #define NV_FIFO_READ(reg) *(volatile u_int32_t *)(nmesa->fifo.mmio + (reg)) diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index d1beafe40e..75da632447 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -24,9 +24,23 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +#include "glheader.h" +#include "imports.h" +#include "mtypes.h" +#include "framebuffer.h" +#include "renderbuffer.h" + #include "nouveau_context.h" #include "nouveau_screen.h" #include "nouveau_object.h" +#include "nouveau_span.h" + +#include "utils.h" +#include "context.h" +#include "vblank.h" +#include "drirenderbuffer.h" + +#include "GL/internal/dri_interface.h" #include "xmlpool.h" @@ -38,6 +52,8 @@ DRI_CONF_BEGIN DRI_CONF_END; static const GLuint __driNConfigOptions = 1; +extern const struct dri_extension common_extensions[]; + static nouveauScreenPtr nouveauCreateScreen(__DRIscreenPrivate *sPriv) { nouveauScreenPtr screen; @@ -49,12 +65,35 @@ static nouveauScreenPtr nouveauCreateScreen(__DRIscreenPrivate *sPriv) __driUtilMessage("%s: Could not allocate memory for screen structure",__FUNCTION__); return NULL; } - /* parse information in __driConfigOptions */ driParseOptionInfo (&screen->optionCache,__driConfigOptions, __driNConfigOptions); + screen->fbFormat = dri_priv->bpp / 8; + screen->frontOffset = dri_priv->front_offset; + screen->frontPitch = dri_priv->front_pitch; + screen->backOffset = dri_priv->back_offset; + screen->backPitch = dri_priv->back_pitch; + screen->depthOffset = dri_priv->depth_offset; + screen->depthPitch = dri_priv->depth_pitch; + screen->card=nouveau_card_lookup(dri_priv->device_id); + screen->driScreen = sPriv; + return screen; +} + +static void +nouveauDestroyScreen(__DRIscreenPrivate *sPriv) +{ + nouveauScreenPtr screen = (nouveauScreenPtr)sPriv->private; + + if (!screen) return; + + /* free all option information */ + driDestroyOptionInfo (&screen->optionCache); + + FREE(screen); + sPriv->private = NULL; } static GLboolean nouveauInitDriver(__DRIscreenPrivate *sPriv) @@ -68,3 +107,271 @@ static GLboolean nouveauInitDriver(__DRIscreenPrivate *sPriv) return GL_TRUE; } +/** + * Create the Mesa framebuffer and renderbuffers for a given window/drawable. + * + * \todo This function (and its interface) will need to be updated to support + * pbuffers. + */ +static GLboolean +nouveauCreateBuffer(__DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + const __GLcontextModes *mesaVis, + GLboolean isPixmap) +{ + nouveauScreenPtr screen = (nouveauScreenPtr) driScrnPriv->private; + + if (isPixmap) { + return GL_FALSE; /* not implemented */ + } + else { + const GLboolean swDepth = GL_FALSE; + const GLboolean swAlpha = GL_FALSE; + const GLboolean swAccum = mesaVis->accumRedBits > 0; + const GLboolean swStencil = mesaVis->stencilBits > 0 && mesaVis->depthBits != 24; + struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis); + + /* front color renderbuffer */ + { + driRenderbuffer *frontRb + = driNewRenderbuffer(GL_RGBA, + driScrnPriv->pFB + screen->frontOffset, + screen->fbFormat, + screen->frontOffset, screen->frontPitch, + driDrawPriv); + nouveauSpanSetFunctions(frontRb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base); + } + + /* back color renderbuffer */ + if (mesaVis->doubleBufferMode) { + driRenderbuffer *backRb + = driNewRenderbuffer(GL_RGBA, + driScrnPriv->pFB + screen->backOffset, + screen->fbFormat, + screen->backOffset, screen->backPitch, + driDrawPriv); + nouveauSpanSetFunctions(backRb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base); + } + + /* depth renderbuffer */ + if (mesaVis->depthBits == 16) { + driRenderbuffer *depthRb + = driNewRenderbuffer(GL_DEPTH_COMPONENT16, + driScrnPriv->pFB + screen->depthOffset, + screen->fbFormat, + screen->depthOffset, screen->depthPitch, + driDrawPriv); + nouveauSpanSetFunctions(depthRb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base); + } + else if (mesaVis->depthBits == 24) { + driRenderbuffer *depthRb + = driNewRenderbuffer(GL_DEPTH_COMPONENT24, + driScrnPriv->pFB + screen->depthOffset, + screen->fbFormat, + screen->depthOffset, screen->depthPitch, + driDrawPriv); + nouveauSpanSetFunctions(depthRb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base); + } + + /* stencil renderbuffer */ + if (mesaVis->stencilBits > 0 && !swStencil) { + driRenderbuffer *stencilRb + = driNewRenderbuffer(GL_STENCIL_INDEX8_EXT, + driScrnPriv->pFB + screen->depthOffset, + screen->fbFormat, + screen->depthOffset, screen->depthPitch, + driDrawPriv); + nouveauSpanSetFunctions(stencilRb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base); + } + + _mesa_add_soft_renderbuffers(fb, + GL_FALSE, /* color */ + swDepth, + swStencil, + swAccum, + swAlpha, + GL_FALSE /* aux */); + driDrawPriv->driverPrivate = (void *) fb; + + return (driDrawPriv->driverPrivate != NULL); + } +} + + +static void +nouveauDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) +{ + _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); +} + +static int +nouveauGetSwapInfo(__DRIdrawablePrivate *dpriv, __DRIswapInfo *sInfo) +{ + return -1; +} + +static const struct __DriverAPIRec nouveauAPI = { + .InitDriver = nouveauInitDriver, + .DestroyScreen = nouveauDestroyScreen, + .CreateContext = nouveauCreateContext, + .DestroyContext = nouveauDestroyContext, + .CreateBuffer = nouveauCreateBuffer, + .DestroyBuffer = nouveauDestroyBuffer, + .SwapBuffers = nouveauSwapBuffers, + .MakeCurrent = nouveauMakeCurrent, + .UnbindContext = nouveauUnbindContext, + .GetSwapInfo = nouveauGetSwapInfo, + .GetMSC = driGetMSC32, + .WaitForMSC = driWaitForMSC32, + .WaitForSBC = NULL, + .SwapBuffersMSC = NULL, + .CopySubBuffer = nouveauCopySubBuffer +}; + + +static __GLcontextModes * +nouveauFillInModes( unsigned pixel_bits, unsigned depth_bits, + unsigned stencil_bits, GLboolean have_back_buffer ) +{ + __GLcontextModes * modes; + __GLcontextModes * m; + unsigned num_modes; + unsigned depth_buffer_factor; + unsigned back_buffer_factor; + GLenum fb_format; + GLenum fb_type; + + /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't + * support pageflipping at all. + */ + static const GLenum back_buffer_modes[] = { + GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML + }; + + u_int8_t depth_bits_array[3]; + u_int8_t stencil_bits_array[3]; + + depth_bits_array[0] = 0; + depth_bits_array[1] = depth_bits; + depth_bits_array[2] = depth_bits; + + /* Just like with the accumulation buffer, always provide some modes + * with a stencil buffer. It will be a sw fallback, but some apps won't + * care about that. + */ + stencil_bits_array[0] = 0; + stencil_bits_array[1] = 0; + stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits; + + depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1; + back_buffer_factor = (have_back_buffer) ? 3 : 1; + + num_modes = depth_buffer_factor * back_buffer_factor * 4; + + if ( pixel_bits == 16 ) { + fb_format = GL_RGB; + fb_type = GL_UNSIGNED_SHORT_5_6_5; + } else { + fb_format = GL_BGRA; + fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; + } + + modes = (*dri_interface->createContextModes)( num_modes, sizeof( __GLcontextModes ) ); + m = modes; + if (!driFillInModes(&m, fb_format, fb_type, + depth_bits_array, stencil_bits_array, depth_buffer_factor, + back_buffer_modes, back_buffer_factor, + GLX_TRUE_COLOR)) { + fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", + __func__, __LINE__ ); + return NULL; + } + if (!driFillInModes(&m, fb_format, fb_type, + depth_bits_array, stencil_bits_array, depth_buffer_factor, + back_buffer_modes, back_buffer_factor, + GLX_DIRECT_COLOR)) { + fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", + __func__, __LINE__ ); + return NULL; + } + + /* Mark the visual as slow if there are "fake" stencil bits. + */ + for ( m = modes ; m != NULL ; m = m->next ) { + if ( (m->stencilBits != 0) && (m->stencilBits != stencil_bits) ) { + m->visualRating = GLX_SLOW_CONFIG; + } + } + + return modes; +} + + +/** + * This is the bootstrap function for the driver. libGL supplies all of the + * requisite information about the system, and the driver initializes itself. + * This routine also fills in the linked list pointed to by \c driver_modes + * with the \c __GLcontextModes that the driver can support for windows or + * pbuffers. + * + * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on + * failure. + */ +PUBLIC +void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc, + const __GLcontextModes * modes, + const __DRIversion * ddx_version, + const __DRIversion * dri_version, + const __DRIversion * drm_version, + const __DRIframebuffer * frame_buffer, + drmAddress pSAREA, int fd, + int internal_api_version, + const __DRIinterfaceMethods * interface, + __GLcontextModes ** driver_modes) + +{ + __DRIscreenPrivate *psp; + static const __DRIversion ddx_expected = { 1, 2, 0 }; + static const __DRIversion dri_expected = { 4, 0, 0 }; + static const __DRIversion drm_expected = { 1, 0, 0 }; + + dri_interface = interface; + + if (!driCheckDriDdxDrmVersions2("nouveau", + dri_version, & dri_expected, + ddx_version, & ddx_expected, + drm_version, & drm_expected)) { + return NULL; + } + + psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, + ddx_version, dri_version, drm_version, + frame_buffer, pSAREA, fd, + internal_api_version, &nouveauAPI); + if ( psp != NULL ) { + NOUVEAUDRIPtr dri_priv = (NOUVEAUDRIPtr)psp->pDevPriv; + + *driver_modes = nouveauFillInModes(dri_priv->bpp, + (dri_priv->bpp == 16) ? 16 : 24, + (dri_priv->bpp == 16) ? 0 : 8, + (dri_priv->back_offset != dri_priv->depth_offset)); + + /* Calling driInitExtensions here, with a NULL context pointer, does not actually + * enable the extensions. It just makes sure that all the dispatch offsets for all + * the extensions that *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is called, but we can't + * enable the extensions until we have a context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions( NULL, common_extensions, GL_FALSE ); + } + + return (void *) psp; +} + -- cgit v1.2.3 From d5d00cf8c93d607876f66ca87e82087497f47d4a Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Sun, 12 Nov 2006 18:18:02 +0000 Subject: Add include guard. --- src/mesa/drivers/dri/nouveau/nouveau_object.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.h b/src/mesa/drivers/dri/nouveau/nouveau_object.h index 5fe7487c47..1065a0be59 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.h @@ -1,3 +1,5 @@ +#ifndef __NOUVEAU_OBJECT_H__ +#define __NOUVEAU_OBJECT_H__ #include "nouveau_context.h" @@ -11,3 +13,4 @@ enum DMASubchannel { NvSub3D = 1, }; +#endif -- cgit v1.2.3 From 47695f06894ed28602ad9ec1449739e658498c82 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 13 Nov 2006 16:01:03 +0000 Subject: Fix segfault in nouveauCalcViewport --- src/mesa/drivers/dri/nouveau/nouveau_context.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index f815ace31c..34a65d6d4b 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -135,6 +135,8 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); + _math_matrix_ctr(&nmesa->viewport); + switch(nmesa->screen->card->type) { case NV_03: -- cgit v1.2.3 From 9021df2d2ad348e1299a74a8ac8df2c13325538c Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Thu, 16 Nov 2006 19:50:56 +0000 Subject: nv10 state copy/pasted from nv30 state --- src/mesa/drivers/dri/nouveau/nv10_state.c | 498 ++++++++++++++++++++++++++++++ 1 file changed, 498 insertions(+) create mode 100644 src/mesa/drivers/dri/nouveau/nv10_state.c (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c new file mode 100644 index 0000000000..e752905841 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -0,0 +1,498 @@ +/************************************************************************** + +Copyright 2006 Nouveau +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_object.h" +#include "nouveau_fifo.h" +#include "nouveau_reg.h" + +#include "tnl/t_pipeline.h" + +#include "mtypes.h" +#include "colormac.h" + +void nv10AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte ubRef; + CLAMPED_FLOAT_TO_UBYTE(ubRef, ref); + + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC, 2); + OUT_RING(func); /* NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC */ + OUT_RING(ubRef); /* NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF */ +} + +void nv10BlendColor(GLcontext *ctx, const GLfloat color[4]) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte cf[4]; + + CLAMPED_FLOAT_TO_UBYTE(cf[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(cf[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(cf[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(cf[3], color[3]); + + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_COLOR, 1); + OUT_RING(PACK_COLOR_8888(cf[3], cf[1], cf[2], cf[0])); +} + +void nv10BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_EQUATION, 1); + OUT_RING((modeA<<16) | modeRGB); +} + + +void nv10BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2); + OUT_RING((sfactorA<<16) | sfactorRGB); + OUT_RING((dfactorA<<16) | dfactorRGB); +} + +/* +void nv30ClearColor(GLcontext *ctx, const GLfloat color[4]) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte c[4]; + UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,color); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB, 1); + OUT_RING(PACK_COLOR_8888(c[3],c[0],c[1],c[2])); +} + +void nv30ClearDepth(GLcontext *ctx, GLclampd d) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nmesa->clear_value=((nmesa->clear_value&0x000000FF)|(((uint32_t)(d*0xFFFFFF))<<8)); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1); + OUT_RING(nmesa->clear_value); +} +*/ + +/* we're don't support indexed buffers + void (*ClearIndex)(GLcontext *ctx, GLuint index) + */ + +/* +void nv30ClearStencil(GLcontext *ctx, GLint s) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nmesa->clear_value=((nmesa->clear_value&0xFFFFFF00)|(s&0x000000FF)); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1); + OUT_RING(nmesa->clear_value); +} +*/ + +void nv10ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4); + OUT_RINGf(equation[0]); + OUT_RINGf(equation[1]); + OUT_RINGf(equation[2]); + OUT_RINGf(equation[3]); +} + +/* Seems does not support alpha in color mask */ +void nv10ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, + GLboolean bmask, GLboolean amask ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_COLOR_MASK, 1); + OUT_RING(/*((amask && 0x01) << 24) |*/ ((rmask && 0x01) << 16) | ((gmask && 0x01)<< 8) | ((bmask && 0x01) << 0)); +} + +void nv10ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode) +{ + // TODO I need sex +} + +void nv10CullFace(GLcontext *ctx, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CULL_FACE, 1); + OUT_RING(mode); +} + +void nv10FrontFace(GLcontext *ctx, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FRONT_FACE, 1); + OUT_RING(mode); +} + +void nv10DepthFunc(GLcontext *ctx, GLenum func) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1); + OUT_RING(func); +} + +void nv10DepthMask(GLcontext *ctx, GLboolean flag) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_MASK, 1); + OUT_RING(flag); +} + +void nv10DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2); + OUT_RINGf(nearval); + OUT_RINGf(farval); +} + +/** Specify the current buffer for writing */ +//void (*DrawBuffer)( GLcontext *ctx, GLenum buffer ); +/** Specify the buffers for writing for fragment programs*/ +//void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers ); + +void nv10Enable(GLcontext *ctx, GLenum cap, GLboolean state) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + switch(cap) + { + case GL_ALPHA_TEST: + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ALPHA_TEST_ENABLE, 1); + OUT_RING(state); + break; +// case GL_AUTO_NORMAL: + case GL_BLEND: + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_ENABLE, 1); + OUT_RING(state); + break; + case GL_CLIP_PLANE0: + case GL_CLIP_PLANE1: + case GL_CLIP_PLANE2: + case GL_CLIP_PLANE3: + case GL_CLIP_PLANE4: + case GL_CLIP_PLANE5: + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1); + OUT_RING(state); + break; + case GL_COLOR_LOGIC_OP: + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LOGIC_OP_ENABLE, 1); + OUT_RING(state); + break; +// case GL_COLOR_MATERIAL: +// case GL_COLOR_SUM_EXT: +// case GL_COLOR_TABLE: +// case GL_CONVOLUTION_1D: +// case GL_CONVOLUTION_2D: + case GL_CULL_FACE: + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1); + OUT_RING(state); + break; + case GL_DEPTH_TEST: + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1); + OUT_RING(state); + break; + case GL_DITHER: + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DITHER_ENABLE, 1); + OUT_RING(state); + break; + case GL_FOG: + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FOG_ENABLE, 1); + OUT_RING(state); + break; +// case GL_HISTOGRAM: +// case GL_INDEX_LOGIC_OP: + case GL_LIGHT0: + case GL_LIGHT1: + case GL_LIGHT2: + case GL_LIGHT3: + case GL_LIGHT4: + case GL_LIGHT5: + case GL_LIGHT6: + case GL_LIGHT7: + { + uint32_t mask=1<<(2*(cap-GL_LIGHT0)); + nmesa->enabled_lights=((nmesa->enabled_lights&mask)|(mask*state)); + if (nmesa->lighting_enabled) + { + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); + OUT_RING(nmesa->enabled_lights); + } + break; + } + case GL_LIGHTING: + nmesa->lighting_enabled=state; + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); + if (nmesa->lighting_enabled) + OUT_RING(nmesa->enabled_lights); + else + OUT_RING(0x0); + break; +// case GL_LINE_SMOOTH: +// case GL_LINE_STIPPLE: +// case GL_MAP1_COLOR_4: +// case GL_MAP1_INDEX: +// case GL_MAP1_NORMAL: +// case GL_MAP1_TEXTURE_COORD_1: +// case GL_MAP1_TEXTURE_COORD_2: +// case GL_MAP1_TEXTURE_COORD_3: +// case GL_MAP1_TEXTURE_COORD_4: +// case GL_MAP1_VERTEX_3: +// case GL_MAP1_VERTEX_4: +// case GL_MAP2_COLOR_4: +// case GL_MAP2_INDEX: +// case GL_MAP2_NORMAL: +// case GL_MAP2_TEXTURE_COORD_1: +// case GL_MAP2_TEXTURE_COORD_2: +// case GL_MAP2_TEXTURE_COORD_3: +// case GL_MAP2_TEXTURE_COORD_4: +// case GL_MAP2_VERTEX_3: +// case GL_MAP2_VERTEX_4: +// case GL_MINMAX: + case GL_NORMALIZE: + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1); + OUT_RING(state); + break; +// case GL_POINT_SMOOTH: + case GL_POLYGON_OFFSET_POINT: + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 1); + OUT_RING(state); + break; + case GL_POLYGON_OFFSET_LINE: + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE, 1); + OUT_RING(state); + break; + case GL_POLYGON_OFFSET_FILL: + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE, 1); + OUT_RING(state); + break; + case GL_POLYGON_SMOOTH: + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1); + OUT_RING(state); + break; + case GL_LINE_SMOOTH: + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1); + OUT_RING(state); + break; + case GL_POINT_SMOOTH: + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POINT_SMOOTH_ENABLE, 1); + OUT_RING(state); + break; +// case GL_POLYGON_STIPPLE: +// case GL_POST_COLOR_MATRIX_COLOR_TABLE: +// case GL_POST_CONVOLUTION_COLOR_TABLE: +// case GL_RESCALE_NORMAL: +// case GL_SCISSOR_TEST: +// case GL_SEPARABLE_2D: + case GL_STENCIL_TEST: + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_TEST_ENABLE, 1); + OUT_RING(state); + break; +// case GL_TEXTURE_GEN_Q: +// case GL_TEXTURE_GEN_R: +// case GL_TEXTURE_GEN_S: +// case GL_TEXTURE_GEN_T: +// case GL_TEXTURE_1D: +// case GL_TEXTURE_2D: +// case GL_TEXTURE_3D: + } +} + +void nv10Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + switch(pname) + { + case GL_FOG_MODE: + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FOG_MODE, 1); + //OUT_RING (params); + break; + /* TODO: unsure about the rest.*/ + default: + break; + } + +} + +void nv10Hint(GLcontext *ctx, GLenum target, GLenum mode) +{ + // TODO I need sex (fog and line_smooth hints) +} + +// void (*IndexMask)(GLcontext *ctx, GLuint mask); + +void nv10Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + /* not sure where the fourth param value goes...*/ + switch(pname) + { + case GL_AMBIENT: + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_AMBIENT(light), 3); + OUT_RINGf(params[0]); + OUT_RINGf(params[1]); + OUT_RINGf(params[2]); + break; + case GL_DIFFUSE: + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_DIFFUSE(light), 3); + OUT_RINGf(params[0]); + OUT_RINGf(params[1]); + OUT_RINGf(params[2]); + break; + case GL_SPECULAR: + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPECULAR(light), 3); + OUT_RINGf(params[0]); + OUT_RINGf(params[1]); + OUT_RINGf(params[2]); + break; +#if 0 + case GL_SPOT_DIRECTION: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(light), 3); + OUT_RINGf(params[0]); + OUT_RINGf(params[1]); + OUT_RINGf(params[2]); + break; + case GL_POSITION: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(light), 3); + OUT_RINGf(params[0]); + OUT_RINGf(params[1]); + OUT_RINGf(params[2]); + break; + case GL_SPOT_EXPONENT: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(light), 1); + OUT_RINGf(*params); + break; + case GL_SPOT_CUTOFF: + /* you can't factor these */ + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(light), 1); + OUT_RINGf(params[0]); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(light), 1); + OUT_RINGf(params[1]); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(light), 1); + OUT_RINGf(params[2]); + break; + case GL_CONSTANT_ATTENUATION: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(light), 1); + OUT_RINGf(*params); + break; + case GL_LINEAR_ATTENUATION: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(light), 1); + OUT_RINGf(*params); + break; + case GL_QUADRATIC_ATTENUATION: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(light), 1); + OUT_RINGf(*params); + break; +#endif + default: + break; + } +} + +/** Set the lighting model parameters */ +void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params); + +/* +void nv30LineStipple(GLcontext *ctx, GLint factor, GLushort pattern ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN, 1); + OUT_RING((pattern << 16) | factor); +} + +void nv30LineWidth(GLcontext *ctx, GLfloat width) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_WIDTH_SMOOTH, 1); + OUT_RINGf(width); +} +*/ + +void nv10LogicOpcode(GLcontext *ctx, GLenum opcode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LOGIC_OP, 1); + OUT_RING(opcode); +} + +void nv10PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + /*TODO: not sure what goes here. */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + +} + +/** Specify the diameter of rasterized points */ +void nv10PointSize(GLcontext *ctx, GLfloat size) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POINT_SIZE, 1); + OUT_RINGf(size); +} + +/** Select a polygon rasterization mode */ +void (*PolygonMode)(GLcontext *ctx, GLenum face, GLenum mode); +/** Set the scale and units used to calculate depth values */ +void (*PolygonOffset)(GLcontext *ctx, GLfloat factor, GLfloat units); +/** Set the polygon stippling pattern */ +void (*PolygonStipple)(GLcontext *ctx, const GLubyte *mask ); +/* Specifies the current buffer for reading */ +void (*ReadBuffer)( GLcontext *ctx, GLenum buffer ); +/** Set rasterization mode */ +void (*RenderMode)(GLcontext *ctx, GLenum mode ); +/** Define the scissor box */ +void (*Scissor)(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h); +/** Select flat or smooth shading */ +void (*ShadeModel)(GLcontext *ctx, GLenum mode); +/** OpenGL 2.0 two-sided StencilFunc */ +void (*StencilFuncSeparate)(GLcontext *ctx, GLenum face, GLenum func, + GLint ref, GLuint mask); +/** OpenGL 2.0 two-sided StencilMask */ +void (*StencilMaskSeparate)(GLcontext *ctx, GLenum face, GLuint mask); +/** OpenGL 2.0 two-sided StencilOp */ +void (*StencilOpSeparate)(GLcontext *ctx, GLenum face, GLenum fail, + GLenum zfail, GLenum zpass); +/** Control the generation of texture coordinates */ +void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname, + const GLfloat *params); +/** Set texture environment parameters */ +void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname, + const GLfloat *param); +/** Set texture parameters */ +void (*TexParameter)(GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj, + GLenum pname, const GLfloat *params); +void (*TextureMatrix)(GLcontext *ctx, GLuint unit, const GLmatrix *mat); + +/** Set the viewport */ +void nv10Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + /* TODO: Where do the VIEWPORT_XFRM_* regs come in? */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2); + OUT_RING((w << 16) | x); + OUT_RING((h << 16) | y); +} + -- cgit v1.2.3 From 0da68e2e6e2756e26040df414bc7d1719c884646 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 16 Nov 2006 23:24:20 +0000 Subject: Add nv30InitStateFuncs --- src/mesa/drivers/dri/nouveau/nouveau_state.h | 2 + src/mesa/drivers/dri/nouveau/nv30_state.c | 117 ++++++++++++++++++++------- 2 files changed, 89 insertions(+), 30 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.h b/src/mesa/drivers/dri/nouveau/nouveau_state.h index 70c50588a8..4e8eda83e1 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.h @@ -32,6 +32,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. extern void nouveauDDInitState(nouveauContextPtr nmesa); extern void nouveauDDInitStateFuncs(GLcontext *ctx); +extern void nv30InitStateFuncs(struct dd_function_table *func); + /* extern void nouveauDDUpdateState(GLcontext *ctx); extern void nouveauDDUpdateHWState(GLcontext *ctx); diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index e6e5fdbd15..ded9d0934f 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -34,7 +34,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "mtypes.h" #include "colormac.h" -void nv30AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) +static void nv30AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); GLubyte ubRef; @@ -45,7 +45,7 @@ void nv30AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) OUT_RING(ubRef); /* NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF */ } -void nv30BlendColor(GLcontext *ctx, const GLfloat color[4]) +static void nv30BlendColor(GLcontext *ctx, const GLfloat color[4]) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); GLubyte cf[4]; @@ -59,7 +59,7 @@ void nv30BlendColor(GLcontext *ctx, const GLfloat color[4]) OUT_RING(PACK_COLOR_8888(cf[3], cf[1], cf[2], cf[0])); } -void nv30BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA) +static void nv30BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_EQUATION, 1); @@ -67,7 +67,7 @@ void nv30BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA) } -void nv30BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, +static void nv30BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); @@ -76,7 +76,7 @@ void nv30BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, OUT_RING((dfactorA<<16) | dfactorRGB); } -void nv30ClearColor(GLcontext *ctx, const GLfloat color[4]) +static void nv30ClearColor(GLcontext *ctx, const GLfloat color[4]) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); GLubyte c[4]; @@ -85,7 +85,7 @@ void nv30ClearColor(GLcontext *ctx, const GLfloat color[4]) OUT_RING(PACK_COLOR_8888(c[3],c[0],c[1],c[2])); } -void nv30ClearDepth(GLcontext *ctx, GLclampd d) +static void nv30ClearDepth(GLcontext *ctx, GLclampd d) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); nmesa->clear_value=((nmesa->clear_value&0x000000FF)|(((uint32_t)(d*0xFFFFFF))<<8)); @@ -97,7 +97,7 @@ void nv30ClearDepth(GLcontext *ctx, GLclampd d) void (*ClearIndex)(GLcontext *ctx, GLuint index) */ -void nv30ClearStencil(GLcontext *ctx, GLint s) +static void nv30ClearStencil(GLcontext *ctx, GLint s) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); nmesa->clear_value=((nmesa->clear_value&0xFFFFFF00)|(s&0x000000FF)); @@ -105,7 +105,7 @@ void nv30ClearStencil(GLcontext *ctx, GLint s) OUT_RING(nmesa->clear_value); } -void nv30ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) +static void nv30ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4); @@ -115,7 +115,7 @@ void nv30ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) OUT_RINGf(equation[3]); } -void nv30ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, +static void nv30ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, GLboolean bmask, GLboolean amask ) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); @@ -123,40 +123,40 @@ void nv30ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, OUT_RING(((amask && 0x01) << 24) | ((rmask && 0x01) << 16) | ((gmask && 0x01)<< 8) | ((bmask && 0x01) << 0)); } -void nv30ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode) +static void nv30ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode) { // TODO I need love } -void nv30CullFace(GLcontext *ctx, GLenum mode) +static void nv30CullFace(GLcontext *ctx, GLenum mode) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CULL_FACE, 1); OUT_RING(mode); } -void nv30FrontFace(GLcontext *ctx, GLenum mode) +static void nv30FrontFace(GLcontext *ctx, GLenum mode) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FRONT_FACE, 1); OUT_RING(mode); } -void nv30DepthFunc(GLcontext *ctx, GLenum func) +static void nv30DepthFunc(GLcontext *ctx, GLenum func) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1); OUT_RING(func); } -void nv30DepthMask(GLcontext *ctx, GLboolean flag) +static void nv30DepthMask(GLcontext *ctx, GLboolean flag) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1); OUT_RING(flag); } -void nv30DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval) +static void nv30DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2); @@ -169,7 +169,7 @@ void nv30DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval) /** Specify the buffers for writing for fragment programs*/ //void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers ); -void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) +static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); switch(cap) @@ -311,7 +311,7 @@ void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) } } -void nv30Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +static void nv30Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); switch(pname) @@ -327,14 +327,14 @@ void nv30Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) } -void nv30Hint(GLcontext *ctx, GLenum target, GLenum mode) +static void nv30Hint(GLcontext *ctx, GLenum target, GLenum mode) { // TODO I need love (fog and line_smooth hints) } // void (*IndexMask)(GLcontext *ctx, GLuint mask); -void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params ) +static void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params ) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); /* not sure where the fourth param value goes...*/ @@ -401,31 +401,31 @@ void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *para } /** Set the lighting model parameters */ -void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params); +static void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params); -void nv30LineStipple(GLcontext *ctx, GLint factor, GLushort pattern ) +static void nv30LineStipple(GLcontext *ctx, GLint factor, GLushort pattern ) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN, 1); OUT_RING((pattern << 16) | factor); } -void nv30LineWidth(GLcontext *ctx, GLfloat width) +static void nv30LineWidth(GLcontext *ctx, GLfloat width) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_WIDTH_SMOOTH, 1); OUT_RINGf(width); } -void nv30LogicOpcode(GLcontext *ctx, GLenum opcode) +static void nv30LogicOpcode(GLcontext *ctx, GLenum opcode) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LOGIC_OP_OP, 1); OUT_RING(opcode); } -void nv30PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +static void nv30PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params) { /*TODO: not sure what goes here. */ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); @@ -433,15 +433,27 @@ void nv30PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params) } /** Specify the diameter of rasterized points */ -void nv30PointSize(GLcontext *ctx, GLfloat size) +static void nv30PointSize(GLcontext *ctx, GLfloat size) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POINT_SIZE, 1); - OUT_RINGf(size); + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POINT_SIZE, 1); + OUT_RINGf(size); } /** Select a polygon rasterization mode */ -void (*PolygonMode)(GLcontext *ctx, GLenum face, GLenum mode); +static void nv30PolygonMode(GLcontext *ctx, GLenum face, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + int method; + + if (face == GL_FRONT) + method = NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT; + else + method = NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK; + BEGIN_RING_SIZE(NvSub3D, method, 1); + OUT_RING(mode); +} + /** Set the scale and units used to calculate depth values */ void (*PolygonOffset)(GLcontext *ctx, GLfloat factor, GLfloat units); /** Set the polygon stippling pattern */ @@ -475,7 +487,7 @@ void (*TexParameter)(GLcontext *ctx, GLenum target, void (*TextureMatrix)(GLcontext *ctx, GLuint unit, const GLmatrix *mat); /** Set the viewport */ -void nv30Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +static void nv30Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) { /* TODO: Where do the VIEWPORT_XFRM_* regs come in? */ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); @@ -484,3 +496,48 @@ void nv30Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) OUT_RING((h << 16) | y); } +void nv30InitStateFuncs(struct dd_function_table *func) +{ + func->AlphaFunc = nv30AlphaFunc; + func->BlendColor = nv30BlendColor; + func->BlendEquationSeparate = nv30BlendEquationSeparate; + func->BlendFuncSeparate = nv30BlendFuncSeparate; + func->ClearColor = nv30ClearColor; + func->ClearDepth = nv30ClearDepth; + func->ClearStencil = nv30ClearStencil; + func->ClipPlane = nv30ClipPlane; + func->ColorMask = nv30ColorMask; + func->ColorMaterial = nv30ColorMaterial; + func->CullFace = nv30CullFace; + func->FrontFace = nv30FrontFace; + func->DepthFunc = nv30DepthFunc; + func->DepthMask = nv30DepthMask; + func->DepthRange = nv30DepthRange; + func->Enable = nv30Enable; + func->Fogfv = nv30Fogfv; + func->Hint = nv30Hint; + func->Lightfv = nv30Lightfv; +/* func->LightModelfv = nv30LightModelfv; */ + func->LineStipple = nv30LineStipple; + func->LineWidth = nv30LineWidth; + func->LogicOpcode = nv30LogicOpcode; + func->PointParameterfv = nv30PointParameterfv; + func->PointSize = nv30PointSize; + func->PolygonMode = nv30PolygonMode; +#if 0 + func->PolygonOffset = nv30PolygonOffset; + func->PolygonStipple = nv30PolygonStipple; + func->ReadBuffer = nv30ReadBuffer; + func->RenderMode = nv30RenderMode; + func->Scissor = nv30Scissor; + func->ShadeModel = nv30ShaderModel; + func->StencilFuncSeparate = nv30StencilFuncSeparate; + func->StencilMaskSeparate = nv30StencilMaskSeparate; + func->StencilOpSeparate = nv30StencilOpSeparate; + func->TexGen = nv30TexGen; + func->TexParameter = nv30TexParameter; + func->TextureMatrix = nv30TextureMatrix; +#endif + func->Viewport = nv30Viewport; +} + -- cgit v1.2.3 From 9daf0812a15ed7df0e3a329019290faed58d21ef Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 16 Nov 2006 23:43:39 +0000 Subject: jkolb pointed out that face can also be FRONT_AND_BACK. Added stencil funcs --- src/mesa/drivers/dri/nouveau/nv30_state.c | 75 ++++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 12 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index ded9d0934f..470f18d80a 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -444,14 +444,15 @@ static void nv30PointSize(GLcontext *ctx, GLfloat size) static void nv30PolygonMode(GLcontext *ctx, GLenum face, GLenum mode) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - int method; - if (face == GL_FRONT) - method = NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT; - else - method = NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK; - BEGIN_RING_SIZE(NvSub3D, method, 1); - OUT_RING(mode); + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 1); + OUT_RING(mode); + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK, 1); + OUT_RING(mode); + } } /** Set the scale and units used to calculate depth values */ @@ -466,14 +467,62 @@ void (*RenderMode)(GLcontext *ctx, GLenum mode ); void (*Scissor)(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h); /** Select flat or smooth shading */ void (*ShadeModel)(GLcontext *ctx, GLenum mode); + /** OpenGL 2.0 two-sided StencilFunc */ -void (*StencilFuncSeparate)(GLcontext *ctx, GLenum face, GLenum func, - GLint ref, GLuint mask); +static void nv30StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, + GLint ref, GLuint mask) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_FUNC, 3); + OUT_RING(func); + OUT_RING(ref); + OUT_RING(mask); + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_FUNC, 3); + OUT_RING(func); + OUT_RING(ref); + OUT_RING(mask); + } +} + /** OpenGL 2.0 two-sided StencilMask */ -void (*StencilMaskSeparate)(GLcontext *ctx, GLenum face, GLuint mask); +static void nv30StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_MASK, 1); + OUT_RING(mask); + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_MASK, 1); + OUT_RING(mask); + } +} + /** OpenGL 2.0 two-sided StencilOp */ -void (*StencilOpSeparate)(GLcontext *ctx, GLenum face, GLenum fail, - GLenum zfail, GLenum zpass); +static void nv30StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, + GLenum zfail, GLenum zpass) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_FAIL, 1); + OUT_RING(fail); + OUT_RING(zfail); + OUT_RING(zpass); + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_FAIL, 1); + OUT_RING(fail); + OUT_RING(zfail); + OUT_RING(zpass); + } +} + /** Control the generation of texture coordinates */ void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname, const GLfloat *params); @@ -531,9 +580,11 @@ void nv30InitStateFuncs(struct dd_function_table *func) func->RenderMode = nv30RenderMode; func->Scissor = nv30Scissor; func->ShadeModel = nv30ShaderModel; +#endif func->StencilFuncSeparate = nv30StencilFuncSeparate; func->StencilMaskSeparate = nv30StencilMaskSeparate; func->StencilOpSeparate = nv30StencilOpSeparate; +#if 0 func->TexGen = nv30TexGen; func->TexParameter = nv30TexParameter; func->TextureMatrix = nv30TextureMatrix; -- cgit v1.2.3 From 10172f7485367182a5745a2114ed7e90830682f8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 17 Nov 2006 04:50:37 +0000 Subject: Adapt FIFO code to deal with cases where the base GET/PUT value isn't 0. --- src/mesa/drivers/dri/nouveau/nouveau_context.h | 1 + src/mesa/drivers/dri/nouveau/nouveau_fifo.c | 16 ++++++++++------ src/mesa/drivers/dri/nouveau/nouveau_fifo.h | 12 +++++++----- 3 files changed, 18 insertions(+), 11 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 1da5b6d61d..85d71cb04c 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -43,6 +43,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. typedef struct nouveau_fifo_t{ u_int32_t* buffer; u_int32_t* mmio; + u_int32_t put_base; u_int32_t current; u_int32_t put; u_int32_t free; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c index 52c227cccc..8d2e88b1f3 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c @@ -46,19 +46,19 @@ void WAIT_RING(nouveauContextPtr nmesa,u_int32_t size) #endif u_int32_t fifo_get; while(nmesa->fifo.free < size+1) { - fifo_get = NV_FIFO_READ(NV03_FIFO_REGS_DMAGET); + fifo_get = NV_FIFO_READ_GET(); 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); \ + OUT_RING(NV03_FIFO_CMD_JUMP | nmesa->fifo.put_base); 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); } + NV_FIFO_WRITE_PUT(RING_SKIPS + 1); + do { fifo_get = NV_FIFO_READ_GET(); } while(fifo_get <= RING_SKIPS); } - NV_FIFO_WRITE(NV03_FIFO_REGS_DMAPUT, RING_SKIPS); + NV_FIFO_WRITE_PUT(RING_SKIPS); nmesa->fifo.current = nmesa->fifo.put = RING_SKIPS; nmesa->fifo.free = fifo_get - (RING_SKIPS + 1); } @@ -134,7 +134,11 @@ GLboolean nouveauFifoInit(nouveauContextPtr nmesa) } /* Setup our initial FIFO tracking params */ - nmesa->fifo.free = fifo_init.cmdbuf_size >> 2; + nmesa->fifo.put_base = fifo_init.put_base; + nmesa->fifo.current = 0; + nmesa->fifo.put = 0; + nmesa->fifo.max = (fifo_init.cmdbuf_size >> 2) - 1; + nmesa->fifo.free = nmesa->fifo.max - nmesa->fifo.current; MESSAGE("Fifo init ok. Using context %d\n", fifo_init.channel); return GL_TRUE; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h index 0edb083388..c1e9fd5dc5 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h @@ -38,6 +38,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #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; +#define NV_FIFO_READ_GET() ((NV_FIFO_READ(NV03_FIFO_REGS_DMAGET) - nmesa->fifo.put_base) >> 2) +#define NV_FIFO_WRITE_PUT(val) NV_FIFO_WRITE(NV03_FIFO_REGS_DMAPUT, ((val)<<2) + nmesa->fifo.put_base) /* * Ring/fifo interface @@ -107,11 +109,11 @@ extern void WAIT_RING(nouveauContextPtr nmesa,u_int32_t size); #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);\ - }\ +#define FIRE_RING() do { \ + if (nmesa->fifo.current!=nmesa->fifo.put) { \ + nmesa->fifo.put=nmesa->fifo.current; \ + NV_FIFO_WRITE_PUT(nmesa->fifo.put); \ + } \ }while(0) extern void nouveauWaitForIdle(nouveauContextPtr nmesa); -- cgit v1.2.3 From 08020927e826068a1ebc208e63c6a0d53711e96e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 17 Nov 2006 21:58:02 +0000 Subject: Use RENDERINPUTS macros to access render_inputs_bitset --- src/mesa/drivers/dri/nouveau/nouveau_context.h | 2 +- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 24 ++++++++++++++---------- 2 files changed, 15 insertions(+), 11 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 85d71cb04c..09972bebac 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -114,7 +114,7 @@ typedef struct nouveau_context { /* The rendering context information */ GLenum current_primitive; /* the current primitive enum */ - GLuint render_inputs_bitset; /* the current render inputs */ + DECLARE_RENDERINPUTS(render_inputs_bitset); /* the current render inputs */ nouveauScreenRec *screen; drm_nouveau_sarea_t *sarea; diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 510704f7d4..772a5368e9 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -627,10 +627,11 @@ static void nv10ChooseRenderState(GLcontext *ctx) -static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa, GLuint index) +static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa) { GLcontext* ctx=nmesa->glCtx; TNLcontext *tnl = TNL_CONTEXT(ctx); + DECLARE_RENDERINPUTS(index); struct vertex_buffer *VB = &tnl->vb; int attr_size[16]; int default_attr_size[8]={3,3,3,4,3,1,4,4}; @@ -638,20 +639,22 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa, GLuint int slots=0; int total_size=0; + RENDERINPUTS_COPY(index, nmesa->render_inputs_bitset); + /* * Determine attribute sizes */ for(i=0;i<8;i++) { - if (index&(1<TexCoordPtr[i]->size; + if (RENDERINPUTS_TEST(index, i)) + attr_size[i]=VB->TexCoordPtr[i-8]->size; else attr_size[i]=0; } @@ -661,7 +664,7 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa, GLuint */ for(i=0;i<16;i++) { - if (index&(1<render_inputs_bitset; - - if (index!=nmesa->render_inputs_bitset) + DECLARE_RENDERINPUTS(index); + + RENDERINPUTS_COPY(index, tnl->render_inputs_bitset); + if (!RENDERINPUTS_EQUAL(index, nmesa->render_inputs_bitset)) { - nmesa->render_inputs_bitset=index; - nv10OutputVertexFormat(nmesa,index); + RENDERINPUTS_COPY(nmesa->render_inputs_bitset, index); + nv10OutputVertexFormat(nmesa); } } -- cgit v1.2.3 From 8532b6e0a56b09e03e034e37850589d26c20805b Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Fri, 17 Nov 2006 22:11:13 +0000 Subject: Small unneeded nv03 fix --- src/mesa/drivers/dri/nouveau/nouveau_card.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_card.c b/src/mesa/drivers/dri/nouveau/nouveau_card.c index c36f62aff6..4a5d5eb9d7 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_card.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_card.c @@ -3,7 +3,7 @@ #include "nouveau_reg.h" static nouveau_card nouveau_card_list[]={ -//x0010, "Riva 128", ????, NV_03, 0}, +//{0x0010, "Riva 128", ????, NV_03, 0}, {0x0020, "TNT/TNT2", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, {0x00A0, "TNT2", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, {0x0100, "GeForce", NV10_TCL_PRIMITIVE_3D, NV_10, 0}, -- cgit v1.2.3 From e722e3480f3a5b975c05b584f9acef222c2c9d6b Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sat, 18 Nov 2006 00:19:22 +0000 Subject: Add nv20_state.c ; hook nv10_state.c into the build ; do the renaming required by the renouveau changes. --- src/mesa/drivers/dri/nouveau/Makefile | 2 + src/mesa/drivers/dri/nouveau/nouveau_reg.h | 61 +-- src/mesa/drivers/dri/nouveau/nv10_state.c | 21 +- src/mesa/drivers/dri/nouveau/nv20_state.c | 575 +++++++++++++++++++++++++++++ src/mesa/drivers/dri/nouveau/nv30_state.c | 4 +- 5 files changed, 621 insertions(+), 42 deletions(-) create mode 100644 src/mesa/drivers/dri/nouveau/nv20_state.c (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile index ed700a7085..2db6f8989d 100644 --- a/src/mesa/drivers/dri/nouveau/Makefile +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -20,6 +20,8 @@ DRIVER_SOURCES = \ nouveau_tex.c \ nouveau_swtcl.c \ nv10_swtcl.c \ + nv10_state.c \ + nv20_state.c \ nv30_state.c C_SOURCES = \ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_reg.h b/src/mesa/drivers/dri/nouveau/nouveau_reg.h index c5052d7c4b..389c541e1c 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_reg.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_reg.h @@ -43,7 +43,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ************************************************************************** - Created from objects.c rev. 1.332 + Created from objects.c rev. 1.337 */ #ifndef _NOUVEAU_REG_H @@ -239,7 +239,7 @@ Object NV04_SCALED_IMAGE_FROM_MEMORY used on: NV04 # define NV04_SCALED_IMAGE_FROM_MEMORY_DU_DX 0x00000318 /* Parameters: int frac*0x100000 */ # define NV04_SCALED_IMAGE_FROM_MEMORY_DV_DY 0x0000031c /* Parameters: int frac*0x100000 */ # define NV04_SCALED_IMAGE_FROM_MEMORY_SIZE 0x00000400 /* Parameters: width height */ -# define NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT 0x00000404 /* Parameters: pitch */ +# define NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT 0x00000404 /* Parameters: pitch origin filter */ # define NV04_SCALED_IMAGE_FROM_MEMORY_OFFSET 0x00000408 # define NV04_SCALED_IMAGE_FROM_MEMORY_POINT 0x0000040c /* Parameters: u_int u_frac*0x10 v_int v_frac*0x10 */ @@ -328,7 +328,7 @@ Object NV10_TCL_PRIMITIVE_3D used on: NV10 # define NV10_TCL_PRIMITIVE_3D_FOG_COLOR 0x000002a8 /* Parameters: a b g r */ # define NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(d) (0x000002c0 + d * 0x0004) /* Parameters: x2 x1 */ # define NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(d) (0x000002e0 + d * 0x0004) /* Parameters: y2 y1 */ -# define NV10_TCL_PRIMITIVE_3D_ALPHA_TEST_ENABLE 0x00000300 +# define NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE 0x00000300 # define NV10_TCL_PRIMITIVE_3D_BLEND_ENABLE 0x00000304 # define NV10_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE 0x00000308 # define NV10_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE 0x0000030c @@ -339,11 +339,11 @@ Object NV10_TCL_PRIMITIVE_3D used on: NV10 # define NV10_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE 0x00000320 # define NV10_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE 0x00000324 # define NV10_TCL_PRIMITIVE_3D_VERTEX_WEIGHT_ENABLE 0x00000328 -# define NV10_TCL_PRIMITIVE_3D_STENCIL_TEST_ENABLE 0x0000032c +# define NV10_TCL_PRIMITIVE_3D_STENCIL_ENABLE 0x0000032c # define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE 0x00000330 # define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE 0x00000334 # define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE 0x00000338 -# define NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC 0x0000033c +# define NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC 0x0000033c # define NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF 0x00000340 # define NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC 0x00000344 # define NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_DST 0x00000348 @@ -351,7 +351,7 @@ Object NV10_TCL_PRIMITIVE_3D used on: NV10 # define NV10_TCL_PRIMITIVE_3D_BLEND_EQUATION 0x00000350 # define NV10_TCL_PRIMITIVE_3D_DEPTH_FUNC 0x00000354 # define NV10_TCL_PRIMITIVE_3D_COLOR_MASK 0x00000358 /* Parameters: r g b */ -# define NV10_TCL_PRIMITIVE_3D_DEPTH_MASK 0x0000035c +# define NV10_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE 0x0000035c # define NV10_TCL_PRIMITIVE_3D_STENCIL_MASK 0x00000360 # define NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC 0x00000364 # define NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_REF 0x00000368 @@ -534,7 +534,7 @@ Object NV15_TCL_PRIMITIVE_3D used on: NV15 # define NV17_TCL_PRIMITIVE_3D_COLOR_MASK_ENABLE 0x000002bc # define NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(d) (0x000002c0 + d * 0x0004) /* Parameters: x2 x1 */ # define NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(d) (0x000002e0 + d * 0x0004) /* Parameters: y2 y1 */ -# define NV10_TCL_PRIMITIVE_3D_ALPHA_TEST_ENABLE 0x00000300 +# define NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE 0x00000300 # define NV10_TCL_PRIMITIVE_3D_BLEND_ENABLE 0x00000304 # define NV10_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE 0x00000308 # define NV10_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE 0x0000030c @@ -545,11 +545,11 @@ Object NV15_TCL_PRIMITIVE_3D used on: NV15 # define NV10_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE 0x00000320 # define NV10_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE 0x00000324 # define NV10_TCL_PRIMITIVE_3D_VERTEX_WEIGHT_ENABLE 0x00000328 -# define NV10_TCL_PRIMITIVE_3D_STENCIL_TEST_ENABLE 0x0000032c +# define NV10_TCL_PRIMITIVE_3D_STENCIL_ENABLE 0x0000032c # define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE 0x00000330 # define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE 0x00000334 # define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE 0x00000338 -# define NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC 0x0000033c +# define NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC 0x0000033c # define NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF 0x00000340 # define NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC 0x00000344 # define NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_DST 0x00000348 @@ -557,7 +557,7 @@ Object NV15_TCL_PRIMITIVE_3D used on: NV15 # define NV10_TCL_PRIMITIVE_3D_BLEND_EQUATION 0x00000350 # define NV10_TCL_PRIMITIVE_3D_DEPTH_FUNC 0x00000354 # define NV10_TCL_PRIMITIVE_3D_COLOR_MASK 0x00000358 /* Parameters: r g b */ -# define NV10_TCL_PRIMITIVE_3D_DEPTH_MASK 0x0000035c +# define NV10_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE 0x0000035c # define NV10_TCL_PRIMITIVE_3D_STENCIL_MASK 0x00000360 # define NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC 0x00000364 # define NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_REF 0x00000368 @@ -797,17 +797,17 @@ Object NV10_CONTEXT_SURFACES_2D used on: NV10 NV15 NV20 NV30 NV40 G70 # define NV10_CONTEXT_SURFACES_2D_OFFSET_DST 0x0000030c /****************************************** -Object NV04_SURFACE used on: NV04 NV10 NV15 +Object NV04_CONTEXT_SURFACES_2D used on: NV04 NV10 NV15 */ -#define NV04_SURFACE 0x00000042 -# define NV04_SURFACE_NOTIFY 0x00000104 -# define NV04_SURFACE_DMA_NOTIFY 0x00000180 -# define NV04_SURFACE_DMA_IMAGE_SOURCE 0x00000184 -# define NV04_SURFACE_DMA_IMAGE_DESTIN 0x00000188 -# define NV04_SURFACE_FORMAT 0x00000300 -# define NV04_SURFACE_PITCH 0x00000304 /* Parameters: source destin */ -# define NV04_SURFACE_OFFSET_SOURCE 0x00000308 -# define NV04_SURFACE_OFFSET_DESTIN 0x0000030c +#define NV04_CONTEXT_SURFACES_2D 0x00000042 +# define NV04_CONTEXT_SURFACES_2D_NOTIFY 0x00000104 +# define NV04_CONTEXT_SURFACES_2D_SET_DMA_NOTIFY 0x00000180 +# define NV04_CONTEXT_SURFACES_2D_SET_DMA_IMAGE_SRC 0x00000184 +# define NV04_CONTEXT_SURFACES_2D_SET_DMA_IMAGE_DST 0x00000188 +# define NV04_CONTEXT_SURFACES_2D_FORMAT 0x00000300 +# define NV04_CONTEXT_SURFACES_2D_PITCH 0x00000304 /* Parameters: src dst */ +# define NV04_CONTEXT_SURFACES_2D_OFFSET_SRC 0x00000308 +# define NV04_CONTEXT_SURFACES_2D_OFFSET_DST 0x0000030c /****************************************** Object NV04_IMAGE_PATTERN used on: NV04 NV10 NV15 NV20 NV30 NV40 G70 @@ -858,16 +858,18 @@ Object NV20_TCL_PRIMITIVE_3D used on: NV20 # define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_CONTROL 0x00000298 /* Parameters: back_specular back_ambient back_diffuse back_emission front_specular front_ambient front_diffuse front_emission */ # define NV20_TCL_PRIMITIVE_3D_FOG_MODE 0x0000029c # define NV20_TCL_PRIMITIVE_3D_FOG_COORD_DIST 0x000002a0 -# define NV20_TCL_PRIMITIVE_3D_ALPHA_TEST_ENABLE 0x00000300 -# define NV20_TCL_PRIMITIVE_3D_BLEND_ENABLE 0x00000304 +# define NV20_TCL_PRIMITIVE_3D_FOG_ENABLE 0x000002a4 +# define NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE 0x00000300 +# define NV20_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE 0x00000304 # define NV20_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE 0x00000308 # define NV20_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE 0x0000030c # define NV20_TCL_PRIMITIVE_3D_DITHER_ENABLE 0x00000310 # define NV20_TCL_PRIMITIVE_3D_LIGHTING_ENABLE 0x00000314 +# define NV20_TCL_PRIMITIVE_3D_POINT_SMOOTH_ENABLE 0x0000031c # define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETERS_ENABLE 0x00000318 # define NV20_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE 0x00000320 # define NV20_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE 0x00000324 -# define NV20_TCL_PRIMITIVE_3D_STENCIL_TEST_ENABLE 0x0000032c +# define NV20_TCL_PRIMITIVE_3D_STENCIL_ENABLE 0x0000032c # define NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE 0x00000330 # define NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE 0x00000334 # define NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE 0x00000338 @@ -879,7 +881,7 @@ Object NV20_TCL_PRIMITIVE_3D used on: NV20 # define NV20_TCL_PRIMITIVE_3D_BLEND_EQUATION 0x00000350 # define NV20_TCL_PRIMITIVE_3D_DEPTH_FUNC 0x00000354 # define NV20_TCL_PRIMITIVE_3D_COLOR_MASK 0x00000358 /* Parameters: a r g b */ -# define NV20_TCL_PRIMITIVE_3D_DEPTH_MASK 0x0000035c +# define NV20_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE 0x0000035c # define NV20_TCL_PRIMITIVE_3D_STENCIL_MASK 0x00000360 # define NV20_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC 0x00000364 # define NV20_TCL_PRIMITIVE_3D_STENCIL_FUNC_REF 0x00000368 @@ -1081,11 +1083,12 @@ Object NV20_TCL_PRIMITIVE_3D used on: NV20 # define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION 0x000017a0 # define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK 0x000017b0 # define NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE 0x000017bc -# define NV20_TCL_PRIMITIVE_3D_LOGIC_OP 0x000017c0 +# define NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP 0x000017c0 # define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_TWO_SIDE_ENABLE 0x000017c4 # define NV20_TCL_PRIMITIVE_3D_BEGIN_END 0x000017fc -# define NV20_TCL_PRIMITIVE_3D_CLEAR_COLOR 0x00001d90 -# define NV20_TCL_PRIMITIVE_3D_CLEAR_MASK 0x00001d94 /* Parameters: clear color a clear color b clear color g clear color r clear depth clear stencil */ +# define NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH 0x00001d8c +# define NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB 0x00001d90 +# define NV20_TCL_PRIMITIVE_3D_CLEAR_WHICH_BUFFERS 0x00001d94 /* Parameters: clear color a clear color b clear color g clear color r clear depth clear stencil */ # define NV20_TCL_PRIMITIVE_3D_INDEX_DATA 0x00001800 /* Parameters: index1 index0 */ # define NV20_TCL_PRIMITIVE_3D_VB_VERTEX_BATCH 0x00001810 /* Parameters: count_vertices offset_vertices */ # define NV20_TCL_PRIMITIVE_3D_VERTEX_DATA 0x00001818 @@ -1330,8 +1333,8 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_TX_DEPTH_UNIT(d) (0x00001840 + d * 0x0004) /* Parameters: depth NPOT pitch */ # define NV30_TCL_PRIMITIVE_3D_VB_VERTEX_BATCH 0x00001814 /* Parameters: count_vertices offset_vertices */ # define NV30_TCL_PRIMITIVE_3D_VERTEX_DATA 0x00001818 -# define NV30_TCL_PRIMITIVE_3D_LOGIC_OP_ENABLE 0x00000374 -# define NV30_TCL_PRIMITIVE_3D_LOGIC_OP_OP 0x00000378 +# define NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE 0x00000374 +# define NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP 0x00000378 # define NV30_TCL_PRIMITIVE_3D_SET_DISPLAY_LIST_MEM_OFFSET 0x0000181c # define NV30_TCL_PRIMITIVE_3D_EXECUTE_DISPLAY_LIST 0x00001824 /* Parameters: length start offset */ # define NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT 0x00001828 diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index e752905841..a8592acc84 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -40,8 +40,8 @@ void nv10AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) GLubyte ubRef; CLAMPED_FLOAT_TO_UBYTE(ubRef, ref); - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC, 2); - OUT_RING(func); /* NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC */ + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2); + OUT_RING(func); /* NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC */ OUT_RING(ubRef); /* NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF */ } @@ -157,7 +157,7 @@ void nv10DepthFunc(GLcontext *ctx, GLenum func) void nv10DepthMask(GLcontext *ctx, GLboolean flag) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_MASK, 1); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1); OUT_RING(flag); } @@ -180,7 +180,7 @@ void nv10Enable(GLcontext *ctx, GLenum cap, GLboolean state) switch(cap) { case GL_ALPHA_TEST: - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ALPHA_TEST_ENABLE, 1); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1); OUT_RING(state); break; // case GL_AUTO_NORMAL: @@ -198,7 +198,7 @@ void nv10Enable(GLcontext *ctx, GLenum cap, GLboolean state) OUT_RING(state); break; case GL_COLOR_LOGIC_OP: - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LOGIC_OP_ENABLE, 1); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1); OUT_RING(state); break; // case GL_COLOR_MATERIAL: @@ -250,7 +250,10 @@ void nv10Enable(GLcontext *ctx, GLenum cap, GLboolean state) else OUT_RING(0x0); break; -// case GL_LINE_SMOOTH: + case GL_LINE_SMOOTH: + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1); + OUT_RING(state); + break; // case GL_LINE_STIPPLE: // case GL_MAP1_COLOR_4: // case GL_MAP1_INDEX: @@ -292,10 +295,6 @@ void nv10Enable(GLcontext *ctx, GLenum cap, GLboolean state) BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1); OUT_RING(state); break; - case GL_LINE_SMOOTH: - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1); - OUT_RING(state); - break; case GL_POINT_SMOOTH: BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POINT_SMOOTH_ENABLE, 1); OUT_RING(state); @@ -307,7 +306,7 @@ void nv10Enable(GLcontext *ctx, GLenum cap, GLboolean state) // case GL_SCISSOR_TEST: // case GL_SEPARABLE_2D: case GL_STENCIL_TEST: - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_TEST_ENABLE, 1); + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_ENABLE, 1); OUT_RING(state); break; // case GL_TEXTURE_GEN_Q: diff --git a/src/mesa/drivers/dri/nouveau/nv20_state.c b/src/mesa/drivers/dri/nouveau/nv20_state.c new file mode 100644 index 0000000000..88b8d6d204 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_state.c @@ -0,0 +1,575 @@ +/************************************************************************** + +Copyright 2006 Nouveau +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_object.h" +#include "nouveau_fifo.h" +#include "nouveau_reg.h" + +#include "tnl/t_pipeline.h" + +#include "mtypes.h" +#include "colormac.h" + +static void nv20AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte ubRef; + CLAMPED_FLOAT_TO_UBYTE(ubRef, ref); + + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2); + OUT_RING(func); /* NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC */ + OUT_RING(ubRef); /* NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF */ +} + +static void nv20BlendColor(GLcontext *ctx, const GLfloat color[4]) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte cf[4]; + + CLAMPED_FLOAT_TO_UBYTE(cf[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(cf[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(cf[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(cf[3], color[3]); + + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_BLEND_COLOR, 1); + OUT_RING(PACK_COLOR_8888(cf[3], cf[1], cf[2], cf[0])); +} + +static void nv20BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_BLEND_EQUATION, 1); + OUT_RING((modeA<<16) | modeRGB); +} + + +static void nv20BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2); + OUT_RING((sfactorA<<16) | sfactorRGB); + OUT_RING((dfactorA<<16) | dfactorRGB); +} + +static void nv20ClearColor(GLcontext *ctx, const GLfloat color[4]) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte c[4]; + UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,color); + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB, 1); + OUT_RING(PACK_COLOR_8888(c[3],c[0],c[1],c[2])); +} + +static void nv20ClearDepth(GLcontext *ctx, GLclampd d) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nmesa->clear_value=((nmesa->clear_value&0x000000FF)|(((uint32_t)(d*0xFFFFFF))<<8)); + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1); + OUT_RING(nmesa->clear_value); +} + +/* we're don't support indexed buffers + void (*ClearIndex)(GLcontext *ctx, GLuint index) + */ + +static void nv20ClearStencil(GLcontext *ctx, GLint s) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nmesa->clear_value=((nmesa->clear_value&0xFFFFFF00)|(s&0x000000FF)); + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1); + OUT_RING(nmesa->clear_value); +} + +static void nv20ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4); + OUT_RINGf(equation[0]); + OUT_RINGf(equation[1]); + OUT_RINGf(equation[2]); + OUT_RINGf(equation[3]); +} + +static void nv20ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, + GLboolean bmask, GLboolean amask ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_COLOR_MASK, 1); + OUT_RING(((amask && 0x01) << 24) | ((rmask && 0x01) << 16) | ((gmask && 0x01)<< 8) | ((bmask && 0x01) << 0)); +} + +static void nv20ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode) +{ + // TODO I need love +} + +static void nv20CullFace(GLcontext *ctx, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CULL_FACE, 1); + OUT_RING(mode); +} + +static void nv20FrontFace(GLcontext *ctx, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_FRONT_FACE, 1); + OUT_RING(mode); +} + +static void nv20DepthFunc(GLcontext *ctx, GLenum func) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1); + OUT_RING(func); +} + +static void nv20DepthMask(GLcontext *ctx, GLboolean flag) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1); + OUT_RING(flag); +} + +static void nv20DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2); + OUT_RINGf(nearval); + OUT_RINGf(farval); +} + +/** Specify the current buffer for writing */ +//void (*DrawBuffer)( GLcontext *ctx, GLenum buffer ); +/** Specify the buffers for writing for fragment programs*/ +//void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers ); + +static void nv20Enable(GLcontext *ctx, GLenum cap, GLboolean state) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + switch(cap) + { + case GL_ALPHA_TEST: + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1); + OUT_RING(state); + break; +// case GL_AUTO_NORMAL: + case GL_BLEND: + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1); + OUT_RING(state); + break; + case GL_CLIP_PLANE0: + case GL_CLIP_PLANE1: + case GL_CLIP_PLANE2: + case GL_CLIP_PLANE3: + case GL_CLIP_PLANE4: + case GL_CLIP_PLANE5: + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1); + OUT_RING(state); + break; + case GL_COLOR_LOGIC_OP: + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1); + OUT_RING(state); + break; +// case GL_COLOR_MATERIAL: +// case GL_COLOR_SUM_EXT: +// case GL_COLOR_TABLE: +// case GL_CONVOLUTION_1D: +// case GL_CONVOLUTION_2D: + case GL_CULL_FACE: + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1); + OUT_RING(state); + break; + case GL_DEPTH_TEST: + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1); + OUT_RING(state); + break; + case GL_DITHER: + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DITHER_ENABLE, 1); + OUT_RING(state); + break; + case GL_FOG: + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_FOG_ENABLE, 1); + OUT_RING(state); + break; +// case GL_HISTOGRAM: +// case GL_INDEX_LOGIC_OP: + case GL_LIGHT0: + case GL_LIGHT1: + case GL_LIGHT2: + case GL_LIGHT3: + case GL_LIGHT4: + case GL_LIGHT5: + case GL_LIGHT6: + case GL_LIGHT7: + { + uint32_t mask=0x11<<(2*(cap-GL_LIGHT0)); + nmesa->enabled_lights=((nmesa->enabled_lights&mask)|(mask*state)); + if (nmesa->lighting_enabled) + { + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); + OUT_RING(nmesa->enabled_lights); + } + break; + } + case GL_LIGHTING: + nmesa->lighting_enabled=state; + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); + if (nmesa->lighting_enabled) + OUT_RING(nmesa->enabled_lights); + else + OUT_RING(0x0); + break; + case GL_LINE_SMOOTH: + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1); + OUT_RING(state); + break; +// case GL_LINE_STIPPLE: +// case GL_MAP1_COLOR_4: +// case GL_MAP1_INDEX: +// case GL_MAP1_NORMAL: +// case GL_MAP1_TEXTURE_COORD_1: +// case GL_MAP1_TEXTURE_COORD_2: +// case GL_MAP1_TEXTURE_COORD_3: +// case GL_MAP1_TEXTURE_COORD_4: +// case GL_MAP1_VERTEX_3: +// case GL_MAP1_VERTEX_4: +// case GL_MAP2_COLOR_4: +// case GL_MAP2_INDEX: +// case GL_MAP2_NORMAL: +// case GL_MAP2_TEXTURE_COORD_1: +// case GL_MAP2_TEXTURE_COORD_2: +// case GL_MAP2_TEXTURE_COORD_3: +// case GL_MAP2_TEXTURE_COORD_4: +// case GL_MAP2_VERTEX_3: +// case GL_MAP2_VERTEX_4: +// case GL_MINMAX: + case GL_NORMALIZE: + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1); + OUT_RING(state); + break; +// case GL_POINT_SMOOTH: + case GL_POLYGON_OFFSET_POINT: + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 1); + OUT_RING(state); + break; + case GL_POLYGON_OFFSET_LINE: + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE, 1); + OUT_RING(state); + break; + case GL_POLYGON_OFFSET_FILL: + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE, 1); + OUT_RING(state); + break; + case GL_POLYGON_SMOOTH: + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1); + OUT_RING(state); + break; + case GL_POLYGON_STIPPLE: + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE, 1); + OUT_RING(state); + break; +// case GL_POST_COLOR_MATRIX_COLOR_TABLE: +// case GL_POST_CONVOLUTION_COLOR_TABLE: +// case GL_RESCALE_NORMAL: +// case GL_SCISSOR_TEST: +// case GL_SEPARABLE_2D: + case GL_STENCIL_TEST: + // TODO BACK and FRONT ? + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_ENABLE, 1); + OUT_RING(state); + break; +// case GL_TEXTURE_GEN_Q: +// case GL_TEXTURE_GEN_R: +// case GL_TEXTURE_GEN_S: +// case GL_TEXTURE_GEN_T: +// case GL_TEXTURE_1D: +// case GL_TEXTURE_2D: +// case GL_TEXTURE_3D: + } +} + +static void nv20Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + switch(pname) + { + case GL_FOG_MODE: + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_FOG_MODE, 1); + //OUT_RING (params); + break; + /* TODO: unsure about the rest.*/ + default: + break; + } + +} + +static void nv20Hint(GLcontext *ctx, GLenum target, GLenum mode) +{ + // TODO I need love (fog and line_smooth hints) +} + +// void (*IndexMask)(GLcontext *ctx, GLuint mask); + +static void nv20Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + /* not sure where the fourth param value goes...*/ + switch(pname) + { + case GL_AMBIENT: + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_A(light), 3); + OUT_RINGf(params[0]); + OUT_RINGf(params[1]); + OUT_RINGf(params[2]); + break; + case GL_DIFFUSE: + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_A(light), 3); + OUT_RINGf(params[0]); + OUT_RINGf(params[1]); + OUT_RINGf(params[2]); + break; + case GL_SPECULAR: + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_A(light), 3); + OUT_RINGf(params[0]); + OUT_RINGf(params[1]); + OUT_RINGf(params[2]); + break; + case GL_SPOT_DIRECTION: + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(light), 3); + OUT_RINGf(params[0]); + OUT_RINGf(params[1]); + OUT_RINGf(params[2]); + break; + case GL_POSITION: + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(light), 3); + OUT_RINGf(params[0]); + OUT_RINGf(params[1]); + OUT_RINGf(params[2]); + break; + case GL_SPOT_EXPONENT: + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(light), 1); + OUT_RINGf(*params); + break; + case GL_SPOT_CUTOFF: + /* you can't factor these */ + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(light), 1); + OUT_RINGf(params[0]); + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(light), 1); + OUT_RINGf(params[1]); + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(light), 1); + OUT_RINGf(params[2]); + break; + case GL_CONSTANT_ATTENUATION: + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(light), 1); + OUT_RINGf(*params); + break; + case GL_LINEAR_ATTENUATION: + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(light), 1); + OUT_RINGf(*params); + break; + case GL_QUADRATIC_ATTENUATION: + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(light), 1); + OUT_RINGf(*params); + break; + default: + break; + } +} + +/** Set the lighting model parameters */ +static void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params); + + +static void nv20LineStipple(GLcontext *ctx, GLint factor, GLushort pattern ) +{ +/* nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN, 1); + OUT_RING((pattern << 16) | factor);*/ +} + +static void nv20LineWidth(GLcontext *ctx, GLfloat width) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LINE_WIDTH, 1); + OUT_RINGf(width); +} + +static void nv20LogicOpcode(GLcontext *ctx, GLenum opcode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP, 1); + OUT_RING(opcode); +} + +static void nv20PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + /*TODO: not sure what goes here. */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + +} + +/** Specify the diameter of rasterized points */ +static void nv20PointSize(GLcontext *ctx, GLfloat size) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POINT_SIZE, 1); + OUT_RINGf(size); +} + +/** Select a polygon rasterization mode */ +static void nv20PolygonMode(GLcontext *ctx, GLenum face, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 1); + OUT_RING(mode); + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK, 1); + OUT_RING(mode); + } +} + +/** Set the scale and units used to calculate depth values */ +void (*PolygonOffset)(GLcontext *ctx, GLfloat factor, GLfloat units); +/** Set the polygon stippling pattern */ +void (*PolygonStipple)(GLcontext *ctx, const GLubyte *mask ); +/* Specifies the current buffer for reading */ +void (*ReadBuffer)( GLcontext *ctx, GLenum buffer ); +/** Set rasterization mode */ +void (*RenderMode)(GLcontext *ctx, GLenum mode ); +/** Define the scissor box */ +void (*Scissor)(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h); +/** Select flat or smooth shading */ +void (*ShadeModel)(GLcontext *ctx, GLenum mode); + +/** OpenGL 2.0 two-sided StencilFunc */ +static void nv20StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, + GLint ref, GLuint mask) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC, 3); + OUT_RING(func); + OUT_RING(ref); + OUT_RING(mask); +} + +/** OpenGL 2.0 two-sided StencilMask */ +static void nv20StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_MASK, 1); + OUT_RING(mask); +} + +/** OpenGL 2.0 two-sided StencilOp */ +static void nv20StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, + GLenum zfail, GLenum zpass) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL, 1); + OUT_RING(fail); + OUT_RING(zfail); + OUT_RING(zpass); +} + +/** Control the generation of texture coordinates */ +void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname, + const GLfloat *params); +/** Set texture environment parameters */ +void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname, + const GLfloat *param); +/** Set texture parameters */ +void (*TexParameter)(GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj, + GLenum pname, const GLfloat *params); +void (*TextureMatrix)(GLcontext *ctx, GLuint unit, const GLmatrix *mat); + +/** Set the viewport */ +static void nv20Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + /* TODO: Where do the VIEWPORT_XFRM_* regs come in? */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2); + OUT_RING((w << 16) | x); + OUT_RING((h << 16) | y); +} + +void nv20InitStateFuncs(struct dd_function_table *func) +{ + func->AlphaFunc = nv20AlphaFunc; + func->BlendColor = nv20BlendColor; + func->BlendEquationSeparate = nv20BlendEquationSeparate; + func->BlendFuncSeparate = nv20BlendFuncSeparate; + func->ClearColor = nv20ClearColor; + func->ClearDepth = nv20ClearDepth; + func->ClearStencil = nv20ClearStencil; + func->ClipPlane = nv20ClipPlane; + func->ColorMask = nv20ColorMask; + func->ColorMaterial = nv20ColorMaterial; + func->CullFace = nv20CullFace; + func->FrontFace = nv20FrontFace; + func->DepthFunc = nv20DepthFunc; + func->DepthMask = nv20DepthMask; + func->DepthRange = nv20DepthRange; + func->Enable = nv20Enable; + func->Fogfv = nv20Fogfv; + func->Hint = nv20Hint; + func->Lightfv = nv20Lightfv; +/* func->LightModelfv = nv20LightModelfv; */ + func->LineStipple = nv20LineStipple; + func->LineWidth = nv20LineWidth; + func->LogicOpcode = nv20LogicOpcode; + func->PointParameterfv = nv20PointParameterfv; + func->PointSize = nv20PointSize; + func->PolygonMode = nv20PolygonMode; +#if 0 + func->PolygonOffset = nv20PolygonOffset; + func->PolygonStipple = nv20PolygonStipple; + func->ReadBuffer = nv20ReadBuffer; + func->RenderMode = nv20RenderMode; + func->Scissor = nv20Scissor; + func->ShadeModel = nv20ShaderModel; +#endif + func->StencilFuncSeparate = nv20StencilFuncSeparate; + func->StencilMaskSeparate = nv20StencilMaskSeparate; + func->StencilOpSeparate = nv20StencilOpSeparate; +#if 0 + func->TexGen = nv20TexGen; + func->TexParameter = nv20TexParameter; + func->TextureMatrix = nv20TextureMatrix; +#endif + func->Viewport = nv20Viewport; +} + diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 470f18d80a..dffd97b4e5 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -193,7 +193,7 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) OUT_RING(state); break; case GL_COLOR_LOGIC_OP: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LOGIC_OP_ENABLE, 1); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1); OUT_RING(state); break; // case GL_COLOR_MATERIAL: @@ -421,7 +421,7 @@ static void nv30LineWidth(GLcontext *ctx, GLfloat width) static void nv30LogicOpcode(GLcontext *ctx, GLenum opcode) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LOGIC_OP_OP, 1); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP, 1); OUT_RING(opcode); } -- cgit v1.2.3 From ae9c633a21a20394f39cd3c8adfa34d212945fae Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sat, 18 Nov 2006 00:36:22 +0000 Subject: More state functions --- src/mesa/drivers/dri/nouveau/nv10_state.c | 45 ++++++++++++++++++++++++++----- src/mesa/drivers/dri/nouveau/nv20_state.c | 11 ++++++-- src/mesa/drivers/dri/nouveau/nv30_state.c | 10 +++++-- 3 files changed, 56 insertions(+), 10 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index a8592acc84..368235ac58 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -463,16 +463,49 @@ void (*ReadBuffer)( GLcontext *ctx, GLenum buffer ); void (*RenderMode)(GLcontext *ctx, GLenum mode ); /** Define the scissor box */ void (*Scissor)(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h); + /** Select flat or smooth shading */ -void (*ShadeModel)(GLcontext *ctx, GLenum mode); +void nv10ShadeModel(GLcontext *ctx, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_SHADE_MODEL, 1); + OUT_RING(mode); +} + /** OpenGL 2.0 two-sided StencilFunc */ -void (*StencilFuncSeparate)(GLcontext *ctx, GLenum face, GLenum func, - GLint ref, GLuint mask); +static void nv10StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, + GLint ref, GLuint mask) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC, 3); + OUT_RING(func); + OUT_RING(ref); + OUT_RING(mask); +} + /** OpenGL 2.0 two-sided StencilMask */ -void (*StencilMaskSeparate)(GLcontext *ctx, GLenum face, GLuint mask); +static void nv10StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_MASK, 1); + OUT_RING(mask); +} + /** OpenGL 2.0 two-sided StencilOp */ -void (*StencilOpSeparate)(GLcontext *ctx, GLenum face, GLenum fail, - GLenum zfail, GLenum zpass); +static void nv10StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, + GLenum zfail, GLenum zpass) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL, 1); + OUT_RING(fail); + OUT_RING(zfail); + OUT_RING(zpass); +} + /** Control the generation of texture coordinates */ void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname, const GLfloat *params); diff --git a/src/mesa/drivers/dri/nouveau/nv20_state.c b/src/mesa/drivers/dri/nouveau/nv20_state.c index 88b8d6d204..3ad5f5bc44 100644 --- a/src/mesa/drivers/dri/nouveau/nv20_state.c +++ b/src/mesa/drivers/dri/nouveau/nv20_state.c @@ -468,8 +468,15 @@ void (*ReadBuffer)( GLcontext *ctx, GLenum buffer ); void (*RenderMode)(GLcontext *ctx, GLenum mode ); /** Define the scissor box */ void (*Scissor)(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h); + /** Select flat or smooth shading */ -void (*ShadeModel)(GLcontext *ctx, GLenum mode); +void nv20ShadeModel(GLcontext *ctx, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SHADE_MODEL, 1); + OUT_RING(mode); +} /** OpenGL 2.0 two-sided StencilFunc */ static void nv20StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, @@ -560,8 +567,8 @@ void nv20InitStateFuncs(struct dd_function_table *func) func->ReadBuffer = nv20ReadBuffer; func->RenderMode = nv20RenderMode; func->Scissor = nv20Scissor; - func->ShadeModel = nv20ShaderModel; #endif + func->ShadeModel = nv20ShadeModel; func->StencilFuncSeparate = nv20StencilFuncSeparate; func->StencilMaskSeparate = nv20StencilMaskSeparate; func->StencilOpSeparate = nv20StencilOpSeparate; diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index dffd97b4e5..12a45d3ea9 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -466,7 +466,13 @@ void (*RenderMode)(GLcontext *ctx, GLenum mode ); /** Define the scissor box */ void (*Scissor)(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h); /** Select flat or smooth shading */ -void (*ShadeModel)(GLcontext *ctx, GLenum mode); +void nv30ShadeModel(GLcontext *ctx, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SHADE_MODEL, 1); + OUT_RING(mode); +} /** OpenGL 2.0 two-sided StencilFunc */ static void nv30StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, @@ -579,8 +585,8 @@ void nv30InitStateFuncs(struct dd_function_table *func) func->ReadBuffer = nv30ReadBuffer; func->RenderMode = nv30RenderMode; func->Scissor = nv30Scissor; - func->ShadeModel = nv30ShaderModel; #endif + func->ShadeModel = nv30ShadeModel; func->StencilFuncSeparate = nv30StencilFuncSeparate; func->StencilMaskSeparate = nv30StencilMaskSeparate; func->StencilOpSeparate = nv30StencilOpSeparate; -- cgit v1.2.3 From 82d0fd26d49f98517d3668dc1c78a7b4ac8e48e6 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 19 Nov 2006 12:00:59 +0000 Subject: poke the correct FIFO regs --- src/mesa/drivers/dri/nouveau/nouveau_fifo.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h index c1e9fd5dc5..58fb378c39 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h @@ -36,8 +36,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #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; +#define NV_FIFO_READ(reg) *(volatile u_int32_t *)(nmesa->fifo.mmio + (reg/4)) +#define NV_FIFO_WRITE(reg,value) *(volatile u_int32_t *)(nmesa->fifo.mmio + (reg/4)) = value; #define NV_FIFO_READ_GET() ((NV_FIFO_READ(NV03_FIFO_REGS_DMAGET) - nmesa->fifo.put_base) >> 2) #define NV_FIFO_WRITE_PUT(val) NV_FIFO_WRITE(NV03_FIFO_REGS_DMAPUT, ((val)<<2) + nmesa->fifo.put_base) -- cgit v1.2.3 From 08a0946fcc51a0980d1d7a06e11d72ef71efafcf Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 19 Nov 2006 14:10:54 +0000 Subject: Stupid bug.. --- src/mesa/drivers/dri/nouveau/nv30_state.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 12a45d3ea9..00ab1c3202 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -516,13 +516,13 @@ static void nv30StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_FAIL, 1); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_FAIL, 3); OUT_RING(fail); OUT_RING(zfail); OUT_RING(zpass); } if (face == GL_BACK || face == GL_FRONT_AND_BACK) { - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_FAIL, 1); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_FAIL, 3); OUT_RING(fail); OUT_RING(zfail); OUT_RING(zpass); -- cgit v1.2.3 From b3fd1556f9e94d6d6f6d3933c404fc37aec7b1a3 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 19 Nov 2006 15:45:36 +0000 Subject: More FIFO fixes. --- src/mesa/drivers/dri/nouveau/nouveau_fifo.c | 5 +++++ src/mesa/drivers/dri/nouveau/nouveau_fifo.h | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c index 8d2e88b1f3..9fac6a48df 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c @@ -112,6 +112,7 @@ void nouveauWaitForIdle(nouveauContextPtr nmesa) GLboolean nouveauFifoInit(nouveauContextPtr nmesa) { drm_nouveau_fifo_alloc_t fifo_init; + int i; #ifdef NOUVEAU_RING_DEBUG return GL_TRUE; @@ -140,6 +141,10 @@ GLboolean nouveauFifoInit(nouveauContextPtr nmesa) nmesa->fifo.max = (fifo_init.cmdbuf_size >> 2) - 1; nmesa->fifo.free = nmesa->fifo.max - nmesa->fifo.current; + for (i=0; ififo.free -= RING_SKIPS; + MESSAGE("Fifo init ok. Using context %d\n", fifo_init.channel); return GL_TRUE; } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h index 58fb378c39..c5e5d6934f 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h @@ -100,9 +100,10 @@ extern void WAIT_RING(nouveauContextPtr nmesa,u_int32_t size); }while(0) #define BEGIN_RING_SIZE(subchannel,tag,size) do { \ - if (nmesa->fifo.freefifo.free <= (size)) \ WAIT_RING(nmesa,(size)); \ - OUT_RING( (size<<18) | ((subchannel) << 13) | (tag)); \ + OUT_RING( ((size)<<18) | ((subchannel) << 13) | (tag)); \ + nmesa->fifo.free -= ((size) + 1); \ }while(0) #define RING_AVAILABLE() (nmesa->fifo.free-1) -- cgit v1.2.3 From a2a747704d1b9572532ec0afd0ede6a4308ef032 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 19 Nov 2006 15:46:31 +0000 Subject: Avoid sharing subchannels with the ddx until context switching is done properly.. --- src/mesa/drivers/dri/nouveau/nouveau_object.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.h b/src/mesa/drivers/dri/nouveau/nouveau_object.h index 1065a0be59..e9a30d127a 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.h @@ -10,7 +10,7 @@ enum DMAObjects { }; enum DMASubchannel { - NvSub3D = 1, + NvSub3D = 7, }; #endif -- cgit v1.2.3 From 80a0ce37df7b7afef9cd1994527c5ed472c5c4cd Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 19 Nov 2006 15:52:18 +0000 Subject: Fix nv30LineWidth, hw expects a ubyte. --- src/mesa/drivers/dri/nouveau/nv30_state.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 00ab1c3202..bf3338d499 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -414,8 +414,12 @@ static void nv30LineStipple(GLcontext *ctx, GLint factor, GLushort pattern ) static void nv30LineWidth(GLcontext *ctx, GLfloat width) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte ubWidth; + + CLAMPED_FLOAT_TO_UBYTE(ubWidth, width); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_WIDTH_SMOOTH, 1); - OUT_RINGf(width); + OUT_RING(ubWidth); } static void nv30LogicOpcode(GLcontext *ctx, GLenum opcode) -- cgit v1.2.3 From a7139168d29e2cb112227ee6f2b5967c34eb91bd Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 19 Nov 2006 16:05:59 +0000 Subject: Don't bother touching lighting stuff if shaders are in use --- src/mesa/drivers/dri/nouveau/nv30_state.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index bf3338d499..66d94d19cd 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -34,6 +34,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "mtypes.h" #include "colormac.h" +#define NOUVEAU_CARD_USING_SHADERS (nmesa->screen->card->type >= NV_40) + static void nv30AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); @@ -229,6 +231,10 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) case GL_LIGHT7: { uint32_t mask=0x11<<(2*(cap-GL_LIGHT0)); + + if (NOUVEAU_CARD_USING_SHADERS) + break; + nmesa->enabled_lights=((nmesa->enabled_lights&mask)|(mask*state)); if (nmesa->lighting_enabled) { @@ -238,6 +244,9 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) break; } case GL_LIGHTING: + if (NOUVEAU_CARD_USING_SHADERS) + break; + nmesa->lighting_enabled=state; BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); if (nmesa->lighting_enabled) @@ -337,6 +346,10 @@ static void nv30Hint(GLcontext *ctx, GLenum target, GLenum mode) static void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params ) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (NOUVEAU_CARD_USING_SHADERS) + return; + /* not sure where the fourth param value goes...*/ switch(pname) { @@ -469,8 +482,9 @@ void (*ReadBuffer)( GLcontext *ctx, GLenum buffer ); void (*RenderMode)(GLcontext *ctx, GLenum mode ); /** Define the scissor box */ void (*Scissor)(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h); + /** Select flat or smooth shading */ -void nv30ShadeModel(GLcontext *ctx, GLenum mode) +static void nv30ShadeModel(GLcontext *ctx, GLenum mode) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); -- cgit v1.2.3 From 327e2c9220772724173ae7c53f4215400ed94355 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sun, 19 Nov 2006 20:18:45 +0000 Subject: New swtcl implementation. It's simpler than the previous one (doesn't use templates) and it is probably faster as well --- src/mesa/drivers/dri/nouveau/nouveau_context.c | 6 +- src/mesa/drivers/dri/nouveau/nouveau_fifo.h | 2 +- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 572 ++++++++----------------- 3 files changed, 171 insertions(+), 409 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 34a65d6d4b..a2b6f1c674 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -137,6 +137,9 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, _math_matrix_ctr(&nmesa->viewport); + nouveauDDInitStateFuncs( ctx ); + nouveauSpanInitFunctions( ctx ); + nouveauDDInitState( nmesa ); switch(nmesa->screen->card->type) { case NV_03: @@ -155,9 +158,6 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, nv10TriInitFunctions( ctx ); break; } - nouveauDDInitStateFuncs( ctx ); - nouveauSpanInitFunctions( ctx ); - nouveauDDInitState( nmesa ); driContextPriv->driverPrivate = (void *)nmesa; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h index c5e5d6934f..39e67176de 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h @@ -74,7 +74,7 @@ int i; printf("OUT_RINGp:\n"); for(i=0;ififo.buffer+nmesa->fifo.current,ptr,sz); \ - nmesa->fifo.current+=(sz/sizeof(*ptr)); \ + nmesa->fifo.current+=(sz/4); \ }while(0) #define OUT_RING(n) do { \ diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 772a5368e9..1afba77966 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -71,7 +71,7 @@ static void nv10ResetLineStipple( GLcontext *ctx ); /* the size above which we fire the ring. this is a performance-tunable */ #define NOUVEAU_FIRE_SIZE (2048/4) -static inline void nv10StartPrimitive(struct nouveau_context* nmesa) +static inline void nv10StartPrimitive(struct nouveau_context* nmesa,uint32_t primitive,uint32_t size) { if (nmesa->screen->card->type==NV_10) BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_BEGIN_END,1); @@ -79,14 +79,14 @@ static inline void nv10StartPrimitive(struct nouveau_context* nmesa) BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_BEGIN_END,1); else BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_BEGIN_END,1); - OUT_RING(nmesa->current_primitive); + OUT_RING(primitive); if (nmesa->screen->card->type==NV_10) - BEGIN_RING_PRIM(NvSub3D,NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_DATA,NOUVEAU_MIN_PRIM_SIZE); + BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_DATA,size); else if (nmesa->screen->card->type==NV_20) - BEGIN_RING_PRIM(NvSub3D,NV20_TCL_PRIMITIVE_3D_VERTEX_DATA,NOUVEAU_MIN_PRIM_SIZE); + BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_VERTEX_DATA,size); else - BEGIN_RING_PRIM(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_DATA,NOUVEAU_MIN_PRIM_SIZE); + BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_DATA,size); } inline void nv10FinishPrimitive(struct nouveau_context *nmesa) @@ -105,15 +105,8 @@ inline void nv10FinishPrimitive(struct nouveau_context *nmesa) static inline void nv10ExtendPrimitive(struct nouveau_context* nmesa, int size) { - /* when the fifo has enough stuff (2048 bytes) or there is not enough room, fire */ - if ((RING_AHEAD()>=NOUVEAU_FIRE_SIZE)||(RING_AVAILABLE()verts; + GLuint vertsize = nmesa->vertex_size; + GLuint size_dword = vertsize*(count-start); -#define CTX_ARG nouveauContextPtr nmesa -#define GET_VERTEX_DWORDS() nmesa->vertex_size -#define LOCAL_VARS \ - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); \ - const char *nouveauverts = (char *)nmesa->verts; -#define VERT(x) (nouveauVertex *)(nouveauverts + ((x) * vertsize * sizeof(int))) -#define VERTEX nouveauVertex - -#undef TAG -#define TAG(x) nouveau_##x -#include "tnl_dd/t_dd_triemit.h" - -/*********************************************************************** - * 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 \ - nv10_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 \ - nv10_draw_quad(nmesa, a, b, c, d); \ - } while (0) - -#define LINE(v0, v1) \ - do { \ - if (DO_FALLBACK) \ - nmesa->draw_line(nmesa, v0, v1); \ - else \ - nv10_draw_line(nmesa, v0, v1); \ - } while (0) + nv10ExtendPrimitive(nmesa, size_dword); + nv10StartPrimitive(nmesa,prim+1,size_dword); + OUT_RINGp((nouveauVertex*)(vertptr+(start*vertsize*4)),size_dword); + nv10FinishPrimitive(nmesa); +} -#define POINT(v0) \ - do { \ - if (DO_FALLBACK) \ - nmesa->draw_point(nmesa, v0); \ - else \ - nv10_draw_point(nmesa, v0); \ - } while (0) +static void nv10_render_points_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_POINTS); +} -#undef TAG +static void nv10_render_lines_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_LINES); +} -/*********************************************************************** - * Build render functions from dd templates * - ***********************************************************************/ +static void nv10_render_line_strip_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_LINE_STRIP); +} -#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 - - -#define DEPTH_SCALE 1.0 -#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->vertex_size * sizeof(int))) - -#define VERT_SET_RGBA( v, c ) \ - do { \ - nouveau_color_t *color = (nouveau_color_t *)&((v)->f[coloroffset]); \ - color->red=(c)[0]; \ - color->green=(c)[1]; \ - color->blue=(c)[2]; \ - color->alpha=(c)[3]; \ - } while (0) +static void nv10_render_line_loop_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_LINE_LOOP); +} -#define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset] +static void nv10_render_triangles_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_TRIANGLES); +} -#define VERT_SET_SPEC( v, c ) \ - do { \ - if (specoffset) { \ - nouveau_color_t *color = (nouveau_color_t *)&((v)->f[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) { \ - nouveau_color_t *spec0 = (nouveau_color_t *)&((v0)->ui[specoffset]); \ - nouveau_color_t *spec1 = (nouveau_color_t *)&((v1)->ui[specoffset]); \ - spec0->red = spec1->red; \ - spec0->green = spec1->green; \ - spec0->blue = spec1->blue; \ - } \ - } while (0) +static void nv10_render_tri_strip_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_TRIANGLE_STRIP); +} +static void nv10_render_tri_fan_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_TRIANGLE_FAN); +} -#define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->f[coloroffset] -#define VERT_RESTORE_RGBA( idx ) v[idx]->f[coloroffset] = color[idx] -#define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->f[specoffset] -#define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->f[specoffset] = spec[idx] +static void nv10_render_quads_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_QUADS); +} +static void nv10_render_quad_strip_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_QUAD_STRIP); +} -#undef LOCAL_VARS -#define LOCAL_VARS(n) \ - struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); \ -GLuint color[n], spec[n]; \ -GLuint coloroffset = nmesa->color_offset; \ -GLuint specoffset = nmesa->specular_offset; \ -(void)color; (void)spec; (void)coloroffset; (void)specoffset; +static void nv10_render_poly_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_verts(ctx,start,count,flags,GL_POLYGON); +} +static void nv10_render_noop_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ +} -/*********************************************************************** - * Helpers for rendering unfilled primitives * - ***********************************************************************/ +static inline void nv10_render_generic_primitive_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags,GLuint prim) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + GLuint size_dword = vertsize*(count-start); + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; + GLuint j; + + nv10ExtendPrimitive(nmesa, size_dword); + nv10StartPrimitive(nmesa,prim+1,size_dword); + for (j=start; jcurrent_primitive -#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! */ +static void nv10_render_points_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_POINTS); } +static void nv10_render_lines_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_LINES); +} -/**********************************************************************/ -/* 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) nv10RasterPrimitive(ctx, x, hw_prim[x]) -#undef LOCAL_VARS -#define LOCAL_VARS \ - struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); \ -GLubyte *vertptr = (GLubyte *)nmesa->verts; \ -const GLuint vertsize = nmesa->vertex_size; \ -const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ -const GLboolean stipple = ctx->Line.StippleFlag; \ -(void) elt; (void) stipple; -#define RESET_STIPPLE if ( stipple ) nv10ResetLineStipple( 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 +static void nv10_render_line_strip_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_LINE_STRIP); +} +static void nv10_render_line_loop_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_LINE_LOOP); +} -/**********************************************************************/ -/* Render clipped primitives */ -/**********************************************************************/ +static void nv10_render_triangles_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_TRIANGLES); +} +static void nv10_render_tri_strip_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_TRIANGLE_STRIP); +} +static void nv10_render_tri_fan_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_TRIANGLE_FAN); +} -static void nouveauRenderClippedPoly(GLcontext *ctx, const GLuint *elts, - GLuint n) +static void nv10_render_quads_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) { - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - GLuint prim = NOUVEAU_CONTEXT(ctx)->current_primitive; + nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_QUADS); +} - /* 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; - } +static void nv10_render_quad_strip_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_QUAD_STRIP); +} - /* Restore the render primitive - */ - if (prim != GL_POLYGON && - prim != GL_POLYGON + 1) - tnl->Driver.Render.PrimitiveNotify( ctx, prim ); +static void nv10_render_poly_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + nv10_render_generic_primitive_elts(ctx,start,count,flags,GL_POLYGON); } -static void nouveauRenderClippedLine(GLcontext *ctx, GLuint ii, GLuint jj) +static void nv10_render_noop_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) { - TNLcontext *tnl = TNL_CONTEXT(ctx); - tnl->Driver.Render.Line(ctx, ii, jj); } -static void nouveauFastRenderClippedPoly(GLcontext *ctx, const GLuint *elts, - GLuint n) +static void (*nv10_render_tab_elts[GL_POLYGON+2])(GLcontext *, + GLuint, + GLuint, + GLuint) = { - struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - GLuint vertsize = nmesa->vertex_size; - nv10ExtendPrimitive(nmesa, (n - 2) * 3 * 4 * vertsize); - GLubyte *vertptr = (GLubyte *)nmesa->verts; - const GLuint *start = (const GLuint *)V(elts[0]); - int i; + nv10_render_points_elts, + nv10_render_lines_elts, + nv10_render_line_loop_elts, + nv10_render_line_strip_elts, + nv10_render_triangles_elts, + nv10_render_tri_strip_elts, + nv10_render_tri_fan_elts, + nv10_render_quads_elts, + nv10_render_quad_strip_elts, + nv10_render_poly_elts, + nv10_render_noop_elts, +}; - for (i = 2; i < n; i++) { - OUT_RINGp(V(elts[i-1]),vertsize); - OUT_RINGp(V(elts[i]),vertsize); - OUT_RINGp(start,vertsize); - } -} /**********************************************************************/ /* Choose render functions */ @@ -571,58 +370,15 @@ static void nv10ChooseRenderState(GLcontext *ctx) { TNLcontext *tnl = TNL_CONTEXT(ctx); struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - GLuint flags = ctx->_TriangleCaps; - GLuint index = 0; nmesa->draw_point = nv10_draw_point; nmesa->draw_line = nv10_draw_line; nmesa->draw_tri = nv10_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->render_index != index) { - nmesa->render_index = 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; - } - } + tnl->Driver.Render.PrimTabVerts = nv10_render_tab_verts; + tnl->Driver.Render.PrimTabElts = nv10_render_tab_elts; + tnl->Driver.Render.ClippedLine = NULL; + tnl->Driver.Render.ClippedPolygon = NULL; } @@ -817,6 +573,19 @@ void nv10RasterPrimitive(GLcontext *ctx, } } +static const GLuint hw_prim[GL_POLYGON+1] = { + GL_POINTS+1, + GL_LINES+1, + GL_LINE_STRIP+1, + GL_LINE_LOOP+1, + GL_TRIANGLES+1, + GL_TRIANGLE_STRIP+1, + GL_TRIANGLE_FAN+1, + GL_QUADS+1, + GL_QUAD_STRIP+1, + GL_POLYGON+1 +}; + /* Callback for mesa: */ static void nv10RenderPrimitive( GLcontext *ctx, GLuint prim ) @@ -839,12 +608,6 @@ void nv10TriInitFunctions(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 = nv10RenderStart; @@ -856,10 +619,9 @@ void nv10TriInitFunctions(GLcontext *ctx) tnl->Driver.Render.Interp = _tnl_interp; _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12, - (6 + 2*ctx->Const.MaxTextureUnits) * sizeof(GLfloat) ); + 16 * sizeof(GLfloat) ); nmesa->verts = (GLubyte *)tnl->clipspace.vertex_buf; - } -- cgit v1.2.3 From 3613eba085dea61d11cda61d1f70bf9824282661 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sun, 19 Nov 2006 21:29:41 +0000 Subject: Fix the fifo debugging feature. --- src/mesa/drivers/dri/nouveau/nouveau_fifo.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h index 39e67176de..92acc002d9 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h @@ -32,7 +32,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_context.h" #include "nouveau_ctrlreg.h" -//#define NOUVEAU_RING_DEBUG +#define NOUVEAU_RING_DEBUG #define NV_READ(reg) *(volatile u_int32_t *)(nmesa->mmio + (reg)) @@ -67,7 +67,7 @@ int i; printf("OUT_RINGp:\n"); for(i=0;i Date: Sun, 19 Nov 2006 21:51:28 +0000 Subject: Oops. --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 1afba77966..c1348b1363 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -91,7 +91,6 @@ static inline void nv10StartPrimitive(struct nouveau_context* nmesa,uint32_t pri inline void nv10FinishPrimitive(struct nouveau_context *nmesa) { - FINISH_RING_PRIM(); if (nmesa->screen->card->type==NV_10) BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_BEGIN_END,1); else if (nmesa->screen->card->type==NV_20) -- cgit v1.2.3 From fe2e6100ece780437c622c8469efbec2b98f7a6f Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sun, 19 Nov 2006 22:16:54 +0000 Subject: More fifo debug fixes --- src/mesa/drivers/dri/nouveau/nouveau_fifo.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h index 92acc002d9..b738fa8ee1 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h @@ -32,7 +32,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_context.h" #include "nouveau_ctrlreg.h" -#define NOUVEAU_RING_DEBUG +//#define NOUVEAU_RING_DEBUG #define NV_READ(reg) *(volatile u_int32_t *)(nmesa->mmio + (reg)) @@ -59,15 +59,16 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef NOUVEAU_RING_DEBUG #define OUT_RINGp(ptr,sz) do { \ -int i; printf("OUT_RINGp:\n"); for(i=0;i Date: Sun, 19 Nov 2006 23:16:29 +0000 Subject: More work on the swtcl --- src/mesa/drivers/dri/nouveau/nouveau_fifo.h | 6 +++--- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 4 +--- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h index b738fa8ee1..da2dadada7 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h @@ -60,7 +60,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define OUT_RINGp(ptr,sz) do { \ uint32_t* p=(uint32_t*)ptr; \ -int i; printf("OUT_RINGp:\n"); for(i=0;ififo.buffer+nmesa->fifo.current,ptr,sz); \ - nmesa->fifo.current+=(sz/4); \ + memcpy(nmesa->fifo.buffer+nmesa->fifo.current,ptr,sz*4); \ + nmesa->fifo.current+=sz; \ }while(0) #define OUT_RING(n) do { \ diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index c1348b1363..48f41cf2fa 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -549,8 +549,6 @@ static void nv10RenderStart(GLcontext *ctx) static void nv10RenderFinish(GLcontext *ctx) { - struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - nv10FinishPrimitive(nmesa); } @@ -618,7 +616,7 @@ void nv10TriInitFunctions(GLcontext *ctx) tnl->Driver.Render.Interp = _tnl_interp; _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12, - 16 * sizeof(GLfloat) ); + 64 * sizeof(GLfloat) ); nmesa->verts = (GLubyte *)tnl->clipspace.vertex_buf; } -- cgit v1.2.3 From ac208c95cdef7711a9f4ba1a451dbb497912a40e Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sun, 19 Nov 2006 23:39:16 +0000 Subject: Use NONINC_METHOD for vertex data. --- src/mesa/drivers/dri/nouveau/nouveau_ctrlreg.h | 2 ++ src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_ctrlreg.h b/src/mesa/drivers/dri/nouveau/nouveau_ctrlreg.h index 2f4c3f6d5d..c9b2d59007 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_ctrlreg.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_ctrlreg.h @@ -40,3 +40,5 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV03_FIFO_CMD_REWIND (NV03_FIFO_CMD_JUMP | (0 & NV03_FIFO_CMD_JUMP_OFFSET_MASK)) +#define NONINC_METHOD 0x40000000 + diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 48f41cf2fa..f128926182 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -82,11 +82,11 @@ static inline void nv10StartPrimitive(struct nouveau_context* nmesa,uint32_t pri OUT_RING(primitive); if (nmesa->screen->card->type==NV_10) - BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_DATA,size); + BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_DATA|NONINC_METHOD,size); else if (nmesa->screen->card->type==NV_20) - BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_VERTEX_DATA,size); + BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_VERTEX_DATA|NONINC_METHOD,size); else - BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_DATA,size); + BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_DATA|NONINC_METHOD,size); } inline void nv10FinishPrimitive(struct nouveau_context *nmesa) -- cgit v1.2.3 From 50c85daf02b90fcee239172d7067b582680d2169 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sun, 19 Nov 2006 23:47:24 +0000 Subject: Cleanup the swtcl code. --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 27 --------------------------- 1 file changed, 27 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index f128926182..832ce4ad21 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -56,18 +56,6 @@ static void nv10ResetLineStipple( GLcontext *ctx ); -/*********************************************************************** - * 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) - - -/* the free room we want before we start a vertex batch. this is a performance-tunable */ -#define NOUVEAU_MIN_PRIM_SIZE (32/4) /* the size above which we fire the ring. this is a performance-tunable */ #define NOUVEAU_FIRE_SIZE (2048/4) @@ -342,21 +330,6 @@ static void (*nv10_render_tab_elts[GL_POLYGON+2])(GLcontext *, /**********************************************************************/ - - -#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) - #define EMIT_ATTR( ATTR, STYLE ) \ do { \ nmesa->vertex_attrs[nmesa->vertex_attr_count].attrib = (ATTR); \ -- cgit v1.2.3 From afb49fef9033d84d989d62928a03615ec5dbda04 Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Mon, 20 Nov 2006 17:25:54 +0000 Subject: Add state initialization to context creation. --- src/mesa/drivers/dri/nouveau/nouveau_context.c | 2 + src/mesa/drivers/dri/nouveau/nouveau_state.c | 114 ++++++++++++++++++++++++- src/mesa/drivers/dri/nouveau/nouveau_state.h | 3 + 3 files changed, 118 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index a2b6f1c674..a2ac056010 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -159,6 +159,8 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, break; } + nouveauInitState(ctx); + driContextPriv->driverPrivate = (void *)nmesa; NOUVEAU_DEBUG = driParseDebugString( getenv( "NOUVEAU_DEBUG" ), diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c index 94c92aeb8a..9811606311 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -154,7 +154,26 @@ static void nouveauDDInvalidateState(GLcontext *ctx, GLuint new_state) /* Initialize the context's hardware state. */ void nouveauDDInitState(nouveauContextPtr nmesa) { - + uint32_t type = nmesa->screen->card->type; + switch(type) + { + case NV_03: + case NV_04: + case NV_05: + case NV_10: + //nv10InitStateFuncs(&nmesa->glCtx->Driver); + break; + case NV_20: + nv20InitStateFuncs(&nmesa->glCtx->Driver); + break; + case NV_30: + case NV_40: + case G_70: + nv30InitStateFuncs(&nmesa->glCtx->Driver); + break; + default: + break; + } } /* Initialize the driver's state functions */ @@ -211,3 +230,96 @@ void nouveauDDInitStateFuncs(GLcontext *ctx) ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; } + +void nouveauInitState(GLcontext *ctx) +{ + /* + * Mesa should do this for us: + */ + ctx->Driver.AlphaFunc( ctx, + ctx->Color.AlphaFunc, + ctx->Color.AlphaRef); + + ctx->Driver.BlendColor( ctx, + ctx->Color.BlendColor ); + + ctx->Driver.BlendEquationSeparate( ctx, + ctx->Color.BlendEquationRGB, + ctx->Color.BlendEquationA); + + ctx->Driver.BlendFuncSeparate( ctx, + ctx->Color.BlendSrcRGB, + ctx->Color.BlendDstRGB, + ctx->Color.BlendSrcA, + ctx->Color.BlendDstA); + + ctx->Driver.ColorMask( ctx, + ctx->Color.ColorMask[RCOMP], + ctx->Color.ColorMask[GCOMP], + ctx->Color.ColorMask[BCOMP], + ctx->Color.ColorMask[ACOMP]); + + ctx->Driver.CullFace( ctx, ctx->Polygon.CullFaceMode ); + ctx->Driver.DepthFunc( ctx, ctx->Depth.Func ); + ctx->Driver.DepthMask( ctx, ctx->Depth.Mask ); + + ctx->Driver.Enable( ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled ); + ctx->Driver.Enable( ctx, GL_BLEND, ctx->Color.BlendEnabled ); + ctx->Driver.Enable( ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled ); + ctx->Driver.Enable( ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled ); + ctx->Driver.Enable( ctx, GL_CULL_FACE, ctx->Polygon.CullFlag ); + ctx->Driver.Enable( ctx, GL_DEPTH_TEST, ctx->Depth.Test ); + ctx->Driver.Enable( ctx, GL_DITHER, ctx->Color.DitherFlag ); + ctx->Driver.Enable( ctx, GL_FOG, ctx->Fog.Enabled ); + ctx->Driver.Enable( ctx, GL_LIGHTING, ctx->Light.Enabled ); + ctx->Driver.Enable( ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag ); + ctx->Driver.Enable( ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag ); + ctx->Driver.Enable( ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled ); + ctx->Driver.Enable( ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled ); + ctx->Driver.Enable( ctx, GL_TEXTURE_1D, GL_FALSE ); + ctx->Driver.Enable( ctx, GL_TEXTURE_2D, GL_FALSE ); + ctx->Driver.Enable( ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE ); + ctx->Driver.Enable( ctx, GL_TEXTURE_3D, GL_FALSE ); + ctx->Driver.Enable( ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE ); + + ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color ); + ctx->Driver.Fogfv( ctx, GL_FOG_MODE, 0 ); + ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density ); + ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start ); + ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End ); + + ctx->Driver.FrontFace( ctx, ctx->Polygon.FrontFace ); + + { + GLfloat f = (GLfloat)ctx->Light.Model.ColorControl; + ctx->Driver.LightModelfv( ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f ); + } + + ctx->Driver.LineWidth( ctx, ctx->Line.Width ); + ctx->Driver.LogicOpcode( ctx, ctx->Color.LogicOp ); + ctx->Driver.PointSize( ctx, ctx->Point.Size ); + ctx->Driver.PolygonStipple( ctx, (const GLubyte *)ctx->PolygonStipple ); + ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height ); + ctx->Driver.ShadeModel( ctx, ctx->Light.ShadeModel ); + ctx->Driver.StencilFuncSeparate( ctx, GL_FRONT, + ctx->Stencil.Function[0], + ctx->Stencil.Ref[0], + ctx->Stencil.ValueMask[0] ); + ctx->Driver.StencilFuncSeparate( ctx, GL_BACK, + ctx->Stencil.Function[1], + ctx->Stencil.Ref[1], + ctx->Stencil.ValueMask[1] ); + ctx->Driver.StencilMaskSeparate( ctx, GL_FRONT, ctx->Stencil.WriteMask[0] ); + ctx->Driver.StencilMaskSeparate( ctx, GL_BACK, ctx->Stencil.WriteMask[1] ); + ctx->Driver.StencilOpSeparate( ctx, GL_FRONT, + ctx->Stencil.FailFunc[0], + ctx->Stencil.ZFailFunc[0], + ctx->Stencil.ZPassFunc[0]); + ctx->Driver.StencilOpSeparate( ctx, GL_BACK, + ctx->Stencil.FailFunc[1], + ctx->Stencil.ZFailFunc[1], + ctx->Stencil.ZPassFunc[1]); + + ctx->Driver.DrawBuffer( ctx, ctx->Color.DrawBuffer[0] ); +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.h b/src/mesa/drivers/dri/nouveau/nouveau_state.h index 4e8eda83e1..f8fd0cea50 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.h @@ -32,8 +32,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. extern void nouveauDDInitState(nouveauContextPtr nmesa); extern void nouveauDDInitStateFuncs(GLcontext *ctx); +extern void nv10InitStateFuncs(struct dd_function_table *func); +extern void nv20InitStateFuncs(struct dd_function_table *func); extern void nv30InitStateFuncs(struct dd_function_table *func); +extern void nouveauInitState(GLcontext *ctx); /* extern void nouveauDDUpdateState(GLcontext *ctx); extern void nouveauDDUpdateHWState(GLcontext *ctx); -- cgit v1.2.3 From a20cf73053c2c834abe971c9dc824f14c31884fb Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Tue, 21 Nov 2006 02:47:13 +0000 Subject: More state. --- src/mesa/drivers/dri/nouveau/nv30_state.c | 56 ++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 13 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 66d94d19cd..a6cbcb8c8d 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -28,6 +28,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_object.h" #include "nouveau_fifo.h" #include "nouveau_reg.h" +#include "nouveau_state.h" #include "tnl/t_pipeline.h" @@ -414,7 +415,7 @@ static void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa } /** Set the lighting model parameters */ -static void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params); +void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params); static void nv30LineStipple(GLcontext *ctx, GLint factor, GLushort pattern ) @@ -473,15 +474,37 @@ static void nv30PolygonMode(GLcontext *ctx, GLenum face, GLenum mode) } /** Set the scale and units used to calculate depth values */ -void (*PolygonOffset)(GLcontext *ctx, GLfloat factor, GLfloat units); +static void nv30PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR, 2); + OUT_RINGf(factor); + + /* Looks like we always multiply units by 2.0... according to the dumps.*/ + OUT_RINGf(units * 2.0); +} + /** Set the polygon stippling pattern */ -void (*PolygonStipple)(GLcontext *ctx, const GLubyte *mask ); +static void nv30PolygonStipple(GLcontext *ctx, const GLubyte *mask ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(0), 32); + OUT_RINGp(mask, 32); +} + /* Specifies the current buffer for reading */ void (*ReadBuffer)( GLcontext *ctx, GLenum buffer ); /** Set rasterization mode */ void (*RenderMode)(GLcontext *ctx, GLenum mode ); + /** Define the scissor box */ -void (*Scissor)(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h); +static void nv30Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS, 2); + OUT_RING((w << 16) | x); + OUT_RING((y << 16) | y); +} /** Select flat or smooth shading */ static void nv30ShadeModel(GLcontext *ctx, GLenum mode) @@ -557,16 +580,23 @@ void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname, void (*TexParameter)(GLcontext *ctx, GLenum target, struct gl_texture_object *texObj, GLenum pname, const GLfloat *params); -void (*TextureMatrix)(GLcontext *ctx, GLuint unit, const GLmatrix *mat); + +static void nv30TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16); + /*XXX: This SHOULD work.*/ + OUT_RINGp(mat->m, 16); +} /** Set the viewport */ static void nv30Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) { - /* TODO: Where do the VIEWPORT_XFRM_* regs come in? */ - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_0, 2); - OUT_RING((w << 16) | x); - OUT_RING((h << 16) | y); + /* TODO: Where do the VIEWPORT_XFRM_* regs come in? */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_0, 2); + OUT_RING((w << 16) | x); + OUT_RING((h << 16) | y); } void nv30InitStateFuncs(struct dd_function_table *func) @@ -597,13 +627,13 @@ void nv30InitStateFuncs(struct dd_function_table *func) func->PointParameterfv = nv30PointParameterfv; func->PointSize = nv30PointSize; func->PolygonMode = nv30PolygonMode; -#if 0 func->PolygonOffset = nv30PolygonOffset; func->PolygonStipple = nv30PolygonStipple; +#if 0 func->ReadBuffer = nv30ReadBuffer; func->RenderMode = nv30RenderMode; - func->Scissor = nv30Scissor; #endif + func->Scissor = nv30Scissor; func->ShadeModel = nv30ShadeModel; func->StencilFuncSeparate = nv30StencilFuncSeparate; func->StencilMaskSeparate = nv30StencilMaskSeparate; @@ -611,8 +641,8 @@ void nv30InitStateFuncs(struct dd_function_table *func) #if 0 func->TexGen = nv30TexGen; func->TexParameter = nv30TexParameter; - func->TextureMatrix = nv30TextureMatrix; #endif + func->TextureMatrix = nv30TextureMatrix; func->Viewport = nv30Viewport; } -- cgit v1.2.3 From 0ea45b1ad822ebdce2af3faef77ed776ca32d46b Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Tue, 21 Nov 2006 12:43:16 +0000 Subject: Add the state caching mechanism. It seems to work, from what I can see. --- src/mesa/drivers/dri/nouveau/Makefile | 3 +- src/mesa/drivers/dri/nouveau/nouveau_context.h | 5 +- src/mesa/drivers/dri/nouveau/nouveau_fifo.h | 37 ++- src/mesa/drivers/dri/nouveau/nouveau_state.c | 104 ++++---- src/mesa/drivers/dri/nouveau/nouveau_state_cache.c | 64 +++++ src/mesa/drivers/dri/nouveau/nouveau_state_cache.h | 23 ++ src/mesa/drivers/dri/nouveau/nv10_state.c | 260 +++++++++---------- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 53 ++-- src/mesa/drivers/dri/nouveau/nv20_state.c | 268 +++++++++---------- src/mesa/drivers/dri/nouveau/nv30_state.c | 284 ++++++++++----------- 10 files changed, 605 insertions(+), 496 deletions(-) create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_state_cache.c create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_state_cache.h (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile index 2db6f8989d..4d1e3e6c70 100644 --- a/src/mesa/drivers/dri/nouveau/Makefile +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -22,7 +22,8 @@ DRIVER_SOURCES = \ nv10_swtcl.c \ nv10_state.c \ nv20_state.c \ - nv30_state.c + nv30_state.c \ + nouveau_state_cache.c C_SOURCES = \ $(COMMON_SOURCES) \ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 09972bebac..8ae7be015d 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -37,6 +37,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tnl/t_vertex.h" #include "nouveau_screen.h" +#include "nouveau_state_cache.h" #include "xmlconfig.h" @@ -73,7 +74,6 @@ typedef void (*nouveau_line_func)( struct nouveau_context*, typedef void (*nouveau_point_func)( struct nouveau_context*, nouveauVertex * ); - typedef struct nouveau_context { /* Mesa context */ GLcontext *glCtx; @@ -102,6 +102,9 @@ typedef struct nouveau_context { GLboolean lighting_enabled; uint32_t enabled_lights; + /* Cached state */ + nouveau_state_cache state_cache; + /* The drawing fallbacks */ GLuint Fallback; nouveau_tri_func draw_tri; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h index da2dadada7..259e5a1dc7 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h @@ -45,7 +45,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * 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 @@ -59,7 +58,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef NOUVEAU_RING_DEBUG #define OUT_RINGp(ptr,sz) do { \ -uint32_t* p=(uint32_t*)ptr; \ +uint32_t* p=(uint32_t*)(ptr); \ int i; printf("OUT_RINGp: (size 0x%x dwords)\n",sz); for(i=0;ififo.buffer+nmesa->fifo.current,ptr,sz*4); \ - nmesa->fifo.current+=sz; \ + memcpy(nmesa->fifo.buffer+nmesa->fifo.current,ptr,(sz)*4); \ + nmesa->fifo.current+=(sz); \ }while(0) #define OUT_RING(n) do { \ -nmesa->fifo.buffer[nmesa->fifo.current++]=n; \ +nmesa->fifo.buffer[nmesa->fifo.current++]=(n); \ }while(0) #define OUT_RINGf(n) do { \ -*((float*)(nmesa->fifo.buffer+nmesa->fifo.current++))=n; \ +*((float*)(nmesa->fifo.buffer+nmesa->fifo.current++))=(n); \ }while(0) #endif extern void WAIT_RING(nouveauContextPtr nmesa,u_int32_t size); +extern void nouveau_state_cache_flush(nouveauContextPtr nmesa); +extern void nouveau_state_cache_init(nouveauContextPtr nmesa); -#define BEGIN_RING_PRIM(subchannel,tag,size) do { \ - if (nmesa->fifo.freestate_cache.dirty=1; \ + nmesa->state_cache.current_pos=((tag)/4); \ +}while(0) + +#define OUT_RING_CACHE(n) do { \ + if (nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value!=(n)) { \ + nmesa->state_cache.atoms[nmesa->state_cache.current_pos].dirty=1; \ + nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value=(n); \ + } \ + nmesa->state_cache.current_pos++; \ }while(0) -#define FINISH_RING_PRIM() do{ \ - nmesa->fifo.buffer[nmesa->fifo.put]|=((nmesa->fifo.current-nmesa->fifo.put) << 18); \ +#define OUT_RING_CACHEf(n) do { \ + if ((*(float*)(&nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value))!=(n)){ \ + nmesa->state_cache.atoms[nmesa->state_cache.current_pos].dirty=1; \ + (*(float*)(&nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value))=(n);\ + } \ + nmesa->state_cache.current_pos++; \ }while(0) #define BEGIN_RING_SIZE(subchannel,tag,size) do { \ + nouveau_state_cache_flush(nmesa); \ if (nmesa->fifo.free <= (size)) \ WAIT_RING(nmesa,(size)); \ OUT_RING( ((size)<<18) | ((subchannel) << 13) | (tag)); \ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c index 9811606311..2f8f3248ce 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -108,8 +108,6 @@ static void nouveauDDUpdateHWState(GLcontext *ctx) if ( new_state || nmesa->new_render_state & _NEW_TEXTURE ) { - FINISH_RING_PRIM(); - nmesa->new_state = 0; /* Update the various parts of the context's state. @@ -174,6 +172,7 @@ void nouveauDDInitState(nouveauContextPtr nmesa) default: break; } + nouveau_state_cache_init(nmesa); } /* Initialize the driver's state functions */ @@ -231,95 +230,98 @@ void nouveauDDInitStateFuncs(GLcontext *ctx) ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; } +#define STATE_INIT(a) if (ctx->Driver.a) ctx->Driver.a + void nouveauInitState(GLcontext *ctx) { /* * Mesa should do this for us: */ - ctx->Driver.AlphaFunc( ctx, + + STATE_INIT(AlphaFunc)( ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef); - ctx->Driver.BlendColor( ctx, + STATE_INIT(BlendColor)( ctx, ctx->Color.BlendColor ); - ctx->Driver.BlendEquationSeparate( ctx, + STATE_INIT(BlendEquationSeparate)( ctx, ctx->Color.BlendEquationRGB, ctx->Color.BlendEquationA); - ctx->Driver.BlendFuncSeparate( ctx, + STATE_INIT(BlendFuncSeparate)( ctx, ctx->Color.BlendSrcRGB, ctx->Color.BlendDstRGB, ctx->Color.BlendSrcA, ctx->Color.BlendDstA); - ctx->Driver.ColorMask( ctx, + STATE_INIT(ColorMask)( ctx, ctx->Color.ColorMask[RCOMP], ctx->Color.ColorMask[GCOMP], ctx->Color.ColorMask[BCOMP], ctx->Color.ColorMask[ACOMP]); - ctx->Driver.CullFace( ctx, ctx->Polygon.CullFaceMode ); - ctx->Driver.DepthFunc( ctx, ctx->Depth.Func ); - ctx->Driver.DepthMask( ctx, ctx->Depth.Mask ); - - ctx->Driver.Enable( ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled ); - ctx->Driver.Enable( ctx, GL_BLEND, ctx->Color.BlendEnabled ); - ctx->Driver.Enable( ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled ); - ctx->Driver.Enable( ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled ); - ctx->Driver.Enable( ctx, GL_CULL_FACE, ctx->Polygon.CullFlag ); - ctx->Driver.Enable( ctx, GL_DEPTH_TEST, ctx->Depth.Test ); - ctx->Driver.Enable( ctx, GL_DITHER, ctx->Color.DitherFlag ); - ctx->Driver.Enable( ctx, GL_FOG, ctx->Fog.Enabled ); - ctx->Driver.Enable( ctx, GL_LIGHTING, ctx->Light.Enabled ); - ctx->Driver.Enable( ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag ); - ctx->Driver.Enable( ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag ); - ctx->Driver.Enable( ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled ); - ctx->Driver.Enable( ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled ); - ctx->Driver.Enable( ctx, GL_TEXTURE_1D, GL_FALSE ); - ctx->Driver.Enable( ctx, GL_TEXTURE_2D, GL_FALSE ); - ctx->Driver.Enable( ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE ); - ctx->Driver.Enable( ctx, GL_TEXTURE_3D, GL_FALSE ); - ctx->Driver.Enable( ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE ); - - ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color ); - ctx->Driver.Fogfv( ctx, GL_FOG_MODE, 0 ); - ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density ); - ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start ); - ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End ); - - ctx->Driver.FrontFace( ctx, ctx->Polygon.FrontFace ); + STATE_INIT(CullFace)( ctx, ctx->Polygon.CullFaceMode ); + STATE_INIT(DepthFunc)( ctx, ctx->Depth.Func ); + STATE_INIT(DepthMask)( ctx, ctx->Depth.Mask ); + + STATE_INIT(Enable)( ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled ); + STATE_INIT(Enable)( ctx, GL_BLEND, ctx->Color.BlendEnabled ); + STATE_INIT(Enable)( ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled ); + STATE_INIT(Enable)( ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled ); + STATE_INIT(Enable)( ctx, GL_CULL_FACE, ctx->Polygon.CullFlag ); + STATE_INIT(Enable)( ctx, GL_DEPTH_TEST, ctx->Depth.Test ); + STATE_INIT(Enable)( ctx, GL_DITHER, ctx->Color.DitherFlag ); + STATE_INIT(Enable)( ctx, GL_FOG, ctx->Fog.Enabled ); + STATE_INIT(Enable)( ctx, GL_LIGHTING, ctx->Light.Enabled ); + STATE_INIT(Enable)( ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag ); + STATE_INIT(Enable)( ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag ); + STATE_INIT(Enable)( ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled ); + STATE_INIT(Enable)( ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled ); + STATE_INIT(Enable)( ctx, GL_TEXTURE_1D, GL_FALSE ); + STATE_INIT(Enable)( ctx, GL_TEXTURE_2D, GL_FALSE ); + STATE_INIT(Enable)( ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE ); + STATE_INIT(Enable)( ctx, GL_TEXTURE_3D, GL_FALSE ); + STATE_INIT(Enable)( ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE ); + + STATE_INIT(Fogfv)( ctx, GL_FOG_COLOR, ctx->Fog.Color ); + STATE_INIT(Fogfv)( ctx, GL_FOG_MODE, 0 ); + STATE_INIT(Fogfv)( ctx, GL_FOG_DENSITY, &ctx->Fog.Density ); + STATE_INIT(Fogfv)( ctx, GL_FOG_START, &ctx->Fog.Start ); + STATE_INIT(Fogfv)( ctx, GL_FOG_END, &ctx->Fog.End ); + + STATE_INIT(FrontFace)( ctx, ctx->Polygon.FrontFace ); { GLfloat f = (GLfloat)ctx->Light.Model.ColorControl; - ctx->Driver.LightModelfv( ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f ); + STATE_INIT(LightModelfv)( ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f ); } - ctx->Driver.LineWidth( ctx, ctx->Line.Width ); - ctx->Driver.LogicOpcode( ctx, ctx->Color.LogicOp ); - ctx->Driver.PointSize( ctx, ctx->Point.Size ); - ctx->Driver.PolygonStipple( ctx, (const GLubyte *)ctx->PolygonStipple ); - ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y, + STATE_INIT(LineWidth)( ctx, ctx->Line.Width ); + STATE_INIT(LogicOpcode)( ctx, ctx->Color.LogicOp ); + STATE_INIT(PointSize)( ctx, ctx->Point.Size ); + STATE_INIT(PolygonStipple)( ctx, (const GLubyte *)ctx->PolygonStipple ); + STATE_INIT(Scissor)( ctx, ctx->Scissor.X, ctx->Scissor.Y, ctx->Scissor.Width, ctx->Scissor.Height ); - ctx->Driver.ShadeModel( ctx, ctx->Light.ShadeModel ); - ctx->Driver.StencilFuncSeparate( ctx, GL_FRONT, + STATE_INIT(ShadeModel)( ctx, ctx->Light.ShadeModel ); + STATE_INIT(StencilFuncSeparate)( ctx, GL_FRONT, ctx->Stencil.Function[0], ctx->Stencil.Ref[0], ctx->Stencil.ValueMask[0] ); - ctx->Driver.StencilFuncSeparate( ctx, GL_BACK, + STATE_INIT(StencilFuncSeparate)( ctx, GL_BACK, ctx->Stencil.Function[1], ctx->Stencil.Ref[1], ctx->Stencil.ValueMask[1] ); - ctx->Driver.StencilMaskSeparate( ctx, GL_FRONT, ctx->Stencil.WriteMask[0] ); - ctx->Driver.StencilMaskSeparate( ctx, GL_BACK, ctx->Stencil.WriteMask[1] ); - ctx->Driver.StencilOpSeparate( ctx, GL_FRONT, + STATE_INIT(StencilMaskSeparate)( ctx, GL_FRONT, ctx->Stencil.WriteMask[0] ); + STATE_INIT(StencilMaskSeparate)( ctx, GL_BACK, ctx->Stencil.WriteMask[1] ); + STATE_INIT(StencilOpSeparate)( ctx, GL_FRONT, ctx->Stencil.FailFunc[0], ctx->Stencil.ZFailFunc[0], ctx->Stencil.ZPassFunc[0]); - ctx->Driver.StencilOpSeparate( ctx, GL_BACK, + STATE_INIT(StencilOpSeparate)( ctx, GL_BACK, ctx->Stencil.FailFunc[1], ctx->Stencil.ZFailFunc[1], ctx->Stencil.ZPassFunc[1]); - ctx->Driver.DrawBuffer( ctx, ctx->Color.DrawBuffer[0] ); + STATE_INIT(DrawBuffer)( ctx, ctx->Color.DrawBuffer[0] ); } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state_cache.c b/src/mesa/drivers/dri/nouveau/nouveau_state_cache.c new file mode 100644 index 0000000000..36f0c1024b --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_state_cache.c @@ -0,0 +1,64 @@ + +#include "nouveau_state_cache.h" +#include "nouveau_context.h" +#include "nouveau_object.h" +#include "nouveau_fifo.h" + +#define BEGIN_RING_NOFLUSH(subchannel,tag,size) do { \ + if (nmesa->fifo.free <= (size)) \ + WAIT_RING(nmesa,(size)); \ + OUT_RING( ((size)<<18) | ((subchannel) << 13) | (tag)); \ + nmesa->fifo.free -= ((size) + 1); \ +}while(0) + +// flush all the dirty state +void nouveau_state_cache_flush(nouveauContextPtr nmesa) +{ + int i=0; + int run=0; + + // fast-path no state changes + if (!nmesa->state_cache.dirty) + return; + nmesa->state_cache.dirty=0; + + do + { + // jump to a dirty state + while((nmesa->state_cache.atoms[i].dirty==0)&&(istate_cache.atoms[i+run].dirty)&&(i+run0) { + int j; + + BEGIN_RING_NOFLUSH(NvSub3D, i*4, run); + for(j=0;jstate_cache.atoms[i+j].value); + nmesa->state_cache.atoms[i+j].dirty=0; + } + i+=run; + } + } + while(istate_cache.atoms[i].dirty=0; + nmesa->state_cache.atoms[i].value=0xDEADBEEF; // nvidia cards like beef + } + nmesa->state_cache.dirty=0; +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state_cache.h b/src/mesa/drivers/dri/nouveau/nouveau_state_cache.h new file mode 100644 index 0000000000..2488274846 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_state_cache.h @@ -0,0 +1,23 @@ + +#ifndef __NOUVEAU_STATE_CACHE_H__ +#define __NOUVEAU_STATE_CACHE_H__ + +#include "mtypes.h" + +#define NOUVEAU_STATE_CACHE_ENTRIES 2048 + +typedef struct nouveau_state_atom_t{ + uint32_t value; + uint32_t dirty; +}nouveau_state_atom; + +typedef struct nouveau_state_cache_t{ + nouveau_state_atom atoms[NOUVEAU_STATE_CACHE_ENTRIES]; + uint32_t current_pos; + // master dirty flag + uint32_t dirty; +}nouveau_state_cache; + + +#endif + diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 368235ac58..0d19ce94af 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -40,9 +40,9 @@ void nv10AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) GLubyte ubRef; CLAMPED_FLOAT_TO_UBYTE(ubRef, ref); - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2); - OUT_RING(func); /* NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC */ - OUT_RING(ubRef); /* NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF */ + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2); + OUT_RING_CACHE(func); /* NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC */ + OUT_RING_CACHE(ubRef); /* NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF */ } void nv10BlendColor(GLcontext *ctx, const GLfloat color[4]) @@ -55,15 +55,15 @@ void nv10BlendColor(GLcontext *ctx, const GLfloat color[4]) CLAMPED_FLOAT_TO_UBYTE(cf[2], color[2]); CLAMPED_FLOAT_TO_UBYTE(cf[3], color[3]); - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_COLOR, 1); - OUT_RING(PACK_COLOR_8888(cf[3], cf[1], cf[2], cf[0])); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_COLOR, 1); + OUT_RING_CACHE(PACK_COLOR_8888(cf[3], cf[1], cf[2], cf[0])); } void nv10BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_EQUATION, 1); - OUT_RING((modeA<<16) | modeRGB); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_EQUATION, 1); + OUT_RING_CACHE((modeA<<16) | modeRGB); } @@ -71,9 +71,9 @@ void nv10BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2); - OUT_RING((sfactorA<<16) | sfactorRGB); - OUT_RING((dfactorA<<16) | dfactorRGB); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2); + OUT_RING_CACHE((sfactorA<<16) | sfactorRGB); + OUT_RING_CACHE((dfactorA<<16) | dfactorRGB); } /* @@ -82,16 +82,16 @@ void nv30ClearColor(GLcontext *ctx, const GLfloat color[4]) nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); GLubyte c[4]; UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,color); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB, 1); - OUT_RING(PACK_COLOR_8888(c[3],c[0],c[1],c[2])); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB, 1); + OUT_RING_CACHE(PACK_COLOR_8888(c[3],c[0],c[1],c[2])); } void nv30ClearDepth(GLcontext *ctx, GLclampd d) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); nmesa->clear_value=((nmesa->clear_value&0x000000FF)|(((uint32_t)(d*0xFFFFFF))<<8)); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1); - OUT_RING(nmesa->clear_value); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1); + OUT_RING_CACHE(nmesa->clear_value); } */ @@ -104,19 +104,19 @@ void nv30ClearStencil(GLcontext *ctx, GLint s) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); nmesa->clear_value=((nmesa->clear_value&0xFFFFFF00)|(s&0x000000FF)); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1); - OUT_RING(nmesa->clear_value); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1); + OUT_RING_CACHE(nmesa->clear_value); } */ void nv10ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4); - OUT_RINGf(equation[0]); - OUT_RINGf(equation[1]); - OUT_RINGf(equation[2]); - OUT_RINGf(equation[3]); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4); + OUT_RING_CACHEf(equation[0]); + OUT_RING_CACHEf(equation[1]); + OUT_RING_CACHEf(equation[2]); + OUT_RING_CACHEf(equation[3]); } /* Seems does not support alpha in color mask */ @@ -124,8 +124,8 @@ void nv10ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, GLboolean bmask, GLboolean amask ) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_COLOR_MASK, 1); - OUT_RING(/*((amask && 0x01) << 24) |*/ ((rmask && 0x01) << 16) | ((gmask && 0x01)<< 8) | ((bmask && 0x01) << 0)); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_COLOR_MASK, 1); + OUT_RING_CACHE(/*((amask && 0x01) << 24) |*/ ((rmask && 0x01) << 16) | ((gmask && 0x01)<< 8) | ((bmask && 0x01) << 0)); } void nv10ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode) @@ -136,37 +136,37 @@ void nv10ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode) void nv10CullFace(GLcontext *ctx, GLenum mode) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CULL_FACE, 1); - OUT_RING(mode); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CULL_FACE, 1); + OUT_RING_CACHE(mode); } void nv10FrontFace(GLcontext *ctx, GLenum mode) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FRONT_FACE, 1); - OUT_RING(mode); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FRONT_FACE, 1); + OUT_RING_CACHE(mode); } void nv10DepthFunc(GLcontext *ctx, GLenum func) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1); - OUT_RING(func); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1); + OUT_RING_CACHE(func); } void nv10DepthMask(GLcontext *ctx, GLboolean flag) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1); - OUT_RING(flag); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1); + OUT_RING_CACHE(flag); } void nv10DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2); - OUT_RINGf(nearval); - OUT_RINGf(farval); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2); + OUT_RING_CACHEf(nearval); + OUT_RING_CACHEf(farval); } /** Specify the current buffer for writing */ @@ -180,13 +180,13 @@ void nv10Enable(GLcontext *ctx, GLenum cap, GLboolean state) switch(cap) { case GL_ALPHA_TEST: - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1); + OUT_RING_CACHE(state); break; // case GL_AUTO_NORMAL: case GL_BLEND: - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_ENABLE, 1); + OUT_RING_CACHE(state); break; case GL_CLIP_PLANE0: case GL_CLIP_PLANE1: @@ -194,12 +194,12 @@ void nv10Enable(GLcontext *ctx, GLenum cap, GLboolean state) case GL_CLIP_PLANE3: case GL_CLIP_PLANE4: case GL_CLIP_PLANE5: - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1); + OUT_RING_CACHE(state); break; case GL_COLOR_LOGIC_OP: - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1); + OUT_RING_CACHE(state); break; // case GL_COLOR_MATERIAL: // case GL_COLOR_SUM_EXT: @@ -207,20 +207,20 @@ void nv10Enable(GLcontext *ctx, GLenum cap, GLboolean state) // case GL_CONVOLUTION_1D: // case GL_CONVOLUTION_2D: case GL_CULL_FACE: - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1); + OUT_RING_CACHE(state); break; case GL_DEPTH_TEST: - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1); + OUT_RING_CACHE(state); break; case GL_DITHER: - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DITHER_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DITHER_ENABLE, 1); + OUT_RING_CACHE(state); break; case GL_FOG: - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FOG_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FOG_ENABLE, 1); + OUT_RING_CACHE(state); break; // case GL_HISTOGRAM: // case GL_INDEX_LOGIC_OP: @@ -237,22 +237,22 @@ void nv10Enable(GLcontext *ctx, GLenum cap, GLboolean state) nmesa->enabled_lights=((nmesa->enabled_lights&mask)|(mask*state)); if (nmesa->lighting_enabled) { - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); - OUT_RING(nmesa->enabled_lights); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); + OUT_RING_CACHE(nmesa->enabled_lights); } break; } case GL_LIGHTING: nmesa->lighting_enabled=state; - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); if (nmesa->lighting_enabled) - OUT_RING(nmesa->enabled_lights); + OUT_RING_CACHE(nmesa->enabled_lights); else - OUT_RING(0x0); + OUT_RING_CACHE(0x0); break; case GL_LINE_SMOOTH: - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1); + OUT_RING_CACHE(state); break; // case GL_LINE_STIPPLE: // case GL_MAP1_COLOR_4: @@ -275,29 +275,29 @@ void nv10Enable(GLcontext *ctx, GLenum cap, GLboolean state) // case GL_MAP2_VERTEX_4: // case GL_MINMAX: case GL_NORMALIZE: - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1); + OUT_RING_CACHE(state); break; // case GL_POINT_SMOOTH: case GL_POLYGON_OFFSET_POINT: - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 1); + OUT_RING_CACHE(state); break; case GL_POLYGON_OFFSET_LINE: - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE, 1); + OUT_RING_CACHE(state); break; case GL_POLYGON_OFFSET_FILL: - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE, 1); + OUT_RING_CACHE(state); break; case GL_POLYGON_SMOOTH: - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1); + OUT_RING_CACHE(state); break; case GL_POINT_SMOOTH: - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POINT_SMOOTH_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POINT_SMOOTH_ENABLE, 1); + OUT_RING_CACHE(state); break; // case GL_POLYGON_STIPPLE: // case GL_POST_COLOR_MATRIX_COLOR_TABLE: @@ -306,8 +306,8 @@ void nv10Enable(GLcontext *ctx, GLenum cap, GLboolean state) // case GL_SCISSOR_TEST: // case GL_SEPARABLE_2D: case GL_STENCIL_TEST: - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_ENABLE, 1); + OUT_RING_CACHE(state); break; // case GL_TEXTURE_GEN_Q: // case GL_TEXTURE_GEN_R: @@ -325,8 +325,8 @@ void nv10Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) switch(pname) { case GL_FOG_MODE: - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FOG_MODE, 1); - //OUT_RING (params); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FOG_MODE, 1); + //OUT_RING_CACHE (params); break; /* TODO: unsure about the rest.*/ default: @@ -349,60 +349,60 @@ void nv10Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *para switch(pname) { case GL_AMBIENT: - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_AMBIENT(light), 3); - OUT_RINGf(params[0]); - OUT_RINGf(params[1]); - OUT_RINGf(params[2]); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_AMBIENT(light), 3); + OUT_RING_CACHEf(params[0]); + OUT_RING_CACHEf(params[1]); + OUT_RING_CACHEf(params[2]); break; case GL_DIFFUSE: - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_DIFFUSE(light), 3); - OUT_RINGf(params[0]); - OUT_RINGf(params[1]); - OUT_RINGf(params[2]); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_DIFFUSE(light), 3); + OUT_RING_CACHEf(params[0]); + OUT_RING_CACHEf(params[1]); + OUT_RING_CACHEf(params[2]); break; case GL_SPECULAR: - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPECULAR(light), 3); - OUT_RINGf(params[0]); - OUT_RINGf(params[1]); - OUT_RINGf(params[2]); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPECULAR(light), 3); + OUT_RING_CACHEf(params[0]); + OUT_RING_CACHEf(params[1]); + OUT_RING_CACHEf(params[2]); break; #if 0 case GL_SPOT_DIRECTION: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(light), 3); - OUT_RINGf(params[0]); - OUT_RINGf(params[1]); - OUT_RINGf(params[2]); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(light), 3); + OUT_RING_CACHEf(params[0]); + OUT_RING_CACHEf(params[1]); + OUT_RING_CACHEf(params[2]); break; case GL_POSITION: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(light), 3); - OUT_RINGf(params[0]); - OUT_RINGf(params[1]); - OUT_RINGf(params[2]); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(light), 3); + OUT_RING_CACHEf(params[0]); + OUT_RING_CACHEf(params[1]); + OUT_RING_CACHEf(params[2]); break; case GL_SPOT_EXPONENT: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(light), 1); - OUT_RINGf(*params); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(light), 1); + OUT_RING_CACHEf(*params); break; case GL_SPOT_CUTOFF: /* you can't factor these */ - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(light), 1); - OUT_RINGf(params[0]); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(light), 1); - OUT_RINGf(params[1]); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(light), 1); - OUT_RINGf(params[2]); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(light), 1); + OUT_RING_CACHEf(params[0]); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(light), 1); + OUT_RING_CACHEf(params[1]); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(light), 1); + OUT_RING_CACHEf(params[2]); break; case GL_CONSTANT_ATTENUATION: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(light), 1); - OUT_RINGf(*params); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(light), 1); + OUT_RING_CACHEf(*params); break; case GL_LINEAR_ATTENUATION: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(light), 1); - OUT_RINGf(*params); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(light), 1); + OUT_RING_CACHEf(*params); break; case GL_QUADRATIC_ATTENUATION: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(light), 1); - OUT_RINGf(*params); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(light), 1); + OUT_RING_CACHEf(*params); break; #endif default: @@ -417,23 +417,23 @@ void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params); void nv30LineStipple(GLcontext *ctx, GLint factor, GLushort pattern ) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN, 1); - OUT_RING((pattern << 16) | factor); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN, 1); + OUT_RING_CACHE((pattern << 16) | factor); } void nv30LineWidth(GLcontext *ctx, GLfloat width) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_WIDTH_SMOOTH, 1); - OUT_RINGf(width); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_WIDTH_SMOOTH, 1); + OUT_RING_CACHEf(width); } */ void nv10LogicOpcode(GLcontext *ctx, GLenum opcode) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LOGIC_OP, 1); - OUT_RING(opcode); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LOGIC_OP, 1); + OUT_RING_CACHE(opcode); } void nv10PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params) @@ -447,8 +447,8 @@ void nv10PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params) void nv10PointSize(GLcontext *ctx, GLfloat size) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POINT_SIZE, 1); - OUT_RINGf(size); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POINT_SIZE, 1); + OUT_RING_CACHEf(size); } /** Select a polygon rasterization mode */ @@ -469,8 +469,8 @@ void nv10ShadeModel(GLcontext *ctx, GLenum mode) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_SHADE_MODEL, 1); - OUT_RING(mode); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_SHADE_MODEL, 1); + OUT_RING_CACHE(mode); } /** OpenGL 2.0 two-sided StencilFunc */ @@ -479,10 +479,10 @@ static void nv10StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC, 3); - OUT_RING(func); - OUT_RING(ref); - OUT_RING(mask); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC, 3); + OUT_RING_CACHE(func); + OUT_RING_CACHE(ref); + OUT_RING_CACHE(mask); } /** OpenGL 2.0 two-sided StencilMask */ @@ -490,8 +490,8 @@ static void nv10StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_MASK, 1); - OUT_RING(mask); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_MASK, 1); + OUT_RING_CACHE(mask); } /** OpenGL 2.0 two-sided StencilOp */ @@ -500,10 +500,10 @@ static void nv10StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL, 1); - OUT_RING(fail); - OUT_RING(zfail); - OUT_RING(zpass); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL, 1); + OUT_RING_CACHE(fail); + OUT_RING_CACHE(zfail); + OUT_RING_CACHE(zpass); } /** Control the generation of texture coordinates */ @@ -523,8 +523,8 @@ void nv10Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) { /* TODO: Where do the VIEWPORT_XFRM_* regs come in? */ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2); - OUT_RING((w << 16) | x); - OUT_RING((h << 16) | y); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2); + OUT_RING_CACHE((w << 16) | x); + OUT_RING_CACHE((h << 16) | y); } diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 832ce4ad21..198e3a2668 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -61,6 +61,7 @@ static void nv10ResetLineStipple( GLcontext *ctx ); static inline void nv10StartPrimitive(struct nouveau_context* nmesa,uint32_t primitive,uint32_t size) { + // FIXME the primitive type can probably go trough the caching system as well if (nmesa->screen->card->type==NV_10) BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_BEGIN_END,1); else if (nmesa->screen->card->type==NV_20) @@ -79,6 +80,7 @@ static inline void nv10StartPrimitive(struct nouveau_context* nmesa,uint32_t pri inline void nv10FinishPrimitive(struct nouveau_context *nmesa) { + // FIXME this is probably not needed if (nmesa->screen->card->type==NV_10) BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_BEGIN_END,1); else if (nmesa->screen->card->type==NV_20) @@ -216,23 +218,6 @@ static void nv10_render_noop_verts(GLcontext *ctx,GLuint start,GLuint count,GLui { } -static inline void nv10_render_generic_primitive_elts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags,GLuint prim) -{ - struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - GLubyte *vertptr = (GLubyte *)nmesa->verts; - GLuint vertsize = nmesa->vertex_size; - GLuint size_dword = vertsize*(count-start); - const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; - GLuint j; - - nv10ExtendPrimitive(nmesa, size_dword); - nv10StartPrimitive(nmesa,prim+1,size_dword); - for (j=start; jverts; + GLuint vertsize = nmesa->vertex_size; + GLuint size_dword = vertsize*(count-start); + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; + GLuint j; + + nv10ExtendPrimitive(nmesa, size_dword); + nv10StartPrimitive(nmesa,prim+1,size_dword); + for (j=start; jscreen->card->type==NV_20) { for(i=0;i<16;i++) { int size=attr_size[i]; - BEGIN_RING_SIZE(NvSub3D,NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR(i),1); - OUT_RING(NV_VERTEX_ATTRIBUTE_TYPE_FLOAT|(size*0x10)); + BEGIN_RING_CACHE(NvSub3D,NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR(i),1); + OUT_RING_CACHE(NV_VERTEX_ATTRIBUTE_TYPE_FLOAT|(size*0x10)); } } else { - BEGIN_RING_SIZE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR0_POS,slots); + BEGIN_RING_CACHE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR0_POS,slots); for(i=0;iclear_value=((nmesa->clear_value&0x000000FF)|(((uint32_t)(d*0xFFFFFF))<<8)); - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1); - OUT_RING(nmesa->clear_value); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1); + OUT_RING_CACHE(nmesa->clear_value); } /* we're don't support indexed buffers @@ -101,26 +101,26 @@ static void nv20ClearStencil(GLcontext *ctx, GLint s) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); nmesa->clear_value=((nmesa->clear_value&0xFFFFFF00)|(s&0x000000FF)); - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1); - OUT_RING(nmesa->clear_value); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1); + OUT_RING_CACHE(nmesa->clear_value); } static void nv20ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4); - OUT_RINGf(equation[0]); - OUT_RINGf(equation[1]); - OUT_RINGf(equation[2]); - OUT_RINGf(equation[3]); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4); + OUT_RING_CACHEf(equation[0]); + OUT_RING_CACHEf(equation[1]); + OUT_RING_CACHEf(equation[2]); + OUT_RING_CACHEf(equation[3]); } static void nv20ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, GLboolean bmask, GLboolean amask ) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_COLOR_MASK, 1); - OUT_RING(((amask && 0x01) << 24) | ((rmask && 0x01) << 16) | ((gmask && 0x01)<< 8) | ((bmask && 0x01) << 0)); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_COLOR_MASK, 1); + OUT_RING_CACHE(((amask && 0x01) << 24) | ((rmask && 0x01) << 16) | ((gmask && 0x01)<< 8) | ((bmask && 0x01) << 0)); } static void nv20ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode) @@ -131,37 +131,37 @@ static void nv20ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode) static void nv20CullFace(GLcontext *ctx, GLenum mode) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CULL_FACE, 1); - OUT_RING(mode); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CULL_FACE, 1); + OUT_RING_CACHE(mode); } static void nv20FrontFace(GLcontext *ctx, GLenum mode) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_FRONT_FACE, 1); - OUT_RING(mode); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_FRONT_FACE, 1); + OUT_RING_CACHE(mode); } static void nv20DepthFunc(GLcontext *ctx, GLenum func) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1); - OUT_RING(func); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1); + OUT_RING_CACHE(func); } static void nv20DepthMask(GLcontext *ctx, GLboolean flag) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1); - OUT_RING(flag); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1); + OUT_RING_CACHE(flag); } static void nv20DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2); - OUT_RINGf(nearval); - OUT_RINGf(farval); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2); + OUT_RING_CACHEf(nearval); + OUT_RING_CACHEf(farval); } /** Specify the current buffer for writing */ @@ -175,13 +175,13 @@ static void nv20Enable(GLcontext *ctx, GLenum cap, GLboolean state) switch(cap) { case GL_ALPHA_TEST: - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1); + OUT_RING_CACHE(state); break; // case GL_AUTO_NORMAL: case GL_BLEND: - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1); + OUT_RING_CACHE(state); break; case GL_CLIP_PLANE0: case GL_CLIP_PLANE1: @@ -189,12 +189,12 @@ static void nv20Enable(GLcontext *ctx, GLenum cap, GLboolean state) case GL_CLIP_PLANE3: case GL_CLIP_PLANE4: case GL_CLIP_PLANE5: - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1); + OUT_RING_CACHE(state); break; case GL_COLOR_LOGIC_OP: - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1); + OUT_RING_CACHE(state); break; // case GL_COLOR_MATERIAL: // case GL_COLOR_SUM_EXT: @@ -202,20 +202,20 @@ static void nv20Enable(GLcontext *ctx, GLenum cap, GLboolean state) // case GL_CONVOLUTION_1D: // case GL_CONVOLUTION_2D: case GL_CULL_FACE: - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1); + OUT_RING_CACHE(state); break; case GL_DEPTH_TEST: - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1); + OUT_RING_CACHE(state); break; case GL_DITHER: - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DITHER_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_DITHER_ENABLE, 1); + OUT_RING_CACHE(state); break; case GL_FOG: - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_FOG_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_FOG_ENABLE, 1); + OUT_RING_CACHE(state); break; // case GL_HISTOGRAM: // case GL_INDEX_LOGIC_OP: @@ -232,22 +232,22 @@ static void nv20Enable(GLcontext *ctx, GLenum cap, GLboolean state) nmesa->enabled_lights=((nmesa->enabled_lights&mask)|(mask*state)); if (nmesa->lighting_enabled) { - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); - OUT_RING(nmesa->enabled_lights); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); + OUT_RING_CACHE(nmesa->enabled_lights); } break; } case GL_LIGHTING: nmesa->lighting_enabled=state; - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); if (nmesa->lighting_enabled) - OUT_RING(nmesa->enabled_lights); + OUT_RING_CACHE(nmesa->enabled_lights); else - OUT_RING(0x0); + OUT_RING_CACHE(0x0); break; case GL_LINE_SMOOTH: - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1); + OUT_RING_CACHE(state); break; // case GL_LINE_STIPPLE: // case GL_MAP1_COLOR_4: @@ -270,29 +270,29 @@ static void nv20Enable(GLcontext *ctx, GLenum cap, GLboolean state) // case GL_MAP2_VERTEX_4: // case GL_MINMAX: case GL_NORMALIZE: - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1); + OUT_RING_CACHE(state); break; // case GL_POINT_SMOOTH: case GL_POLYGON_OFFSET_POINT: - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 1); + OUT_RING_CACHE(state); break; case GL_POLYGON_OFFSET_LINE: - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE, 1); + OUT_RING_CACHE(state); break; case GL_POLYGON_OFFSET_FILL: - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE, 1); + OUT_RING_CACHE(state); break; case GL_POLYGON_SMOOTH: - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1); + OUT_RING_CACHE(state); break; case GL_POLYGON_STIPPLE: - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE, 1); + OUT_RING_CACHE(state); break; // case GL_POST_COLOR_MATRIX_COLOR_TABLE: // case GL_POST_CONVOLUTION_COLOR_TABLE: @@ -301,8 +301,8 @@ static void nv20Enable(GLcontext *ctx, GLenum cap, GLboolean state) // case GL_SEPARABLE_2D: case GL_STENCIL_TEST: // TODO BACK and FRONT ? - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_ENABLE, 1); + OUT_RING_CACHE(state); break; // case GL_TEXTURE_GEN_Q: // case GL_TEXTURE_GEN_R: @@ -320,8 +320,8 @@ static void nv20Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) switch(pname) { case GL_FOG_MODE: - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_FOG_MODE, 1); - //OUT_RING (params); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_FOG_MODE, 1); + //OUT_RING_CACHE (params); break; /* TODO: unsure about the rest.*/ default: @@ -344,59 +344,59 @@ static void nv20Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa switch(pname) { case GL_AMBIENT: - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_A(light), 3); - OUT_RINGf(params[0]); - OUT_RINGf(params[1]); - OUT_RINGf(params[2]); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_A(light), 3); + OUT_RING_CACHEf(params[0]); + OUT_RING_CACHEf(params[1]); + OUT_RING_CACHEf(params[2]); break; case GL_DIFFUSE: - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_A(light), 3); - OUT_RINGf(params[0]); - OUT_RINGf(params[1]); - OUT_RINGf(params[2]); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_A(light), 3); + OUT_RING_CACHEf(params[0]); + OUT_RING_CACHEf(params[1]); + OUT_RING_CACHEf(params[2]); break; case GL_SPECULAR: - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_A(light), 3); - OUT_RINGf(params[0]); - OUT_RINGf(params[1]); - OUT_RINGf(params[2]); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_A(light), 3); + OUT_RING_CACHEf(params[0]); + OUT_RING_CACHEf(params[1]); + OUT_RING_CACHEf(params[2]); break; case GL_SPOT_DIRECTION: - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(light), 3); - OUT_RINGf(params[0]); - OUT_RINGf(params[1]); - OUT_RINGf(params[2]); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(light), 3); + OUT_RING_CACHEf(params[0]); + OUT_RING_CACHEf(params[1]); + OUT_RING_CACHEf(params[2]); break; case GL_POSITION: - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(light), 3); - OUT_RINGf(params[0]); - OUT_RINGf(params[1]); - OUT_RINGf(params[2]); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(light), 3); + OUT_RING_CACHEf(params[0]); + OUT_RING_CACHEf(params[1]); + OUT_RING_CACHEf(params[2]); break; case GL_SPOT_EXPONENT: - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(light), 1); - OUT_RINGf(*params); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(light), 1); + OUT_RING_CACHEf(*params); break; case GL_SPOT_CUTOFF: /* you can't factor these */ - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(light), 1); - OUT_RINGf(params[0]); - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(light), 1); - OUT_RINGf(params[1]); - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(light), 1); - OUT_RINGf(params[2]); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(light), 1); + OUT_RING_CACHEf(params[0]); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(light), 1); + OUT_RING_CACHEf(params[1]); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(light), 1); + OUT_RING_CACHEf(params[2]); break; case GL_CONSTANT_ATTENUATION: - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(light), 1); - OUT_RINGf(*params); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(light), 1); + OUT_RING_CACHEf(*params); break; case GL_LINEAR_ATTENUATION: - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(light), 1); - OUT_RINGf(*params); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(light), 1); + OUT_RING_CACHEf(*params); break; case GL_QUADRATIC_ATTENUATION: - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(light), 1); - OUT_RINGf(*params); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(light), 1); + OUT_RING_CACHEf(*params); break; default: break; @@ -410,22 +410,22 @@ static void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params) static void nv20LineStipple(GLcontext *ctx, GLint factor, GLushort pattern ) { /* nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN, 1); - OUT_RING((pattern << 16) | factor);*/ + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN, 1); + OUT_RING_CACHE((pattern << 16) | factor);*/ } static void nv20LineWidth(GLcontext *ctx, GLfloat width) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LINE_WIDTH, 1); - OUT_RINGf(width); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LINE_WIDTH, 1); + OUT_RING_CACHEf(width); } static void nv20LogicOpcode(GLcontext *ctx, GLenum opcode) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP, 1); - OUT_RING(opcode); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP, 1); + OUT_RING_CACHE(opcode); } static void nv20PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params) @@ -439,8 +439,8 @@ static void nv20PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *pa static void nv20PointSize(GLcontext *ctx, GLfloat size) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POINT_SIZE, 1); - OUT_RINGf(size); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POINT_SIZE, 1); + OUT_RING_CACHEf(size); } /** Select a polygon rasterization mode */ @@ -449,12 +449,12 @@ static void nv20PolygonMode(GLcontext *ctx, GLenum face, GLenum mode) nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 1); - OUT_RING(mode); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 1); + OUT_RING_CACHE(mode); } if (face == GL_BACK || face == GL_FRONT_AND_BACK) { - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK, 1); - OUT_RING(mode); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK, 1); + OUT_RING_CACHE(mode); } } @@ -474,8 +474,8 @@ void nv20ShadeModel(GLcontext *ctx, GLenum mode) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SHADE_MODEL, 1); - OUT_RING(mode); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SHADE_MODEL, 1); + OUT_RING_CACHE(mode); } /** OpenGL 2.0 two-sided StencilFunc */ @@ -484,10 +484,10 @@ static void nv20StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC, 3); - OUT_RING(func); - OUT_RING(ref); - OUT_RING(mask); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC, 3); + OUT_RING_CACHE(func); + OUT_RING_CACHE(ref); + OUT_RING_CACHE(mask); } /** OpenGL 2.0 two-sided StencilMask */ @@ -495,8 +495,8 @@ static void nv20StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_MASK, 1); - OUT_RING(mask); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_MASK, 1); + OUT_RING_CACHE(mask); } /** OpenGL 2.0 two-sided StencilOp */ @@ -505,10 +505,10 @@ static void nv20StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL, 1); - OUT_RING(fail); - OUT_RING(zfail); - OUT_RING(zpass); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL, 1); + OUT_RING_CACHE(fail); + OUT_RING_CACHE(zfail); + OUT_RING_CACHE(zpass); } /** Control the generation of texture coordinates */ @@ -528,9 +528,9 @@ static void nv20Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) { /* TODO: Where do the VIEWPORT_XFRM_* regs come in? */ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2); - OUT_RING((w << 16) | x); - OUT_RING((h << 16) | y); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2); + OUT_RING_CACHE((w << 16) | x); + OUT_RING_CACHE((h << 16) | y); } void nv20InitStateFuncs(struct dd_function_table *func) diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index a6cbcb8c8d..7b50cbc461 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -43,9 +43,9 @@ static void nv30AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) GLubyte ubRef; CLAMPED_FLOAT_TO_UBYTE(ubRef, ref); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2); - OUT_RING(func); /* NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC */ - OUT_RING(ubRef); /* NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF */ + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2); + OUT_RING_CACHE(func); /* NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC */ + OUT_RING_CACHE(ubRef); /* NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF */ } static void nv30BlendColor(GLcontext *ctx, const GLfloat color[4]) @@ -58,15 +58,15 @@ static void nv30BlendColor(GLcontext *ctx, const GLfloat color[4]) CLAMPED_FLOAT_TO_UBYTE(cf[2], color[2]); CLAMPED_FLOAT_TO_UBYTE(cf[3], color[3]); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_COLOR, 1); - OUT_RING(PACK_COLOR_8888(cf[3], cf[1], cf[2], cf[0])); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_COLOR, 1); + OUT_RING_CACHE(PACK_COLOR_8888(cf[3], cf[1], cf[2], cf[0])); } static void nv30BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_EQUATION, 1); - OUT_RING((modeA<<16) | modeRGB); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_EQUATION, 1); + OUT_RING_CACHE((modeA<<16) | modeRGB); } @@ -74,9 +74,9 @@ static void nv30BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfac GLenum sfactorA, GLenum dfactorA) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2); - OUT_RING((sfactorA<<16) | sfactorRGB); - OUT_RING((dfactorA<<16) | dfactorRGB); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2); + OUT_RING_CACHE((sfactorA<<16) | sfactorRGB); + OUT_RING_CACHE((dfactorA<<16) | dfactorRGB); } static void nv30ClearColor(GLcontext *ctx, const GLfloat color[4]) @@ -84,16 +84,16 @@ static void nv30ClearColor(GLcontext *ctx, const GLfloat color[4]) nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); GLubyte c[4]; UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,color); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB, 1); - OUT_RING(PACK_COLOR_8888(c[3],c[0],c[1],c[2])); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB, 1); + OUT_RING_CACHE(PACK_COLOR_8888(c[3],c[0],c[1],c[2])); } static void nv30ClearDepth(GLcontext *ctx, GLclampd d) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); nmesa->clear_value=((nmesa->clear_value&0x000000FF)|(((uint32_t)(d*0xFFFFFF))<<8)); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1); - OUT_RING(nmesa->clear_value); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1); + OUT_RING_CACHE(nmesa->clear_value); } /* we're don't support indexed buffers @@ -104,26 +104,26 @@ static void nv30ClearStencil(GLcontext *ctx, GLint s) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); nmesa->clear_value=((nmesa->clear_value&0xFFFFFF00)|(s&0x000000FF)); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1); - OUT_RING(nmesa->clear_value); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1); + OUT_RING_CACHE(nmesa->clear_value); } static void nv30ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4); - OUT_RINGf(equation[0]); - OUT_RINGf(equation[1]); - OUT_RINGf(equation[2]); - OUT_RINGf(equation[3]); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4); + OUT_RING_CACHEf(equation[0]); + OUT_RING_CACHEf(equation[1]); + OUT_RING_CACHEf(equation[2]); + OUT_RING_CACHEf(equation[3]); } static void nv30ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, GLboolean bmask, GLboolean amask ) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_MASK, 1); - OUT_RING(((amask && 0x01) << 24) | ((rmask && 0x01) << 16) | ((gmask && 0x01)<< 8) | ((bmask && 0x01) << 0)); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_MASK, 1); + OUT_RING_CACHE(((amask && 0x01) << 24) | ((rmask && 0x01) << 16) | ((gmask && 0x01)<< 8) | ((bmask && 0x01) << 0)); } static void nv30ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode) @@ -134,37 +134,37 @@ static void nv30ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode) static void nv30CullFace(GLcontext *ctx, GLenum mode) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CULL_FACE, 1); - OUT_RING(mode); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CULL_FACE, 1); + OUT_RING_CACHE(mode); } static void nv30FrontFace(GLcontext *ctx, GLenum mode) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FRONT_FACE, 1); - OUT_RING(mode); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FRONT_FACE, 1); + OUT_RING_CACHE(mode); } static void nv30DepthFunc(GLcontext *ctx, GLenum func) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1); - OUT_RING(func); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1); + OUT_RING_CACHE(func); } static void nv30DepthMask(GLcontext *ctx, GLboolean flag) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1); - OUT_RING(flag); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1); + OUT_RING_CACHE(flag); } static void nv30DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2); - OUT_RINGf(nearval); - OUT_RINGf(farval); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2); + OUT_RING_CACHEf(nearval); + OUT_RING_CACHEf(farval); } /** Specify the current buffer for writing */ @@ -178,13 +178,13 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) switch(cap) { case GL_ALPHA_TEST: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1); + OUT_RING_CACHE(state); break; // case GL_AUTO_NORMAL: case GL_BLEND: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1); + OUT_RING_CACHE(state); break; case GL_CLIP_PLANE0: case GL_CLIP_PLANE1: @@ -192,12 +192,12 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) case GL_CLIP_PLANE3: case GL_CLIP_PLANE4: case GL_CLIP_PLANE5: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1); + OUT_RING_CACHE(state); break; case GL_COLOR_LOGIC_OP: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1); + OUT_RING_CACHE(state); break; // case GL_COLOR_MATERIAL: // case GL_COLOR_SUM_EXT: @@ -205,20 +205,20 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) // case GL_CONVOLUTION_1D: // case GL_CONVOLUTION_2D: case GL_CULL_FACE: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1); + OUT_RING_CACHE(state); break; case GL_DEPTH_TEST: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1); + OUT_RING_CACHE(state); break; case GL_DITHER: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DITHER_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DITHER_ENABLE, 1); + OUT_RING_CACHE(state); break; case GL_FOG: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_ENABLE, 1); + OUT_RING_CACHE(state); break; // case GL_HISTOGRAM: // case GL_INDEX_LOGIC_OP: @@ -239,8 +239,8 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) nmesa->enabled_lights=((nmesa->enabled_lights&mask)|(mask*state)); if (nmesa->lighting_enabled) { - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); - OUT_RING(nmesa->enabled_lights); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); + OUT_RING_CACHE(nmesa->enabled_lights); } break; } @@ -249,11 +249,11 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) break; nmesa->lighting_enabled=state; - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_ENABLED_LIGHTS, 1); if (nmesa->lighting_enabled) - OUT_RING(nmesa->enabled_lights); + OUT_RING_CACHE(nmesa->enabled_lights); else - OUT_RING(0x0); + OUT_RING_CACHE(0x0); break; // case GL_LINE_SMOOTH: // case GL_LINE_STIPPLE: @@ -277,29 +277,29 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) // case GL_MAP2_VERTEX_4: // case GL_MINMAX: case GL_NORMALIZE: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1); + OUT_RING_CACHE(state); break; // case GL_POINT_SMOOTH: case GL_POLYGON_OFFSET_POINT: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 1); + OUT_RING_CACHE(state); break; case GL_POLYGON_OFFSET_LINE: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE, 1); + OUT_RING_CACHE(state); break; case GL_POLYGON_OFFSET_FILL: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE, 1); + OUT_RING_CACHE(state); break; case GL_POLYGON_SMOOTH: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1); + OUT_RING_CACHE(state); break; case GL_POLYGON_STIPPLE: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE, 1); + OUT_RING_CACHE(state); break; // case GL_POST_COLOR_MATRIX_COLOR_TABLE: // case GL_POST_CONVOLUTION_COLOR_TABLE: @@ -308,8 +308,8 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) // case GL_SEPARABLE_2D: case GL_STENCIL_TEST: // TODO BACK and FRONT ? - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_ENABLE, 1); - OUT_RING(state); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_ENABLE, 1); + OUT_RING_CACHE(state); break; // case GL_TEXTURE_GEN_Q: // case GL_TEXTURE_GEN_R: @@ -327,8 +327,8 @@ static void nv30Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) switch(pname) { case GL_FOG_MODE: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_MODE, 1); - //OUT_RING (params); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_MODE, 1); + //OUT_RING_CACHE (params); break; /* TODO: unsure about the rest.*/ default: @@ -355,59 +355,59 @@ static void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa switch(pname) { case GL_AMBIENT: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_A(light), 3); - OUT_RINGf(params[0]); - OUT_RINGf(params[1]); - OUT_RINGf(params[2]); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_A(light), 3); + OUT_RING_CACHEf(params[0]); + OUT_RING_CACHEf(params[1]); + OUT_RING_CACHEf(params[2]); break; case GL_DIFFUSE: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_A(light), 3); - OUT_RINGf(params[0]); - OUT_RINGf(params[1]); - OUT_RINGf(params[2]); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_A(light), 3); + OUT_RING_CACHEf(params[0]); + OUT_RING_CACHEf(params[1]); + OUT_RING_CACHEf(params[2]); break; case GL_SPECULAR: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_A(light), 3); - OUT_RINGf(params[0]); - OUT_RINGf(params[1]); - OUT_RINGf(params[2]); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_A(light), 3); + OUT_RING_CACHEf(params[0]); + OUT_RING_CACHEf(params[1]); + OUT_RING_CACHEf(params[2]); break; case GL_SPOT_DIRECTION: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(light), 3); - OUT_RINGf(params[0]); - OUT_RINGf(params[1]); - OUT_RINGf(params[2]); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(light), 3); + OUT_RING_CACHEf(params[0]); + OUT_RING_CACHEf(params[1]); + OUT_RING_CACHEf(params[2]); break; case GL_POSITION: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(light), 3); - OUT_RINGf(params[0]); - OUT_RINGf(params[1]); - OUT_RINGf(params[2]); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(light), 3); + OUT_RING_CACHEf(params[0]); + OUT_RING_CACHEf(params[1]); + OUT_RING_CACHEf(params[2]); break; case GL_SPOT_EXPONENT: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(light), 1); - OUT_RINGf(*params); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(light), 1); + OUT_RING_CACHEf(*params); break; case GL_SPOT_CUTOFF: /* you can't factor these */ - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(light), 1); - OUT_RINGf(params[0]); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(light), 1); - OUT_RINGf(params[1]); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(light), 1); - OUT_RINGf(params[2]); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(light), 1); + OUT_RING_CACHEf(params[0]); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(light), 1); + OUT_RING_CACHEf(params[1]); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(light), 1); + OUT_RING_CACHEf(params[2]); break; case GL_CONSTANT_ATTENUATION: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(light), 1); - OUT_RINGf(*params); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(light), 1); + OUT_RING_CACHEf(*params); break; case GL_LINEAR_ATTENUATION: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(light), 1); - OUT_RINGf(*params); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(light), 1); + OUT_RING_CACHEf(*params); break; case GL_QUADRATIC_ATTENUATION: - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(light), 1); - OUT_RINGf(*params); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(light), 1); + OUT_RING_CACHEf(*params); break; default: break; @@ -421,8 +421,8 @@ void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params); static void nv30LineStipple(GLcontext *ctx, GLint factor, GLushort pattern ) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN, 1); - OUT_RING((pattern << 16) | factor); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN, 1); + OUT_RING_CACHE((pattern << 16) | factor); } static void nv30LineWidth(GLcontext *ctx, GLfloat width) @@ -432,15 +432,15 @@ static void nv30LineWidth(GLcontext *ctx, GLfloat width) CLAMPED_FLOAT_TO_UBYTE(ubWidth, width); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_WIDTH_SMOOTH, 1); - OUT_RING(ubWidth); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_WIDTH_SMOOTH, 1); + OUT_RING_CACHE(ubWidth); } static void nv30LogicOpcode(GLcontext *ctx, GLenum opcode) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP, 1); - OUT_RING(opcode); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP, 1); + OUT_RING_CACHE(opcode); } static void nv30PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params) @@ -454,8 +454,8 @@ static void nv30PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *pa static void nv30PointSize(GLcontext *ctx, GLfloat size) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POINT_SIZE, 1); - OUT_RINGf(size); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POINT_SIZE, 1); + OUT_RING_CACHEf(size); } /** Select a polygon rasterization mode */ @@ -464,12 +464,12 @@ static void nv30PolygonMode(GLcontext *ctx, GLenum face, GLenum mode) nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 1); - OUT_RING(mode); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 1); + OUT_RING_CACHE(mode); } if (face == GL_BACK || face == GL_FRONT_AND_BACK) { - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK, 1); - OUT_RING(mode); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK, 1); + OUT_RING_CACHE(mode); } } @@ -511,8 +511,8 @@ static void nv30ShadeModel(GLcontext *ctx, GLenum mode) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SHADE_MODEL, 1); - OUT_RING(mode); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SHADE_MODEL, 1); + OUT_RING_CACHE(mode); } /** OpenGL 2.0 two-sided StencilFunc */ @@ -522,16 +522,16 @@ static void nv30StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_FUNC, 3); - OUT_RING(func); - OUT_RING(ref); - OUT_RING(mask); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_FUNC, 3); + OUT_RING_CACHE(func); + OUT_RING_CACHE(ref); + OUT_RING_CACHE(mask); } if (face == GL_BACK || face == GL_FRONT_AND_BACK) { - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_FUNC, 3); - OUT_RING(func); - OUT_RING(ref); - OUT_RING(mask); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_FUNC, 3); + OUT_RING_CACHE(func); + OUT_RING_CACHE(ref); + OUT_RING_CACHE(mask); } } @@ -541,12 +541,12 @@ static void nv30StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask) nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_MASK, 1); - OUT_RING(mask); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_MASK, 1); + OUT_RING_CACHE(mask); } if (face == GL_BACK || face == GL_FRONT_AND_BACK) { - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_MASK, 1); - OUT_RING(mask); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_MASK, 1); + OUT_RING_CACHE(mask); } } @@ -557,16 +557,16 @@ static void nv30StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_FAIL, 3); - OUT_RING(fail); - OUT_RING(zfail); - OUT_RING(zpass); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_FAIL, 3); + OUT_RING_CACHE(fail); + OUT_RING_CACHE(zfail); + OUT_RING_CACHE(zpass); } if (face == GL_BACK || face == GL_FRONT_AND_BACK) { - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_FAIL, 3); - OUT_RING(fail); - OUT_RING(zfail); - OUT_RING(zpass); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_FAIL, 3); + OUT_RING_CACHE(fail); + OUT_RING_CACHE(zfail); + OUT_RING_CACHE(zpass); } } @@ -594,9 +594,9 @@ static void nv30Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) { /* TODO: Where do the VIEWPORT_XFRM_* regs come in? */ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_0, 2); - OUT_RING((w << 16) | x); - OUT_RING((h << 16) | y); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_0, 2); + OUT_RING_CACHE((w << 16) | x); + OUT_RING_CACHE((h << 16) | y); } void nv30InitStateFuncs(struct dd_function_table *func) -- cgit v1.2.3 From fb6545070418820609a57f4dd975b41c93d499a9 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Tue, 21 Nov 2006 13:07:48 +0000 Subject: Remaining state cache changes --- src/mesa/drivers/dri/nouveau/nouveau_fifo.h | 5 +++++ src/mesa/drivers/dri/nouveau/nv30_state.c | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 10 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h index 259e5a1dc7..ce465cdca5 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h @@ -112,6 +112,11 @@ extern void nouveau_state_cache_init(nouveauContextPtr nmesa); nmesa->state_cache.current_pos++; \ }while(0) +#define OUT_RING_CACHEp(ptr,sz) do { \ +uint32_t* p=(uint32_t*)(ptr); \ +int i; for(i=0;ififo.free <= (size)) \ diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 7b50cbc461..0fc3d16751 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -477,19 +477,19 @@ static void nv30PolygonMode(GLcontext *ctx, GLenum face, GLenum mode) static void nv30PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR, 2); - OUT_RINGf(factor); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR, 2); + OUT_RING_CACHEf(factor); /* Looks like we always multiply units by 2.0... according to the dumps.*/ - OUT_RINGf(units * 2.0); + OUT_RING_CACHEf(units * 2.0); } /** Set the polygon stippling pattern */ static void nv30PolygonStipple(GLcontext *ctx, const GLubyte *mask ) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(0), 32); - OUT_RINGp(mask, 32); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(0), 32); + OUT_RING_CACHEp(mask, 32); } /* Specifies the current buffer for reading */ @@ -501,9 +501,9 @@ void (*RenderMode)(GLcontext *ctx, GLenum mode ); static void nv30Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS, 2); - OUT_RING((w << 16) | x); - OUT_RING((y << 16) | y); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS, 2); + OUT_RING_CACHE((w << 16) | x); + OUT_RING_CACHE((y << 16) | y); } /** Select flat or smooth shading */ @@ -584,9 +584,9 @@ void (*TexParameter)(GLcontext *ctx, GLenum target, static void nv30TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16); /*XXX: This SHOULD work.*/ - OUT_RINGp(mat->m, 16); + OUT_RING_CACHEp(mat->m, 16); } /** Set the viewport */ -- cgit v1.2.3 From a75440bcf04efb7a4840e9b0d1f0903b40b952bf Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 21 Nov 2006 14:03:06 +0000 Subject: nouveauCreateDmaObject --- src/mesa/drivers/dri/nouveau/nouveau_context.c | 1 + src/mesa/drivers/dri/nouveau/nouveau_object.c | 37 +++++++++++++++++++++++--- src/mesa/drivers/dri/nouveau/nouveau_object.h | 2 ++ 3 files changed, 36 insertions(+), 4 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index a2ac056010..d3fbdab9f3 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -45,6 +45,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_object.h" #include "nouveau_fifo.h" #include "nouveau_tex.h" +#include "nouveau_msg.h" #include "nv10_swtcl.h" #include "vblank.h" diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.c b/src/mesa/drivers/dri/nouveau/nouveau_object.c index 9003fb1eae..fe3b44df69 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.c @@ -3,8 +3,7 @@ #include "nouveau_object.h" -static GLboolean NVDmaCreateContextObject(nouveauContextPtr nmesa, int handle, int class, uint32_t flags, - uint32_t dma_in, uint32_t dma_out, uint32_t dma_notifier) +static GLboolean nouveauCreateContextObject(nouveauContextPtr nmesa, int handle, int class, uint32_t flags, uint32_t dma_in, uint32_t dma_out, uint32_t dma_notifier) { drm_nouveau_object_init_t cto; int ret; @@ -20,7 +19,27 @@ static GLboolean NVDmaCreateContextObject(nouveauContextPtr nmesa, int handle, i return ret == 0; } -static void nouveauObjectOnSubchannel(nouveauContextPtr nmesa, int handle, int subchannel) +static GLboolean nouveauCreateDmaObject(nouveauContextPtr nmesa, + uint32_t handle, + uint32_t offset, + uint32_t size, + int target, + int access) +{ + drm_nouveau_dma_object_init_t dma; + int ret; + + dma.handle = handle; + dma.target = target; + dma.access = access; + dma.offset = offset; + dma.handle = handle; + ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_DMA_OBJECT_INIT, + &dma, sizeof(dma)); + return ret == 0; +} + +void nouveauObjectOnSubchannel(nouveauContextPtr nmesa, int subchannel, int handle) { BEGIN_RING_SIZE(subchannel, 0, 1); OUT_RING(handle); @@ -28,8 +47,18 @@ static void nouveauObjectOnSubchannel(nouveauContextPtr nmesa, int handle, int s void nouveauObjectInit(nouveauContextPtr nmesa) { - NVDmaCreateContextObject(nmesa, Nv3D, nmesa->screen->card->class_3d, 0, 0, 0, 0); +#ifdef NOUVEAU_RING_DEBUG + return; +#endif + + nouveauCreateContextObject(nmesa, Nv3D, nmesa->screen->card->class_3d, 0, 0, 0, 0); nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); +/* We need to know vram size.. */ +#if 0 + nouveauCreateDmaObject( nmesa, NvDmaFB, + 0, (256*1024*1024), + 0 /*NV_DMA_TARGET_FB*/, 0 /*NV_DMA_ACCESS_RW*/); +#endif } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.h b/src/mesa/drivers/dri/nouveau/nouveau_object.h index e9a30d127a..8386f923c3 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.h @@ -7,10 +7,12 @@ void nouveauObjectInit(nouveauContextPtr nmesa); enum DMAObjects { Nv3D = 0x80000019, + NvDmaFB = 0xD0FB0001 }; enum DMASubchannel { NvSub3D = 7, }; +extern void nouveauObjectOnSubchannel(nouveauContextPtr nmesa, int subchannel, int handle); #endif -- cgit v1.2.3 From b5e800068b8a5102bb7a7a34f1fa1b890ff9d443 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 21 Nov 2006 19:56:15 +0000 Subject: nv10: update state --- src/mesa/drivers/dri/nouveau/nv10_state.c | 188 ++++++++++++++++++------------ 1 file changed, 116 insertions(+), 72 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 0d19ce94af..d77816a117 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -34,7 +34,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "mtypes.h" #include "colormac.h" -void nv10AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) +static void nv10AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); GLubyte ubRef; @@ -45,7 +45,7 @@ void nv10AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) OUT_RING_CACHE(ubRef); /* NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF */ } -void nv10BlendColor(GLcontext *ctx, const GLfloat color[4]) +static void nv10BlendColor(GLcontext *ctx, const GLfloat color[4]) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); GLubyte cf[4]; @@ -59,7 +59,7 @@ void nv10BlendColor(GLcontext *ctx, const GLfloat color[4]) OUT_RING_CACHE(PACK_COLOR_8888(cf[3], cf[1], cf[2], cf[0])); } -void nv10BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA) +static void nv10BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_EQUATION, 1); @@ -67,7 +67,7 @@ void nv10BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA) } -void nv10BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, +static void nv10BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); @@ -77,21 +77,12 @@ void nv10BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, } /* -void nv30ClearColor(GLcontext *ctx, const GLfloat color[4]) +static void nv10ClearColor(GLcontext *ctx, const GLfloat color[4]) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - GLubyte c[4]; - UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,color); - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB, 1); - OUT_RING_CACHE(PACK_COLOR_8888(c[3],c[0],c[1],c[2])); } -void nv30ClearDepth(GLcontext *ctx, GLclampd d) +static void nv10ClearDepth(GLcontext *ctx, GLclampd d) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - nmesa->clear_value=((nmesa->clear_value&0x000000FF)|(((uint32_t)(d*0xFFFFFF))<<8)); - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1); - OUT_RING_CACHE(nmesa->clear_value); } */ @@ -100,16 +91,12 @@ void nv30ClearDepth(GLcontext *ctx, GLclampd d) */ /* -void nv30ClearStencil(GLcontext *ctx, GLint s) +static void nv10ClearStencil(GLcontext *ctx, GLint s) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - nmesa->clear_value=((nmesa->clear_value&0xFFFFFF00)|(s&0x000000FF)); - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH, 1); - OUT_RING_CACHE(nmesa->clear_value); } */ -void nv10ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) +static void nv10ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4); @@ -120,7 +107,7 @@ void nv10ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) } /* Seems does not support alpha in color mask */ -void nv10ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, +static void nv10ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, GLboolean bmask, GLboolean amask ) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); @@ -128,40 +115,40 @@ void nv10ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, OUT_RING_CACHE(/*((amask && 0x01) << 24) |*/ ((rmask && 0x01) << 16) | ((gmask && 0x01)<< 8) | ((bmask && 0x01) << 0)); } -void nv10ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode) +static void nv10ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode) { - // TODO I need sex + // TODO I need love } -void nv10CullFace(GLcontext *ctx, GLenum mode) +static void nv10CullFace(GLcontext *ctx, GLenum mode) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_CULL_FACE, 1); OUT_RING_CACHE(mode); } -void nv10FrontFace(GLcontext *ctx, GLenum mode) +static void nv10FrontFace(GLcontext *ctx, GLenum mode) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FRONT_FACE, 1); OUT_RING_CACHE(mode); } -void nv10DepthFunc(GLcontext *ctx, GLenum func) +static void nv10DepthFunc(GLcontext *ctx, GLenum func) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1); OUT_RING_CACHE(func); } -void nv10DepthMask(GLcontext *ctx, GLboolean flag) +static void nv10DepthMask(GLcontext *ctx, GLboolean flag) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1); OUT_RING_CACHE(flag); } -void nv10DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval) +static void nv10DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2); @@ -174,7 +161,7 @@ void nv10DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval) /** Specify the buffers for writing for fragment programs*/ //void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers ); -void nv10Enable(GLcontext *ctx, GLenum cap, GLboolean state) +static void nv10Enable(GLcontext *ctx, GLenum cap, GLboolean state) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); switch(cap) @@ -185,7 +172,7 @@ void nv10Enable(GLcontext *ctx, GLenum cap, GLboolean state) break; // case GL_AUTO_NORMAL: case GL_BLEND: - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_ENABLE, 1); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1); OUT_RING_CACHE(state); break; case GL_CLIP_PLANE0: @@ -295,10 +282,6 @@ void nv10Enable(GLcontext *ctx, GLenum cap, GLboolean state) BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1); OUT_RING_CACHE(state); break; - case GL_POINT_SMOOTH: - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POINT_SMOOTH_ENABLE, 1); - OUT_RING_CACHE(state); - break; // case GL_POLYGON_STIPPLE: // case GL_POST_COLOR_MATRIX_COLOR_TABLE: // case GL_POST_CONVOLUTION_COLOR_TABLE: @@ -306,6 +289,7 @@ void nv10Enable(GLcontext *ctx, GLenum cap, GLboolean state) // case GL_SCISSOR_TEST: // case GL_SEPARABLE_2D: case GL_STENCIL_TEST: + // TODO BACK and FRONT ? BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_ENABLE, 1); OUT_RING_CACHE(state); break; @@ -319,7 +303,7 @@ void nv10Enable(GLcontext *ctx, GLenum cap, GLboolean state) } } -void nv10Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +static void nv10Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); switch(pname) @@ -335,108 +319,106 @@ void nv10Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) } -void nv10Hint(GLcontext *ctx, GLenum target, GLenum mode) +static void nv10Hint(GLcontext *ctx, GLenum target, GLenum mode) { - // TODO I need sex (fog and line_smooth hints) + // TODO I need love (fog and line_smooth hints) } // void (*IndexMask)(GLcontext *ctx, GLuint mask); -void nv10Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params ) +static void nv10Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params ) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); /* not sure where the fourth param value goes...*/ switch(pname) { case GL_AMBIENT: - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_AMBIENT(light), 3); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_A(light), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; case GL_DIFFUSE: - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_DIFFUSE(light), 3); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_A(light), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; case GL_SPECULAR: - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPECULAR(light), 3); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_A(light), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; -#if 0 +#if 0 /* FIXME, should be easy to do */ case GL_SPOT_DIRECTION: - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(light), 3); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(light), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; +#endif case GL_POSITION: - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(light), 3); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(light), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; +#if 0 /* FIXME, should be easy to do */ case GL_SPOT_EXPONENT: - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(light), 1); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(light), 1); OUT_RING_CACHEf(*params); break; case GL_SPOT_CUTOFF: /* you can't factor these */ - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(light), 1); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(light), 1); OUT_RING_CACHEf(params[0]); - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(light), 1); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(light), 1); OUT_RING_CACHEf(params[1]); - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(light), 1); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(light), 1); OUT_RING_CACHEf(params[2]); break; +#endif case GL_CONSTANT_ATTENUATION: - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(light), 1); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(light), 1); OUT_RING_CACHEf(*params); break; case GL_LINEAR_ATTENUATION: - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(light), 1); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(light), 1); OUT_RING_CACHEf(*params); break; case GL_QUADRATIC_ATTENUATION: - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(light), 1); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(light), 1); OUT_RING_CACHEf(*params); break; -#endif default: break; } } /** Set the lighting model parameters */ -void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params); +static void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params); -/* -void nv30LineStipple(GLcontext *ctx, GLint factor, GLushort pattern ) + +static void nv10LineStipple(GLcontext *ctx, GLint factor, GLushort pattern ) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN, 1); - OUT_RING_CACHE((pattern << 16) | factor); } -void nv30LineWidth(GLcontext *ctx, GLfloat width) +static void nv10LineWidth(GLcontext *ctx, GLfloat width) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_WIDTH_SMOOTH, 1); - OUT_RING_CACHEf(width); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LINE_WIDTH, 1); + OUT_RING_CACHE(((int) (width * 8.0)) & -4); } -*/ -void nv10LogicOpcode(GLcontext *ctx, GLenum opcode) +static void nv10LogicOpcode(GLcontext *ctx, GLenum opcode) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LOGIC_OP, 1); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP, 1); OUT_RING_CACHE(opcode); } -void nv10PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +static void nv10PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params) { /*TODO: not sure what goes here. */ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); @@ -444,15 +426,28 @@ void nv10PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params) } /** Specify the diameter of rasterized points */ -void nv10PointSize(GLcontext *ctx, GLfloat size) +static void nv10PointSize(GLcontext *ctx, GLfloat size) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POINT_SIZE, 1); - OUT_RING_CACHEf(size); + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POINT_SIZE, 1); + OUT_RING_CACHE(((int) (size * 8.0)) & -4); } /** Select a polygon rasterization mode */ -void (*PolygonMode)(GLcontext *ctx, GLenum face, GLenum mode); +static void nv10PolygonMode(GLcontext *ctx, GLenum face, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 1); + OUT_RING_CACHE(mode); + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK, 1); + OUT_RING_CACHE(mode); + } +} + /** Set the scale and units used to calculate depth values */ void (*PolygonOffset)(GLcontext *ctx, GLfloat factor, GLfloat units); /** Set the polygon stippling pattern */ @@ -519,7 +514,7 @@ void (*TexParameter)(GLcontext *ctx, GLenum target, void (*TextureMatrix)(GLcontext *ctx, GLuint unit, const GLmatrix *mat); /** Set the viewport */ -void nv10Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +static void nv10Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) { /* TODO: Where do the VIEWPORT_XFRM_* regs come in? */ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); @@ -528,3 +523,52 @@ void nv10Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) OUT_RING_CACHE((h << 16) | y); } +void nv10InitStateFuncs(struct dd_function_table *func) +{ + func->AlphaFunc = nv10AlphaFunc; + func->BlendColor = nv10BlendColor; + func->BlendEquationSeparate = nv10BlendEquationSeparate; + func->BlendFuncSeparate = nv10BlendFuncSeparate; +#if 0 + func->ClearColor = nv10ClearColor; + func->ClearDepth = nv10ClearDepth; + func->ClearStencil = nv10ClearStencil; +#endif + func->ClipPlane = nv10ClipPlane; + func->ColorMask = nv10ColorMask; + func->ColorMaterial = nv10ColorMaterial; + func->CullFace = nv10CullFace; + func->FrontFace = nv10FrontFace; + func->DepthFunc = nv10DepthFunc; + func->DepthMask = nv10DepthMask; + func->DepthRange = nv10DepthRange; + func->Enable = nv10Enable; + func->Fogfv = nv10Fogfv; + func->Hint = nv10Hint; + func->Lightfv = nv10Lightfv; +/* func->LightModelfv = nv10LightModelfv; */ + func->LineStipple = nv10LineStipple; + func->LineWidth = nv10LineWidth; + func->LogicOpcode = nv10LogicOpcode; + func->PointParameterfv = nv10PointParameterfv; + func->PointSize = nv10PointSize; + func->PolygonMode = nv10PolygonMode; +#if 0 + func->PolygonOffset = nv10PolygonOffset; + func->PolygonStipple = nv10PolygonStipple; + func->ReadBuffer = nv10ReadBuffer; + func->RenderMode = nv10RenderMode; + func->Scissor = nv10Scissor; +#endif + func->ShadeModel = nv10ShadeModel; + func->StencilFuncSeparate = nv10StencilFuncSeparate; + func->StencilMaskSeparate = nv10StencilMaskSeparate; + func->StencilOpSeparate = nv10StencilOpSeparate; +#if 0 + func->TexGen = nv10TexGen; + func->TexParameter = nv10TexParameter; + func->TextureMatrix = nv10TextureMatrix; +#endif + func->Viewport = nv10Viewport; +} + -- cgit v1.2.3 From 4ed78e20a4aa23d11e67a29a99aafb27e7f9f661 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 21 Nov 2006 20:29:09 +0000 Subject: update from renouveau --- src/mesa/drivers/dri/nouveau/nouveau_reg.h | 195 ++++++++++++++++++++--------- 1 file changed, 137 insertions(+), 58 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_reg.h b/src/mesa/drivers/dri/nouveau/nouveau_reg.h index 389c541e1c..b2ccf141fb 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_reg.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_reg.h @@ -43,7 +43,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ************************************************************************** - Created from objects.c rev. 1.337 + Created from objects.c rev. 1.335 */ #ifndef _NOUVEAU_REG_H @@ -329,7 +329,7 @@ Object NV10_TCL_PRIMITIVE_3D used on: NV10 # define NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(d) (0x000002c0 + d * 0x0004) /* Parameters: x2 x1 */ # define NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(d) (0x000002e0 + d * 0x0004) /* Parameters: y2 y1 */ # define NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE 0x00000300 -# define NV10_TCL_PRIMITIVE_3D_BLEND_ENABLE 0x00000304 +# define NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE 0x00000304 # define NV10_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE 0x00000308 # define NV10_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE 0x0000030c # define NV10_TCL_PRIMITIVE_3D_DITHER_ENABLE 0x00000310 @@ -370,7 +370,7 @@ Object NV10_TCL_PRIMITIVE_3D used on: NV10 # define NV10_TCL_PRIMITIVE_3D_CULL_FACE 0x0000039c # define NV10_TCL_PRIMITIVE_3D_FRONT_FACE 0x000003a0 # define NV10_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE 0x000003a4 -# define NV10_TCL_PRIMITIVE_3D_MATERIAL_DIFFUSE_ALPHA 0x000003b4 +# define NV10_TCL_PRIMITIVE_3D_MATERIAL_DIFFUSE_ALPHA_FRONT 0x000003b4 # define NV10_TCL_PRIMITIVE_3D_COLOR_CONTROL 0x000003b8 /* Parameters: color_control */ # define NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS 0x000003bc /* Parameters: light 7 light 6 light 5 light 4 light 3 light 2 light 1 light 0 */ # define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE( d) (0x000003c0 + d * 0x0004) @@ -388,13 +388,15 @@ Object NV10_TCL_PRIMITIVE_3D used on: NV10 # define NV10_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT 0x00000680 # define NV10_TCL_PRIMITIVE_3D_FOG_EQUATION_LINEAR 0x00000684 # define NV10_TCL_PRIMITIVE_3D_FOG_EQUATION_QUADRATIC 0x00000688 -# define NV10_TCL_PRIMITIVE_3D_SHININESS_A 0x000006a0 -# define NV10_TCL_PRIMITIVE_3D_SHININESS_B 0x000006a4 -# define NV10_TCL_PRIMITIVE_3D_SHININESS_C 0x000006a8 -# define NV10_TCL_PRIMITIVE_3D_SHININESS_D 0x000006ac -# define NV10_TCL_PRIMITIVE_3D_SHININESS_E 0x000006b0 -# define NV10_TCL_PRIMITIVE_3D_SHININESS_F 0x000006b4 -# define NV10_TCL_PRIMITIVE_3D_MATERIAL_AMBIENT_EMISSION 0x000006c4 +# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_A 0x000006a0 +# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_B 0x000006a4 +# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_C 0x000006a8 +# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_D 0x000006ac +# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_E 0x000006b0 +# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_F 0x000006b4 +# define NV10_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R 0x000006c4 +# define NV10_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_G 0x000006c8 +# define NV10_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_B 0x000006cc # define NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X 0x000006e8 # define NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_Y 0x000006ec # define NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_Z 0x000006f0 @@ -407,14 +409,28 @@ Object NV10_TCL_PRIMITIVE_3D used on: NV10 # define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_F 0x0000070c # define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_G 0x00000710 # define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_H 0x00000714 -# define NV10_TCL_PRIMITIVE_3D_LIGHT_AMBIENT(d) (0x00000800 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_DIFFUSE(d) (0x0000080c + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPECULAR(d) (0x00000818 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR(d) (0x00000828 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION0(d) (0x00000834 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(d) (0x00000800 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_G(d) (0x00000804 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_B(d) (0x00000808 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(d) (0x0000080c + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_G(d) (0x00000810 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_B(d) (0x00000814 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(d) (0x00000818 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_G(d) (0x0000081c + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_B(d) (0x00000820 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_X(d) (0x00000828 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_Y(d) (0x0000082c + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_Z(d) (0x00000830 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_X(d) (0x00000834 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_Y(d) (0x00000838 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_Z(d) (0x0000083c + d * 0x0080) # define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_LIGHT(d) (0x00000840 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION1(d) (0x0000085c + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_NORMAL(d) (0x00000868 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(d) (0x0000085c + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_Y(d) (0x00000860 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_Z(d) (0x00000864 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(d) (0x00000868 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(d) (0x0000086c + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(d) (0x00000870 + d * 0x0080) # define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_X 0x00000c00 # define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_Y 0x00000c04 # define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_Z 0x00000c08 @@ -478,7 +494,7 @@ Object NV10_TCL_PRIMITIVE_3D used on: NV10 # define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_FOG 0x00000d38 # define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_FOG 0x00000d3c /* Parameters: stride fields type */ # define NV10_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE 0x00000d40 -# define NV10_TCL_PRIMITIVE_3D_LOGIC_OP 0x00000d44 +# define NV10_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP 0x00000d44 # define NV10_TCL_PRIMITIVE_3D_BEGIN_END 0x00000dfc # define NV10_TCL_PRIMITIVE_3D_INDEX_DATA 0x00000e00 /* Parameters: index1 index0 */ # define NV10_TCL_PRIMITIVE_3D_VERTEX_BUFFER_BEGIN_END 0x000013fc @@ -535,7 +551,7 @@ Object NV15_TCL_PRIMITIVE_3D used on: NV15 # define NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(d) (0x000002c0 + d * 0x0004) /* Parameters: x2 x1 */ # define NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(d) (0x000002e0 + d * 0x0004) /* Parameters: y2 y1 */ # define NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE 0x00000300 -# define NV10_TCL_PRIMITIVE_3D_BLEND_ENABLE 0x00000304 +# define NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE 0x00000304 # define NV10_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE 0x00000308 # define NV10_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE 0x0000030c # define NV10_TCL_PRIMITIVE_3D_DITHER_ENABLE 0x00000310 @@ -576,7 +592,7 @@ Object NV15_TCL_PRIMITIVE_3D used on: NV15 # define NV10_TCL_PRIMITIVE_3D_CULL_FACE 0x0000039c # define NV10_TCL_PRIMITIVE_3D_FRONT_FACE 0x000003a0 # define NV10_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE 0x000003a4 -# define NV10_TCL_PRIMITIVE_3D_MATERIAL_DIFFUSE_ALPHA 0x000003b4 +# define NV10_TCL_PRIMITIVE_3D_MATERIAL_DIFFUSE_ALPHA_FRONT 0x000003b4 # define NV10_TCL_PRIMITIVE_3D_COLOR_CONTROL 0x000003b8 /* Parameters: color_control */ # define NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS 0x000003bc /* Parameters: light 7 light 6 light 5 light 4 light 3 light 2 light 1 light 0 */ # define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE( d) (0x000003c0 + d * 0x0004) @@ -594,13 +610,15 @@ Object NV15_TCL_PRIMITIVE_3D used on: NV15 # define NV10_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT 0x00000680 # define NV10_TCL_PRIMITIVE_3D_FOG_EQUATION_LINEAR 0x00000684 # define NV10_TCL_PRIMITIVE_3D_FOG_EQUATION_QUADRATIC 0x00000688 -# define NV10_TCL_PRIMITIVE_3D_SHININESS_A 0x000006a0 -# define NV10_TCL_PRIMITIVE_3D_SHININESS_B 0x000006a4 -# define NV10_TCL_PRIMITIVE_3D_SHININESS_C 0x000006a8 -# define NV10_TCL_PRIMITIVE_3D_SHININESS_D 0x000006ac -# define NV10_TCL_PRIMITIVE_3D_SHININESS_E 0x000006b0 -# define NV10_TCL_PRIMITIVE_3D_SHININESS_F 0x000006b4 -# define NV10_TCL_PRIMITIVE_3D_MATERIAL_AMBIENT_EMISSION 0x000006c4 +# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_A 0x000006a0 +# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_B 0x000006a4 +# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_C 0x000006a8 +# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_D 0x000006ac +# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_E 0x000006b0 +# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_F 0x000006b4 +# define NV10_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R 0x000006c4 +# define NV10_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_G 0x000006c8 +# define NV10_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_B 0x000006cc # define NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X 0x000006e8 # define NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_Y 0x000006ec # define NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_Z 0x000006f0 @@ -613,14 +631,28 @@ Object NV15_TCL_PRIMITIVE_3D used on: NV15 # define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_F 0x0000070c # define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_G 0x00000710 # define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_H 0x00000714 -# define NV10_TCL_PRIMITIVE_3D_LIGHT_AMBIENT(d) (0x00000800 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_DIFFUSE(d) (0x0000080c + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPECULAR(d) (0x00000818 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR(d) (0x00000828 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION0(d) (0x00000834 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(d) (0x00000800 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_G(d) (0x00000804 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_B(d) (0x00000808 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(d) (0x0000080c + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_G(d) (0x00000810 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_B(d) (0x00000814 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(d) (0x00000818 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_G(d) (0x0000081c + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_B(d) (0x00000820 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_X(d) (0x00000828 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_Y(d) (0x0000082c + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_Z(d) (0x00000830 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_X(d) (0x00000834 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_Y(d) (0x00000838 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_Z(d) (0x0000083c + d * 0x0080) # define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_LIGHT(d) (0x00000840 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION1(d) (0x0000085c + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_NORMAL(d) (0x00000868 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(d) (0x0000085c + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_Y(d) (0x00000860 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_Z(d) (0x00000864 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(d) (0x00000868 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(d) (0x0000086c + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(d) (0x00000870 + d * 0x0080) # define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_X 0x00000c00 # define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_Y 0x00000c04 # define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_Z 0x00000c08 @@ -685,7 +717,7 @@ Object NV15_TCL_PRIMITIVE_3D used on: NV15 # define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_FOG 0x00000d38 # define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_FOG 0x00000d3c /* Parameters: stride fields type */ # define NV10_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE 0x00000d40 -# define NV10_TCL_PRIMITIVE_3D_LOGIC_OP 0x00000d44 +# define NV10_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP 0x00000d44 # define NV17_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH 0x00000d5c /* Parameters: pitch */ # define NV17_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_OFFSET 0x00000d60 # define NV17_TCL_PRIMITIVE_3D_LMA_DEPTH_FILL_VALUE 0x00000d68 @@ -901,6 +933,7 @@ Object NV20_TCL_PRIMITIVE_3D used on: NV20 # define NV20_TCL_PRIMITIVE_3D_FRONT_FACE 0x000003a0 # define NV20_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE 0x000003a4 # define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT 0x000003a8 +# define NV20_TCL_PRIMITIVE_3D_MATERIAL_DIFFUSE_ALPHA_FRONT 0x000003b4 # define NV20_TCL_PRIMITIVE_3D_SEPARATE_SPECULAR_ENABLE 0x000003b8 # define NV20_TCL_PRIMITIVE_3D_ENABLED_LIGHTS 0x000003bc /* Parameters: light 7 light 6 light 5 light 4 light 3 light 2 light 1 light 0 */ # define NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(d) (0x000003c0 + d * 0x0004) @@ -917,7 +950,12 @@ Object NV20_TCL_PRIMITIVE_3D used on: NV20 # define NV20_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT 0x000009c0 # define NV20_TCL_PRIMITIVE_3D_FOG_EQUATION_LINEAR 0x000009c4 # define NV20_TCL_PRIMITIVE_3D_FOG_EQUATION_QUADRATIC 0x000009c8 -# define NV20_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS 0x000009e0 +# define NV20_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_A 0x000009e0 +# define NV20_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_B 0x000009e4 +# define NV20_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_C 0x000009e8 +# define NV20_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_D 0x000009ec +# define NV20_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_E 0x000009f0 +# define NV20_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_F 0x000009f4 # define NV20_TCL_PRIMITIVE_3D_POINT_SPRITE 0x00000a1c /* Parameters: coord_replace r_mode enable */ # define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_A 0x00000a30 # define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_B 0x00000a34 @@ -936,7 +974,9 @@ Object NV20_TCL_PRIMITIVE_3D used on: NV20 # define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_Z 0x00000b88 # define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_W 0x00000b8c # define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_ID 0x00001ea4 -# define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION 0x00000a10 +# define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R 0x00000a10 +# define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_G 0x00000a14 +# define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_B 0x00000a18 # define NV20_TCL_PRIMITIVE_3D_TX_OFFSET(d) (0x00001b00 + d * 0x0040) # define NV20_TCL_PRIMITIVE_3D_TX_FORMAT(d) (0x00001b04 + d * 0x0040) /* Parameters: log2(height) log2(width) lod format cube_map */ # define NV20_TCL_PRIMITIVE_3D_TX_ENABLE(d) (0x00001b0c + d * 0x0040) /* Parameters: enable anisotropy */ @@ -957,16 +997,21 @@ Object NV20_TCL_PRIMITIVE_3D used on: NV20 # define NV20_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(d) (0x0000105c + d * 0x0080) # define NV20_TCL_PRIMITIVE_3D_LIGHT_POSITION_Y(d) (0x00001060 + d * 0x0080) # define NV20_TCL_PRIMITIVE_3D_LIGHT_POSITION_Z(d) (0x00001064 + d * 0x0080) -# define NV20_TCL_PRIMITIVE_3D_LIGHT_HVEC_AND_DIR(d) (0x00001028 + d * 0x0080) -# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_A(d) (0x00001000 + d * 0x0080) -# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_B(d) (0x00001004 + d * 0x0080) -# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_C(d) (0x00001008 + d * 0x0080) -# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_A(d) (0x0000100c + d * 0x0080) -# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_B(d) (0x00001010 + d * 0x0080) -# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_C(d) (0x00001014 + d * 0x0080) -# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_A(d) (0x00001018 + d * 0x0080) -# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_B(d) (0x0000101c + d * 0x0080) -# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_C(d) (0x00001020 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_X(d) (0x00001028 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_Y(d) (0x0000102c + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_Z(d) (0x00001030 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_X(d) (0x00001034 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_Y(d) (0x00001038 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_Z(d) (0x0000103c + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(d) (0x00001000 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_G(d) (0x00001004 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_B(d) (0x00001008 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(d) (0x0000100c + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_G(d) (0x00001010 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_B(d) (0x00001014 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(d) (0x00001018 + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_G(d) (0x0000101c + d * 0x0080) +# define NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_B(d) (0x00001020 + d * 0x0080) # define NV20_TCL_PRIMITIVE_3D_LIGHT_BACK_SIDE_PRODUCT_AMBIENT(d) (0x00000c00 + d * 0x0040) # define NV20_TCL_PRIMITIVE_3D_LIGHT_BACK_SIDE_PRODUCT_DIFFUSE(d) (0x00000c0c + d * 0x0040) # define NV20_TCL_PRIMITIVE_3D_LIGHT_BACK_SIDE_PRODUCT_SPECULAR(d) (0x00000c18 + d * 0x0040) @@ -980,7 +1025,12 @@ Object NV20_TCL_PRIMITIVE_3D used on: NV20 # define NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_Y(d) (0x00001050 + d * 0x0080) # define NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_Z(d) (0x00001054 + d * 0x0080) # define NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(d) (0x00001058 + d * 0x0080) -# define NV20_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS 0x00001e28 +# define NV20_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_A 0x00001e28 +# define NV20_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_B 0x00001e2c +# define NV20_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_C 0x00001e30 +# define NV20_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_D 0x00001e34 +# define NV20_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_E 0x00001e38 +# define NV20_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_F 0x00001e3c # define NV20_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE 0x0000147c # define NV20_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(d) (0x00001480 + d * 0x0004) # define NV20_TCL_PRIMITIVE_3D_VERTEX_POS_3F_X 0x00001500 @@ -1080,7 +1130,10 @@ Object NV20_TCL_PRIMITIVE_3D used on: NV20 # define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR13_TX5 0x00001794 /* Parameters: stride fields type */ # define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR14_TX6 0x00001798 /* Parameters: stride fields type */ # define NV20_TCL_PRIMITIVE_3D_VERTEX_ATTR15_TX7 0x0000179c /* Parameters: stride fields type */ -# define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION 0x000017a0 +# define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R 0x000017a0 +# define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_G 0x000017a4 +# define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_B 0x000017a8 +# define NV20_TCL_PRIMITIVE_3D_MATERIAL_DIFFUSE_ALPHA_BACK 0x000017ac # define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK 0x000017b0 # define NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE 0x000017bc # define NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP 0x000017c0 @@ -1154,6 +1207,7 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE 0x0000037c # define NV30_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR 0x00000394 # define NV30_TCL_PRIMITIVE_3D_DEPTH_RANGE_FAR 0x00000398 +# define NV30_TCL_PRIMITIVE_3D_MATERIAL_DIFFUSE_ALPHA_FRONT 0x000003b4 # define NV30_TCL_PRIMITIVE_3D_LINE_WIDTH_SMOOTH 0x000003b8 # define NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(d) (0x00000400 + d * 0x0004) # define NV30_TCL_PRIMITIVE_3D_MODELVIEW_MATRIX( d) (0x00000480 + d * 0x0004) @@ -1178,6 +1232,9 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_OFS1 0x000002c4 /* Parameters: height y_offset */ # define NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_0 0x00000a00 /* Parameters: width x_offset */ # define NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_1 0x00000a04 /* Parameters: height y_offset */ +# define NV30_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R 0x00000a10 +# define NV30_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_G 0x00000a14 +# define NV30_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_B 0x00000a18 # define NV30_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS 0x000008c0 /* Parameters: width x_offset */ # define NV30_TCL_PRIMITIVE_3D_SCISSOR_HEIGHT_YPOS 0x000008c4 /* Parameters: height y_offset */ # define NV30_TCL_PRIMITIVE_3D_POINT_SPRITE 0x00001ee8 /* Parameters: coord_replace r_mode enable */ @@ -1216,15 +1273,21 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_B(d) (0x00000e04 + d * 0x0010) # define NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_C(d) (0x00000e08 + d * 0x0010) # define NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_D(d) (0x00000e0c + d * 0x0010) -# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_A(d) (0x00001000 + d * 0x0040) -# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_B(d) (0x00001004 + d * 0x0040) -# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_C(d) (0x00001008 + d * 0x0040) -# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_A(d) (0x0000100c + d * 0x0040) -# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_B(d) (0x00001010 + d * 0x0040) -# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_C(d) (0x00001014 + d * 0x0040) -# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_A(d) (0x00001018 + d * 0x0040) -# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_B(d) (0x0000101c + d * 0x0040) -# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_C(d) (0x00001020 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(d) (0x00001000 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_G(d) (0x00001004 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_B(d) (0x00001008 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(d) (0x0000100c + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_G(d) (0x00001010 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_B(d) (0x00001014 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(d) (0x00001018 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_G(d) (0x0000101c + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_B(d) (0x00001020 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_X(d) (0x00001028 + d * 0x0080) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_Y(d) (0x0000102c + d * 0x0080) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_Z(d) (0x00001030 + d * 0x0080) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_X(d) (0x00001034 + d * 0x0080) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_Y(d) (0x00001038 + d * 0x0080) +# define NV30_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_Z(d) (0x0000103c + d * 0x0080) # define NV30_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(d) (0x00001228 + d * 0x0040) # define NV30_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(d) (0x0000122c + d * 0x0040) # define NV30_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(d) (0x00001230 + d * 0x0040) @@ -1238,6 +1301,12 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(d) (0x0000121c + d * 0x0040) # define NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_Y(d) (0x00001220 + d * 0x0040) # define NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_Z(d) (0x00001224 + d * 0x0040) +# define NV30_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_A 0x00001400 +# define NV30_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_B 0x00001404 +# define NV30_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_C 0x00001408 +# define NV30_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_D 0x0000140c +# define NV30_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_E 0x00001410 +# define NV30_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_F 0x00001414 # define NV30_TCL_PRIMITIVE_3D_ENABLED_LIGHTS 0x00001420 /* Parameters: light 7 light 6 light 5 light 4 light 3 light 2 light 1 light 0 */ # define NV30_TCL_PRIMITIVE_3D_LINE_STIPPLE 0x00001db4 # define NV30_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN 0x00001db8 /* Parameters: factor pattern */ @@ -1249,6 +1318,12 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH 0x00001d8c # define NV30_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB 0x00001d90 /* Parameters: a r g b */ # define NV30_TCL_PRIMITIVE_3D_CLEAR_WHICH_BUFFERS 0x00001d94 +# define NV30_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_A 0x00001e20 +# define NV30_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_B 0x00001e24 +# define NV30_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_C 0x00001e28 +# define NV30_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_D 0x00001e2c +# define NV30_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_E 0x00001e30 +# define NV30_TCL_PRIMITIVE_3D_BACK_MATERIAL_SHININESS_F 0x00001e34 # define NV30_TCL_PRIMITIVE_3D_DO_VERTICES 0x00001dac # define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_FROM_ID 0x00001e9c # define NV30_TCL_PRIMITIVE_3D_VP_PROGRAM_START_ID 0x00001ea0 @@ -1321,6 +1396,10 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR13_TX5 0x00001774 /* Parameters: stride fields type */ # define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR14_TX6 0x00001778 /* Parameters: stride fields type */ # define NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR15_TX7 0x0000177c /* Parameters: stride fields type */ +# define NV30_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R 0x000017a0 +# define NV30_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_G 0x000017a4 +# define NV30_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_B 0x000017a8 +# define NV30_TCL_PRIMITIVE_3D_MATERIAL_DIFFUSE_ALPHA_BACK 0x000017c0 # define NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM 0x000008e4 # define NV30_TCL_PRIMITIVE_3D_TX_ADDRESS_UNIT(d) (0x00001a00 + d * 0x0020) # define NV30_TCL_PRIMITIVE_3D_TX_FORMAT_UNIT(d) (0x00001a04 + d * 0x0020) /* Parameters: mipmap type format ncomp cubic */ -- cgit v1.2.3 From 81ae0bd249d1da31e57123583a1bcec154c471cc Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 21 Nov 2006 20:38:14 +0000 Subject: ah, correct revision now --- src/mesa/drivers/dri/nouveau/nouveau_reg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_reg.h b/src/mesa/drivers/dri/nouveau/nouveau_reg.h index b2ccf141fb..2081fd3ec7 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_reg.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_reg.h @@ -43,7 +43,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ************************************************************************** - Created from objects.c rev. 1.335 + Created from objects.c rev. 1.345 */ #ifndef _NOUVEAU_REG_H -- cgit v1.2.3 From 677666eb70faea6ac30d69f99f2c4b776e9954bf Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 21 Nov 2006 21:11:58 +0000 Subject: nv10,nv20,nv30: color light components renamed from a,b,c to r,g,b --- src/mesa/drivers/dri/nouveau/nv10_state.c | 6 +++--- src/mesa/drivers/dri/nouveau/nv20_state.c | 6 +++--- src/mesa/drivers/dri/nouveau/nv30_state.c | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index d77816a117..fe2d971a9f 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -333,19 +333,19 @@ static void nv10Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa switch(pname) { case GL_AMBIENT: - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_A(light), 3); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(light), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; case GL_DIFFUSE: - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_A(light), 3); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(light), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; case GL_SPECULAR: - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_A(light), 3); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(light), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); diff --git a/src/mesa/drivers/dri/nouveau/nv20_state.c b/src/mesa/drivers/dri/nouveau/nv20_state.c index 7d93368a53..bffca44547 100644 --- a/src/mesa/drivers/dri/nouveau/nv20_state.c +++ b/src/mesa/drivers/dri/nouveau/nv20_state.c @@ -344,19 +344,19 @@ static void nv20Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa switch(pname) { case GL_AMBIENT: - BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_A(light), 3); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(light), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; case GL_DIFFUSE: - BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_A(light), 3); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(light), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; case GL_SPECULAR: - BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_A(light), 3); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(light), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 0fc3d16751..630b84df63 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -355,19 +355,19 @@ static void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa switch(pname) { case GL_AMBIENT: - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_A(light), 3); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(light), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; case GL_DIFFUSE: - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_A(light), 3); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(light), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; case GL_SPECULAR: - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_A(light), 3); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(light), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); -- cgit v1.2.3 From ac09b567a8257960677be742cc92e3c9a4bd0fc7 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 21 Nov 2006 21:15:49 +0000 Subject: nv10,nv20: nvX0ShadeModel static function --- src/mesa/drivers/dri/nouveau/nv10_state.c | 2 +- src/mesa/drivers/dri/nouveau/nv20_state.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index fe2d971a9f..e99824814f 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -460,7 +460,7 @@ void (*RenderMode)(GLcontext *ctx, GLenum mode ); void (*Scissor)(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h); /** Select flat or smooth shading */ -void nv10ShadeModel(GLcontext *ctx, GLenum mode) +static void nv10ShadeModel(GLcontext *ctx, GLenum mode) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); diff --git a/src/mesa/drivers/dri/nouveau/nv20_state.c b/src/mesa/drivers/dri/nouveau/nv20_state.c index bffca44547..338cfd43b0 100644 --- a/src/mesa/drivers/dri/nouveau/nv20_state.c +++ b/src/mesa/drivers/dri/nouveau/nv20_state.c @@ -470,7 +470,7 @@ void (*RenderMode)(GLcontext *ctx, GLenum mode ); void (*Scissor)(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h); /** Select flat or smooth shading */ -void nv20ShadeModel(GLcontext *ctx, GLenum mode) +static void nv20ShadeModel(GLcontext *ctx, GLenum mode) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); -- cgit v1.2.3 From 3e4a5c0642c05b25e3987c762e07c04eec3f0603 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 21 Nov 2006 21:44:16 +0000 Subject: Enable nv10 tcl state --- src/mesa/drivers/dri/nouveau/nouveau_state.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c index 2f8f3248ce..2094691ce2 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -158,8 +158,10 @@ void nouveauDDInitState(nouveauContextPtr nmesa) case NV_03: case NV_04: case NV_05: + /* No TCL engines for these ones */ + break; case NV_10: - //nv10InitStateFuncs(&nmesa->glCtx->Driver); + nv10InitStateFuncs(&nmesa->glCtx->Driver); break; case NV_20: nv20InitStateFuncs(&nmesa->glCtx->Driver); -- cgit v1.2.3 From 7398748addd3e7a776f30f30376f4ed37f77da8d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 22 Nov 2006 20:15:56 +0000 Subject: Some missing state init --- src/mesa/drivers/dri/nouveau/nouveau_state.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c index 2094691ce2..1445ee7449 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -257,6 +257,10 @@ void nouveauInitState(GLcontext *ctx) ctx->Color.BlendSrcA, ctx->Color.BlendDstA); + STATE_INIT(ClearColor)( ctx, ctx->Color.ClearColor); + STATE_INIT(ClearDepth)( ctx, ctx->Depth.Clear); + STATE_INIT(ClearStencil)( ctx, ctx->Stencil.Clear); + STATE_INIT(ColorMask)( ctx, ctx->Color.ColorMask[RCOMP], ctx->Color.ColorMask[GCOMP], @@ -266,6 +270,7 @@ void nouveauInitState(GLcontext *ctx) STATE_INIT(CullFace)( ctx, ctx->Polygon.CullFaceMode ); STATE_INIT(DepthFunc)( ctx, ctx->Depth.Func ); STATE_INIT(DepthMask)( ctx, ctx->Depth.Mask ); + STATE_INIT(DepthRange)( ctx, ctx->Viewport.Near, ctx->Viewport.Far ); STATE_INIT(Enable)( ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled ); STATE_INIT(Enable)( ctx, GL_BLEND, ctx->Color.BlendEnabled ); @@ -277,6 +282,12 @@ void nouveauInitState(GLcontext *ctx) STATE_INIT(Enable)( ctx, GL_FOG, ctx->Fog.Enabled ); STATE_INIT(Enable)( ctx, GL_LIGHTING, ctx->Light.Enabled ); STATE_INIT(Enable)( ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag ); + STATE_INIT(Enable)( ctx, GL_LINE_STIPPLE, ctx->Line.StippleFlag ); + STATE_INIT(Enable)( ctx, GL_POINT_SMOOTH, ctx->Point.SmoothFlag ); + STATE_INIT(Enable)( ctx, GL_POLYGON_OFFSET_FILL, ctx->Polygon.OffsetFill); + STATE_INIT(Enable)( ctx, GL_POLYGON_OFFSET_LINE, ctx->Polygon.OffsetLine); + STATE_INIT(Enable)( ctx, GL_POLYGON_OFFSET_POINT, ctx->Polygon.OffsetPoint); + STATE_INIT(Enable)( ctx, GL_POLYGON_SMOOTH, ctx->Polygon.SmoothFlag ); STATE_INIT(Enable)( ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag ); STATE_INIT(Enable)( ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled ); STATE_INIT(Enable)( ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled ); @@ -299,9 +310,15 @@ void nouveauInitState(GLcontext *ctx) STATE_INIT(LightModelfv)( ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f ); } + STATE_INIT(LineStipple)( ctx, ctx->Line.StippleFactor, ctx->Line.StipplePattern ); STATE_INIT(LineWidth)( ctx, ctx->Line.Width ); STATE_INIT(LogicOpcode)( ctx, ctx->Color.LogicOp ); STATE_INIT(PointSize)( ctx, ctx->Point.Size ); + STATE_INIT(PolygonMode)( ctx, GL_FRONT, ctx->Polygon.FrontMode ); + STATE_INIT(PolygonMode)( ctx, GL_BACK, ctx->Polygon.BackMode ); + STATE_INIT(PolygonOffset)( ctx, + ctx->Polygon.OffsetFactor, + ctx->Polygon.OffsetUnits ); STATE_INIT(PolygonStipple)( ctx, (const GLubyte *)ctx->PolygonStipple ); STATE_INIT(Scissor)( ctx, ctx->Scissor.X, ctx->Scissor.Y, ctx->Scissor.Width, ctx->Scissor.Height ); @@ -325,5 +342,9 @@ void nouveauInitState(GLcontext *ctx) ctx->Stencil.ZFailFunc[1], ctx->Stencil.ZPassFunc[1]); + STATE_INIT(Viewport)( ctx, + ctx->Viewport.X, ctx->Viewport.Y, + ctx->Viewport.Width, ctx->Viewport.Height ); + STATE_INIT(DrawBuffer)( ctx, ctx->Color.DrawBuffer[0] ); } -- cgit v1.2.3 From 0faf23c26aca46568c32272bc189356e2e9fd373 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Thu, 23 Nov 2006 09:21:44 +0000 Subject: That was really stupid. --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 198e3a2668..4d05a439bb 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -427,7 +427,11 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa) total_size+=attr_size[i]; } } - nmesa->vertex_size=total_size; + nmesa->vertex_size=_tnl_install_attrs( ctx, + nmesa->vertex_attrs, + nmesa->vertex_attr_count, + NULL, 0 ); + assert(nmesa->vertex_size==total_size*4); /* * Tell the hardware about the vertex format -- cgit v1.2.3 From 78e5f414cbe0db6600609092390d795d2039d963 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 24 Nov 2006 23:23:18 +0000 Subject: nv10: rename spot light coefs like nv20,nv30 --- src/mesa/drivers/dri/nouveau/nouveau_reg.h | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_reg.h b/src/mesa/drivers/dri/nouveau/nouveau_reg.h index 2081fd3ec7..e79436cc41 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_reg.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_reg.h @@ -43,7 +43,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ************************************************************************** - Created from objects.c rev. 1.345 + Created from objects.c rev. 1.346 */ #ifndef _NOUVEAU_REG_H @@ -424,7 +424,13 @@ Object NV10_TCL_PRIMITIVE_3D used on: NV10 # define NV10_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_X(d) (0x00000834 + d * 0x0080) # define NV10_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_Y(d) (0x00000838 + d * 0x0080) # define NV10_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_Z(d) (0x0000083c + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_LIGHT(d) (0x00000840 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(d) (0x00000840 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(d) (0x00000844 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(d) (0x00000848 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(d) (0x0000084c + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_Y(d) (0x00000850 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_Z(d) (0x00000854 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(d) (0x00000858 + d * 0x0080) # define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(d) (0x0000085c + d * 0x0080) # define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_Y(d) (0x00000860 + d * 0x0080) # define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_Z(d) (0x00000864 + d * 0x0080) @@ -646,7 +652,13 @@ Object NV15_TCL_PRIMITIVE_3D used on: NV15 # define NV10_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_X(d) (0x00000834 + d * 0x0080) # define NV10_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_Y(d) (0x00000838 + d * 0x0080) # define NV10_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_Z(d) (0x0000083c + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_LIGHT(d) (0x00000840 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(d) (0x00000840 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(d) (0x00000844 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(d) (0x00000848 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(d) (0x0000084c + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_Y(d) (0x00000850 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_Z(d) (0x00000854 + d * 0x0080) +# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(d) (0x00000858 + d * 0x0080) # define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(d) (0x0000085c + d * 0x0080) # define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_Y(d) (0x00000860 + d * 0x0080) # define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_Z(d) (0x00000864 + d * 0x0080) -- cgit v1.2.3 From 291155172733b08238d77440ae935f82bff70bf9 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 24 Nov 2006 23:34:03 +0000 Subject: nv10,nv20,nv30: send correct values for spot light direction X,Y,Z and cutoff parameter C --- src/mesa/drivers/dri/nouveau/nv10_state.c | 55 ++++++++++++++++++------------- src/mesa/drivers/dri/nouveau/nv20_state.c | 50 ++++++++++++++++++---------- src/mesa/drivers/dri/nouveau/nv30_state.c | 49 +++++++++++++++++---------- 3 files changed, 95 insertions(+), 59 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index e99824814f..da26ccba87 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -329,66 +329,75 @@ static void nv10Hint(GLcontext *ctx, GLenum target, GLenum mode) static void nv10Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params ) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - /* not sure where the fourth param value goes...*/ + GLint p = light - GL_LIGHT0; + struct gl_light *l = &ctx->Light.Light[p]; + switch(pname) { case GL_AMBIENT: - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(light), 3); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(p), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; case GL_DIFFUSE: - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(light), 3); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(p), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; case GL_SPECULAR: - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(light), 3); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(p), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; -#if 0 /* FIXME, should be easy to do */ case GL_SPOT_DIRECTION: - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(light), 3); - OUT_RING_CACHEf(params[0]); - OUT_RING_CACHEf(params[1]); - OUT_RING_CACHEf(params[2]); + { + GLfloat x,y,z; + x = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[0]; + y = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[1]; + z = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[2]; + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p), 3); + OUT_RING_CACHEf(x); + OUT_RING_CACHEf(y); + OUT_RING_CACHEf(z); + } break; -#endif case GL_POSITION: - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(light), 3); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(p), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; -#if 0 /* FIXME, should be easy to do */ case GL_SPOT_EXPONENT: - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(light), 1); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(p), 1); OUT_RING_CACHEf(*params); break; case GL_SPOT_CUTOFF: /* you can't factor these */ - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(light), 1); - OUT_RING_CACHEf(params[0]); - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(light), 1); - OUT_RING_CACHEf(params[1]); - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(light), 1); - OUT_RING_CACHEf(params[2]); + { + GLfloat c; + c = -2.0 * (0.5 + l->_CosCutoff); + + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 1); + OUT_RING_CACHEf(params[0]); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(p), 1); + OUT_RING_CACHEf(params[1]); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(p), 1); + OUT_RING_CACHEf(c); + } break; -#endif case GL_CONSTANT_ATTENUATION: - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(light), 1); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p), 1); OUT_RING_CACHEf(*params); break; case GL_LINEAR_ATTENUATION: - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(light), 1); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(p), 1); OUT_RING_CACHEf(*params); break; case GL_QUADRATIC_ATTENUATION: - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(light), 1); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(p), 1); OUT_RING_CACHEf(*params); break; default: diff --git a/src/mesa/drivers/dri/nouveau/nv20_state.c b/src/mesa/drivers/dri/nouveau/nv20_state.c index 338cfd43b0..082dc64b83 100644 --- a/src/mesa/drivers/dri/nouveau/nv20_state.c +++ b/src/mesa/drivers/dri/nouveau/nv20_state.c @@ -340,62 +340,76 @@ static void nv20Hint(GLcontext *ctx, GLenum target, GLenum mode) static void nv20Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params ) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLint p = light - GL_LIGHT0; + struct gl_light *l = &ctx->Light.Light[p]; + /* not sure where the fourth param value goes...*/ switch(pname) { case GL_AMBIENT: - BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(light), 3); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(p), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; case GL_DIFFUSE: - BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(light), 3); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(p), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; case GL_SPECULAR: - BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(light), 3); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(p), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; case GL_SPOT_DIRECTION: - BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(light), 3); - OUT_RING_CACHEf(params[0]); - OUT_RING_CACHEf(params[1]); - OUT_RING_CACHEf(params[2]); + { + GLfloat x,y,z; + x = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[0]; + y = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[1]; + z = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[2]; + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p), 3); + OUT_RING_CACHEf(x); + OUT_RING_CACHEf(y); + OUT_RING_CACHEf(z); + } break; case GL_POSITION: - BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(light), 3); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(p), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; case GL_SPOT_EXPONENT: - BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(light), 1); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(p), 1); OUT_RING_CACHEf(*params); break; case GL_SPOT_CUTOFF: /* you can't factor these */ - BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(light), 1); - OUT_RING_CACHEf(params[0]); - BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(light), 1); - OUT_RING_CACHEf(params[1]); - BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(light), 1); - OUT_RING_CACHEf(params[2]); + { + GLfloat c; + c = -2.0 * (0.5 + l->_CosCutoff); + + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 1); + OUT_RING_CACHEf(params[0]); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(p), 1); + OUT_RING_CACHEf(params[1]); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(p), 1); + OUT_RING_CACHEf(c); + } break; case GL_CONSTANT_ATTENUATION: - BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(light), 1); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p), 1); OUT_RING_CACHEf(*params); break; case GL_LINEAR_ATTENUATION: - BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(light), 1); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(p), 1); OUT_RING_CACHEf(*params); break; case GL_QUADRATIC_ATTENUATION: - BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(light), 1); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(p), 1); OUT_RING_CACHEf(*params); break; default: diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 630b84df63..11795a75c2 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -347,6 +347,8 @@ static void nv30Hint(GLcontext *ctx, GLenum target, GLenum mode) static void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params ) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLint p = light - GL_LIGHT0; + struct gl_light *l = &ctx->Light.Light[p]; if (NOUVEAU_CARD_USING_SHADERS) return; @@ -355,58 +357,69 @@ static void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa switch(pname) { case GL_AMBIENT: - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(light), 3); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(p), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; case GL_DIFFUSE: - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(light), 3); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(p), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; case GL_SPECULAR: - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(light), 3); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(p), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; case GL_SPOT_DIRECTION: - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(light), 3); - OUT_RING_CACHEf(params[0]); - OUT_RING_CACHEf(params[1]); - OUT_RING_CACHEf(params[2]); + { + GLfloat x,y,z; + x = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[0]; + y = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[1]; + z = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[2]; + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p), 3); + OUT_RING_CACHEf(x); + OUT_RING_CACHEf(y); + OUT_RING_CACHEf(z); + } break; case GL_POSITION: - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(light), 3); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(p), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; case GL_SPOT_EXPONENT: - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(light), 1); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(p), 1); OUT_RING_CACHEf(*params); break; case GL_SPOT_CUTOFF: /* you can't factor these */ - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(light), 1); - OUT_RING_CACHEf(params[0]); - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(light), 1); - OUT_RING_CACHEf(params[1]); - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(light), 1); - OUT_RING_CACHEf(params[2]); + { + GLfloat c; + c = -2.0 * (0.5 + l->_CosCutoff); + + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 1); + OUT_RING_CACHEf(params[0]); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(p), 1); + OUT_RING_CACHEf(params[1]); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(p), 1); + OUT_RING_CACHEf(c); + } break; case GL_CONSTANT_ATTENUATION: - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(light), 1); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p), 1); OUT_RING_CACHEf(*params); break; case GL_LINEAR_ATTENUATION: - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(light), 1); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(p), 1); OUT_RING_CACHEf(*params); break; case GL_QUADRATIC_ATTENUATION: - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(light), 1); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(p), 1); OUT_RING_CACHEf(*params); break; default: -- cgit v1.2.3 From 902b26a0d670ca7d2f37103d1c4de242694ff337 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 25 Nov 2006 06:02:10 +0000 Subject: fix scissor --- src/mesa/drivers/dri/nouveau/nv30_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 11795a75c2..851641c0c9 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -516,7 +516,7 @@ static void nv30Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS, 2); OUT_RING_CACHE((w << 16) | x); - OUT_RING_CACHE((y << 16) | y); + OUT_RING_CACHE((h << 16) | y); } /** Select flat or smooth shading */ -- cgit v1.2.3 From 9c9e6abbf82fbf591575a9c352f86721bc72aa90 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 25 Nov 2006 09:58:35 +0000 Subject: Incomplete shader stuff, should mostly work for NV40. Other cards, not so much.. --- src/mesa/drivers/dri/nouveau/Makefile | 11 +- src/mesa/drivers/dri/nouveau/nouveau_context.c | 8 + src/mesa/drivers/dri/nouveau/nouveau_context.h | 7 + src/mesa/drivers/dri/nouveau/nouveau_fifo.h | 28 +- src/mesa/drivers/dri/nouveau/nouveau_object.c | 2 +- src/mesa/drivers/dri/nouveau/nouveau_shader.c | 734 +++++++++++++++++++++ src/mesa/drivers/dri/nouveau/nouveau_shader.h | 362 ++++++++++ .../drivers/dri/nouveau/nouveau_shader_0_arb.c | 694 +++++++++++++++++++ src/mesa/drivers/dri/nouveau/nouveau_shader_1.c | 318 +++++++++ src/mesa/drivers/dri/nouveau/nouveau_shader_2.c | 238 +++++++ src/mesa/drivers/dri/nouveau/nouveau_state.h | 1 + src/mesa/drivers/dri/nouveau/nv20_shader.h | 121 ++++ src/mesa/drivers/dri/nouveau/nv20_vertprog.c | 447 +++++++++++++ src/mesa/drivers/dri/nouveau/nv30_fragprog.c | 707 ++++++++++++++++++++ src/mesa/drivers/dri/nouveau/nv30_shader.h | 378 +++++++++++ src/mesa/drivers/dri/nouveau/nv30_state.c | 2 +- src/mesa/drivers/dri/nouveau/nv30_vertprog.c | 356 ++++++++++ src/mesa/drivers/dri/nouveau/nv40_fragprog.c | 152 +++++ src/mesa/drivers/dri/nouveau/nv40_shader.h | 467 +++++++++++++ src/mesa/drivers/dri/nouveau/nv40_vertprog.c | 647 ++++++++++++++++++ 20 files changed, 5667 insertions(+), 13 deletions(-) create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_shader.c create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_shader.h create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_shader_0_arb.c create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_shader_1.c create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_shader_2.c create mode 100644 src/mesa/drivers/dri/nouveau/nv20_shader.h create mode 100644 src/mesa/drivers/dri/nouveau/nv20_vertprog.c create mode 100644 src/mesa/drivers/dri/nouveau/nv30_fragprog.c create mode 100644 src/mesa/drivers/dri/nouveau/nv30_shader.h create mode 100644 src/mesa/drivers/dri/nouveau/nv30_vertprog.c create mode 100644 src/mesa/drivers/dri/nouveau/nv40_fragprog.c create mode 100644 src/mesa/drivers/dri/nouveau/nv40_shader.h create mode 100644 src/mesa/drivers/dri/nouveau/nv40_vertprog.c (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile index 4d1e3e6c70..384713eeeb 100644 --- a/src/mesa/drivers/dri/nouveau/Makefile +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -17,13 +17,22 @@ DRIVER_SOURCES = \ nouveau_screen.c \ nouveau_span.c \ nouveau_state.c \ + nouveau_shader.c \ + nouveau_shader_0_arb.c \ + nouveau_shader_1.c \ + nouveau_shader_2.c \ nouveau_tex.c \ nouveau_swtcl.c \ nv10_swtcl.c \ nv10_state.c \ nv20_state.c \ nv30_state.c \ - nouveau_state_cache.c + nouveau_state_cache.c \ + nv20_vertprog.c \ + nv30_fragprog.c \ + nv30_vertprog.c \ + nv40_fragprog.c \ + nv40_vertprog.c C_SOURCES = \ $(COMMON_SOURCES) \ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index d3fbdab9f3..4ae0c68fa9 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -35,6 +35,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tnl/tnl.h" #include "tnl/t_pipeline.h" +#include "tnl/t_vp_build.h" #include "drivers/common/driverfuncs.h" @@ -130,6 +131,13 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, nmesa->current_primitive = -1; + nouveauShaderInitFuncs(ctx); + /* Install Mesa's fixed-function shader support */ + if (nmesa->screen->card->type >= NV_40) { + ctx->_MaintainTnlProgram = GL_TRUE; + ctx->_MaintainTexEnvProgram = GL_TRUE; + } + /* Initialize the swrast */ _swrast_CreateContext( ctx ); _ac_CreateContext( ctx ); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 8ae7be015d..e488f9d42d 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -38,6 +38,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_screen.h" #include "nouveau_state_cache.h" +#include "nouveau_shader.h" #include "xmlconfig.h" @@ -119,6 +120,12 @@ typedef struct nouveau_context { GLenum current_primitive; /* the current primitive enum */ DECLARE_RENDERINPUTS(render_inputs_bitset); /* the current render inputs */ + /* Shader state */ + nvsFunc VPfunc; + nvsFunc FPfunc; + nouveauShader *current_fragprog; + nouveauShader *current_vertprog; + nouveauScreenRec *screen; drm_nouveau_sarea_t *sarea; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h index ce465cdca5..44b9f356d1 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h @@ -33,6 +33,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_ctrlreg.h" //#define NOUVEAU_RING_DEBUG +//#define NOUVEAU_STATE_CACHE_DISABLE #define NV_READ(reg) *(volatile u_int32_t *)(nmesa->mmio + (reg)) @@ -63,11 +64,11 @@ int i; printf("OUT_RINGp: (size 0x%x dwords)\n",sz); for(i=0;ififo.buffer[nmesa->fifo.current++]=(n); \ #endif +#define BEGIN_RING_SIZE(subchannel,tag,size) do { \ + nouveau_state_cache_flush(nmesa); \ + if (nmesa->fifo.free <= (size)) \ + WAIT_RING(nmesa,(size)); \ + OUT_RING( ((size)<<18) | ((subchannel) << 13) | (tag)); \ + nmesa->fifo.free -= ((size) + 1); \ +}while(0) + extern void WAIT_RING(nouveauContextPtr nmesa,u_int32_t size); extern void nouveau_state_cache_flush(nouveauContextPtr nmesa); extern void nouveau_state_cache_init(nouveauContextPtr nmesa); +#ifdef NOUVEAU_STATE_CACHE_DISABLE +#define BEGIN_RING_CACHE(subc,tag,size) BEGIN_RING_SIZE((subc), (tag), (size)) +#define OUT_RING_CACHE(n) OUT_RING((n)) +#define OUT_RING_CACHEf(n) OUT_RINGf((n)) +#define OUT_RING_CACHEp(ptr, sz) OUT_RINGp((ptr), (sz)) +#else #define BEGIN_RING_CACHE(subchannel,tag,size) do { \ nmesa->state_cache.dirty=1; \ nmesa->state_cache.current_pos=((tag)/4); \ @@ -116,14 +131,7 @@ extern void nouveau_state_cache_init(nouveauContextPtr nmesa); uint32_t* p=(uint32_t*)(ptr); \ int i; for(i=0;ififo.free <= (size)) \ - WAIT_RING(nmesa,(size)); \ - OUT_RING( ((size)<<18) | ((subchannel) << 13) | (tag)); \ - nmesa->fifo.free -= ((size) + 1); \ -}while(0) +#endif #define RING_AVAILABLE() (nmesa->fifo.free-1) diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.c b/src/mesa/drivers/dri/nouveau/nouveau_object.c index fe3b44df69..cd46feff7c 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.c @@ -54,7 +54,7 @@ void nouveauObjectInit(nouveauContextPtr nmesa) nouveauCreateContextObject(nmesa, Nv3D, nmesa->screen->card->class_3d, 0, 0, 0, 0); nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); /* We need to know vram size.. */ -#if 0 +#if 0 nouveauCreateDmaObject( nmesa, NvDmaFB, 0, (256*1024*1024), 0 /*NV_DMA_TARGET_FB*/, 0 /*NV_DMA_ACCESS_RW*/); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.c b/src/mesa/drivers/dri/nouveau/nouveau_shader.c new file mode 100644 index 0000000000..97ea1ee547 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.c @@ -0,0 +1,734 @@ +/* + * Copyright (C) 2006 Ben Skeggs. + * + * 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, 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: + * Ben Skeggs + */ + +#include "glheader.h" +#include "macros.h" +#include "enums.h" +#include "extensions.h" + +#include "program.h" +#include "tnl/tnl.h" + +#include "nouveau_context.h" +#include "nouveau_shader.h" + +/***************************************************************************** + * Mesa entry points + */ +static void +nouveauBindProgram(GLcontext *ctx, GLenum target, struct gl_program *prog) +{ +} + +static struct gl_program * +nouveauNewProgram(GLcontext *ctx, GLenum target, GLuint id) +{ + nouveauShader *nvs; + + nvs = CALLOC_STRUCT(_nouveauShader); + switch (target) { + case GL_VERTEX_PROGRAM_ARB: + return _mesa_init_vertex_program(ctx, &nvs->mesa.vp, target, id); + case GL_FRAGMENT_PROGRAM_ARB: + return _mesa_init_fragment_program(ctx, &nvs->mesa.fp, target, id); + default: + _mesa_problem(ctx, "Unsupported shader target"); + break; + } + + FREE(nvs); + return NULL; +} + +static void +nouveauDeleteProgram(GLcontext *ctx, struct gl_program *prog) +{ + nouveauShader *nvs = (nouveauShader *)prog; + + if (nvs->translated) + FREE(nvs->program); + _mesa_delete_program(ctx, prog); +} + +static void +nouveauProgramStringNotify(GLcontext *ctx, GLenum target, + struct gl_program *prog) +{ + nouveauShader *nvs = (nouveauShader *)prog; + + if (nvs->translated) + FREE(nvs->program); + nvs->translated = 0; + + _tnl_program_string(ctx, target, prog); +} + +static GLboolean +nouveauIsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog) +{ + nouveauShader *nvs = (nouveauShader *)prog; + + return nvs->translated; +} + +GLboolean +nvsUpdateShader(GLcontext *ctx, nouveauShader *nvs) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + struct gl_program_parameter_list *plist; + int i; + + /* Translate to HW format now if necessary */ + if (!nvs->translated) { + /* Mesa ASM shader -> nouveauShader */ + if (!nouveau_shader_pass0_arb(ctx, nvs)) + return GL_FALSE; + /* Basic dead code elimination + register usage info */ + if (!nouveau_shader_pass1(nvs)) + return GL_FALSE; + /* nouveauShader -> HW bytecode, HW register alloc */ + if (!nouveau_shader_pass2(nvs)) + return GL_FALSE; + assert(nvs->translated); + assert(nvs->program); + } + + /* Update state parameters */ + plist = nvs->mesa.vp.Base.Parameters; + _mesa_load_state_parameters(ctx, plist); + for (i=0; iNumParameters; i++) { + if (!nvs->on_hardware) { + /* if we've been kicked off the hardware there's no guarantee our + * consts are still there.. reupload them all + */ + nvs->func->UpdateConst(ctx, nvs, i); + } else if (plist->Parameters[i].Type == PROGRAM_STATE_VAR) { + /* update any changed state parameters */ + if (!TEST_EQ_4V(nvs->params[i].val, nvs->params[i].source_val)) + nvs->func->UpdateConst(ctx, nvs, i); + } + } + + /* Upload program to hardware, this must come after state param update + * as >=NV30 fragprogs inline consts into the bytecode. + */ + if (!nvs->on_hardware) { + nouveauShader **current; + + if (nvs->mesa.vp.Base.Target == GL_VERTEX_PROGRAM_ARB) + current = &nmesa->current_vertprog; + else + current = &nmesa->current_fragprog; + if (*current) (*current)->on_hardware = 0; + + nvs->func->UploadToHW(ctx, nvs); + nvs->on_hardware = 1; + + *current = nvs; + } + + return GL_TRUE; +} + +void +nouveauShaderInitFuncs(GLcontext * ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + switch (nmesa->screen->card->type) { + case NV_20: + NV20VPInitShaderFuncs(&nmesa->VPfunc); + break; + case NV_30: + NV30VPInitShaderFuncs(&nmesa->VPfunc); + NV30FPInitShaderFuncs(&nmesa->FPfunc); + break; + case NV_40: + case G_70: + NV40VPInitShaderFuncs(&nmesa->VPfunc); + NV40FPInitShaderFuncs(&nmesa->FPfunc); + break; + default: + return; + } + + _mesa_enable_extension(ctx, "GL_ARB_vertex_program"); + ctx->Const.VertexProgram.MaxNativeInstructions = nmesa->VPfunc.MaxInst; + ctx->Const.VertexProgram.MaxNativeAluInstructions = nmesa->VPfunc.MaxInst; + ctx->Const.VertexProgram.MaxNativeTexInstructions = nmesa->VPfunc.MaxInst; + ctx->Const.VertexProgram.MaxNativeTexIndirections = + ctx->Const.VertexProgram.MaxNativeTexInstructions; + ctx->Const.VertexProgram.MaxNativeAttribs = nmesa->VPfunc.MaxAttrib; + ctx->Const.VertexProgram.MaxNativeTemps = nmesa->VPfunc.MaxTemp; + ctx->Const.VertexProgram.MaxNativeAddressRegs = nmesa->VPfunc.MaxAddress; + ctx->Const.VertexProgram.MaxNativeParameters = nmesa->VPfunc.MaxConst; + + if (nmesa->screen->card->type >= NV_30) { + _mesa_enable_extension(ctx, "GL_ARB_fragment_program"); + + ctx->Const.FragmentProgram.MaxNativeInstructions = nmesa->FPfunc.MaxInst; + ctx->Const.FragmentProgram.MaxNativeAluInstructions = nmesa->FPfunc.MaxInst; + ctx->Const.FragmentProgram.MaxNativeTexInstructions = nmesa->FPfunc.MaxInst; + ctx->Const.FragmentProgram.MaxNativeTexIndirections = + ctx->Const.FragmentProgram.MaxNativeTexInstructions; + ctx->Const.FragmentProgram.MaxNativeAttribs = nmesa->FPfunc.MaxAttrib; + ctx->Const.FragmentProgram.MaxNativeTemps = nmesa->FPfunc.MaxTemp; + ctx->Const.FragmentProgram.MaxNativeAddressRegs = nmesa->FPfunc.MaxAddress; + ctx->Const.FragmentProgram.MaxNativeParameters = nmesa->FPfunc.MaxConst; + } + + ctx->Driver.NewProgram = nouveauNewProgram; + ctx->Driver.BindProgram = nouveauBindProgram; + ctx->Driver.DeleteProgram = nouveauDeleteProgram; + ctx->Driver.ProgramStringNotify = nouveauProgramStringNotify; + ctx->Driver.IsProgramNative = nouveauIsProgramNative; +} + + +/***************************************************************************** + * Disassembly support structs + */ +#define CHECK_RANGE(idx, arr) ((idx)= (sizeof(ops) / sizeof(struct _opcode_info))) + return NULL; + if (ops[op].name == NULL) + return NULL; + return &ops[op]; +} + +static const char *_SFR_STRING[] = { + [NVS_FR_POSITION] = "position", + [NVS_FR_WEIGHT] = "weight", + [NVS_FR_NORMAL] = "normal", + [NVS_FR_COL0] = "color", + [NVS_FR_COL1] = "color.secondary", + [NVS_FR_BFC0] = "bfc", + [NVS_FR_BFC1] = "bfc.secondary", + [NVS_FR_FOGCOORD] = "fogcoord", + [NVS_FR_POINTSZ] = "pointsize", + [NVS_FR_TEXCOORD0] = "texcoord[0]", + [NVS_FR_TEXCOORD1] = "texcoord[1]", + [NVS_FR_TEXCOORD2] = "texcoord[2]", + [NVS_FR_TEXCOORD3] = "texcoord[3]", + [NVS_FR_TEXCOORD4] = "texcoord[4]", + [NVS_FR_TEXCOORD5] = "texcoord[5]", + [NVS_FR_TEXCOORD6] = "texcoord[6]", + [NVS_FR_TEXCOORD7] = "texcoord[7]", + [NVS_FR_FRAGDATA0] = "data[0]", + [NVS_FR_FRAGDATA1] = "data[1]", + [NVS_FR_FRAGDATA2] = "data[2]", + [NVS_FR_FRAGDATA3] = "data[3]", + [NVS_FR_CLIP0] = "clip_plane[0]", + [NVS_FR_CLIP1] = "clip_plane[1]", + [NVS_FR_CLIP2] = "clip_plane[2]", + [NVS_FR_CLIP3] = "clip_plane[3]", + [NVS_FR_CLIP4] = "clip_plane[4]", + [NVS_FR_CLIP5] = "clip_plane[5]", + [NVS_FR_CLIP6] = "clip_plane[6]", + [NVS_FR_FACING] = "facing", +}; + +#define SFR_STRING(idx) CHECK_RANGE((idx), SFR_STRING) + +static const char *_SWZ_STRING[] = { + [NVS_SWZ_X] = "x", + [NVS_SWZ_Y] = "y", + [NVS_SWZ_Z] = "z", + [NVS_SWZ_W] = "w" +}; + +#define SWZ_STRING(idx) CHECK_RANGE((idx), SWZ_STRING) + +static const char *_NVS_PREC_STRING[] = { + [NVS_PREC_FLOAT32] = "R", + [NVS_PREC_FLOAT16] = "H", + [NVS_PREC_FIXED12] = "X", + [NVS_PREC_UNKNOWN] = "?" +}; + +#define NVS_PREC_STRING(idx) CHECK_RANGE((idx), NVS_PREC_STRING) + +static const char *_NVS_COND_STRING[] = { + [NVS_COND_FL] = "FL", + [NVS_COND_LT] = "LT", + [NVS_COND_EQ] = "EQ", + [NVS_COND_LE] = "LE", + [NVS_COND_GT] = "GT", + [NVS_COND_NE] = "NE", + [NVS_COND_GE] = "GE", + [NVS_COND_TR] = "TR", + [NVS_COND_UNKNOWN] = "??" +}; + +#define NVS_COND_STRING(idx) CHECK_RANGE((idx), NVS_COND_STRING) + +/***************************************************************************** + * ShaderFragment dumping + */ +static void +nvsDumpIndent(int lvl) +{ + while (lvl--) + printf(" "); +} + +static void +nvsDumpSwizzle(nvsSwzComp *swz) +{ + printf(".%s%s%s%s", + SWZ_STRING(swz[0]), + SWZ_STRING(swz[1]), SWZ_STRING(swz[2]), SWZ_STRING(swz[3]) + ); +} + +static void +nvsDumpReg(nvsInstruction * inst, nvsRegister * reg) +{ + if (reg->negate) + printf("-"); + if (reg->abs) + printf("abs("); + + switch (reg->file) { + case NVS_FILE_TEMP: + printf("R%d", reg->index); + nvsDumpSwizzle(reg->swizzle); + break; + case NVS_FILE_ATTRIB: + printf("attrib.%s", SFR_STRING(reg->index)); + nvsDumpSwizzle(reg->swizzle); + break; + case NVS_FILE_ADDRESS: + printf("A%d", reg->index); + break; + case NVS_FILE_CONST: + if (reg->indexed) + printf("const[A%d.%s + %d]", + reg->addr_reg, SWZ_STRING(reg->addr_comp), reg->index); + else + printf("const[%d]", reg->index); + nvsDumpSwizzle(reg->swizzle); + break; + default: + printf("UNKNOWN_FILE"); + break; + } + + if (reg->abs) + printf(")"); +} + +void +nvsDumpInstruction(nvsInstruction * inst, int slot, int lvl) +{ + struct _opcode_info *opr = &ops[inst->op]; + int i; + + nvsDumpIndent(lvl); + printf("%s ", opr->name); + + if (!opr->flags & NODS) { + switch (inst->dest.file) { + case NVS_FILE_RESULT: + printf("result.%s", SFR_STRING(inst->dest.index)); + break; + case NVS_FILE_TEMP: + printf("R%d", inst->dest.index); + break; + case NVS_FILE_ADDRESS: + printf("A%d", inst->dest.index); + break; + default: + printf("UNKNOWN_DST_FILE"); + break; + } + + if (inst->mask != SMASK_ALL) { + printf("."); + if (inst->mask & SMASK_X) + printf("x"); + if (inst->mask & SMASK_Y) + printf("y"); + if (inst->mask & SMASK_Z) + printf("z"); + if (inst->mask & SMASK_W) + printf("w"); + } + + if (opr->numsrc) + printf(", "); + } + + for (i = 0; i < opr->numsrc; i++) { + nvsDumpReg(inst, &inst->src[i]); + if (i != opr->numsrc - 1) + printf(", "); + } + if (opr->flags & TI_UNIT) + printf(", texture[%d]", inst->tex_unit); + + printf("\n"); +} + +void +nvsDumpFragmentList(nvsFragmentList *f, int lvl) +{ + while (f) { + switch (f->fragment->type) { + case NVS_INSTRUCTION: + nvsDumpInstruction((nvsInstruction*)f->fragment, 0, lvl); + break; + default: + fprintf(stderr, "%s: Only NVS_INSTRUCTION fragments can be in" + "nvsFragmentList!\n", __func__); + return; + } + f = f->next; + } +} + +/***************************************************************************** + * HW shader disassembly + */ +static void +nvsDisasmHWShaderOp(nvsFunc * shader, int merged) +{ + struct _opcode_info *opi; + nvsOpcode op; + nvsRegFile file; + nvsSwzComp swz[4]; + int i; + + op = shader->GetOpcode(shader, merged); + opi = _get_op_info(op); + if (!opi) { + printf("NO OPINFO!"); + return; + } + + printf("%s", opi->name); + if (shader->GetPrecision && + (!(opi->flags & BRANCH_ALL)) && (!(opi->flags * NODS)) && + (op != NVS_OP_NOP)) + printf("%s", NVS_PREC_STRING(shader->GetPrecision(shader))); + if (shader->SupportsConditional && shader->SupportsConditional(shader)) { + if (shader->GetConditionUpdate(shader)) { + printf("C%d", shader->GetCondRegID(shader)); + } + } + if (shader->GetSaturate && shader->GetSaturate(shader)) + printf("_SAT"); + + if (!(opi->flags & NODS)) { + int mask = shader->GetDestMask(shader, merged); + + switch (shader->GetDestFile(shader, merged)) { + case NVS_FILE_ADDRESS: + printf(" A%d", shader->GetDestID(shader, merged)); + break; + case NVS_FILE_TEMP: + printf(" R%d", shader->GetDestID(shader, merged)); + break; + case NVS_FILE_RESULT: + printf(" result.%s", (SFR_STRING(shader->GetDestID(shader, merged)))); + break; + default: + printf(" BAD_RESULT_FILE"); + break; + } + + if (mask != SMASK_ALL) { + printf("."); + if (mask & SMASK_X) printf("x"); + if (mask & SMASK_Y) printf("y"); + if (mask & SMASK_Z) printf("z"); + if (mask & SMASK_W) printf("w"); + } + } + + if (shader->SupportsConditional && shader->SupportsConditional(shader) && + shader->GetConditionTest(shader)) { + shader->GetCondRegSwizzle(shader, swz); + + printf(" (%s%d.%s%s%s%s)", + NVS_COND_STRING(shader->GetCondition(shader)), + shader->GetCondRegID(shader), + SWZ_STRING(swz[NVS_SWZ_X]), + SWZ_STRING(swz[NVS_SWZ_Y]), + SWZ_STRING(swz[NVS_SWZ_Z]), + SWZ_STRING(swz[NVS_SWZ_W]) + ); + } + + /* looping */ + if (opi->flags & COUNT_ALL) { + printf(" { "); + if (opi->flags & COUNT_NUM) { + printf("%d", shader->GetLoopCount(shader)); + } + if (opi->flags & COUNT_IND) { + printf(", %d", shader->GetLoopInitial(shader)); + } + if (opi->flags & COUNT_INC) { + printf(", %d", shader->GetLoopIncrement(shader)); + } + printf(" }"); + } + + /* branching */ + if (opi->flags & BRANCH_TR) + printf(" %d", shader->GetBranch(shader)); + if (opi->flags & BRANCH_EL) + printf(" ELSE %d", shader->GetBranchElse(shader)); + if (opi->flags & BRANCH_EN) + printf(" END %d", shader->GetBranchEnd(shader)); + + if (!(opi->flags & NODS) && opi->numsrc) + printf(","); + printf(" "); + + for (i = 0; i < opi->numsrc; i++) { + if (shader->GetSourceAbs(shader, merged, i)) + printf("abs("); + if (shader->GetSourceNegate(shader, merged, i)) + printf("-"); + + file = shader->GetSourceFile(shader, merged, i); + switch (file) { + case NVS_FILE_TEMP: + printf("R%d", shader->GetSourceID(shader, merged, i)); + break; + case NVS_FILE_CONST: + if (shader->GetSourceIndexed(shader, merged, i)) { + printf("c[A%d.%s + 0x%x]", + shader->GetRelAddressRegID(shader), + SWZ_STRING(shader->GetRelAddressSwizzle(shader)), + shader->GetSourceID(shader, merged, i) + ); + } else { + float val[4]; + + if (shader->GetSourceConstVal) { + shader->GetSourceConstVal(shader, merged, i, val); + printf("{ %.02f, %.02f, %.02f, %.02f }", + val[0], val[1], val[2], val[3]); + } else { + printf("c[0x%x]", shader->GetSourceID(shader, merged, i)); + } + } + break; + case NVS_FILE_ATTRIB: + if (shader->GetSourceIndexed(shader, merged, i)) { + printf("attrib[A%d.%s + %d]", + shader->GetRelAddressRegID(shader), + SWZ_STRING(shader->GetRelAddressSwizzle(shader)), + shader->GetSourceID(shader, merged, i) + ); + } + else { + printf("attrib.%s", + SFR_STRING(shader->GetSourceID(shader, merged, i)) + ); + } + break; + case NVS_FILE_ADDRESS: + printf("A%d", shader->GetRelAddressRegID(shader)); + break; + default: + printf("UNKNOWN_SRC_FILE"); + break; + } + + shader->GetSourceSwizzle(shader, merged, i, swz); + if (file != NVS_FILE_ADDRESS && + (swz[NVS_SWZ_X] != NVS_SWZ_X || swz[NVS_SWZ_Y] != NVS_SWZ_Y || + swz[NVS_SWZ_Z] != NVS_SWZ_Z || swz[NVS_SWZ_W] != NVS_SWZ_W)) { + printf(".%s%s%s%s", SWZ_STRING(swz[NVS_SWZ_X]), + SWZ_STRING(swz[NVS_SWZ_Y]), + SWZ_STRING(swz[NVS_SWZ_Z]), + SWZ_STRING(swz[NVS_SWZ_W])); + } + + if (shader->GetSourceAbs(shader, merged, i)) + printf(")"); + if (shader->GetSourceScale) { + int scale = shader->GetSourceScale(shader, merged, i); + if (scale > 1) + printf("{scaled %dx}", scale); + } + if (i < (opi->numsrc - 1)) + printf(", "); + } + + if (shader->IsLastInst(shader)) + printf(" + END"); +} + +void +nvsDisasmHWShader(nvsPtr nvs) +{ + nvsFunc *shader = nvs->func; + unsigned int iaddr = 0; + + if (!nvs->program) { + fprintf(stderr, "No HW program present"); + return; + } + + shader->inst = nvs->program; + while (1) { + if (shader->inst >= (nvs->program + nvs->program_size)) { + fprintf(stderr, "Reached end of program, but HW inst has no END"); + break; + } + + printf("\t0x%08x:\n", shader->inst[0]); + printf("\t0x%08x:\n", shader->inst[1]); + printf("\t0x%08x:\n", shader->inst[2]); + printf("\t0x%08x:", shader->inst[3]); + + printf("\n\t\tINST %d.0: ", iaddr); + nvsDisasmHWShaderOp(shader, 0); + if (shader->HasMergedInst(shader)) { + printf("\n\t\tINST %d.1: ", iaddr); + nvsDisasmHWShaderOp(shader, 1); + } + printf("\n"); + + if (shader->IsLastInst(shader)) + break; + + shader->inst += shader->GetOffsetNext(shader); + iaddr++; + } + + printf("\n"); +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h new file mode 100644 index 0000000000..baf59d0259 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -0,0 +1,362 @@ +#ifndef __SHADER_COMMON_H__ +#define __SHADER_COMMON_H__ + +#include "mtypes.h" + +typedef struct _nvsFunc nvsFunc; + +#define NVS_MAX_TEMPS 32 +#define NVS_MAX_ATTRIBS 16 +#define NVS_MAX_CONSTS 256 +#define NVS_MAX_ADDRESS 2 +#define NVS_MAX_INSNS 4096 + +typedef struct { + enum { + NVS_INSTRUCTION, + } type; + int position; +} nvsFragmentHeader; + +typedef struct _nvs_fragment_list { + struct _nvs_fragment_list *prev; + struct _nvs_fragment_list *next; + nvsFragmentHeader *fragment; +} nvsFragmentList; + +typedef struct _nouveauShader { + union { + struct gl_vertex_program vp; + struct gl_fragment_program fp; + } mesa; + GLcontext *ctx; + nvsFunc *func; + + /* State of the final program */ + GLboolean translated; + GLboolean on_hardware; + unsigned int *program; + unsigned int program_size; + unsigned int program_alloc_size; + unsigned int program_start_id; + unsigned int program_current; + unsigned int inputs_read; + unsigned int outputs_written; + int inst_count; + + struct { + GLfloat *source_val; /* NULL if invariant */ + float val[4]; + int hw_index; /* hw-specific value */ + } params[NVS_MAX_CONSTS]; + + struct { + int last_use; + } temps[NVS_MAX_TEMPS]; + + /* Pass-private data */ + void *pass_rec; + + nvsFragmentList *list_head; + nvsFragmentList *list_tail; +} nouveauShader, *nvsPtr; + +typedef enum { + NVS_FILE_NONE, + NVS_FILE_TEMP, + NVS_FILE_ATTRIB, + NVS_FILE_CONST, + NVS_FILE_RESULT, + NVS_FILE_ADDRESS, + NVS_FILE_UNKNOWN +} nvsRegFile; + +typedef enum { + NVS_OP_UNKNOWN = 0, + NVS_OP_NOP, + NVS_OP_ABS, NVS_OP_ADD, NVS_OP_ARA, NVS_OP_ARL, NVS_OP_ARR, + NVS_OP_BRA, NVS_OP_BRK, + NVS_OP_CAL, NVS_OP_CMP, NVS_OP_COS, + NVS_OP_DDX, NVS_OP_DDY, NVS_OP_DIV, NVS_OP_DP2, NVS_OP_DP2A, NVS_OP_DP3, + NVS_OP_DP4, NVS_OP_DPH, NVS_OP_DST, + NVS_OP_EX2, NVS_OP_EXP, + NVS_OP_FLR, NVS_OP_FRC, + NVS_OP_IF, + NVS_OP_KIL, + NVS_OP_LG2, NVS_OP_LIT, NVS_OP_LOG, NVS_OP_LOOP, NVS_OP_LRP, + NVS_OP_MAD, NVS_OP_MAX, NVS_OP_MIN, NVS_OP_MOV, NVS_OP_MUL, + NVS_OP_NRM, + NVS_OP_PK2H, NVS_OP_PK2US, NVS_OP_PK4B, NVS_OP_PK4UB, NVS_OP_POW, + NVS_OP_POPA, NVS_OP_PUSHA, + NVS_OP_RCC, NVS_OP_RCP, NVS_OP_REP, NVS_OP_RET, NVS_OP_RFL, NVS_OP_RSQ, + NVS_OP_SCS, NVS_OP_SEQ, NVS_OP_SFL, NVS_OP_SGE, NVS_OP_SGT, NVS_OP_SIN, + NVS_OP_SLE, NVS_OP_SLT, NVS_OP_SNE, NVS_OP_SSG, NVS_OP_STR, NVS_OP_SUB, + NVS_OP_SWZ, + NVS_OP_TEX, NVS_OP_TXB, NVS_OP_TXD, NVS_OP_TXL, NVS_OP_TXP, + NVS_OP_UP2H, NVS_OP_UP2US, NVS_OP_UP4B, NVS_OP_UP4UB, + NVS_OP_X2D, NVS_OP_XPD, + NVS_OP_EMUL +} nvsOpcode; + +typedef enum { + NVS_PREC_FLOAT32, + NVS_PREC_FLOAT16, + NVS_PREC_FIXED12, + NVS_PREC_UNKNOWN +} nvsPrecision; + +typedef enum { + NVS_SWZ_X = 0, + NVS_SWZ_Y = 1, + NVS_SWZ_Z = 2, + NVS_SWZ_W = 3 +} nvsSwzComp; + +typedef enum { + NVS_FR_POSITION, + NVS_FR_WEIGHT, + NVS_FR_NORMAL, + NVS_FR_COL0, + NVS_FR_COL1, + NVS_FR_BFC0, + NVS_FR_BFC1, + NVS_FR_FOGCOORD, + NVS_FR_POINTSZ, + NVS_FR_TEXCOORD0, + NVS_FR_TEXCOORD1, + NVS_FR_TEXCOORD2, + NVS_FR_TEXCOORD3, + NVS_FR_TEXCOORD4, + NVS_FR_TEXCOORD5, + NVS_FR_TEXCOORD6, + NVS_FR_TEXCOORD7, + NVS_FR_FRAGDATA0, + NVS_FR_FRAGDATA1, + NVS_FR_FRAGDATA2, + NVS_FR_FRAGDATA3, + NVS_FR_CLIP0, + NVS_FR_CLIP1, + NVS_FR_CLIP2, + NVS_FR_CLIP3, + NVS_FR_CLIP4, + NVS_FR_CLIP5, + NVS_FR_CLIP6, + NVS_FR_FACING, + NVS_FR_UNKNOWN +} nvsFixedReg; + +typedef enum { + NVS_COND_FL, NVS_COND_LT, NVS_COND_EQ, NVS_COND_LE, NVS_COND_GT, + NVS_COND_NE, NVS_COND_GE, NVS_COND_TR, NVS_COND_UN, + NVS_COND_UNKNOWN +} nvsCond; + +typedef struct { + nvsRegFile file; + unsigned int index; + + unsigned int indexed; + unsigned int addr_reg; + nvsSwzComp addr_comp; + + nvsSwzComp swizzle[4]; + int negate; + int abs; +} nvsRegister; + +static const nvsRegister nvr_unused = { + .file = NVS_FILE_ATTRIB, + .index = 0, + .indexed = 0, + .addr_reg = 0, + .addr_comp = NVS_SWZ_X, + .swizzle = {NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W}, + .negate = 0, + .abs = 0, +}; + +typedef enum { + NVS_TEX_TARGET_1D, + NVS_TEX_TARGET_2D, + NVS_TEX_TARGET_3D, + NVS_TEX_TARGET_CUBE, + NVS_TEX_TARGET_RECT, + NVS_TEX_TARGET_UNKNOWN = 0 +} nvsTexTarget; + +typedef struct { + nvsFragmentHeader header; + + nvsOpcode op; + unsigned int saturate; + + nvsRegister dest; + unsigned int mask; + + nvsRegister src[3]; + + unsigned int tex_unit; + nvsTexTarget tex_target; + + nvsCond cond; + nvsSwzComp cond_swizzle[4]; + int cond_reg; + int cond_test; + int cond_update; +} nvsInstruction; + +#define SMASK_X (1<<0) +#define SMASK_Y (1<<1) +#define SMASK_Z (1<<2) +#define SMASK_W (1<<3) +#define SMASK_ALL (SMASK_X|SMASK_Y|SMASK_Z|SMASK_W) + +#define SPOS_ADDRESS 3 +struct _op_xlat { + unsigned int NV; + nvsOpcode SOP; + int srcpos[3]; +}; +#define MOD_OPCODE(t,hw,sop,s0,s1,s2) do { \ + t[hw].NV = hw; \ + t[hw].SOP = sop; \ + t[hw].srcpos[0] = s0; \ + t[hw].srcpos[1] = s1; \ + t[hw].srcpos[2] = s2; \ +} while(0) + +extern unsigned int NVVP_TX_VOP_COUNT; +extern unsigned int NVVP_TX_NVS_OP_COUNT; +extern struct _op_xlat NVVP_TX_VOP[]; +extern struct _op_xlat NVVP_TX_SOP[]; + +extern unsigned int NVFP_TX_AOP_COUNT; +extern unsigned int NVFP_TX_BOP_COUNT; +extern struct _op_xlat NVFP_TX_AOP[]; +extern struct _op_xlat NVFP_TX_BOP[]; + +#define SCAP_SRC_ABS (1<<0) + +struct _nvsFunc { + unsigned int MaxInst; + unsigned int MaxAttrib; + unsigned int MaxTemp; + unsigned int MaxAddress; + unsigned int MaxConst; + unsigned int caps; + + unsigned int *inst; + void (*UploadToHW) (GLcontext *, nouveauShader *); + void (*UpdateConst) (GLcontext *, nouveauShader *, int); + + struct _op_xlat*(*GetOPTXRec) (nvsFunc *, int merged); + struct _op_xlat*(*GetOPTXFromSOP) (nvsOpcode, int *id); + + int (*SupportsOpcode) (nvsFunc *, nvsOpcode); + void (*SetOpcode) (nvsFunc *, unsigned int opcode, + int slot); + void (*SetCCUpdate) (nvsFunc *); + void (*SetCondition) (nvsFunc *, int on, nvsCond, int reg, + nvsSwzComp *swizzle); + void (*SetResult) (nvsFunc *, nvsRegister *, + unsigned int mask, int slot); + void (*SetSource) (nvsFunc *, nvsRegister *, int pos); + void (*SetUnusedSource) (nvsFunc *, int pos); + void (*SetTexImageUnit) (nvsFunc *, int unit); + void (*SetSaturate) (nvsFunc *); + void (*SetLastInst) (nvsFunc *); + + int (*HasMergedInst) (nvsFunc *); + int (*IsLastInst) (nvsFunc *); + int (*GetOffsetNext) (nvsFunc *); + + int (*GetOpcodeSlot) (nvsFunc *, int merged); + unsigned int (*GetOpcodeHW) (nvsFunc *, int slot); + nvsOpcode (*GetOpcode) (nvsFunc *, int merged); + + nvsPrecision (*GetPrecision) (nvsFunc *); + int (*GetSaturate) (nvsFunc *); + + nvsRegFile (*GetDestFile) (nvsFunc *, int merged); + unsigned int (*GetDestID) (nvsFunc *, int merged); + unsigned int (*GetDestMask) (nvsFunc *, int merged); + + unsigned int (*GetSourceHW) (nvsFunc *, int merged, int pos); + nvsRegFile (*GetSourceFile) (nvsFunc *, int merged, int pos); + int (*GetSourceID) (nvsFunc *, int merged, int pos); + int (*GetTexImageUnit) (nvsFunc *); + int (*GetSourceNegate) (nvsFunc *, int merged, int pos); + int (*GetSourceAbs) (nvsFunc *, int merged, int pos); + void (*GetSourceSwizzle) (nvsFunc *, int merged, int pos, + nvsSwzComp *swz); + int (*GetSourceIndexed) (nvsFunc *, int merged, int pos); + void (*GetSourceConstVal) (nvsFunc *, int merged, int pos, + float *val); + int (*GetSourceScale) (nvsFunc *, int merged, int pos); + + int (*GetRelAddressRegID) (nvsFunc *); + nvsSwzComp (*GetRelAddressSwizzle) (nvsFunc *); + + int (*SupportsConditional) (nvsFunc *); + int (*GetConditionUpdate) (nvsFunc *); + int (*GetConditionTest) (nvsFunc *); + nvsCond (*GetCondition) (nvsFunc *); + void (*GetCondRegSwizzle) (nvsFunc *, nvsSwzComp *swz); + int (*GetCondRegID) (nvsFunc *); + int (*GetBranch) (nvsFunc *); + int (*GetBranchElse) (nvsFunc *); + int (*GetBranchEnd) (nvsFunc *); + + int (*GetLoopCount) (nvsFunc *); + int (*GetLoopInitial) (nvsFunc *); + int (*GetLoopIncrement) (nvsFunc *); +}; + +static inline nvsRegister +nvsNegate(nvsRegister reg) +{ + reg.negate = !reg.negate; + return reg; +} + +static inline nvsRegister +nvsAbs(nvsRegister reg) +{ + reg.abs = 1; + return reg; +} + +static inline nvsRegister +nvsSwizzle(nvsRegister reg, nvsSwzComp x, nvsSwzComp y, + nvsSwzComp z, nvsSwzComp w) +{ + nvsSwzComp sc[4] = { x, y, z, w }; + nvsSwzComp oc[4]; + int i; + + for (i=0;i<4;i++) + oc[i] = reg.swizzle[i]; + for (i=0;i<4;i++) + reg.swizzle[i] = oc[sc[i]]; + return reg; +} + +extern GLboolean nvsUpdateShader(GLcontext *ctx, nouveauShader *nvs); +extern void nvsDisasmHWShader(nvsPtr); + +extern void NV20VPInitShaderFuncs(nvsFunc *); +extern void NV30VPInitShaderFuncs(nvsFunc *); +extern void NV40VPInitShaderFuncs(nvsFunc *); + +extern void NV30FPInitShaderFuncs(nvsFunc *); +extern void NV40FPInitShaderFuncs(nvsFunc *); + +extern void nouveauShaderInitFuncs(GLcontext *ctx); + +extern GLboolean nouveau_shader_pass0_arb(GLcontext *ctx, nouveauShader *nvs); +extern GLboolean nouveau_shader_pass0_slang(GLcontext *ctx, nouveauShader *nvs); +extern GLboolean nouveau_shader_pass1(nvsPtr nvs); +extern GLboolean nouveau_shader_pass2(nvsPtr nvs); + +#endif + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0_arb.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0_arb.c new file mode 100644 index 0000000000..8b5222d069 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0_arb.c @@ -0,0 +1,694 @@ +/* + * Copyright (C) 2006 Ben Skeggs. + * + * 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, 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: + * Ben Skeggs + */ + +#include "glheader.h" +#include "macros.h" +#include "enums.h" + +#include "program.h" +#include "programopt.h" +#include "program_instruction.h" + +#include "nouveau_context.h" +#include "nouveau_shader.h" + +static nvsFixedReg _tx_mesa_vp_dst_reg[VERT_RESULT_MAX] = { + NVS_FR_POSITION, NVS_FR_COL0, NVS_FR_COL1, NVS_FR_FOGCOORD, + NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, + NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7, + NVS_FR_POINTSZ, NVS_FR_BFC0, NVS_FR_BFC1, NVS_FR_UNKNOWN /* EDGE */ +}; + +static nvsFixedReg _tx_mesa_fp_dst_reg[FRAG_RESULT_MAX] = { + NVS_FR_FRAGDATA0 /* COLR */, NVS_FR_FRAGDATA0 /* COLH */, + NVS_FR_UNKNOWN /* DEPR */ +}; + +static nvsFixedReg _tx_mesa_vp_src_reg[VERT_ATTRIB_MAX] = { + NVS_FR_POSITION, NVS_FR_WEIGHT, NVS_FR_NORMAL, NVS_FR_COL0, NVS_FR_COL1, + NVS_FR_FOGCOORD, NVS_FR_UNKNOWN /* COLOR_INDEX */, NVS_FR_UNKNOWN, + NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, + NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7, +/* Generic attribs 0-15, aliased to the above */ + NVS_FR_POSITION, NVS_FR_WEIGHT, NVS_FR_NORMAL, NVS_FR_COL0, NVS_FR_COL1, + NVS_FR_FOGCOORD, NVS_FR_UNKNOWN /* COLOR_INDEX */, NVS_FR_UNKNOWN, + NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, + NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7 +}; + +static nvsFixedReg _tx_mesa_fp_src_reg[FRAG_ATTRIB_MAX] = { + NVS_FR_POSITION, NVS_FR_COL0, NVS_FR_COL1, NVS_FR_FOGCOORD, + NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, + NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7 +}; + +static nvsSwzComp _tx_mesa_swizzle[4] = { + NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W +}; + +static nvsOpcode _tx_mesa_opcode[] = { + [OPCODE_ABS] = NVS_OP_ABS, [OPCODE_ADD] = NVS_OP_ADD, + [OPCODE_ARA] = NVS_OP_ARA, [OPCODE_ARL] = NVS_OP_ARL, + [OPCODE_ARL_NV] = NVS_OP_ARL, [OPCODE_ARR] = NVS_OP_ARR, + [OPCODE_CMP] = NVS_OP_CMP, [OPCODE_COS] = NVS_OP_COS, + [OPCODE_DDX] = NVS_OP_DDX, [OPCODE_DDY] = NVS_OP_DDY, + [OPCODE_DP3] = NVS_OP_DP3, [OPCODE_DP4] = NVS_OP_DP4, + [OPCODE_DPH] = NVS_OP_DPH, [OPCODE_DST] = NVS_OP_DST, + [OPCODE_EX2] = NVS_OP_EX2, [OPCODE_EXP] = NVS_OP_EXP, + [OPCODE_FLR] = NVS_OP_FLR, [OPCODE_FRC] = NVS_OP_FRC, + [OPCODE_KIL] = NVS_OP_EMUL, [OPCODE_KIL_NV] = NVS_OP_KIL, + [OPCODE_LG2] = NVS_OP_LG2, [OPCODE_LIT] = NVS_OP_LIT, + [OPCODE_LOG] = NVS_OP_LOG, + [OPCODE_LRP] = NVS_OP_LRP, + [OPCODE_MAD] = NVS_OP_MAD, [OPCODE_MAX] = NVS_OP_MAX, + [OPCODE_MIN] = NVS_OP_MIN, [OPCODE_MOV] = NVS_OP_MOV, + [OPCODE_MUL] = NVS_OP_MUL, + [OPCODE_PK2H] = NVS_OP_PK2H, [OPCODE_PK2US] = NVS_OP_PK2US, + [OPCODE_PK4B] = NVS_OP_PK4B, [OPCODE_PK4UB] = NVS_OP_PK4UB, + [OPCODE_POW] = NVS_OP_POW, [OPCODE_POPA] = NVS_OP_POPA, + [OPCODE_PUSHA] = NVS_OP_PUSHA, + [OPCODE_RCC] = NVS_OP_RCC, [OPCODE_RCP] = NVS_OP_RCP, + [OPCODE_RFL] = NVS_OP_RFL, [OPCODE_RSQ] = NVS_OP_RSQ, + [OPCODE_SCS] = NVS_OP_SCS, [OPCODE_SEQ] = NVS_OP_SEQ, + [OPCODE_SFL] = NVS_OP_SFL, [OPCODE_SGE] = NVS_OP_SGE, + [OPCODE_SGT] = NVS_OP_SGT, [OPCODE_SIN] = NVS_OP_SIN, + [OPCODE_SLE] = NVS_OP_SLE, [OPCODE_SLT] = NVS_OP_SLT, + [OPCODE_SNE] = NVS_OP_SNE, [OPCODE_SSG] = NVS_OP_SSG, + [OPCODE_STR] = NVS_OP_STR, [OPCODE_SUB] = NVS_OP_SUB, + [OPCODE_SWZ] = NVS_OP_MOV, + [OPCODE_TEX] = NVS_OP_TEX, [OPCODE_TXB] = NVS_OP_TXB, + [OPCODE_TXD] = NVS_OP_TXD, + [OPCODE_TXL] = NVS_OP_TXL, [OPCODE_TXP] = NVS_OP_TXP, + [OPCODE_TXP_NV] = NVS_OP_TXP, + [OPCODE_UP2H] = NVS_OP_UP2H, [OPCODE_UP2US] = NVS_OP_UP2US, + [OPCODE_UP4B] = NVS_OP_UP4B, [OPCODE_UP4UB] = NVS_OP_UP4UB, + [OPCODE_X2D] = NVS_OP_X2D, + [OPCODE_XPD] = NVS_OP_XPD +}; + +static nvsCond _tx_mesa_condmask[] = { + NVS_COND_UNKNOWN, NVS_COND_GT, NVS_COND_LT, NVS_COND_UN, NVS_COND_GE, + NVS_COND_LE, NVS_COND_NE, NVS_COND_NE, NVS_COND_TR, NVS_COND_FL +}; + +struct pass0_rec { + int nvs_ipos; + int next_temp; + int swzconst_done; + int swzconst_id; +}; + +#define X NVS_SWZ_X +#define Y NVS_SWZ_Y +#define Z NVS_SWZ_Z +#define W NVS_SWZ_W + +static void +pass0_append_fragment(nouveauShader *nvs, nvsFragmentHeader *fragment) +{ + nvsFragmentList *list = calloc(1, sizeof(nvsFragmentList)); + if (!list) + return; + + list->fragment = fragment; + list->prev = nvs->list_tail; + if ( nvs->list_tail) + nvs->list_tail->next = list; + if (!nvs->list_head) + nvs->list_head = list; + nvs->list_tail = list; + + nvs->inst_count++; +} + +static void +pass0_make_reg(nouveauShader *nvs, nvsRegister *reg, + nvsRegFile file, unsigned int index) +{ + struct pass0_rec *rec = nvs->pass_rec; + + /* defaults */ + *reg = nvr_unused; + /* -1 == quick-and-dirty temp alloc */ + if (file == NVS_FILE_TEMP && index == -1) { + index = rec->next_temp++; + assert(index < NVS_MAX_TEMPS); + } + reg->file = file; + reg->index = index; +} + +static void +pass0_make_swizzle(nvsSwzComp *swz, unsigned int mesa) +{ + int i; + + for (i=0;i<4;i++) + swz[i] = _tx_mesa_swizzle[GET_SWZ(mesa, i)]; +} + +static nvsOpcode +pass0_make_opcode(enum prog_opcode op) +{ + if (op > MAX_OPCODE) + return NVS_OP_UNKNOWN; + return _tx_mesa_opcode[op]; +} + +static nvsCond +pass0_make_condmask(GLuint mesa) +{ + if (mesa > COND_FL) + return NVS_COND_UNKNOWN; + return _tx_mesa_condmask[mesa]; +} + +static unsigned int +pass0_make_mask(GLuint mesa_mask) +{ + unsigned int mask = 0; + + if (mesa_mask & WRITEMASK_X) mask |= SMASK_X; + if (mesa_mask & WRITEMASK_Y) mask |= SMASK_Y; + if (mesa_mask & WRITEMASK_Z) mask |= SMASK_Z; + if (mesa_mask & WRITEMASK_W) mask |= SMASK_W; + + return mask; +} + +static nvsTexTarget +pass0_make_tex_target(GLuint mesa) +{ + switch (mesa) { + case TEXTURE_1D_INDEX: return NVS_TEX_TARGET_1D; + case TEXTURE_2D_INDEX: return NVS_TEX_TARGET_2D; + case TEXTURE_3D_INDEX: return NVS_TEX_TARGET_3D; + case TEXTURE_CUBE_INDEX: return NVS_TEX_TARGET_CUBE; + case TEXTURE_RECT_INDEX: return NVS_TEX_TARGET_RECT; + default: + return NVS_TEX_TARGET_UNKNOWN; + } +} + +static void +pass0_make_dst_reg(nvsPtr nvs, nvsRegister *reg, + struct prog_dst_register *dst) +{ + struct gl_program *mesa = (struct gl_program*)&nvs->mesa.vp; + nvsFixedReg sfr; + + switch (dst->File) { + case PROGRAM_OUTPUT: + if (mesa->Target == GL_VERTEX_PROGRAM_ARB) { + sfr = (dst->Index < VERT_RESULT_MAX) ? + _tx_mesa_vp_dst_reg[dst->Index] : NVS_FR_UNKNOWN; + } else { + sfr = (dst->Index < FRAG_RESULT_MAX) ? + _tx_mesa_fp_dst_reg[dst->Index] : NVS_FR_UNKNOWN; + } + pass0_make_reg(nvs, reg, NVS_FILE_RESULT, sfr); + break; + case PROGRAM_TEMPORARY: + pass0_make_reg(nvs, reg, NVS_FILE_TEMP, dst->Index); + break; + case PROGRAM_ADDRESS: + pass0_make_reg(nvs, reg, NVS_FILE_ADDRESS, dst->Index); + break; + default: + fprintf(stderr, "Unknown dest file %d\n", dst->File); + assert(0); + } +} + +static void +pass0_make_src_reg(nvsPtr nvs, nvsRegister *reg, struct prog_src_register *src) +{ + struct gl_program *mesa = (struct gl_program *)&nvs->mesa.vp.Base; + struct gl_program_parameter_list *p = mesa->Parameters; + + *reg = nvr_unused; + + switch (src->File) { + case PROGRAM_INPUT: + reg->file = NVS_FILE_ATTRIB; + if (mesa->Target == GL_VERTEX_PROGRAM_ARB) { + reg->index = (src->Index < VERT_ATTRIB_MAX) ? + _tx_mesa_vp_src_reg[src->Index] : NVS_FR_UNKNOWN; + } else { + reg->index = (src->Index < FRAG_ATTRIB_MAX) ? + _tx_mesa_fp_src_reg[src->Index] : NVS_FR_UNKNOWN; + } + break; + /* All const types seem to get shoved into here, not really sure why */ + case PROGRAM_STATE_VAR: + switch (p->Parameters[src->Index].Type) { + case PROGRAM_NAMED_PARAM: + case PROGRAM_CONSTANT: + nvs->params[src->Index].source_val = NULL; + COPY_4V(nvs->params[src->Index].val, p->ParameterValues[src->Index]); + break; + case PROGRAM_STATE_VAR: + nvs->params[src->Index].source_val = p->ParameterValues[src->Index]; + break; + default: + fprintf(stderr, "Unknown parameter type %d\n", + p->Parameters[src->Index].Type); + assert(0); + break; + } + + if (src->RelAddr) { + reg->indexed = 1; + reg->addr_reg = 0; + reg->addr_comp = NVS_SWZ_X; + } else + reg->indexed = 0; + reg->file = NVS_FILE_CONST; + reg->index = src->Index; + break; + case PROGRAM_TEMPORARY: + reg->file = NVS_FILE_TEMP; + reg->index = src->Index; + break; + default: + fprintf(stderr, "Unknown source type %d\n", src->File); + assert(0); + } + + /* per-component negate handled elsewhere */ + reg->negate = src->NegateBase != 0; + reg->abs = src->Abs; + pass0_make_swizzle(reg->swizzle, src->Swizzle); +} + +static nvsInstruction * +pass0_emit(nouveauShader *nvs, nvsOpcode op, nvsRegister dst, + unsigned int mask, int saturate, + nvsRegister src0, nvsRegister src1, nvsRegister src2) +{ + struct pass0_rec *rec = nvs->pass_rec; + nvsInstruction *sif = NULL; + + /* Seems mesa doesn't explicitly 0 this.. */ + if (nvs->mesa.vp.Base.Target == GL_VERTEX_PROGRAM_ARB) + saturate = 0; + + sif = calloc(1, sizeof(nvsInstruction)); + if (sif) { + sif->header.type = NVS_INSTRUCTION; + sif->header.position = rec->nvs_ipos++; + sif->op = op; + sif->saturate = saturate; + sif->dest = dst; + sif->mask = mask; + sif->src[0] = src0; + sif->src[1] = src1; + sif->src[2] = src2; + sif->cond = COND_TR; + sif->cond_reg = 0; + sif->cond_test = 0; + sif->cond_update = 0; + pass0_make_swizzle(sif->cond_swizzle, SWIZZLE_NOOP); + pass0_append_fragment(nvs, (nvsFragmentHeader *)sif); + } + + return sif; +} + +static void +pass0_fixup_swizzle(nvsPtr nvs, + struct prog_src_register *src, + unsigned int sm1, + unsigned int sm2) +{ + static const float sc[4] = { 1.0, 0.0, -1.0, 0.0 }; + struct pass0_rec *rec = nvs->pass_rec; + int fixup_1, fixup_2; + nvsRegister sr, dr = nvr_unused; + nvsRegister sm1const, sm2const; + + if (!rec->swzconst_done) { + struct gl_program *prog = &nvs->mesa.vp.Base; + rec->swzconst_id = _mesa_add_unnamed_constant(prog->Parameters, sc, 4); + rec->swzconst_done = 1; + COPY_4V(nvs->params[rec->swzconst_id].val, sc); + } + + fixup_1 = (sm1 != MAKE_SWIZZLE4(0,0,0,0) && sm2 != MAKE_SWIZZLE4(2,2,2,2)); + fixup_2 = (sm2 != MAKE_SWIZZLE4(2,2,2,2)); + + if (src->File != PROGRAM_TEMPORARY && src->File != PROGRAM_INPUT) { + /* We can't use more than one const in an instruction, so move the const + * into a temp, and swizzle from there. + *TODO: should just emit the swizzled const, instead of swizzling it + * in the shader.. would need to reswizzle any state params when they + * change however.. + */ + pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); + pass0_make_src_reg(nvs, &sr, src); + pass0_emit(nvs, NVS_OP_MOV, dr, SMASK_ALL, 0, sr, nvr_unused, nvr_unused); + pass0_make_reg(nvs, &sr, NVS_FILE_TEMP, dr.index); + } else { + if (fixup_1) + src->NegateBase = 0; + pass0_make_src_reg(nvs, &sr, src); + pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); + } + + pass0_make_reg(nvs, &sm1const, NVS_FILE_CONST, rec->swzconst_id); + pass0_make_swizzle(sm1const.swizzle, sm1); + if (fixup_1 && fixup_2) { + /* Any combination with SWIZZLE_ONE */ + pass0_make_reg(nvs, &sm2const, NVS_FILE_CONST, rec->swzconst_id); + pass0_make_swizzle(sm2const.swizzle, sm2); + pass0_emit(nvs, NVS_OP_MAD, dr, SMASK_ALL, 0, sr, sm1const, sm2const); + } else { + /* SWIZZLE_ZERO || arbitrary negate */ + pass0_emit(nvs, NVS_OP_MUL, dr, SMASK_ALL, 0, sr, sm1const, nvr_unused); + } + + src->File = PROGRAM_TEMPORARY; + src->Index = dr.index; + src->Swizzle = SWIZZLE_NOOP; +} + +#define SET_SWZ(fs, cp, c) fs = (fs & ~(0x7<<(cp*3))) | (c<<(cp*3)) +static void +pass0_check_sources(nvsPtr nvs, struct prog_instruction *inst) +{ + unsigned int insrc = -1, constsrc = -1; + int i; + + for (i=0;i<_mesa_num_inst_src_regs(inst->Opcode);i++) { + struct prog_src_register *src = &inst->SrcReg[i]; + unsigned int sm_1 = 0, sm_2 = 0; + nvsRegister sr, dr; + int do_mov = 0, c; + + /* Build up swizzle masks as if we were going to use + * "MAD new, src, const1, const2" to support arbitrary negation + * and SWIZZLE_ZERO/SWIZZLE_ONE. + */ + for (c=0;c<4;c++) { + if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ZERO) { + SET_SWZ(sm_1, c, SWIZZLE_Y); /* 0.0 */ + SET_SWZ(sm_2, c, SWIZZLE_Y); + SET_SWZ(src->Swizzle, c, SWIZZLE_X); + } else if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ONE) { + SET_SWZ(sm_1, c, SWIZZLE_Y); + if (src->NegateBase & (1<Swizzle, c, SWIZZLE_X); + } else { + if (src->NegateBase & (1<File) { + case PROGRAM_INPUT: + if (insrc != -1 && insrc != src->Index) + do_mov = 1; + else insrc = src->Index; + break; + case PROGRAM_STATE_VAR: + if (constsrc != -1 && constsrc != src->Index) + do_mov = 1; + else constsrc = src->Index; + break; + default: + break; + } + + /* Emit any extra ATTRIB/CONST to a temp, and modify the Mesa instruction + * to point at the temp. + */ + if (do_mov) { + pass0_make_src_reg(nvs, &sr, src); + pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); + pass0_emit(nvs, NVS_OP_MOV, dr, SMASK_ALL, 0, + sr, nvr_unused, nvr_unused); + + src->File = PROGRAM_TEMPORARY; + src->Index = dr.index; + src->Swizzle= SWIZZLE_NOOP; + } + } +} + +static GLboolean +pass0_emulate_instruction(nouveauShader *nvs, struct prog_instruction *inst) +{ + nvsFunc *shader = nvs->func; + nvsRegister src[3], dest, temp; + nvsInstruction *nvsinst; + unsigned int mask = pass0_make_mask(inst->DstReg.WriteMask); + int i, sat; + + sat = (inst->SaturateMode == SATURATE_ZERO_ONE); + + /* Build all the "real" regs for the instruction */ + for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++) + pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]); + if (inst->Opcode != OPCODE_KIL) + pass0_make_dst_reg(nvs, &dest, &inst->DstReg); + + switch (inst->Opcode) { + case OPCODE_ABS: + if (shader->caps & SCAP_SRC_ABS) + pass0_emit(nvs, NVS_OP_MOV, dest, mask, sat, + nvsAbs(src[0]), nvr_unused, nvr_unused); + else + pass0_emit(nvs, NVS_OP_MAX, dest, mask, sat, + src[0], nvsNegate(src[0]), nvr_unused); + break; + case OPCODE_KIL: + /* This is only in ARB shaders, so we don't have to worry + * about clobbering a CC reg as they aren't supported anyway. + */ + /* MOVC0 temp, src */ + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + nvsinst = pass0_emit(nvs, NVS_OP_MOV, temp, SMASK_ALL, 0, + src[0], nvr_unused, nvr_unused); + nvsinst->cond_update = 1; + nvsinst->cond_reg = 0; + /* KIL_NV (LT0.xyzw) temp */ + nvsinst = pass0_emit(nvs, NVS_OP_KIL, nvr_unused, 0, 0, + nvr_unused, nvr_unused, nvr_unused); + nvsinst->cond = COND_LT; + nvsinst->cond_reg = 0; + nvsinst->cond_test = 1; + pass0_make_swizzle(nvsinst->cond_swizzle, MAKE_SWIZZLE4(0,1,2,3)); + break; + case OPCODE_LIT: + break; + case OPCODE_LRP: + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + pass0_emit(nvs, NVS_OP_MAD, temp, mask, 0, + nvsNegate(src[0]), src[2], src[2]); + pass0_emit(nvs, NVS_OP_MAD, dest, mask, sat, + src[0], src[1], temp); + break; + case OPCODE_POW: + if (shader->SupportsOpcode(shader, NVS_OP_LG2) && + shader->SupportsOpcode(shader, NVS_OP_EX2)) { + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + /* LG2 temp.x, src0.c */ + pass0_emit(nvs, NVS_OP_LG2, temp, SMASK_X, 0, + nvsSwizzle(src[0], X, X, X, X), + nvr_unused, + nvr_unused); + /* MUL temp.x, temp.x, src1.c */ + pass0_emit(nvs, NVS_OP_MUL, temp, SMASK_X, 0, + nvsSwizzle(temp, X, X, X, X), + nvsSwizzle(src[1], X, X, X, X), + nvr_unused); + /* EX2 dest, temp.x */ + pass0_emit(nvs, NVS_OP_EX2, dest, mask, sat, + nvsSwizzle(temp, X, X, X, X), + nvr_unused, + nvr_unused); + } else { + /* can we use EXP/LOG instead of EX2/LG2?? */ + fprintf(stderr, "Implement POW for NV20 vtxprog!\n"); + return GL_FALSE; + } + break; + case OPCODE_RSQ: + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + pass0_emit(nvs, NVS_OP_LG2, temp, SMASK_X, 0, + nvsAbs(nvsSwizzle(src[0], X, X, X, X)), nvr_unused, nvr_unused); + pass0_emit(nvs, NVS_OP_EX2, dest, mask, sat, + nvsSwizzle(temp, X, X, X, X), nvr_unused, nvr_unused); + break; + case OPCODE_SCS: + if (mask & SMASK_X) + pass0_emit(nvs, NVS_OP_COS, dest, SMASK_X, sat, + nvsSwizzle(src[0], X, X, X, X), + nvr_unused, + nvr_unused); + if (mask & SMASK_Y) + pass0_emit(nvs, NVS_OP_SIN, dest, SMASK_Y, sat, + nvsSwizzle(src[0], X, X, X, X), + nvr_unused, + nvr_unused); + break; + case OPCODE_SUB: + pass0_emit(nvs, NVS_OP_ADD, dest, mask, sat, + src[0], nvsNegate(src[1]), nvr_unused); + break; + case OPCODE_XPD: + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + pass0_emit(nvs, NVS_OP_MUL, temp, SMASK_ALL, 0, + nvsSwizzle(src[0], Z, X, Y, Y), + nvsSwizzle(src[1], Y, Z, X, X), + nvr_unused); + pass0_emit(nvs, NVS_OP_MAD, dest, (mask & ~SMASK_W), sat, + nvsSwizzle(src[0], Y, Z, X, X), + nvsSwizzle(src[1], Z, X, Y, Y), + nvsNegate(temp)); + break; + default: + fprintf(stderr, "hw doesn't support opcode \"%s\", and no emulation found\n", + _mesa_opcode_string(inst->Opcode)); + return GL_FALSE; + } + + return GL_TRUE; +} + +static GLboolean +pass0_translate_instructions(nouveauShader *nvs) +{ + struct gl_program *prog = (struct gl_program *)&nvs->mesa.vp; + struct pass0_rec *rec = nvs->pass_rec; + nvsFunc *shader = nvs->func; + int ipos; + + for (ipos=0; iposNumInstructions; ipos++) { + struct prog_instruction *inst = &prog->Instructions[ipos]; + + if (inst->Opcode == OPCODE_END) + break; + + /* Deal with multiple ATTRIB/PARAM in a single instruction */ + pass0_check_sources(nvs, inst); + + /* Now it's safe to do the prog_instruction->nvsInstruction conversion */ + if (shader->SupportsOpcode(shader, pass0_make_opcode(inst->Opcode))) { + nvsInstruction *nvsinst; + nvsRegister src[3], dest; + int i; + + for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++) + pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]); + pass0_make_dst_reg(nvs, &dest, &inst->DstReg); + + nvsinst = pass0_emit(nvs, + pass0_make_opcode(inst->Opcode), + dest, + pass0_make_mask(inst->DstReg.WriteMask), + (inst->SaturateMode != SATURATE_OFF), + src[0], src[1], src[2]); + nvsinst->tex_unit = inst->TexSrcUnit; + nvsinst->tex_target = pass0_make_tex_target(inst->TexSrcTarget); + /* TODO when NV_fp/vp is implemented */ + nvsinst->cond = COND_TR; + } else { + if (!pass0_emulate_instruction(nvs, inst)) + return GL_FALSE; + } + } + + return GL_TRUE; +} + +GLboolean +nouveau_shader_pass0_arb(GLcontext *ctx, nouveauShader *nvs) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + struct gl_program *prog = (struct gl_program*)nvs; + struct gl_vertex_program *vp = (struct gl_vertex_program *)prog; + struct gl_fragment_program *fp = (struct gl_fragment_program *)prog; + struct pass0_rec *rec; + int ret; + + switch (prog->Target) { + case GL_VERTEX_PROGRAM_ARB: + nvs->func = &nmesa->VPfunc; + if (vp->IsPositionInvariant) + _mesa_insert_mvp_code(ctx, vp); +#if 0 + if (IS_FIXEDFUNCTION_PROG && CLIP_PLANES_USED) + pass0_insert_ff_clip_planes(); +#endif + break; + case GL_FRAGMENT_PROGRAM_ARB: + nvs->func = &nmesa->FPfunc; + if (fp->FogOption != GL_NONE) + _mesa_append_fog_code(ctx, fp); + break; + default: + fprintf(stderr, "Unknown program type %d", prog->Target); + return GL_FALSE; + } + + rec = calloc(1, sizeof(struct pass0_rec)); + rec->next_temp = prog->NumTemporaries; + nvs->pass_rec = rec; + + ret = pass0_translate_instructions(nvs); + if (!ret) { + /* DESTROY list */ + } + + free(nvs->pass_rec); + return ret; +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_1.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_1.c new file mode 100644 index 0000000000..5de9017f58 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_1.c @@ -0,0 +1,318 @@ +/* + * Copyright (C) 2006 Ben Skeggs. + * + * 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, 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: + * Ben Skeggs + */ + +#include "glheader.h" +#include "macros.h" +#include "enums.h" + +#include "nouveau_shader.h" + +#define PASS1_OK 0 +#define PASS1_KILL 1 +#define PASS1_FAIL 2 + +struct pass1_rec { + unsigned int temp[NVS_MAX_TEMPS]; + unsigned int result[NVS_MAX_ATTRIBS]; + unsigned int address[NVS_MAX_ADDRESS]; + unsigned int cc[2]; +}; + +static void +pass1_remove_fragment(nvsPtr nvs, nvsFragmentList *item) +{ + if (item->prev) item->prev->next = item->next; + if (item->next) item->next->prev = item->prev; + if (nvs->list_head == item) nvs->list_head = item->next; + if (nvs->list_tail == item) nvs->list_tail = item->prev; + + nvs->inst_count--; +} + +static int +pass1_result_needed(struct pass1_rec *rec, nvsInstruction *inst) +{ + if (inst->cond_update && rec->cc[inst->cond_reg]) + return 1; + /* Only write components that are read later */ + if (inst->dest.file == NVS_FILE_TEMP) + return (inst->mask & rec->temp[inst->dest.index]); + if (inst->dest.file == NVS_FILE_ADDRESS) + return (inst->mask & rec->address[inst->dest.index]); + /* No point writing result components that are written later */ + if (inst->dest.file == NVS_FILE_RESULT) + return (inst->mask & ~rec->result[inst->dest.index]); + assert(0); +} + +static void +pass1_track_result(struct pass1_rec *rec, nvsInstruction *inst) +{ + if (inst->cond_test) + rec->cc[inst->cond_reg] = 1; + if (inst->dest.file == NVS_FILE_TEMP) { + inst->mask &= rec->temp[inst->dest.index]; + } else if (inst->dest.file == NVS_FILE_RESULT) { + inst->mask &= ~rec->result[inst->dest.index]; + rec->result[inst->dest.index] |= inst->mask; + } else if (inst->dest.file == NVS_FILE_ADDRESS) { + inst->mask &= rec->address[inst->dest.index]; + } +} + +static void +pass1_track_source(nouveauShader *nvs, nvsInstruction *inst, int pos, + unsigned int read) +{ + struct pass1_rec *rec = nvs->pass_rec; + nvsRegister *src = &inst->src[pos]; + unsigned int really_read = 0; + int i,sc; + + /* Account for swizzling */ + for (i=0; i<4; i++) + if (read & (1<swizzle[i]); + + /* Track register reads */ + if (src->file == NVS_FILE_TEMP) { + if (nvs->temps[src->index].last_use == -1) + nvs->temps[src->index].last_use = inst->header.position; + rec->temp [src->index] |= really_read; + } else if (src->indexed) { + rec->address[src->addr_reg] |= (1<addr_comp); + } + + /* Modify swizzle to only access read components */ + /* Find a component that is used.. */ + for (sc=0;sc<4;sc++) + if (really_read & (1<swizzle[i] = sc; +} + +static int +pass1_check_instruction(nouveauShader *nvs, nvsInstruction *inst) +{ + struct pass1_rec *rec = nvs->pass_rec; + unsigned int read0, read1, read2; + + if (inst->op != NVS_OP_KIL) { + if (!pass1_result_needed(rec, inst)) + return PASS1_KILL; + } + pass1_track_result(rec, inst); + + read0 = read1 = read2 = 0; + + switch (inst->op) { + case NVS_OP_FLR: + case NVS_OP_FRC: + case NVS_OP_MOV: + case NVS_OP_SSG: + case NVS_OP_ARL: + read0 = inst->mask; + break; + case NVS_OP_ADD: + case NVS_OP_MAX: + case NVS_OP_MIN: + case NVS_OP_MUL: + case NVS_OP_SEQ: + case NVS_OP_SFL: + case NVS_OP_SGE: + case NVS_OP_SGT: + case NVS_OP_SLE: + case NVS_OP_SLT: + case NVS_OP_SNE: + case NVS_OP_STR: + case NVS_OP_SUB: + read0 = inst->mask; + read1 = inst->mask; + break; + case NVS_OP_CMP: + case NVS_OP_LRP: + case NVS_OP_MAD: + read0 = inst->mask; + read1 = inst->mask; + read2 = inst->mask; + break; + case NVS_OP_XPD: + if (inst->mask & SMASK_X) read0 |= SMASK_Y|SMASK_Z; + if (inst->mask & SMASK_Y) read0 |= SMASK_X|SMASK_Z; + if (inst->mask & SMASK_Z) read0 |= SMASK_X|SMASK_Y; + read1 = read0; + break; + case NVS_OP_COS: + case NVS_OP_EX2: + case NVS_OP_EXP: + case NVS_OP_LG2: + case NVS_OP_LOG: + case NVS_OP_RCC: + case NVS_OP_RCP: + case NVS_OP_RSQ: + case NVS_OP_SCS: + case NVS_OP_SIN: + read0 = SMASK_X; + break; + case NVS_OP_POW: + read0 = SMASK_X; + read1 = SMASK_X; + break; + case NVS_OP_DIV: + read0 = inst->mask; + read1 = SMASK_X; + break; + case NVS_OP_DP2: + read0 = SMASK_X|SMASK_Y; + read1 = SMASK_X|SMASK_Y; + break; + case NVS_OP_DP3: + case NVS_OP_RFL: + read0 = SMASK_X|SMASK_Y|SMASK_Z; + read1 = SMASK_X|SMASK_Y|SMASK_Z; + break; + case NVS_OP_DP4: + read0 = SMASK_ALL; + read1 = SMASK_ALL; + break; + case NVS_OP_DPH: + read0 = SMASK_X|SMASK_Y|SMASK_Z; + read1 = SMASK_ALL; + break; + case NVS_OP_DST: + if (inst->mask & SMASK_Y) read0 = read1 = SMASK_Y; + if (inst->mask & SMASK_Z) read0 |= SMASK_Z; + if (inst->mask & SMASK_W) read1 |= SMASK_W; + break; + case NVS_OP_NRM: + read0 = SMASK_X|SMASK_Y|SMASK_Z; + break; + case NVS_OP_PK2H: + case NVS_OP_PK2US: + read0 = SMASK_X|SMASK_Y; + break; + case NVS_OP_DDX: + case NVS_OP_DDY: + case NVS_OP_UP2H: + case NVS_OP_UP2US: + case NVS_OP_PK4B: + case NVS_OP_PK4UB: + case NVS_OP_UP4B: + case NVS_OP_UP4UB: + read0 = SMASK_ALL; + break; + case NVS_OP_X2D: + read1 = SMASK_X|SMASK_Y; + if (inst->mask & (SMASK_X|SMASK_Z)) { + read0 |= SMASK_X; + read2 |= SMASK_X|SMASK_Y; + } + if (inst->mask & (SMASK_Y|SMASK_W)) { + read0 |= SMASK_Y; + read2 |= SMASK_Z|SMASK_W; + } + break; + case NVS_OP_LIT: + read0 |= SMASK_X|SMASK_Y|SMASK_W; + break; + case NVS_OP_TEX: + case NVS_OP_TXP: + case NVS_OP_TXL: + case NVS_OP_TXB: + read0 = SMASK_ALL; + break; + case NVS_OP_TXD: + read0 = SMASK_ALL; + read1 = SMASK_ALL; + read2 = SMASK_ALL; + break; + case NVS_OP_KIL: + break; + default: + fprintf(stderr, "Unknown sop=%d", inst->op); + return PASS1_FAIL; + } + + /* Any values that are written by this inst can't have been read further up */ + if (inst->dest.file == NVS_FILE_TEMP) + rec->temp[inst->dest.index] &= ~inst->mask; + + if (read0) pass1_track_source(nvs, inst, 0, read0); + if (read1) pass1_track_source(nvs, inst, 1, read1); + if (read2) pass1_track_source(nvs, inst, 2, read2); + + return PASS1_OK; +} + +/* Some basic dead code elimination + * - Remove unused instructions + * - Don't write unused register components + * - Modify swizzles to not reference unneeded components. + */ +GLboolean +nouveau_shader_pass1(nvsPtr nvs) +{ + nvsFragmentList *list = nvs->list_tail; + int i; + + for (i=0; itemps[i].last_use = -1; + + nvs->pass_rec = calloc(1, sizeof(struct pass1_rec)); + + while (list) { + assert(list->fragment->type == NVS_INSTRUCTION); + + switch(pass1_check_instruction(nvs, (nvsInstruction *)list->fragment)) { + case PASS1_OK: + break; + case PASS1_KILL: + pass1_remove_fragment(nvs, list); + break; + case PASS1_FAIL: + default: + free(nvs->pass_rec); + nvs->pass_rec = NULL; + return GL_FALSE; + } + + list = list->prev; + } + + free(nvs->pass_rec); + nvs->pass_rec = NULL; + + return GL_TRUE; +} + + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c new file mode 100644 index 0000000000..1f09b6d453 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c @@ -0,0 +1,238 @@ +/* + * Copyright (C) 2006 Ben Skeggs. + * + * 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, 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: + * Ben Skeggs + */ + +#include "glheader.h" +#include "macros.h" +#include "enums.h" + +#include "nouveau_shader.h" + +struct pass2_rec { + /* Map nvsRegister temp ID onto hw temp ID */ + unsigned int temps[NVS_MAX_TEMPS]; + /* Track free hw registers */ + unsigned int hw_temps[NVS_MAX_TEMPS]; +}; + +static int +pass2_alloc_hw_temp(nvsPtr nvs) +{ + struct pass2_rec *rec = nvs->pass_rec; + int i; + + for (i=0; ifunc->MaxTemp; i++) { + /* This is a *horrible* hack.. R0 is both temp0 and result.color + * in NV30/40 fragprogs, we can use R0 as a temp before result is + * written however.. + */ + if (nvs->mesa.vp.Base.Target == GL_FRAGMENT_PROGRAM_ARB && i==0) + continue; + + if (rec->hw_temps[i] == 0) { + rec->hw_temps[i] = 1; + return i; + } + } + return -1; +} + +static void +pass2_free_hw_temp(nvsPtr nvs, int reg) +{ + struct pass2_rec *rec = nvs->pass_rec; + rec->hw_temps[reg] = 0; +} + +static nvsRegister +pass2_mangle_reg(nvsPtr nvs, nvsInstruction *inst, nvsRegister reg) +{ + struct pass2_rec *rec = nvs->pass_rec; + + if (reg.file == NVS_FILE_TEMP) { + int hwidx; + + if (rec->temps[reg.index] == -1) + rec->temps[reg.index] = pass2_alloc_hw_temp(nvs); + hwidx = rec->temps[reg.index]; + + if (nvs->temps[reg.index].last_use <= inst->header.position) + pass2_free_hw_temp(nvs, hwidx); + + reg.index = hwidx; + } + + return reg; +} + +static void +pass2_add_instruction(nvsPtr nvs, nvsInstruction *inst, + struct _op_xlat *op, int slot) +{ + nvsSwzComp default_swz[4] = { NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W }; + nvsFunc *shader = nvs->func; + nvsRegister reg; + int i, srcpos_used = ~7; + + shader->SetOpcode(shader, op->NV, slot); + if (inst->saturate ) shader->SetSaturate(shader); + if (inst->cond_update) shader->SetCCUpdate(shader); + if (inst->cond_test ) shader->SetCondition(shader, 1, inst->cond, + inst->cond_reg, + inst->cond_swizzle); + else shader->SetCondition(shader, 0, NVS_COND_TR, + 0, + default_swz); + switch (inst->op) { + case NVS_OP_TEX: + case NVS_OP_TXB: + case NVS_OP_TXL: + case NVS_OP_TXP: + case NVS_OP_TXD: + shader->SetTexImageUnit(shader, inst->tex_unit); + break; + default: + break; + } + + for (i = 0; i < 3; i++) { + if (op->srcpos[i] != -1) { + reg = pass2_mangle_reg(nvs, inst, inst->src[i]); + if (reg.file == NVS_FILE_ATTRIB) + nvs->inputs_read |= (1 << reg.index); + shader->SetSource(shader, ®, op->srcpos[i]); + srcpos_used |= (1<srcpos[i]); + if (reg.file == NVS_FILE_CONST && shader->GetSourceConstVal) + nvs->params[reg.index].hw_index = nvs->program_current + 4; + } + } + for (i = 0; i < 3; i++) { + if (!(srcpos_used & (1<SetUnusedSource(shader, i); + } + + reg = pass2_mangle_reg(nvs, inst, inst->dest); + if (reg.file == NVS_FILE_RESULT) + nvs->outputs_written |= (1 << reg.index); + shader->SetResult(shader, ®, inst->mask, slot); +} + +static int +pass2_assemble_instruction(nvsPtr nvs, nvsInstruction *inst, int last) +{ + nvsFunc *shader = nvs->func; + struct _op_xlat *op, *op2; + unsigned int hw_inst[8] = {0,0,0,0,0,0,0,0,0}; + int slot, slot2; + int instsz; + int i; + + shader->inst = hw_inst; + + /* Assemble this instruction */ + if (!(op = shader->GetOPTXFromSOP(inst->op, &slot))) + return 0; + pass2_add_instruction(nvs, inst, op, slot); + if (last) + shader->SetLastInst(shader); + + instsz = shader->GetOffsetNext(nvs->func); + if (nvs->program_size + instsz >= nvs->program_alloc_size) { + nvs->program_alloc_size *= 2; + nvs->program = realloc(nvs->program, + nvs->program_alloc_size * sizeof(uint32_t)); + } + + for (i=0; iprogram[nvs->program_current++] = hw_inst[i]; + nvs->program_size = nvs->program_current; + return 1; +} + +/* Translate program into hardware format */ +GLboolean +nouveau_shader_pass2(nvsPtr nvs) +{ + nvsFragmentList *list = nvs->list_head; + struct pass2_rec *rec; + int i; + + rec = calloc(1, sizeof(struct pass2_rec)); + for (i=0; itemps[i] = -1; + nvs->pass_rec = rec; + + /* Start off with allocating 4 uint32_t's for each inst, will be grown + * if necessary.. + */ + nvs->program_alloc_size = nvs->inst_count * 4; + nvs->program = calloc(nvs->program_alloc_size, sizeof(uint32_t)); + nvs->program_size = 0; + nvs->program_current = 0; + + while (list) { + assert(list->fragment->type == NVS_INSTRUCTION); + + if (!pass2_assemble_instruction(nvs, (nvsInstruction *)list->fragment, list->next ? 0 : 1)) { + free(nvs->program); + nvs->program = NULL; + return GL_FALSE; + } + + list = list->next; + } + + /* Shrink allocated memory to only what we need */ + nvs->program = realloc(nvs->program, nvs->program_size * sizeof(uint32_t)); + nvs->program_alloc_size = nvs->program_size; + + nvs->translated = 1; + nvs->on_hardware = 0; + +#if 1 + fflush(stdout); fflush(stderr); + fprintf(stderr, "----------------MESA PROGRAM\n"); + fflush(stdout); fflush(stderr); + _mesa_print_program(&nvs->mesa.vp.Base); + fflush(stdout); fflush(stderr); + fprintf(stderr, "^^^^^^^^^^^^^^^^MESA PROGRAM\n"); + fflush(stdout); fflush(stderr); + fprintf(stderr, "----------------NV40 PROGRAM\n"); + fflush(stdout); fflush(stderr); + nvsDisasmHWShader(nvs); + fflush(stdout); fflush(stderr); + fprintf(stderr, "^^^^^^^^^^^^^^^^NV40 PROGRAM\n"); + fflush(stdout); fflush(stderr); +#endif + + return GL_TRUE; +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.h b/src/mesa/drivers/dri/nouveau/nouveau_state.h index f8fd0cea50..37f04f41bd 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.h @@ -37,6 +37,7 @@ extern void nv20InitStateFuncs(struct dd_function_table *func); extern void nv30InitStateFuncs(struct dd_function_table *func); extern void nouveauInitState(GLcontext *ctx); + /* extern void nouveauDDUpdateState(GLcontext *ctx); extern void nouveauDDUpdateHWState(GLcontext *ctx); diff --git a/src/mesa/drivers/dri/nouveau/nv20_shader.h b/src/mesa/drivers/dri/nouveau/nv20_shader.h new file mode 100644 index 0000000000..7d2e29db66 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_shader.h @@ -0,0 +1,121 @@ +/* NV20_TCL_PRIMITIVE_3D_0x0B00 */ +#define NV20_VP_INST_0B00 0x00000000 /* always 0? */ +#define NV20_VP_INST0_KNOWN 0 + +/* NV20_TCL_PRIMITIVE_3D_0x0B04 */ +#define NV20_VP_INST_SCA_OPCODE_SHIFT 25 +#define NV20_VP_INST_SCA_OPCODE_MASK (0x0F << 25) +#define NV20_VP_INST_OPCODE_RCP 0x2 +#define NV20_VP_INST_OPCODE_RCC 0x3 +#define NV20_VP_INST_OPCODE_RSQ 0x4 +#define NV20_VP_INST_OPCODE_EXP 0x5 +#define NV20_VP_INST_OPCODE_LOG 0x6 +#define NV20_VP_INST_OPCODE_LIT 0x7 +#define NV20_VP_INST_VEC_OPCODE_SHIFT 21 +#define NV20_VP_INST_VEC_OPCODE_MASK (0x0F << 21) +#define NV20_VP_INST_OPCODE_NOP 0x0 /* guess */ +#define NV20_VP_INST_OPCODE_MOV 0x1 +#define NV20_VP_INST_OPCODE_MUL 0x2 +#define NV20_VP_INST_OPCODE_ADD 0x3 +#define NV20_VP_INST_OPCODE_MAD 0x4 +#define NV20_VP_INST_OPCODE_DP3 0x5 +#define NV20_VP_INST_OPCODE_DPH 0x6 +#define NV20_VP_INST_OPCODE_DP4 0x7 +#define NV20_VP_INST_OPCODE_DST 0x8 +#define NV20_VP_INST_OPCODE_MIN 0x9 +#define NV20_VP_INST_OPCODE_MAX 0xA +#define NV20_VP_INST_OPCODE_SLT 0xB +#define NV20_VP_INST_OPCODE_SGE 0xC +#define NV20_VP_INST_OPCODE_ARL 0xD +#define NV20_VP_INST_CONST_SRC_SHIFT 13 +#define NV20_VP_INST_CONST_SRC_MASK (0xFF << 13) +#define NV20_VP_INST_INPUT_SRC_SHIFT 9 +#define NV20_VP_INST_INPUT_SRC_MASK (0xF << 9) /* guess */ +#define NV20_VP_INST_INPUT_SRC_POS 0 +#define NV20_VP_INST_INPUT_SRC_COL0 3 +#define NV20_VP_INST_INPUT_SRC_COL1 4 +#define NV20_VP_INST_INPUT_SRC_TC(n) (9+n) +#define NV20_VP_INST_SRC0H_SHIFT 0 +#define NV20_VP_INST_SRC0H_MASK (0x1FF << 0) +#define NV20_VP_INST1_KNOWN ( \ + NV20_VP_INST_OPCODE_MASK | \ + NV20_VP_INST_CONST_SRC_MASK | \ + NV20_VP_INST_INPUT_SRC_MASK | \ + NV20_VP_INST_SRC0H_MASK \ + ) + +/* NV20_TCL_PRIMITIVE_3D_0x0B08 */ +#define NV20_VP_INST_SRC0L_SHIFT 26 +#define NV20_VP_INST_SRC0L_MASK (0x3F <<26) +#define NV20_VP_INST_SRC1_SHIFT 11 +#define NV20_VP_INST_SRC1_MASK (0x7FFF<<11) +#define NV20_VP_INST_SRC2H_SHIFT 0 +#define NV20_VP_INST_SRC2H_MASK (0x7FF << 0) + +/* NV20_TCL_PRIMITIVE_3D_0x0B0C */ +#define NV20_VP_INST_SRC2L_SHIFT 28 +#define NV20_VP_INST_SRC2L_MASK (0x0F <<28) +#define NV20_VP_INST_VTEMP_WRITEMASK_SHIFT 24 +#define NV20_VP_INST_VTEMP_WRITEMASK_MASK (0x0F <<24) +# define NV20_VP_INST_TEMP_WRITEMASK_X (1<<27) +# define NV20_VP_INST_TEMP_WRITEMASK_Y (1<<26) +# define NV20_VP_INST_TEMP_WRITEMASK_Z (1<<25) +# define NV20_VP_INST_TEMP_WRITEMASK_W (1<<24) +#define NV20_VP_INST_DEST_TEMP_ID_SHIFT 20 +#define NV20_VP_INST_DEST_TEMP_ID_MASK (0x0F <<20) +#define NV20_VP_INST_STEMP_WRITEMASK_SHIFT 16 +#define NV20_VP_INST_STEMP_WRITEMASK_MASK (0x0F <<16) +# define NV20_VP_INST_STEMP_WRITEMASK_X (1<<19) +# define NV20_VP_INST_STEMP_WRITEMASK_Y (1<<18) +# define NV20_VP_INST_STEMP_WRITEMASK_Z (1<<17) +# define NV20_VP_INST_STEMP_WRITEMASK_W (1<<16) +#define NV20_VP_INST_DEST_WRITEMASK_SHIFT 12 +#define NV20_VP_INST_DEST_WRITEMASK_MASK (0x0F <<12) +# define NV20_VP_INST_DEST_WRITEMASK_X (1<<15) +# define NV20_VP_INST_DEST_WRITEMASK_Y (1<<14) +# define NV20_VP_INST_DEST_WRITEMASK_Z (1<<13) +# define NV20_VP_INST_DEST_WRITEMASK_W (1<<12) +#define NV20_VP_INST_DEST_SHIFT 3 +#define NV20_VP_INST_DEST_MASK (0xF << 3) /* guess */ +#define NV20_VP_INST_DEST_POS 0 +#define NV20_VP_INST_DEST_COL0 3 +#define NV20_VP_INST_DEST_COL1 4 +#define NV20_VP_INST_DEST_TC(n) (9+n) +#define NV20_VP_INST_INDEX_CONST (1<<1) +#define NV20_VP_INST3_KNOWN ( \ + NV20_VP_INST_SRC2L_MASK | \ + NV20_VP_INST_TEMP_WRITEMASK_MASK | \ + NV20_VP_INST_DEST_TEMP_ID_MASK | \ + NV20_VP_INST_STEMP_WRITEMASK_MASK | \ + NV20_VP_INST_DEST_WRITEMASK_MASK | \ + NV20_VP_INST_DEST_MASK | \ + NV20_VP_INST_INDEX_CONST \ + ) + +/* Useful to split the source selection regs into their pieces */ +#define NV20_VP_SRC0_HIGH_SHIFT 6 +#define NV20_VP_SRC0_HIGH_MASK 0x00007FC0 +#define NV20_VP_SRC0_LOW_MASK 0x0000003F +#define NV20_VP_SRC2_HIGH_SHIFT 4 +#define NV20_VP_SRC2_HIGH_MASK 0x00007FF0 +#define NV20_VP_SRC2_LOW_MASK 0x0000000F + +#define NV20_VP_SRC_REG_NEGATE (1<<14) +#define NV20_VP_SRC_REG_SWZ_X_SHIFT 12 +#define NV20_VP_SRC_REG_SWZ_X_MASK (0x03 <<12) +#define NV20_VP_SRC_REG_SWZ_Y_SHIFT 10 +#define NV20_VP_SRC_REG_SWZ_Y_MASK (0x03 <<10) +#define NV20_VP_SRC_REG_SWZ_Z_SHIFT 8 +#define NV20_VP_SRC_REG_SWZ_Z_MASK (0x03 << 8) +#define NV20_VP_SRC_REG_SWZ_W_SHIFT 6 +#define NV20_VP_SRC_REG_SWZ_W_MASK (0x03 << 6) +#define NV20_VP_SRC_REG_SWZ_ALL_SHIFT 6 +#define NV20_VP_SRC_REG_SWZ_ALL_MASK (0xFF << 6) +#define NV20_VP_SRC_REG_TEMP_ID_SHIFT 2 +#define NV20_VP_SRC_REG_TEMP_ID_MASK (0x0F << 0) +#define NV20_VP_SRC_REG_TYPE_SHIFT 0 +#define NV20_VP_SRC_REG_TYPE_MASK (0x03 << 0) +#define NV20_VP_SRC_REG_TYPE_TEMP 1 +#define NV20_VP_SRC_REG_TYPE_INPUT 2 +#define NV20_VP_SRC_REG_TYPE_CONST 3 /* guess */ + diff --git a/src/mesa/drivers/dri/nouveau/nv20_vertprog.c b/src/mesa/drivers/dri/nouveau/nv20_vertprog.c new file mode 100644 index 0000000000..60cfcd7056 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_vertprog.c @@ -0,0 +1,447 @@ +#include "nouveau_context.h" +#include "nouveau_object.h" +#include "nouveau_fifo.h" +#include "nouveau_reg.h" + +#include "nouveau_shader.h" +#include "nv20_shader.h" + +unsigned int NVVP_TX_VOP_COUNT = 16; +unsigned int NVVP_TX_NVS_OP_COUNT = 16; +struct _op_xlat NVVP_TX_VOP[32]; +struct _op_xlat NVVP_TX_SOP[32]; + +nvsSwzComp NV20VP_TX_SWIZZLE[4] = { NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W }; + +/***************************************************************************** + * Support routines + */ +static void +NV20VPUploadToHW(GLcontext *ctx, nouveauShader *nvs) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + int i; + + /* XXX: missing a way to say what insn we're uploading from, and possible + * the program start position (if NV20 has one) */ + for (i=0; iprogram_size; i+=4) { + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_INST0, 4); + OUT_RING(nvs->program[i + 0]); + OUT_RING(nvs->program[i + 1]); + OUT_RING(nvs->program[i + 2]); + OUT_RING(nvs->program[i + 3]); + } +} + +static void +NV20VPUpdateConst(GLcontext *ctx, nouveauShader *nvs, int id) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + /* Worth checking if the value *actually* changed? Mesa doesn't tell us this + * as far as I know.. + */ + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_ID, 1); + OUT_RING (id); + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_X, 4); + OUT_RINGf(nvs->params[id].source_val[0]); + OUT_RINGf(nvs->params[id].source_val[1]); + OUT_RINGf(nvs->params[id].source_val[2]); + OUT_RINGf(nvs->params[id].source_val[3]); +} + +/***************************************************************************** + * Assembly routines + */ + +/***************************************************************************** + * Disassembly routines + */ +void +NV20VPTXSwizzle(int hwswz, nvsSwzComp *swz) +{ + swz[NVS_SWZ_X] = NV20VP_TX_SWIZZLE[(hwswz & 0xC0) >> 6]; + swz[NVS_SWZ_Y] = NV20VP_TX_SWIZZLE[(hwswz & 0x30) >> 4]; + swz[NVS_SWZ_Z] = NV20VP_TX_SWIZZLE[(hwswz & 0x0C) >> 2]; + swz[NVS_SWZ_W] = NV20VP_TX_SWIZZLE[(hwswz & 0x03) >> 0]; +} + +static int +NV20VPHasMergedInst(nvsFunc * shader) +{ + if (shader->GetOpcodeHW(shader, 0) != NV20_VP_INST_OPCODE_NOP && + shader->GetOpcodeHW(shader, 1) != NV20_VP_INST_OPCODE_NOP) + printf + ("\n\n*****both opcode fields have values - PLEASE REPORT*****\n"); + return 0; +} + +static int +NV20VPIsLastInst(nvsFunc * shader) +{ + return ((shader->inst[3] & (1 << 0)) ? 1 : 0); +} + +static int +NV20VPGetOffsetNext(nvsFunc * shader) +{ + return 4; +} + +static struct _op_xlat * +NV20VPGetOPTXRec(nvsFunc * shader, int merged) +{ + struct _op_xlat *opr; + int op; + + if (shader->GetOpcodeSlot(shader, merged)) { + opr = NVVP_TX_SOP; + op = shader->GetOpcodeHW(shader, 1); + if (op >= NVVP_TX_NVS_OP_COUNT) + return NULL; + } + else { + opr = NVVP_TX_VOP; + op = shader->GetOpcodeHW(shader, 0); + if (op >= NVVP_TX_VOP_COUNT) + return NULL; + } + + if (opr[op].SOP == NVS_OP_UNKNOWN) + return NULL; + return &opr[op]; +} + +static struct _op_xlat * +NV20VPGetOPTXFromSOP(nvsOpcode sop, int *id) +{ + int i; + + for (i=0;iHasMergedInst(shader)) + return merged; + if (shader->GetOpcodeHW(shader, 0) == NV20_VP_INST_OPCODE_NOP) + return 1; + return 0; +} + +static nvsOpcode +NV20VPGetOpcode(nvsFunc * shader, int merged) +{ + struct _op_xlat *opr; + + opr = shader->GetOPTXRec(shader, merged); + if (!opr) + return NVS_OP_UNKNOWN; + + return opr->SOP; +} + +static nvsOpcode +NV20VPGetOpcodeHW(nvsFunc * shader, int slot) +{ + if (slot) + return (shader->inst[1] & NV20_VP_INST_SCA_OPCODE_MASK) + >> NV20_VP_INST_SCA_OPCODE_SHIFT; + return (shader->inst[1] & NV20_VP_INST_VEC_OPCODE_MASK) + >> NV20_VP_INST_VEC_OPCODE_SHIFT; +} + +static nvsRegFile +NV20VPGetDestFile(nvsFunc * shader, int merged) +{ + switch (shader->GetOpcode(shader, merged)) { + case NVS_OP_ARL: + return NVS_FILE_ADDRESS; + default: + /*FIXME: This probably isn't correct.. */ + if ((shader->inst[3] & NV20_VP_INST_DEST_WRITEMASK_MASK) == 0) + return NVS_FILE_TEMP; + return NVS_FILE_RESULT; + } +} + +static unsigned int +NV20VPGetDestID(nvsFunc * shader, int merged) +{ + int id; + + switch (shader->GetDestFile(shader, merged)) { + case NVS_FILE_RESULT: + id = ((shader->inst[3] & NV20_VP_INST_DEST_MASK) + >> NV20_VP_INST_DEST_SHIFT); + switch (id) { + case NV20_VP_INST_DEST_POS : return NVS_FR_POSITION; + case NV20_VP_INST_DEST_COL0 : return NVS_FR_COL0; + case NV20_VP_INST_DEST_COL1 : return NVS_FR_COL1; + case NV20_VP_INST_DEST_TC(0): return NVS_FR_TEXCOORD0; + case NV20_VP_INST_DEST_TC(1): return NVS_FR_TEXCOORD1; + case NV20_VP_INST_DEST_TC(2): return NVS_FR_TEXCOORD2; + case NV20_VP_INST_DEST_TC(3): return NVS_FR_TEXCOORD3; + default: + return -1; + } + case NVS_FILE_ADDRESS: + return 0; + case NVS_FILE_TEMP: + id = ((shader->inst[3] & NV20_VP_INST_DEST_TEMP_ID_MASK) + >> NV20_VP_INST_DEST_TEMP_ID_SHIFT); + return id; + default: + return -1; + } +} + +static unsigned int +NV20VPGetDestMask(nvsFunc * shader, int merged) +{ + int hwmask, mask = 0; + + /* Special handling for ARL - hardware only supports a + * 1-component address reg + */ + if (shader->GetOpcode(shader, merged) == NVS_OP_ARL) + return SMASK_X; + + if (shader->GetDestFile(shader, merged) == NVS_FILE_RESULT) + hwmask = (shader->inst[3] & NV20_VP_INST_DEST_WRITEMASK_MASK) + >> NV20_VP_INST_DEST_WRITEMASK_SHIFT; + else if (shader->GetOpcodeSlot(shader, merged)) + hwmask = (shader->inst[3] & NV20_VP_INST_STEMP_WRITEMASK_MASK) + >> NV20_VP_INST_STEMP_WRITEMASK_SHIFT; + else + hwmask = (shader->inst[3] & NV20_VP_INST_VTEMP_WRITEMASK_MASK) + >> NV20_VP_INST_VTEMP_WRITEMASK_SHIFT; + + if (hwmask & (1 << 3)) mask |= SMASK_X; + if (hwmask & (1 << 2)) mask |= SMASK_Y; + if (hwmask & (1 << 1)) mask |= SMASK_Z; + if (hwmask & (1 << 0)) mask |= SMASK_W; + + return mask; +} + +static unsigned int +NV20VPGetSourceHW(nvsFunc * shader, int merged, int pos) +{ + struct _op_xlat *opr; + unsigned int src; + + opr = shader->GetOPTXRec(shader, merged); + if (!opr) + return -1; + + switch (opr->srcpos[pos]) { + case 0: + src = ((shader->inst[1] & NV20_VP_INST_SRC0H_MASK) + >> NV20_VP_INST_SRC0H_SHIFT) + << NV20_VP_SRC0_HIGH_SHIFT; + src |= ((shader->inst[2] & NV20_VP_INST_SRC0L_MASK) + >> NV20_VP_INST_SRC0L_SHIFT); + break; + case 1: + src = ((shader->inst[2] & NV20_VP_INST_SRC1_MASK) + >> NV20_VP_INST_SRC1_SHIFT); + break; + case 2: + src = ((shader->inst[2] & NV20_VP_INST_SRC2H_MASK) + >> NV20_VP_INST_SRC2H_SHIFT) + << NV20_VP_SRC2_HIGH_SHIFT; + src |= ((shader->inst[3] & NV20_VP_INST_SRC2L_MASK) + >> NV20_VP_INST_SRC2L_SHIFT); + break; + default: + src = -1; + } + + return src; +} + +static nvsRegFile +NV20VPGetSourceFile(nvsFunc * shader, int merged, int pos) +{ + unsigned int src; + struct _op_xlat *opr; + int file; + + opr = shader->GetOPTXRec(shader, merged); + if (!opr || opr->srcpos[pos] == -1) + return -1; + + switch (opr->srcpos[pos]) { + case SPOS_ADDRESS: + return NVS_FILE_ADDRESS; + default: + src = NV20VPGetSourceHW(shader, merged, pos); + file = (src & NV20_VP_SRC_REG_TYPE_MASK) >> NV20_VP_SRC_REG_TYPE_SHIFT; + + switch (file) { + case NV20_VP_SRC_REG_TYPE_TEMP : return NVS_FILE_TEMP; + case NV20_VP_SRC_REG_TYPE_INPUT: return NVS_FILE_ATTRIB; + case NV20_VP_SRC_REG_TYPE_CONST: return NVS_FILE_CONST; + default: + return NVS_FILE_UNKNOWN; + } + } +} + +static int +NV20VPGetSourceID(nvsFunc * shader, int merged, int pos) +{ + unsigned int src; + + switch (shader->GetSourceFile(shader, merged, pos)) { + case NVS_FILE_TEMP: + src = shader->GetSourceHW(shader, merged, pos); + return ((src & NV20_VP_SRC_REG_TEMP_ID_MASK) >> + NV20_VP_SRC_REG_TEMP_ID_SHIFT); + case NVS_FILE_CONST: + return ((shader->inst[1] & NV20_VP_INST_CONST_SRC_MASK) + >> NV20_VP_INST_CONST_SRC_SHIFT); + case NVS_FILE_ATTRIB: + src = ((shader->inst[1] & NV20_VP_INST_INPUT_SRC_MASK) + >> NV20_VP_INST_INPUT_SRC_SHIFT); + switch (src) { + case NV20_VP_INST_INPUT_SRC_POS : return NVS_FR_POSITION; + case NV20_VP_INST_INPUT_SRC_COL0 : return NVS_FR_COL0; + case NV20_VP_INST_INPUT_SRC_COL1 : return NVS_FR_COL1; + case NV20_VP_INST_INPUT_SRC_TC(0): return NVS_FR_TEXCOORD0; + case NV20_VP_INST_INPUT_SRC_TC(1): return NVS_FR_TEXCOORD1; + case NV20_VP_INST_INPUT_SRC_TC(2): return NVS_FR_TEXCOORD2; + case NV20_VP_INST_INPUT_SRC_TC(3): return NVS_FR_TEXCOORD3; + default: + return NVS_FR_UNKNOWN; + } + default: + return -1; + } +} + +static int +NV20VPGetSourceNegate(nvsFunc * shader, int merged, int pos) +{ + unsigned int src; + + src = shader->GetSourceHW(shader, merged, pos); + + return ((src & NV20_VP_SRC_REG_NEGATE) ? 1 : 0); +} + +static int +NV20VPGetSourceAbs(nvsFunc * shader, int merged, int pos) +{ + /* NV20 can't do ABS on sources? Appears to be emulated with + * MAX reg, reg, -reg + */ + return 0; +} + +static void +NV20VPGetSourceSwizzle(nvsFunc * shader, int merged, int pos, nvsSwzComp *swz) +{ + unsigned int src; + int swzbits; + + src = shader->GetSourceHW(shader, merged, pos); + swzbits = + (src & NV20_VP_SRC_REG_SWZ_ALL_MASK) >> NV20_VP_SRC_REG_SWZ_ALL_SHIFT; + return NV20VPTXSwizzle(swzbits, swz); +} + +static int +NV20VPGetSourceIndexed(nvsFunc * shader, int merged, int pos) +{ + /* I don't think NV20 can index into attribs, at least no GL + * extension is exposed that will allow it. + */ + if (shader->GetSourceFile(shader, merged, pos) != NVS_FILE_CONST) + return 0; + if (shader->inst[3] & NV20_VP_INST_INDEX_CONST) + return 1; + return 0; +} + +static int +NV20VPGetAddressRegID(nvsFunc * shader) +{ + /* Only 1 address reg */ + return 0; +} + +static nvsSwzComp +NV20VPGetAddressRegSwizzle(nvsFunc * shader) +{ + /* Only A0.x available */ + return NVS_SWZ_X; +} + +void +NV20VPInitShaderFuncs(nvsFunc * shader) +{ + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_NOP, NVS_OP_NOP, -1, -1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_MOV, NVS_OP_MOV, 0, -1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_MUL, NVS_OP_MUL, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_ADD, NVS_OP_ADD, 0, 2, -1); + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_MAD, NVS_OP_MAD, 0, 1, 2); + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_DP3, NVS_OP_DP3, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_DPH, NVS_OP_DPH, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_DP4, NVS_OP_DP4, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_DST, NVS_OP_DST, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_MIN, NVS_OP_MIN, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_MAX, NVS_OP_MAX, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_SLT, NVS_OP_SLT, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_SGE, NVS_OP_SGE, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_ARL, NVS_OP_ARL, 0, -1, -1); + + MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_NOP, NVS_OP_NOP, -1, -1, -1); + MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_RCP, NVS_OP_RCP, 2, -1, -1); + MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_RCC, NVS_OP_RCC, 2, -1, -1); + MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_RSQ, NVS_OP_RSQ, 2, -1, -1); + MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_EXP, NVS_OP_EXP, 2, -1, -1); + MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_LOG, NVS_OP_LOG, 2, -1, -1); + MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_LIT, NVS_OP_LIT, 2, -1, -1); + + shader->UploadToHW = NV20VPUploadToHW; + shader->UpdateConst = NV20VPUpdateConst; + + shader->GetOPTXRec = NV20VPGetOPTXRec; + shader->GetOPTXFromSOP = NV20VPGetOPTXFromSOP; + + shader->HasMergedInst = NV20VPHasMergedInst; + shader->IsLastInst = NV20VPIsLastInst; + shader->GetOffsetNext = NV20VPGetOffsetNext; + shader->GetOpcodeSlot = NV20VPGetOpcodeSlot; + shader->GetOpcode = NV20VPGetOpcode; + shader->GetOpcodeHW = NV20VPGetOpcodeHW; + shader->GetDestFile = NV20VPGetDestFile; + shader->GetDestID = NV20VPGetDestID; + shader->GetDestMask = NV20VPGetDestMask; + shader->GetSourceHW = NV20VPGetSourceHW; + shader->GetSourceFile = NV20VPGetSourceFile; + shader->GetSourceID = NV20VPGetSourceID; + shader->GetSourceNegate = NV20VPGetSourceNegate; + shader->GetSourceAbs = NV20VPGetSourceAbs; + shader->GetSourceSwizzle = NV20VPGetSourceSwizzle; + shader->GetSourceIndexed = NV20VPGetSourceIndexed; + shader->GetRelAddressRegID = NV20VPGetAddressRegID; + shader->GetRelAddressSwizzle = NV20VPGetAddressRegSwizzle; +} diff --git a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c new file mode 100644 index 0000000000..2e35d08c07 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c @@ -0,0 +1,707 @@ +#include + +#include "glheader.h" +#include "macros.h" + +#include "nouveau_context.h" +#include "nouveau_fifo.h" +#include "nouveau_reg.h" +#include "nouveau_drm.h" +#include "nouveau_shader.h" +#include "nouveau_object.h" +#include "nouveau_msg.h" +#include "nv30_shader.h" + +unsigned int NVFP_TX_AOP_COUNT = 64; +struct _op_xlat NVFP_TX_AOP[64]; + +/******************************************************************************* + * Support routines + */ + +/*XXX: bad bad bad bad */ +static uint64_t fragprog_ofs; +static uint32_t *fragprog_buf = NULL; + +static void +NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + drm_nouveau_mem_alloc_t mem; + + if (!fragprog_buf) { + mem.flags = NOUVEAU_MEM_FB|NOUVEAU_MEM_MAPPED; + mem.size = nvs->program_size * sizeof(uint32_t); + mem.alignment = 0; + mem.region_offset = &fragprog_ofs; + if (drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_MEM_ALLOC, &mem, + sizeof(mem))) { + fprintf(stderr, "MEM_ALLOC fail\n"); + return; + } + + if (drmMap(nmesa->driFd, fragprog_ofs, mem.size, &fragprog_buf)) { + fprintf(stderr, "MEM_MAP fail\n"); + return; + } + } + + /*XXX: should do a DMA.. and not copy over a possibly in-use program.. */ + /* not using state cache here, updated programs at the same address + * seem to not take effect unless ACTIVE_PROGRAM is called again. hw + * caches the program somewhere? so, maybe not so bad to just clobber the + * old program in vram.. + */ + memcpy(fragprog_buf, nvs->program, nvs->program_size * sizeof(uint32_t)); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM, 1); + OUT_RING(((uint32_t)fragprog_ofs-0xE0000000)|1); +} + +static void +NV30FPUpdateConst(GLcontext *ctx, nouveauShader *nvs, int id) +{ + uint32_t *current = nvs->program + nvs->params[id].hw_index; + uint32_t *new = nvs->params[id].source_val ? + nvs->params[id].source_val : nvs->params[id].val; + + COPY_4V(current, new); + nvs->on_hardware = 0; +} + +/******************************************************************************* + * Assembly helpers + */ +static struct _op_xlat * +NV30FPGetOPTXFromSOP(nvsOpcode op, int *id) +{ + int i; + + for (i=0; iGetOPTXFromSOP(op, NULL)) + return 1; + return 0; +} + +static void +NV30FPSetOpcode(nvsFunc *shader, unsigned int opcode, int slot) +{ + shader->inst[0] |= (opcode << NV30_FP_OP_OPCODE_SHIFT); +} + +static void +NV30FPSetCCUpdate(nvsFunc *shader) +{ + shader->inst[0] |= NV30_FP_OP_COND_WRITE_ENABLE; +} + +static void +NV30FPSetCondition(nvsFunc *shader, int on, nvsCond cond, int reg, + nvsSwzComp *swz) +{ + nvsSwzComp default_swz[4] = { NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W }; + unsigned int hwcond; + + /* cond masking is always enabled */ + if (!on) { + cond = NVS_COND_TR; + reg = 0; + swz = default_swz; + } + + switch (cond) { + case NVS_COND_TR: hwcond = NV30_FP_OP_COND_TR; break; + case NVS_COND_FL: hwcond = NV30_FP_OP_COND_FL; break; + case NVS_COND_LT: hwcond = NV30_FP_OP_COND_LT; break; + case NVS_COND_GT: hwcond = NV30_FP_OP_COND_GT; break; + case NVS_COND_LE: hwcond = NV30_FP_OP_COND_LE; break; + case NVS_COND_GE: hwcond = NV30_FP_OP_COND_GE; break; + case NVS_COND_EQ: hwcond = NV30_FP_OP_COND_EQ; break; + case NVS_COND_NE: hwcond = NV30_FP_OP_COND_NE; break; + default: + WARN_ONCE("unknown fp condmask=%d\n", cond); + hwcond = NV30_FP_OP_COND_TR; + break; + } + + shader->inst[1] |= (hwcond << NV30_FP_OP_COND_SHIFT); + shader->inst[1] |= (swz[NVS_SWZ_X] << NV30_FP_OP_COND_SWZ_X_SHIFT); + shader->inst[1] |= (swz[NVS_SWZ_Y] << NV30_FP_OP_COND_SWZ_Y_SHIFT); + shader->inst[1] |= (swz[NVS_SWZ_Z] << NV30_FP_OP_COND_SWZ_Z_SHIFT); + shader->inst[1] |= (swz[NVS_SWZ_W] << NV30_FP_OP_COND_SWZ_W_SHIFT); +} + +static void +NV30FPSetResult(nvsFunc *shader, nvsRegister *reg, unsigned int mask, int slot) +{ + unsigned int hwreg, hwmask = 0; + + if (mask & SMASK_X) shader->inst[0] |= NV30_FP_OP_OUT_X; + if (mask & SMASK_Y) shader->inst[0] |= NV30_FP_OP_OUT_Y; + if (mask & SMASK_Z) shader->inst[0] |= NV30_FP_OP_OUT_Z; + if (mask & SMASK_W) shader->inst[0] |= NV30_FP_OP_OUT_W; + + if (reg->file == NVS_FILE_RESULT) { + hwreg = 0; /* FIXME: this is only fragment.color */ + /* This is *not* correct, I have no idea what it is either */ + shader->inst[0] |= NV30_FP_OP_UNK0_7; + } else + hwreg = reg->index; + shader->inst[0] |= (hwreg << NV30_FP_OP_OUT_REG_SHIFT); +} + +static void +NV30FPSetSource(nvsFunc *shader, nvsRegister *reg, int pos) +{ + unsigned int hwsrc = 0; + + switch (reg->file) { + case NVS_FILE_TEMP: + hwsrc |= (NV30_FP_REG_TYPE_TEMP << NV30_FP_REG_TYPE_SHIFT); + hwsrc |= (reg->index << NV30_FP_REG_SRC_SHIFT); + break; + case NVS_FILE_ATTRIB: + { + unsigned int hwin; + + switch (reg->index) { + case NVS_FR_POSITION : hwin = NV30_FP_OP_INPUT_SRC_POSITION; break; + case NVS_FR_COL0 : hwin = NV30_FP_OP_INPUT_SRC_COL0; break; + case NVS_FR_COL1 : hwin = NV30_FP_OP_INPUT_SRC_COL1; break; + case NVS_FR_FOGCOORD : hwin = NV30_FP_OP_INPUT_SRC_FOGC; break; + case NVS_FR_TEXCOORD0: hwin = NV30_FP_OP_INPUT_SRC_TC(0); break; + case NVS_FR_TEXCOORD1: hwin = NV30_FP_OP_INPUT_SRC_TC(1); break; + case NVS_FR_TEXCOORD2: hwin = NV30_FP_OP_INPUT_SRC_TC(2); break; + case NVS_FR_TEXCOORD3: hwin = NV30_FP_OP_INPUT_SRC_TC(3); break; + case NVS_FR_TEXCOORD4: hwin = NV30_FP_OP_INPUT_SRC_TC(4); break; + case NVS_FR_TEXCOORD5: hwin = NV30_FP_OP_INPUT_SRC_TC(5); break; + case NVS_FR_TEXCOORD6: hwin = NV30_FP_OP_INPUT_SRC_TC(6); break; + case NVS_FR_TEXCOORD7: hwin = NV30_FP_OP_INPUT_SRC_TC(7); break; + default: + WARN_ONCE("unknown fp input %d\n", reg->index); + hwin = NV30_FP_OP_INPUT_SRC_COL0; + break; + } + shader->inst[0] |= (hwin << NV30_FP_OP_INPUT_SRC_SHIFT); + hwsrc |= (hwin << NV30_FP_REG_SRC_SHIFT); + } + hwsrc |= (NV30_FP_REG_TYPE_INPUT << NV30_FP_REG_TYPE_SHIFT); + break; + case NVS_FILE_CONST: + /* consts are inlined after the inst */ + hwsrc |= (NV30_FP_REG_TYPE_CONST << NV30_FP_REG_TYPE_SHIFT); + break; + default: + assert(0); + break; + } + + if (reg->negate) + hwsrc |= NV30_FP_REG_NEGATE; + if (reg->abs) + shader->inst[1] |= (1 << (29+pos)); + hwsrc |= (reg->swizzle[NVS_SWZ_X] << NV30_FP_REG_SWZ_X_SHIFT); + hwsrc |= (reg->swizzle[NVS_SWZ_Y] << NV30_FP_REG_SWZ_Y_SHIFT); + hwsrc |= (reg->swizzle[NVS_SWZ_Z] << NV30_FP_REG_SWZ_Z_SHIFT); + hwsrc |= (reg->swizzle[NVS_SWZ_W] << NV30_FP_REG_SWZ_W_SHIFT); + + shader->inst[pos+1] |= hwsrc; +} + +static void +NV30FPSetUnusedSource(nvsFunc *shader, int pos) +{ + shader->inst[pos+1] |= ( + (NV30_FP_REG_TYPE_INPUT << NV30_FP_REG_TYPE_SHIFT) | + (NVS_SWZ_X << NV30_FP_REG_SWZ_X_SHIFT) | + (NVS_SWZ_Y << NV30_FP_REG_SWZ_Y_SHIFT) | + (NVS_SWZ_Z << NV30_FP_REG_SWZ_Z_SHIFT) | + (NVS_SWZ_W << NV30_FP_REG_SWZ_W_SHIFT) + ); +} + +static void +NV30FPSetTexImageUnit(nvsFunc *shader, int unit) +{ + shader->inst[0] |= (unit << NV30_FP_OP_TEX_UNIT_SHIFT); +} + +static void +NV30FPSetSaturate(nvsFunc *shader) +{ + shader->inst[0] |= NV30_FP_OP_OUT_SAT; +} + +static void +NV30FPSetLastInst(nvsFunc *shader) +{ + shader->inst[0] |= 1; + +} + +/******************************************************************************* + * Disassembly helpers + */ +static struct _op_xlat * +NV30FPGetOPTXRec(nvsFunc * shader, int merged) +{ + int op; + + op = shader->GetOpcodeHW(shader, 0); + if (op > NVFP_TX_AOP_COUNT) + return NULL; + if (NVFP_TX_AOP[op].SOP == NVS_OP_UNKNOWN) + return NULL; + return &NVFP_TX_AOP[op]; +} + +static int +NV30FPHasMergedInst(nvsFunc * shader) +{ + return 0; +} + +static int +NV30FPIsLastInst(nvsFunc * shader) +{ + return ((shader->inst[0] & NV30_FP_OP_PROGRAM_END) ? 1 : 0); +} + +static int +NV30FPGetOffsetNext(nvsFunc * shader) +{ + int i; + + for (i = 0; i < 3; i++) + if (shader->GetSourceFile(shader, 0, i) == NVS_FILE_CONST) + return 8; + return 4; +} + +static nvsOpcode +NV30FPGetOpcode(nvsFunc * shader, int merged) +{ + struct _op_xlat *opr; + + opr = shader->GetOPTXRec(shader, merged); + if (!opr) + return NVS_OP_UNKNOWN; + + return opr->SOP; +} + +static unsigned int +NV30FPGetOpcodeHW(nvsFunc * shader, int slot) +{ + int op; + + op = (shader->inst[0] & NV30_FP_OP_OPCODE_MASK) >> NV30_FP_OP_OPCODE_SHIFT; + + return op; +} + +static nvsRegFile +NV30FPGetDestFile(nvsFunc * shader, int merged) +{ + /* Result regs overlap temporary regs */ + return NVS_FILE_TEMP; +} + +static unsigned int +NV30FPGetDestID(nvsFunc * shader, int merged) +{ + int id; + + switch (shader->GetDestFile(shader, merged)) { + case NVS_FILE_TEMP: + id = ((shader->inst[0] & NV30_FP_OP_OUT_REG_MASK) + >> NV30_FP_OP_OUT_REG_SHIFT); + return id; + default: + return -1; + } +} + +static unsigned int +NV30FPGetDestMask(nvsFunc * shader, int merged) +{ + unsigned int mask = 0; + + if (shader->inst[0] & NV30_FP_OP_OUT_X) mask |= SMASK_X; + if (shader->inst[0] & NV30_FP_OP_OUT_Y) mask |= SMASK_Y; + if (shader->inst[0] & NV30_FP_OP_OUT_Z) mask |= SMASK_Z; + if (shader->inst[0] & NV30_FP_OP_OUT_W) mask |= SMASK_W; + + return mask; +} + +static unsigned int +NV30FPGetSourceHW(nvsFunc * shader, int merged, int pos) +{ + struct _op_xlat *opr; + + opr = shader->GetOPTXRec(shader, merged); + if (!opr || opr->srcpos[pos] == -1) + return -1; + + return shader->inst[opr->srcpos[pos] + 1]; +} + +static nvsRegFile +NV30FPGetSourceFile(nvsFunc * shader, int merged, int pos) +{ + unsigned int src; + struct _op_xlat *opr; + int file; + + opr = shader->GetOPTXRec(shader, merged); + if (!opr || opr->srcpos[pos] == -1) + return NVS_FILE_UNKNOWN; + + switch (opr->srcpos[pos]) { + case SPOS_ADDRESS: return NVS_FILE_ADDRESS; + default: + src = shader->GetSourceHW(shader, merged, pos); + file = (src & NV30_FP_REG_TYPE_MASK) >> NV30_FP_REG_TYPE_SHIFT; + + switch (file) { + case NV30_FP_REG_TYPE_TEMP : return NVS_FILE_TEMP; + case NV30_FP_REG_TYPE_INPUT: return NVS_FILE_ATTRIB; + case NV30_FP_REG_TYPE_CONST: return NVS_FILE_CONST; + default: + return NVS_FILE_UNKNOWN; + } + } +} + +static int +NV30FPGetSourceID(nvsFunc * shader, int merged, int pos) +{ + switch (shader->GetSourceFile(shader, merged, pos)) { + case NVS_FILE_ATTRIB: + switch ((shader->inst[0] & NV30_FP_OP_INPUT_SRC_MASK) + >> NV30_FP_OP_INPUT_SRC_SHIFT) { + case NV30_FP_OP_INPUT_SRC_POSITION: return NVS_FR_POSITION; + case NV30_FP_OP_INPUT_SRC_COL0 : return NVS_FR_COL0; + case NV30_FP_OP_INPUT_SRC_COL1 : return NVS_FR_COL1; + case NV30_FP_OP_INPUT_SRC_FOGC : return NVS_FR_FOGCOORD; + case NV30_FP_OP_INPUT_SRC_TC(0) : return NVS_FR_TEXCOORD0; + case NV30_FP_OP_INPUT_SRC_TC(1) : return NVS_FR_TEXCOORD1; + case NV30_FP_OP_INPUT_SRC_TC(2) : return NVS_FR_TEXCOORD2; + case NV30_FP_OP_INPUT_SRC_TC(3) : return NVS_FR_TEXCOORD3; + case NV30_FP_OP_INPUT_SRC_TC(4) : return NVS_FR_TEXCOORD4; + case NV30_FP_OP_INPUT_SRC_TC(5) : return NVS_FR_TEXCOORD5; + case NV30_FP_OP_INPUT_SRC_TC(6) : return NVS_FR_TEXCOORD6; + case NV30_FP_OP_INPUT_SRC_TC(7) : return NVS_FR_TEXCOORD7; + default: + return -1; + } + break; + case NVS_FILE_TEMP: + { + unsigned int src; + + src = shader->GetSourceHW(shader, merged, pos); + return ((src & NV30_FP_REG_SRC_MASK) >> NV30_FP_REG_SRC_SHIFT); + } + case NVS_FILE_CONST: /* inlined into fragprog */ + default: + return -1; + } +} + +static int +NV30FPGetTexImageUnit(nvsFunc *shader) +{ + return ((shader->inst[0] & NV30_FP_OP_TEX_UNIT_MASK) + >> NV30_FP_OP_TEX_UNIT_SHIFT); +} + +static int +NV30FPGetSourceNegate(nvsFunc * shader, int merged, int pos) +{ + unsigned int src; + + src = shader->GetSourceHW(shader, merged, pos); + + if (src == -1) + return -1; + return ((src & NV30_FP_REG_NEGATE) ? 1 : 0); +} + +static int +NV30FPGetSourceAbs(nvsFunc * shader, int merged, int pos) +{ + struct _op_xlat *opr; + static unsigned int abspos[3] = { + NV30_FP_OP_OUT_ABS, + (1 << 30), /* guess */ + (1 << 31) /* guess */ + }; + + opr = shader->GetOPTXRec(shader, merged); + if (!opr || opr->srcpos[pos] == -1) + return -1; + + return ((shader->inst[1] & abspos[opr->srcpos[pos]]) ? 1 : 0); +} + +nvsSwzComp NV30FP_TX_SWIZZLE[4] = {NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W }; + +static void +NV30FPTXSwizzle(int hwswz, nvsSwzComp *swz) +{ + swz[NVS_SWZ_W] = NV30FP_TX_SWIZZLE[(hwswz & 0xC0) >> 6]; + swz[NVS_SWZ_Z] = NV30FP_TX_SWIZZLE[(hwswz & 0x30) >> 4]; + swz[NVS_SWZ_Y] = NV30FP_TX_SWIZZLE[(hwswz & 0x0C) >> 2]; + swz[NVS_SWZ_X] = NV30FP_TX_SWIZZLE[(hwswz & 0x03) >> 0]; +} + +static void +NV30FPGetSourceSwizzle(nvsFunc * shader, int merged, int pos, nvsSwzComp *swz) +{ + unsigned int src; + int swzbits; + + src = shader->GetSourceHW(shader, merged, pos); + swzbits = (src & NV30_FP_REG_SWZ_ALL_MASK) >> NV30_FP_REG_SWZ_ALL_SHIFT; + NV30FPTXSwizzle(swzbits, swz); +} + +static int +NV30FPGetSourceIndexed(nvsFunc * shader, int merged, int pos) +{ + switch (shader->GetSourceFile(shader, merged, pos)) { + case NVS_FILE_ATTRIB: + return ((shader->inst[3] & NV30_FP_OP_INDEX_INPUT) ? 1 : 0); + default: + return 0; + } +} + +static void +NV30FPGetSourceConstVal(nvsFunc * shader, int merged, int pos, float *val) +{ + val[0] = *(float *) &(shader->inst[4]); + val[1] = *(float *) &(shader->inst[5]); + val[2] = *(float *) &(shader->inst[6]); + val[3] = *(float *) &(shader->inst[7]); +} + +static int +NV30FPGetSourceScale(nvsFunc * shader, int merged, int pos) +{ +/*FIXME: is this per-source, only for a specific source, or all sources??*/ + return (1 << ((shader->inst[2] & NV30_FP_OP_SRC_SCALE_MASK) + >> NV30_FP_OP_SRC_SCALE_SHIFT)); +} + +static int +NV30FPGetAddressRegID(nvsFunc * shader) +{ + return 0; +} + +static nvsSwzComp +NV30FPGetAddressRegSwizzle(nvsFunc * shader) +{ + return NVS_SWZ_X; +} + +static int +NV30FPSupportsConditional(nvsFunc * shader) +{ + /*FIXME: Is this true of all ops? */ + return 1; +} + +static int +NV30FPGetConditionUpdate(nvsFunc * shader) +{ + return ((shader->inst[0] & NV30_FP_OP_COND_WRITE_ENABLE) ? 1 : 0); +} + +static int +NV30FPGetConditionTest(nvsFunc * shader) +{ + /*FIXME: always? */ + return 1; +} + +static nvsCond +NV30FPGetCondition(nvsFunc * shader) +{ + int cond; + + cond = ((shader->inst[1] & NV30_FP_OP_COND_MASK) + >> NV30_FP_OP_COND_SHIFT); + + switch (cond) { + case NV30_FP_OP_COND_FL: return NVS_COND_FL; + case NV30_FP_OP_COND_LT: return NVS_COND_LT; + case NV30_FP_OP_COND_EQ: return NVS_COND_EQ; + case NV30_FP_OP_COND_LE: return NVS_COND_LE; + case NV30_FP_OP_COND_GT: return NVS_COND_GT; + case NV30_FP_OP_COND_NE: return NVS_COND_NE; + case NV30_FP_OP_COND_GE: return NVS_COND_GE; + case NV30_FP_OP_COND_TR: return NVS_COND_TR; + default: + return NVS_COND_UNKNOWN; + } +} + +static void +NV30FPGetCondRegSwizzle(nvsFunc * shader, nvsSwzComp *swz) +{ + int swzbits; + + swzbits = (shader->inst[1] & NV30_FP_OP_COND_SWZ_ALL_MASK) + >> NV30_FP_OP_COND_SWZ_ALL_SHIFT; + NV30FPTXSwizzle(swzbits, swz); +} + +static int +NV30FPGetCondRegID(nvsFunc * shader) +{ + return 0; +} + +static nvsPrecision +NV30FPGetPrecision(nvsFunc * shader) +{ + int p; + + p = (shader->inst[0] & NV30_FP_OP_PRECISION_MASK) + >> NV30_FP_OP_PRECISION_SHIFT; + + switch (p) { + case NV30_FP_PRECISION_FP32: return NVS_PREC_FLOAT32; + case NV30_FP_PRECISION_FP16: return NVS_PREC_FLOAT16; + case NV30_FP_PRECISION_FX12: return NVS_PREC_FIXED12; + default: + return NVS_PREC_UNKNOWN; + } +} + +static int +NV30FPGetSaturate(nvsFunc * shader) +{ + return ((shader->inst[0] & NV30_FP_OP_OUT_SAT) ? 1 : 0); +} + +/******************************************************************************* + * Init + */ +void +NV30FPInitShaderFuncs(nvsFunc * shader) +{ + /* These are probably bogus, I made them up... */ + shader->MaxInst = 1024; + shader->MaxAttrib = 16; + shader->MaxTemp = 32; + shader->MaxAddress = 1; + shader->MaxConst = 256; + shader->caps = SCAP_SRC_ABS; + + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MOV, NVS_OP_MOV, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MUL, NVS_OP_MUL, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_ADD, NVS_OP_ADD, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MAD, NVS_OP_MAD, 0, 1, 2); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DP3, NVS_OP_DP3, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DP4, NVS_OP_DP4, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DST, NVS_OP_DST, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MIN, NVS_OP_MIN, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MAX, NVS_OP_MAX, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SLT, NVS_OP_SLT, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SGE, NVS_OP_SGE, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_FRC, NVS_OP_FRC, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_FLR, NVS_OP_FLR, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TEX, NVS_OP_TEX, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TXD, NVS_OP_TXD, 0, 1, 2); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TXP, NVS_OP_TXP, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TXB, NVS_OP_TXB, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SEQ, NVS_OP_SEQ, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SGT, NVS_OP_SGT, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SLE, NVS_OP_SLE, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SNE, NVS_OP_SNE, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_RCP, NVS_OP_RCP, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_LG2, NVS_OP_LG2, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_EX2, NVS_OP_EX2, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_COS, NVS_OP_COS, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SIN, NVS_OP_SIN, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_NOP, NVS_OP_NOP, -1, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DDX, NVS_OP_DDX, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DDY, NVS_OP_DDY, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_KIL, NVS_OP_KIL, -1, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK4B, NVS_OP_PK4B, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP4B, NVS_OP_UP4B, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK2H, NVS_OP_PK2H, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP2H, NVS_OP_UP2H, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK4UB, NVS_OP_PK4UB, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP4UB, NVS_OP_UP4UB, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK2US, NVS_OP_PK2US, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP2US, NVS_OP_UP2US, 0, -1, -1); + /*FIXME: Haven't confirmed the source positions for the below opcodes */ + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_LIT, NVS_OP_LIT, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_LRP, NVS_OP_LRP, 0, 1, 2); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_POW, NVS_OP_POW, 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_RSQ, NVS_OP_RSQ, 0, -1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_RFL, NVS_OP_RFL, 0, 1, -1); + + shader->GetOPTXRec = NV30FPGetOPTXRec; + shader->GetOPTXFromSOP = NV30FPGetOPTXFromSOP; + + shader->UploadToHW = NV30FPUploadToHW; + shader->UpdateConst = NV30FPUpdateConst; + + shader->SupportsOpcode = NV30FPSupportsOpcode; + shader->SetOpcode = NV30FPSetOpcode; + shader->SetCCUpdate = NV30FPSetCCUpdate; + shader->SetCondition = NV30FPSetCondition; + shader->SetResult = NV30FPSetResult; + shader->SetSource = NV30FPSetSource; + shader->SetUnusedSource = NV30FPSetUnusedSource; + shader->SetTexImageUnit = NV30FPSetTexImageUnit; + shader->SetSaturate = NV30FPSetSaturate; + shader->SetLastInst = NV30FPSetLastInst; + + shader->HasMergedInst = NV30FPHasMergedInst; + shader->IsLastInst = NV30FPIsLastInst; + shader->GetOffsetNext = NV30FPGetOffsetNext; + shader->GetOpcode = NV30FPGetOpcode; + shader->GetOpcodeHW = NV30FPGetOpcodeHW; + shader->GetDestFile = NV30FPGetDestFile; + shader->GetDestID = NV30FPGetDestID; + shader->GetDestMask = NV30FPGetDestMask; + shader->GetSourceHW = NV30FPGetSourceHW; + shader->GetSourceFile = NV30FPGetSourceFile; + shader->GetSourceID = NV30FPGetSourceID; + shader->GetTexImageUnit = NV30FPGetTexImageUnit; + shader->GetSourceNegate = NV30FPGetSourceNegate; + shader->GetSourceAbs = NV30FPGetSourceAbs; + shader->GetSourceSwizzle = NV30FPGetSourceSwizzle; + shader->GetSourceIndexed = NV30FPGetSourceIndexed; + shader->GetSourceConstVal = NV30FPGetSourceConstVal; + shader->GetSourceScale = NV30FPGetSourceScale; + shader->GetRelAddressRegID = NV30FPGetAddressRegID; + shader->GetRelAddressSwizzle = NV30FPGetAddressRegSwizzle; + shader->GetPrecision = NV30FPGetPrecision; + shader->GetSaturate = NV30FPGetSaturate; + shader->SupportsConditional = NV30FPSupportsConditional; + shader->GetConditionUpdate = NV30FPGetConditionUpdate; + shader->GetConditionTest = NV30FPGetConditionTest; + shader->GetCondition = NV30FPGetCondition; + shader->GetCondRegSwizzle = NV30FPGetCondRegSwizzle; + shader->GetCondRegID = NV30FPGetCondRegID; +} diff --git a/src/mesa/drivers/dri/nouveau/nv30_shader.h b/src/mesa/drivers/dri/nouveau/nv30_shader.h new file mode 100644 index 0000000000..d0bf639930 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv30_shader.h @@ -0,0 +1,378 @@ +#ifndef __NV30_SHADER_H__ +#define __NV30_SHADER_H__ + +/* Vertex programs instruction set + * + * 128bit opcodes, split into 4 32-bit ones for ease of use. + * + * Non-native instructions + * ABS - MOV + NV40_VP_INST0_DEST_ABS + * POW - EX2 + MUL + LG2 + * SUB - ADD, second source negated + * SWZ - MOV + * XPD - + * + * Register access + * - Only one INPUT can be accessed per-instruction (move extras into TEMPs) + * - Only one CONST can be accessed per-instruction (move extras into TEMPs) + * + * Relative Addressing + * According to the value returned for MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB + * there are only two address registers available. The destination in the ARL + * instruction is set to TEMP (The temp isn't actually written). + * + * When using vanilla ARB_v_p, the proprietary driver will squish both the available + * ADDRESS regs into the first hardware reg in the X and Y components. + * + * To use an address reg as an index into consts, the CONST_SRC is set to + * (const_base + offset) and INDEX_CONST is set. + * + * To access the second address reg use ADDR_REG_SELECT_1. A particular component + * of the address regs is selected with ADDR_SWZ. + * + * Only one address register can be accessed per instruction. + * + * Conditional execution (see NV_vertex_program{2,3} for details) + * Conditional execution of an instruction is enabled by setting COND_TEST_ENABLE, and + * selecting the condition which will allow the test to pass with COND_{FL,LT,...}. + * It is possible to swizzle the values in the condition register, which allows for + * testing against an individual component. + * + * Branching + * The BRA/CAL instructions seem to follow a slightly different opcode layout. The + * destination instruction ID (IADDR) overlaps a source field. Instruction ID's seem to + * be numbered based on the UPLOAD_FROM_ID FIFO command, and is incremented automatically + * on each UPLOAD_INST FIFO command. + * + * Conditional branching is achieved by using the condition tests described above. + * There doesn't appear to be dedicated looping instructions, but this can be done + * using a temp reg + conditional branching. + * + * Subroutines may be uploaded before the main program itself, but the first executed + * instruction is determined by the PROGRAM_START_ID FIFO command. + * + */ + +/* DWORD 0 */ +#define NV30_VP_INST_ADDR_REG_SELECT_1 (1 << 24) +#define NV30_VP_INST_SRC2_ABS (1 << 23) /* guess */ +#define NV30_VP_INST_SRC1_ABS (1 << 22) /* guess */ +#define NV30_VP_INST_SRC0_ABS (1 << 21) /* guess */ +#define NV30_VP_INST_OUT_RESULT (1 << 20) +#define NV30_VP_INST_DEST_TEMP_ID_SHIFT 16 +#define NV30_VP_INST_DEST_TEMP_ID_MASK (0x0F << 16) +#define NV30_VP_INST_COND_UPDATE_ENABLE (1<<15) +#define NV30_VP_INST_COND_TEST_ENABLE (1<<14) +#define NV30_VP_INST_COND_SHIFT 11 +#define NV30_VP_INST_COND_MASK (0x07 << 11) +# define NV30_VP_INST_COND_FL 0 /* guess */ +# define NV30_VP_INST_COND_LT 1 +# define NV30_VP_INST_COND_EQ 2 +# define NV30_VP_INST_COND_LE 3 +# define NV30_VP_INST_COND_GT 4 +# define NV30_VP_INST_COND_NE 5 +# define NV30_VP_INST_COND_GE 6 +# define NV30_VP_INST_COND_TR 7 /* guess */ +#define NV30_VP_INST_COND_SWZ_X_SHIFT 9 +#define NV30_VP_INST_COND_SWZ_X_MASK (0x03 << 9) +#define NV30_VP_INST_COND_SWZ_Y_SHIFT 7 +#define NV30_VP_INST_COND_SWZ_Y_MASK (0x03 << 7) +#define NV30_VP_INST_COND_SWZ_Z_SHIFT 5 +#define NV30_VP_INST_COND_SWZ_Z_MASK (0x03 << 5) +#define NV30_VP_INST_COND_SWZ_W_SHIFT 3 +#define NV30_VP_INST_COND_SWZ_W_MASK (0x03 << 3) +#define NV30_VP_INST_COND_SWZ_ALL_SHIFT 3 +#define NV30_VP_INST_COND_SWZ_ALL_MASK (0xFF << 3) +#define NV30_VP_INST_ADDR_SWZ_SHIFT 1 +#define NV30_VP_INST_ADDR_SWZ_MASK (0x03 << 1) +#define NV30_VP_INST_SCA_OPCODEH_SHIFT 0 +#define NV30_VP_INST_SCA_OPCODEH_MASK (0x01 << 0) + +/* DWORD 1 */ +#define NV30_VP_INST_SCA_OPCODEL_SHIFT 28 +#define NV30_VP_INST_SCA_OPCODEL_MASK (0x0F << 28) +# define NV30_VP_INST_OP_NOP 0x00 +# define NV30_VP_INST_OP_RCP 0x02 +# define NV30_VP_INST_OP_RCC 0x03 +# define NV30_VP_INST_OP_RSQ 0x04 +# define NV30_VP_INST_OP_EXP 0x05 +# define NV30_VP_INST_OP_LOG 0x06 +# define NV30_VP_INST_OP_LIT 0x07 +# define NV30_VP_INST_OP_BRA 0x09 +# define NV30_VP_INST_OP_CAL 0x0B +# define NV30_VP_INST_OP_RET 0x0C +# define NV30_VP_INST_OP_LG2 0x0D +# define NV30_VP_INST_OP_EX2 0x0E +# define NV30_VP_INST_OP_SIN 0x0F +# define NV30_VP_INST_OP_COS 0x10 +#define NV30_VP_INST_VEC_OPCODE_SHIFT 23 +#define NV30_VP_INST_VEC_OPCODE_MASK (0x1F << 23) +# define NV30_VP_INST_OP_NOPV 0x00 +# define NV30_VP_INST_OP_MOV 0x01 +# define NV30_VP_INST_OP_MUL 0x02 +# define NV30_VP_INST_OP_ADD 0x03 +# define NV30_VP_INST_OP_MAD 0x04 +# define NV30_VP_INST_OP_DP3 0x05 +# define NV30_VP_INST_OP_DP4 0x07 +# define NV30_VP_INST_OP_DPH 0x06 +# define NV30_VP_INST_OP_DST 0x08 +# define NV30_VP_INST_OP_MIN 0x09 +# define NV30_VP_INST_OP_MAX 0x0A +# define NV30_VP_INST_OP_SLT 0x0B +# define NV30_VP_INST_OP_SGE 0x0C +# define NV30_VP_INST_OP_ARL 0x0D +# define NV30_VP_INST_OP_FRC 0x0E +# define NV30_VP_INST_OP_FLR 0x0F +# define NV30_VP_INST_OP_SEQ 0x10 +# define NV30_VP_INST_OP_SFL 0x11 +# define NV30_VP_INST_OP_SGT 0x12 +# define NV30_VP_INST_OP_SLE 0x13 +# define NV30_VP_INST_OP_SNE 0x14 +# define NV30_VP_INST_OP_STR 0x15 +# define NV30_VP_INST_OP_SSG 0x16 +# define NV30_VP_INST_OP_ARR 0x17 +# define NV30_VP_INST_OP_ARA 0x18 +#define NV30_VP_INST_CONST_SRC_SHIFT 14 +#define NV30_VP_INST_CONST_SRC_MASK (0xFF << 14) +#define NV30_VP_INST_INPUT_SRC_SHIFT 9 /*NV20*/ +#define NV30_VP_INST_INPUT_SRC_MASK (0x0F << 9) /*NV20*/ +# define NV30_VP_INST_IN_POS 0 /* These seem to match the bindings specified in */ +# define NV30_VP_INST_IN_WEIGHT 1 /* the ARB_v_p spec (2.14.3.1) */ +# define NV30_VP_INST_IN_NORMAL 2 +# define NV30_VP_INST_IN_COL0 3 /* Should probably confirm them all though */ +# define NV30_VP_INST_IN_COL1 4 +# define NV30_VP_INST_IN_FOGC 5 +# define NV30_VP_INST_IN_TC0 8 +# define NV30_VP_INST_IN_TC(n) (8+n) +#define NV30_VP_INST_SRC0H_SHIFT 0 /*NV20*/ +#define NV30_VP_INST_SRC0H_MASK (0x1FF << 0) /*NV20*/ + +/* DWORD 2 */ +#define NV30_VP_INST_SRC0L_SHIFT 26 /*NV20*/ +#define NV30_VP_INST_SRC0L_MASK (0x3F <<26) /*NV20*/ +#define NV30_VP_INST_SRC1_SHIFT 11 /*NV20*/ +#define NV30_VP_INST_SRC1_MASK (0x7FFF<<11) /*NV20*/ +#define NV30_VP_INST_SRC2H_SHIFT 0 /*NV20*/ +#define NV30_VP_INST_SRC2H_MASK (0x7FF << 0) /*NV20*/ +#define NV30_VP_INST_IADDR_SHIFT 2 +#define NV30_VP_INST_IADDR_MASK (0xFF << 2) /* guess */ + +/* DWORD 3 */ +#define NV30_VP_INST_SRC2L_SHIFT 28 /*NV20*/ +#define NV30_VP_INST_SRC2L_MASK (0x0F <<28) /*NV20*/ +#define NV30_VP_INST_STEMP_WRITEMASK_SHIFT 24 +#define NV30_VP_INST_STEMP_WRITEMASK_MASK (0x0F << 24) +#define NV30_VP_INST_VTEMP_WRITEMASK_SHIFT 20 +#define NV30_VP_INST_VTEMP_WRITEMASK_MASK (0x0F << 20) +#define NV30_VP_INST_SDEST_WRITEMASK_SHIFT 16 +#define NV30_VP_INST_SDEST_WRITEMASK_MASK (0x0F << 16) +#define NV30_VP_INST_VDEST_WRITEMASK_SHIFT 12 /*NV20*/ +#define NV30_VP_INST_VDEST_WRITEMASK_MASK (0x0F << 12) /*NV20*/ +#define NV30_VP_INST_DEST_ID_SHIFT 2 +#define NV30_VP_INST_DEST_ID_MASK (0x0F << 2) +# define NV30_VP_INST_DEST_POS 0 +# define NV30_VP_INST_DEST_COL0 3 +# define NV30_VP_INST_DEST_COL1 4 +# define NV30_VP_INST_DEST_TC(n) (8+n) + +/* Source-register definition - matches NV20 exactly */ +#define NV30_VP_SRC_REG_NEGATE (1<<14) +#define NV30_VP_SRC_REG_SWZ_X_SHIFT 12 +#define NV30_VP_SRC_REG_SWZ_X_MASK (0x03 <<12) +#define NV30_VP_SRC_REG_SWZ_Y_SHIFT 10 +#define NV30_VP_SRC_REG_SWZ_Y_MASK (0x03 <<10) +#define NV30_VP_SRC_REG_SWZ_Z_SHIFT 8 +#define NV30_VP_SRC_REG_SWZ_Z_MASK (0x03 << 8) +#define NV30_VP_SRC_REG_SWZ_W_SHIFT 6 +#define NV30_VP_SRC_REG_SWZ_W_MASK (0x03 << 6) +#define NV30_VP_SRC_REG_SWZ_ALL_SHIFT 6 +#define NV30_VP_SRC_REG_SWZ_ALL_MASK (0xFF << 6) +#define NV30_VP_SRC_REG_TEMP_ID_SHIFT 2 +#define NV30_VP_SRC_REG_TEMP_ID_MASK (0x0F << 0) +#define NV30_VP_SRC_REG_TYPE_SHIFT 0 +#define NV30_VP_SRC_REG_TYPE_MASK (0x03 << 0) +#define NV30_VP_SRC_REG_TYPE_TEMP 1 +#define NV30_VP_SRC_REG_TYPE_INPUT 2 +#define NV30_VP_SRC_REG_TYPE_CONST 3 /* guess */ + +/* + * Each fragment program opcode appears to be comprised of 4 32-bit values. + * + * 0 - Opcode, output reg/mask, ATTRIB source + * 1 - Source 0 + * 2 - Source 1 + * 3 - Source 2 + * + * There appears to be no special difference between result regs and temp regs. + * result.color == R0.xyzw + * result.depth == R1.z + * When the fragprog contains instructions to write depth, NV30_TCL_PRIMITIVE_3D_UNK1D78=0 + * otherwise it is set to 1. + * + * Constants are inserted directly after the instruction that uses them. + * + * It appears that it's not possible to use two input registers in one + * instruction as the input sourcing is done in the instruction dword + * and not the source selection dwords. As such instructions such as: + * + * ADD result.color, fragment.color, fragment.texcoord[0]; + * + * must be split into two MOV's and then an ADD (nvidia does this) but + * I'm not sure why it's not just one MOV and then source the second input + * in the ADD instruction.. + * + * Negation of the full source is done with NV30_FP_REG_NEGATE, arbitrary + * negation requires multiplication with a const. + * + * Arbitrary swizzling is supported with the exception of SWIZZLE_ZERO/SWIZZLE_ONE + * The temp/result regs appear to be initialised to (0.0, 0.0, 0.0, 0.0) as SWIZZLE_ZERO + * is implemented simply by not writing to the relevant components of the destination. + * + * Conditional execution + * TODO + * + * Non-native instructions: + * LIT + * LRP - MAD+MAD + * SUB - ADD, negate second source + * RSQ - LG2 + EX2 + * POW - LG2 + MUL + EX2 + * SCS - COS + SIN + * XPD + */ + +//== Opcode / Destination selection == +#define NV30_FP_OP_PROGRAM_END (1 << 0) +#define NV30_FP_OP_OUT_REG_SHIFT 1 +#define NV30_FP_OP_OUT_REG_MASK (31 << 1) /* uncertain */ +/* Needs to be set when writing outputs to get expected result.. */ +#define NV30_FP_OP_UNK0_7 (1 << 7) +#define NV30_FP_OP_COND_WRITE_ENABLE (1 << 8) +#define NV30_FP_OP_OUTMASK_SHIFT 9 +#define NV30_FP_OP_OUTMASK_MASK (0xF << 9) +# define NV30_FP_OP_OUT_X (1<<9) +# define NV30_FP_OP_OUT_Y (1<<10) +# define NV30_FP_OP_OUT_Z (1<<11) +# define NV30_FP_OP_OUT_W (1<<12) +/* Uncertain about these, especially the input_src values.. it's possible that + * they can be dynamically changed. + */ +#define NV30_FP_OP_INPUT_SRC_SHIFT 13 +#define NV30_FP_OP_INPUT_SRC_MASK (15 << 13) +# define NV30_FP_OP_INPUT_SRC_POSITION 0x0 +# define NV30_FP_OP_INPUT_SRC_COL0 0x1 +# define NV30_FP_OP_INPUT_SRC_COL1 0x2 +# define NV30_FP_OP_INPUT_SRC_FOGC 0x3 +# define NV30_FP_OP_INPUT_SRC_TC0 0x4 +# define NV30_FP_OP_INPUT_SRC_TC(n) (0x4 + n) +#define NV30_FP_OP_TEX_UNIT_SHIFT 17 +#define NV30_FP_OP_TEX_UNIT_MASK (0xF << 17) /* guess */ +#define NV30_FP_OP_PRECISION_SHIFT 22 +#define NV30_FP_OP_PRECISION_MASK (3 << 22) +# define NV30_FP_PRECISION_FP32 0 +# define NV30_FP_PRECISION_FP16 1 +# define NV30_FP_PRECISION_FX12 2 +#define NV30_FP_OP_OPCODE_SHIFT 24 +#define NV30_FP_OP_OPCODE_MASK (0x3F << 24) +# define NV30_FP_OP_OPCODE_NOP 0x00 +# define NV30_FP_OP_OPCODE_MOV 0x01 +# define NV30_FP_OP_OPCODE_MUL 0x02 +# define NV30_FP_OP_OPCODE_ADD 0x03 +# define NV30_FP_OP_OPCODE_MAD 0x04 +# define NV30_FP_OP_OPCODE_DP3 0x05 +# define NV30_FP_OP_OPCODE_DP4 0x06 +# define NV30_FP_OP_OPCODE_DST 0x07 +# define NV30_FP_OP_OPCODE_MIN 0x08 +# define NV30_FP_OP_OPCODE_MAX 0x09 +# define NV30_FP_OP_OPCODE_SLT 0x0A +# define NV30_FP_OP_OPCODE_SGE 0x0B +# define NV30_FP_OP_OPCODE_SLE 0x0C +# define NV30_FP_OP_OPCODE_SGT 0x0D +# define NV30_FP_OP_OPCODE_SNE 0x0E +# define NV30_FP_OP_OPCODE_SEQ 0x0F +# define NV30_FP_OP_OPCODE_FRC 0x10 +# define NV30_FP_OP_OPCODE_FLR 0x11 +# define NV30_FP_OP_OPCODE_KIL 0x12 +# define NV30_FP_OP_OPCODE_PK4B 0x13 +# define NV30_FP_OP_OPCODE_UP4B 0x14 +# define NV30_FP_OP_OPCODE_DDX 0x15 /* can only write XY */ +# define NV30_FP_OP_OPCODE_DDY 0x16 /* can only write XY */ +# define NV30_FP_OP_OPCODE_TEX 0x17 +# define NV30_FP_OP_OPCODE_TXP 0x18 +# define NV30_FP_OP_OPCODE_TXD 0x19 +# define NV30_FP_OP_OPCODE_RCP 0x1A +# define NV30_FP_OP_OPCODE_RSQ 0x1B +# define NV30_FP_OP_OPCODE_EX2 0x1C +# define NV30_FP_OP_OPCODE_LG2 0x1D +# define NV30_FP_OP_OPCODE_LIT 0x1E +# define NV30_FP_OP_OPCODE_LRP 0x1F +# define NV30_FP_OP_OPCODE_COS 0x22 +# define NV30_FP_OP_OPCODE_SIN 0x23 +# define NV30_FP_OP_OPCODE_PK2H 0x24 +# define NV30_FP_OP_OPCODE_UP2H 0x25 +# define NV30_FP_OP_OPCODE_POW 0x26 +# define NV30_FP_OP_OPCODE_PK4UB 0x27 +# define NV30_FP_OP_OPCODE_UP4UB 0x28 +# define NV30_FP_OP_OPCODE_PK2US 0x29 +# define NV30_FP_OP_OPCODE_UP2US 0x2A +# define NV30_FP_OP_OPCODE_DP2A 0x2E +# define NV30_FP_OP_OPCODE_TXB 0x31 +# define NV30_FP_OP_OPCODE_RFL 0x36 +#define NV30_FP_OP_OUT_SAT (1 << 31) + +/* high order bits of SRC0 */ +#define NV30_FP_OP_OUT_ABS (1 << 29) +#define NV30_FP_OP_COND_SWZ_W_SHIFT 27 +#define NV30_FP_OP_COND_SWZ_W_MASK (3 << 27) +#define NV30_FP_OP_COND_SWZ_Z_SHIFT 25 +#define NV30_FP_OP_COND_SWZ_Z_MASK (3 << 25) +#define NV30_FP_OP_COND_SWZ_Y_SHIFT 23 +#define NV30_FP_OP_COND_SWZ_Y_MASK (3 << 23) +#define NV30_FP_OP_COND_SWZ_X_SHIFT 21 +#define NV30_FP_OP_COND_SWZ_X_MASK (3 << 21) +#define NV30_FP_OP_COND_SWZ_ALL_SHIFT 21 +#define NV30_FP_OP_COND_SWZ_ALL_MASK (0xFF << 21) +#define NV30_FP_OP_COND_SHIFT 18 +#define NV30_FP_OP_COND_MASK (0x07 << 18) +# define NV30_FP_OP_COND_FL 0 +# define NV30_FP_OP_COND_LT 1 +# define NV30_FP_OP_COND_EQ 2 +# define NV30_FP_OP_COND_LE 3 +# define NV30_FP_OP_COND_GT 4 +# define NV30_FP_OP_COND_NE 5 +# define NV30_FP_OP_COND_GE 6 +# define NV30_FP_OP_COND_TR 7 + +/* high order bits of SRC1 */ +#define NV30_FP_OP_SRC_SCALE_SHIFT 28 +#define NV30_FP_OP_SRC_SCALE_MASK (3 << 28) + +/* high order bits of SRC2 */ +#define NV30_FP_OP_INDEX_INPUT (1 << 30) + +//== Register selection == +#define NV30_FP_REG_TYPE_SHIFT 0 +#define NV30_FP_REG_TYPE_MASK (3 << 0) +# define NV30_FP_REG_TYPE_TEMP 0 +# define NV30_FP_REG_TYPE_INPUT 1 +# define NV30_FP_REG_TYPE_CONST 2 +#define NV30_FP_REG_SRC_SHIFT 2 /* uncertain */ +#define NV30_FP_REG_SRC_MASK (31 << 2) +#define NV30_FP_REG_UNK_0 (1 << 8) +#define NV30_FP_REG_SWZ_ALL_SHIFT 9 +#define NV30_FP_REG_SWZ_ALL_MASK (255 << 9) +#define NV30_FP_REG_SWZ_X_SHIFT 9 +#define NV30_FP_REG_SWZ_X_MASK (3 << 9) +#define NV30_FP_REG_SWZ_Y_SHIFT 11 +#define NV30_FP_REG_SWZ_Y_MASK (3 << 11) +#define NV30_FP_REG_SWZ_Z_SHIFT 13 +#define NV30_FP_REG_SWZ_Z_MASK (3 << 13) +#define NV30_FP_REG_SWZ_W_SHIFT 15 +#define NV30_FP_REG_SWZ_W_MASK (3 << 15) +# define NV30_FP_SWIZZLE_X 0 +# define NV30_FP_SWIZZLE_Y 1 +# define NV30_FP_SWIZZLE_Z 2 +# define NV30_FP_SWIZZLE_W 3 +#define NV30_FP_REG_NEGATE (1 << 17) + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 851641c0c9..3ffb5d3a41 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -327,7 +327,7 @@ static void nv30Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) switch(pname) { case GL_FOG_MODE: - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_MODE, 1); + //BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_MODE, 1); //OUT_RING_CACHE (params); break; /* TODO: unsure about the rest.*/ diff --git a/src/mesa/drivers/dri/nouveau/nv30_vertprog.c b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c new file mode 100644 index 0000000000..e60422dad1 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c @@ -0,0 +1,356 @@ +#include "nouveau_context.h" +#include "nouveau_object.h" +#include "nouveau_fifo.h" +#include "nouveau_reg.h" + +#include "nouveau_shader.h" +#include "nv30_shader.h" + +extern nvsSwzComp NV20VP_TX_SWIZZLE[4]; +extern void NV20VPTXSwizzle(int hwswz, nvsSwzComp *swz); + +/***************************************************************************** + * Support routines + */ +static void +NV30VPUploadToHW(GLcontext *ctx, nouveauShader *nvs) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + int i; + + /* We can do better here and keep more than one VP on the hardware, and + * switch between them with PROGRAM_START_ID.. + */ + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_FROM_ID, 1); + OUT_RING(0); + for (i=0; iprogram_size; i+=4) { + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_INST0, 4); + OUT_RING(nvs->program[i + 0]); + OUT_RING(nvs->program[i + 1]); + OUT_RING(nvs->program[i + 2]); + OUT_RING(nvs->program[i + 3]); + } + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_PROGRAM_START_ID, 1); + OUT_RING(0); +} + +static void +NV30VPUpdateConst(GLcontext *ctx, nouveauShader *nvs, int id) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLfloat *val; + + val = nvs->params[id].source_val ? + nvs->params[id].source_val : nvs->params[id].val; + + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_ID, 5); + OUT_RING (id); + OUT_RINGp(val, 4); +} + +/***************************************************************************** + * Assembly routines + */ + +/***************************************************************************** + * Disassembly routines + */ +static unsigned int +NV30VPGetOpcodeHW(nvsFunc * shader, int slot) +{ + int op; + + if (slot) { + op = (shader->inst[1] & NV30_VP_INST_SCA_OPCODEL_MASK) + >> NV30_VP_INST_SCA_OPCODEL_SHIFT; + op |= ((shader->inst[0] & NV30_VP_INST_SCA_OPCODEH_MASK) + >> NV30_VP_INST_SCA_OPCODEH_SHIFT) << 4; + } + else { + op = (shader->inst[1] & NV30_VP_INST_VEC_OPCODE_MASK) + >> NV30_VP_INST_VEC_OPCODE_SHIFT; + } + + return op; +} + +static nvsRegFile +NV30VPGetDestFile(nvsFunc * shader, int merged) +{ + switch (shader->GetOpcode(shader, merged)) { + case NVS_OP_ARL: + case NVS_OP_ARR: + case NVS_OP_ARA: + return NVS_FILE_ADDRESS; + default: + /*FIXME: This probably isn't correct.. */ + if ((shader->inst[3] & NV30_VP_INST_VDEST_WRITEMASK_MASK) != 0) + return NVS_FILE_RESULT; + if ((shader->inst[3] & NV30_VP_INST_SDEST_WRITEMASK_MASK) != 0) + return NVS_FILE_RESULT; + return NVS_FILE_TEMP; + } +} + +static unsigned int +NV30VPGetDestID(nvsFunc * shader, int merged) +{ + int id; + + switch (shader->GetDestFile(shader, merged)) { + case NVS_FILE_RESULT: + id = ((shader->inst[3] & NV30_VP_INST_DEST_ID_MASK) + >> NV30_VP_INST_DEST_ID_SHIFT); + switch (id) { + case NV30_VP_INST_DEST_POS : return NVS_FR_POSITION; + case NV30_VP_INST_DEST_COL0 : return NVS_FR_COL0; + case NV30_VP_INST_DEST_COL1 : return NVS_FR_COL1; + case NV30_VP_INST_DEST_TC(0): return NVS_FR_TEXCOORD0; + case NV30_VP_INST_DEST_TC(1): return NVS_FR_TEXCOORD1; + case NV30_VP_INST_DEST_TC(2): return NVS_FR_TEXCOORD2; + case NV30_VP_INST_DEST_TC(3): return NVS_FR_TEXCOORD3; + case NV30_VP_INST_DEST_TC(4): return NVS_FR_TEXCOORD4; + case NV30_VP_INST_DEST_TC(5): return NVS_FR_TEXCOORD5; + case NV30_VP_INST_DEST_TC(6): return NVS_FR_TEXCOORD6; + case NV30_VP_INST_DEST_TC(7): return NVS_FR_TEXCOORD7; + default: + return -1; + } + case NVS_FILE_ADDRESS: + case NVS_FILE_TEMP: + return (shader->inst[0] & NV30_VP_INST_DEST_TEMP_ID_MASK) + >> NV30_VP_INST_DEST_TEMP_ID_SHIFT; + default: + return -1; + } +} + +static unsigned int +NV30VPGetDestMask(nvsFunc * shader, int merged) +{ + int hwmask, mask = 0; + + if (shader->GetDestFile(shader, merged) == NVS_FILE_RESULT) + if (shader->GetOpcodeSlot(shader, merged)) + hwmask = (shader->inst[3] & NV30_VP_INST_SDEST_WRITEMASK_MASK) + >> NV30_VP_INST_SDEST_WRITEMASK_SHIFT; + else + hwmask = (shader->inst[3] & NV30_VP_INST_VDEST_WRITEMASK_MASK) + >> NV30_VP_INST_VDEST_WRITEMASK_SHIFT; + else if (shader->GetOpcodeSlot(shader, merged)) + hwmask = (shader->inst[3] & NV30_VP_INST_STEMP_WRITEMASK_MASK) + >> NV30_VP_INST_STEMP_WRITEMASK_SHIFT; + else + hwmask = (shader->inst[3] & NV30_VP_INST_VTEMP_WRITEMASK_MASK) + >> NV30_VP_INST_VTEMP_WRITEMASK_SHIFT; + + if (hwmask & (1 << 3)) mask |= SMASK_X; + if (hwmask & (1 << 2)) mask |= SMASK_Y; + if (hwmask & (1 << 1)) mask |= SMASK_Z; + if (hwmask & (1 << 0)) mask |= SMASK_W; + + return mask; +} + +static int +NV30VPGetSourceID(nvsFunc * shader, int merged, int pos) +{ + unsigned int src; + + switch (shader->GetSourceFile(shader, merged, pos)) { + case NVS_FILE_TEMP: + src = shader->GetSourceHW(shader, merged, pos); + return ((src & NV30_VP_SRC_REG_TEMP_ID_MASK) >> + NV30_VP_SRC_REG_TEMP_ID_SHIFT); + case NVS_FILE_CONST: + return ((shader->inst[1] & NV30_VP_INST_CONST_SRC_MASK) + >> NV30_VP_INST_CONST_SRC_SHIFT); + case NVS_FILE_ATTRIB: + src = ((shader->inst[1] & NV30_VP_INST_INPUT_SRC_MASK) + >> NV30_VP_INST_INPUT_SRC_SHIFT); + switch (src) { + case NV30_VP_INST_IN_POS : return NVS_FR_POSITION; + case NV30_VP_INST_IN_COL0 : return NVS_FR_COL0; + case NV30_VP_INST_IN_COL1 : return NVS_FR_COL1; + case NV30_VP_INST_IN_TC(0): return NVS_FR_TEXCOORD0; + case NV30_VP_INST_IN_TC(1): return NVS_FR_TEXCOORD1; + case NV30_VP_INST_IN_TC(2): return NVS_FR_TEXCOORD2; + case NV30_VP_INST_IN_TC(3): return NVS_FR_TEXCOORD3; + case NV30_VP_INST_IN_TC(4): return NVS_FR_TEXCOORD4; + case NV30_VP_INST_IN_TC(5): return NVS_FR_TEXCOORD5; + case NV30_VP_INST_IN_TC(6): return NVS_FR_TEXCOORD6; + case NV30_VP_INST_IN_TC(7): return NVS_FR_TEXCOORD7; + default: + return NVS_FR_UNKNOWN; + } + default: + return -1; + } +} + +static int +NV30VPGetSourceAbs(nvsFunc * shader, int merged, int pos) +{ + struct _op_xlat *opr; + static unsigned int abspos[3] = { + NV30_VP_INST_SRC0_ABS, + NV30_VP_INST_SRC1_ABS, + NV30_VP_INST_SRC2_ABS, + }; + + opr = shader->GetOPTXRec(shader, merged); + if (!opr || opr->srcpos[pos] == -1 || opr->srcpos[pos] > 2) + return 0; + + return ((shader->inst[0] & abspos[opr->srcpos[pos]]) ? 1 : 0); +} + +static int +NV30VPGetRelAddressRegID(nvsFunc * shader) +{ + return ((shader->inst[0] & NV30_VP_INST_ADDR_REG_SELECT_1) ? 1 : 0); +} + +static nvsSwzComp +NV30VPGetRelAddressSwizzle(nvsFunc * shader) +{ + nvsSwzComp swz; + + swz = NV20VP_TX_SWIZZLE[(shader->inst[0] & NV30_VP_INST_ADDR_SWZ_MASK) + >> NV30_VP_INST_ADDR_SWZ_SHIFT]; + return swz; +} + +static int +NV30VPSupportsConditional(nvsFunc * shader) +{ + /*FIXME: Is this true of all ops? */ + return 1; +} + +static int +NV30VPGetConditionUpdate(nvsFunc * shader) +{ + return ((shader->inst[0] & NV30_VP_INST_COND_UPDATE_ENABLE) ? 1 : 0); +} + +static int +NV30VPGetConditionTest(nvsFunc * shader) +{ + int op; + + /* The condition test is unconditionally enabled on some + * instructions. ie: the condition test bit does *NOT* have + * to be set. + * + * FIXME: check other relevant ops for this situation. + */ + op = shader->GetOpcodeHW(shader, 1); + switch (op) { + case NV30_VP_INST_OP_BRA: + return 1; + default: + return ((shader->inst[0] & NV30_VP_INST_COND_TEST_ENABLE) ? 1 : 0); + } +} + +static nvsCond +NV30VPGetCondition(nvsFunc * shader) +{ + int cond; + + cond = ((shader->inst[0] & NV30_VP_INST_COND_MASK) + >> NV30_VP_INST_COND_SHIFT); + + switch (cond) { + case NV30_VP_INST_COND_FL: return NVS_COND_FL; + case NV30_VP_INST_COND_LT: return NVS_COND_LT; + case NV30_VP_INST_COND_EQ: return NVS_COND_EQ; + case NV30_VP_INST_COND_LE: return NVS_COND_LE; + case NV30_VP_INST_COND_GT: return NVS_COND_GT; + case NV30_VP_INST_COND_NE: return NVS_COND_NE; + case NV30_VP_INST_COND_GE: return NVS_COND_GE; + case NV30_VP_INST_COND_TR: return NVS_COND_TR; + default: + return NVS_COND_UNKNOWN; + } +} + +static void +NV30VPGetCondRegSwizzle(nvsFunc * shader, nvsSwzComp *swz) +{ + int swzbits; + + swzbits = (shader->inst[0] & NV30_VP_INST_COND_SWZ_ALL_MASK) + >> NV30_VP_INST_COND_SWZ_ALL_SHIFT; + NV20VPTXSwizzle(swzbits, swz); +} + +static int +NV30VPGetCondRegID(nvsFunc * shader) +{ + return 0; +} + + +static int +NV30VPGetBranch(nvsFunc * shader) +{ + return ((shader->inst[2] & NV30_VP_INST_IADDR_MASK) + >> NV30_VP_INST_IADDR_SHIFT); +} + +void +NV30VPInitShaderFuncs(nvsFunc * shader) +{ + /* Inherit NV20 code, a lot of it is the same */ + NV20VPInitShaderFuncs(shader); + + /* Increase max valid opcode ID, and add new instructions */ + NVVP_TX_VOP_COUNT = NVVP_TX_NVS_OP_COUNT = 32; + + MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_FRC, NVS_OP_FRC, 0, -1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_FLR, NVS_OP_FLR, 0, -1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SEQ, NVS_OP_SEQ, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SFL, NVS_OP_SFL, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SGT, NVS_OP_SGT, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SLE, NVS_OP_SLE, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SNE, NVS_OP_SNE, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_STR, NVS_OP_STR, 0, 1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SSG, NVS_OP_SSG, 0, -1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_ARR, NVS_OP_ARR, 0, -1, -1); + MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_ARA, NVS_OP_ARA, 3, -1, -1); + + MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_BRA, NVS_OP_BRA, -1, -1, -1); + MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_CAL, NVS_OP_CAL, -1, -1, -1); + MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_RET, NVS_OP_RET, -1, -1, -1); + MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_LG2, NVS_OP_LG2, 2, -1, -1); + MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_EX2, NVS_OP_EX2, 2, -1, -1); + MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_SIN, NVS_OP_SIN, 2, -1, -1); + MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_COS, NVS_OP_COS, 2, -1, -1); + + shader->UploadToHW = NV30VPUploadToHW; + shader->UpdateConst = NV30VPUpdateConst; + + shader->GetOpcodeHW = NV30VPGetOpcodeHW; + + shader->GetDestFile = NV30VPGetDestFile; + shader->GetDestID = NV30VPGetDestID; + shader->GetDestMask = NV30VPGetDestMask; + + shader->GetSourceID = NV30VPGetSourceID; + shader->GetSourceAbs = NV30VPGetSourceAbs; + + shader->GetRelAddressRegID = NV30VPGetRelAddressRegID; + shader->GetRelAddressSwizzle = NV30VPGetRelAddressSwizzle; + + shader->SupportsConditional = NV30VPSupportsConditional; + shader->GetConditionUpdate = NV30VPGetConditionUpdate; + shader->GetConditionTest = NV30VPGetConditionTest; + shader->GetCondition = NV30VPGetCondition; + shader->GetCondRegSwizzle = NV30VPGetCondRegSwizzle; + shader->GetCondRegID = NV30VPGetCondRegID; + + shader->GetBranch = NV30VPGetBranch; +} + diff --git a/src/mesa/drivers/dri/nouveau/nv40_fragprog.c b/src/mesa/drivers/dri/nouveau/nv40_fragprog.c new file mode 100644 index 0000000000..3d58d6b666 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv40_fragprog.c @@ -0,0 +1,152 @@ +#include "nouveau_shader.h" +#include "nv40_shader.h" + +/* branching ops */ +unsigned int NVFP_TX_BOP_COUNT = 5; +struct _op_xlat NVFP_TX_BOP[64]; + +static struct _op_xlat * +NV40FPGetOPTXRec(nvsFunc * shader, int merged) +{ + struct _op_xlat *opr; + int op; + + op = shader->GetOpcodeHW(shader, 0); + if (shader->inst[2] & NV40_FP_OP_OPCODE_IS_BRANCH) { + opr = NVFP_TX_BOP; + op &= ~NV40_FP_OP_OPCODE_IS_BRANCH; + if (op > NVFP_TX_BOP_COUNT) + return NULL; + } + else { + opr = NVFP_TX_AOP; + if (op > NVFP_TX_AOP_COUNT) + return NULL; + } + + if (opr[op].SOP == NVS_OP_UNKNOWN) + return NULL; + return &opr[op]; +} + +static int +NV40FPGetSourceID(nvsFunc * shader, int merged, int pos) +{ + switch (shader->GetSourceFile(shader, merged, pos)) { + case NVS_FILE_ATTRIB: + switch ((shader->inst[0] & NV40_FP_OP_INPUT_SRC_MASK) + >> NV40_FP_OP_INPUT_SRC_SHIFT) { + case NV40_FP_OP_INPUT_SRC_POSITION: return NVS_FR_POSITION; + case NV40_FP_OP_INPUT_SRC_COL0 : return NVS_FR_COL0; + case NV40_FP_OP_INPUT_SRC_COL1 : return NVS_FR_COL1; + case NV40_FP_OP_INPUT_SRC_FOGC : return NVS_FR_FOGCOORD; + case NV40_FP_OP_INPUT_SRC_TC(0) : return NVS_FR_TEXCOORD0; + case NV40_FP_OP_INPUT_SRC_TC(1) : return NVS_FR_TEXCOORD1; + case NV40_FP_OP_INPUT_SRC_TC(2) : return NVS_FR_TEXCOORD2; + case NV40_FP_OP_INPUT_SRC_TC(3) : return NVS_FR_TEXCOORD3; + case NV40_FP_OP_INPUT_SRC_TC(4) : return NVS_FR_TEXCOORD4; + case NV40_FP_OP_INPUT_SRC_TC(5) : return NVS_FR_TEXCOORD5; + case NV40_FP_OP_INPUT_SRC_TC(6) : return NVS_FR_TEXCOORD6; + case NV40_FP_OP_INPUT_SRC_TC(7) : return NVS_FR_TEXCOORD7; + case NV40_FP_OP_INPUT_SRC_FACING : return NVS_FR_FACING; + default: + return -1; + } + break; + case NVS_FILE_TEMP: + { + unsigned int src; + + src = shader->GetSourceHW(shader, merged, pos); + return ((src & NV40_FP_REG_SRC_MASK) >> NV40_FP_REG_SRC_SHIFT); + } + case NVS_FILE_CONST: /* inlined into fragprog */ + default: + return -1; + } +} + +static int +NV40FPGetBranch(nvsFunc * shader) +{ + return ((shader->inst[2] & NV40_FP_OP_IADDR_MASK) + >> NV40_FP_OP_IADDR_SHIFT);; +} + +static int +NV40FPGetBranchElse(nvsFunc * shader) +{ + return ((shader->inst[2] & NV40_FP_OP_ELSE_ID_MASK) + >> NV40_FP_OP_ELSE_ID_SHIFT); +} + +static int +NV40FPGetBranchEnd(nvsFunc * shader) +{ + return ((shader->inst[3] & NV40_FP_OP_END_ID_MASK) + >> NV40_FP_OP_END_ID_SHIFT); +} + +static int +NV40FPGetLoopCount(nvsFunc * shader) +{ + return ((shader->inst[2] & NV40_FP_OP_LOOP_COUNT_MASK) + >> NV40_FP_OP_LOOP_COUNT_SHIFT); +} + +static int +NV40FPGetLoopInitial(nvsFunc * shader) +{ + return ((shader->inst[2] & NV40_FP_OP_LOOP_INDEX_MASK) + >> NV40_FP_OP_LOOP_INDEX_SHIFT); +} + +static int +NV40FPGetLoopIncrement(nvsFunc * shader) +{ + return ((shader->inst[2] & NV40_FP_OP_LOOP_INCR_MASK) + >> NV40_FP_OP_LOOP_INCR_SHIFT); +} + +void +NV40FPInitShaderFuncs(nvsFunc * shader) +{ + /* Inherit NV30 FP code, it's mostly the same */ + NV30FPInitShaderFuncs(shader); + + /* Kill off opcodes seen on NV30, but not seen on NV40 - need to find + * out if these actually work or not. + * + * update: either LIT/RSQ don't work on nv40, or I generate bad code for + * them. haven't tested the others yet + */ + MOD_OPCODE(NVFP_TX_AOP, 0x1B, NVS_OP_UNKNOWN, -1, -1, -1); /* NV30 RSQ */ + MOD_OPCODE(NVFP_TX_AOP, 0x1E, NVS_OP_UNKNOWN, -1, -1, -1); /* NV30 LIT */ + MOD_OPCODE(NVFP_TX_AOP, 0x1F, NVS_OP_UNKNOWN, -1, -1, -1); /* NV30 LRP */ + MOD_OPCODE(NVFP_TX_AOP, 0x26, NVS_OP_UNKNOWN, -1, -1, -1); /* NV30 POW */ + MOD_OPCODE(NVFP_TX_AOP, 0x36, NVS_OP_UNKNOWN, -1, -1, -1); /* NV30 RFL */ + + /* Extra opcodes supported on NV40 */ + MOD_OPCODE(NVFP_TX_AOP, NV40_FP_OP_OPCODE_DIV , NVS_OP_DIV , 0, 1, -1); + MOD_OPCODE(NVFP_TX_AOP, NV40_FP_OP_OPCODE_DP2A , NVS_OP_DP2A, 0, 1, 2); + MOD_OPCODE(NVFP_TX_AOP, NV40_FP_OP_OPCODE_TXL , NVS_OP_TXL , 0, -1, -1); + + MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_BRK , NVS_OP_BRK , -1, -1, -1); + MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_CAL , NVS_OP_CAL , -1, -1, -1); + MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_IF , NVS_OP_IF , -1, -1, -1); + MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_LOOP, NVS_OP_LOOP, -1, -1, -1); + MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_REP , NVS_OP_REP , -1, -1, -1); + MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_RET , NVS_OP_RET , -1, -1, -1); + + /* fragment.facing */ + shader->GetSourceID = NV40FPGetSourceID; + + /* branching */ + shader->GetOPTXRec = NV40FPGetOPTXRec; + shader->GetBranch = NV40FPGetBranch; + shader->GetBranchElse = NV40FPGetBranchElse; + shader->GetBranchEnd = NV40FPGetBranchEnd; + shader->GetLoopCount = NV40FPGetLoopCount; + shader->GetLoopInitial = NV40FPGetLoopInitial; + shader->GetLoopIncrement = NV40FPGetLoopIncrement; +} diff --git a/src/mesa/drivers/dri/nouveau/nv40_shader.h b/src/mesa/drivers/dri/nouveau/nv40_shader.h new file mode 100644 index 0000000000..2a2b5639b6 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv40_shader.h @@ -0,0 +1,467 @@ +#ifndef __NV40_SHADER_H__ +#define __NV40_SHADER_H__ + +/* Vertex programs instruction set + * + * The NV40 instruction set is very similar to NV30. Most fields are in + * a slightly different position in the instruction however. + * + * Merged instructions + * In some cases it is possible to put two instructions into one opcode + * slot. The rules for when this is OK is not entirely clear to me yet. + * + * There are separate writemasks and dest temp register fields for each + * grouping of instructions. There is however only one field with the + * ID of a result register. Writing to temp/result regs is selected by + * setting VEC_RESULT/SCA_RESULT. + * + * Temporary registers + * The source/dest temp register fields have been extended by 1 bit, to + * give a total of 32 temporary registers. + * + * Relative Addressing + * NV40 can use an address register to index into vertex attribute regs. + * This is done by putting the offset value into INPUT_SRC and setting + * the INDEX_INPUT flag. + * + * Conditional execution (see NV_vertex_program{2,3} for details) + * There is a second condition code register on NV40, it's use is enabled + * by setting the COND_REG_SELECT_1 flag. + * + * Texture lookup + * TODO + */ + +/* ---- OPCODE BITS 127:96 / data DWORD 0 --- */ +#define NV40_VP_INST_VEC_RESULT (1 << 30) +/* uncertain.. */ +#define NV40_VP_INST_COND_UPDATE_ENABLE ((1 << 14)|1<<29) +/* use address reg as index into attribs */ +#define NV40_VP_INST_INDEX_INPUT (1 << 27) +#define NV40_VP_INST_COND_REG_SELECT_1 (1 << 25) +#define NV40_VP_INST_ADDR_REG_SELECT_1 (1 << 24) +#define NV40_VP_INST_SRC2_ABS (1 << 23) +#define NV40_VP_INST_SRC1_ABS (1 << 22) +#define NV40_VP_INST_SRC0_ABS (1 << 21) +#define NV40_VP_INST_VEC_DEST_TEMP_SHIFT 15 +#define NV40_VP_INST_VEC_DEST_TEMP_MASK (0x1F << 15) +#define NV40_VP_INST_COND_TEST_ENABLE (1 << 13) +#define NV40_VP_INST_COND_SHIFT 10 +#define NV40_VP_INST_COND_MASK (0x7 << 10) +# define NV40_VP_INST_COND_FL 0 +# define NV40_VP_INST_COND_LT 1 +# define NV40_VP_INST_COND_EQ 2 +# define NV40_VP_INST_COND_LE 3 +# define NV40_VP_INST_COND_GT 4 +# define NV40_VP_INST_COND_NE 5 +# define NV40_VP_INST_COND_GE 6 +# define NV40_VP_INST_COND_TR 7 +#define NV40_VP_INST_COND_SWZ_X_SHIFT 8 +#define NV40_VP_INST_COND_SWZ_X_MASK (3 << 8) +#define NV40_VP_INST_COND_SWZ_Y_SHIFT 6 +#define NV40_VP_INST_COND_SWZ_Y_MASK (3 << 6) +#define NV40_VP_INST_COND_SWZ_Z_SHIFT 4 +#define NV40_VP_INST_COND_SWZ_Z_MASK (3 << 4) +#define NV40_VP_INST_COND_SWZ_W_SHIFT 2 +#define NV40_VP_INST_COND_SWZ_W_MASK (3 << 2) +#define NV40_VP_INST_COND_SWZ_ALL_SHIFT 2 +#define NV40_VP_INST_COND_SWZ_ALL_MASK (0xFF << 2) +#define NV40_VP_INST_ADDR_SWZ_SHIFT 0 +#define NV40_VP_INST_ADDR_SWZ_MASK (0x03 << 0) +#define NV40_VP_INST0_KNOWN ( \ + NV40_VP_INST_INDEX_INPUT | \ + NV40_VP_INST_COND_REG_SELECT_1 | \ + NV40_VP_INST_ADDR_REG_SELECT_1 | \ + NV40_VP_INST_SRC2_ABS | \ + NV40_VP_INST_SRC1_ABS | \ + NV40_VP_INST_SRC0_ABS | \ + NV40_VP_INST_VEC_DEST_TEMP_MASK | \ + NV40_VP_INST_COND_TEST_ENABLE | \ + NV40_VP_INST_COND_MASK | \ + NV40_VP_INST_COND_SWZ_ALL_MASK | \ + NV40_VP_INST_ADDR_SWZ_MASK) + +/* ---- OPCODE BITS 95:64 / data DWORD 1 --- */ +#define NV40_VP_INST_VEC_OPCODE_SHIFT 22 +#define NV40_VP_INST_VEC_OPCODE_MASK (0x1F << 22) +# define NV40_VP_INST_OP_NOP 0x00 +# define NV40_VP_INST_OP_MOV 0x01 +# define NV40_VP_INST_OP_MUL 0x02 +# define NV40_VP_INST_OP_ADD 0x03 +# define NV40_VP_INST_OP_MAD 0x04 +# define NV40_VP_INST_OP_DP3 0x05 +# define NV40_VP_INST_OP_DP4 0x07 +# define NV40_VP_INST_OP_DPH 0x06 +# define NV40_VP_INST_OP_DST 0x08 +# define NV40_VP_INST_OP_MIN 0x09 +# define NV40_VP_INST_OP_MAX 0x0A +# define NV40_VP_INST_OP_SLT 0x0B +# define NV40_VP_INST_OP_SGE 0x0C +# define NV40_VP_INST_OP_ARL 0x0D +# define NV40_VP_INST_OP_FRC 0x0E +# define NV40_VP_INST_OP_FLR 0x0F +# define NV40_VP_INST_OP_SEQ 0x10 +# define NV40_VP_INST_OP_SFL 0x11 +# define NV40_VP_INST_OP_SGT 0x12 +# define NV40_VP_INST_OP_SLE 0x13 +# define NV40_VP_INST_OP_SNE 0x14 +# define NV40_VP_INST_OP_STR 0x15 +# define NV40_VP_INST_OP_SSG 0x16 +# define NV40_VP_INST_OP_ARR 0x17 +# define NV40_VP_INST_OP_ARA 0x18 +# define NV40_VP_INST_OP_TXWHAT 0x19 +#define NV40_VP_INST_SCA_OPCODE_SHIFT 27 +#define NV40_VP_INST_SCA_OPCODE_MASK (0x1F << 27) +# define NV40_VP_INST_OP_RCP 0x02 +# define NV40_VP_INST_OP_RCC 0x03 +# define NV40_VP_INST_OP_RSQ 0x04 +# define NV40_VP_INST_OP_EXP 0x05 +# define NV40_VP_INST_OP_LOG 0x06 +# define NV40_VP_INST_OP_LIT 0x07 +# define NV40_VP_INST_OP_BRA 0x09 +# define NV40_VP_INST_OP_CAL 0x0B +# define NV40_VP_INST_OP_RET 0x0C +# define NV40_VP_INST_OP_LG2 0x0D +# define NV40_VP_INST_OP_EX2 0x0E +# define NV40_VP_INST_OP_SIN 0x0F +# define NV40_VP_INST_OP_COS 0x10 +# define NV40_VP_INST_OP_PUSHA 0x13 +# define NV40_VP_INST_OP_POPA 0x14 +#define NV40_VP_INST_CONST_SRC_SHIFT 12 +#define NV40_VP_INST_CONST_SRC_MASK (0xFF << 12) +#define NV40_VP_INST_INPUT_SRC_SHIFT 8 +#define NV40_VP_INST_INPUT_SRC_MASK (0x0F << 8) +# define NV40_VP_INST_IN_POS 0 +# define NV40_VP_INST_IN_WEIGHT 1 +# define NV40_VP_INST_IN_NORMAL 2 +# define NV40_VP_INST_IN_COL0 3 +# define NV40_VP_INST_IN_COL1 4 +# define NV40_VP_INST_IN_FOGC 5 +# define NV40_VP_INST_IN_TC0 8 +# define NV40_VP_INST_IN_TC(n) (8+n) +#define NV40_VP_INST_SRC0H_SHIFT 0 +#define NV40_VP_INST_SRC0H_MASK (0xFF << 0) +#define NV40_VP_INST1_KNOWN ( \ + NV40_VP_INST_VEC_OPCODE_MASK | \ + NV40_VP_INST_SCA_OPCODE_MASK | \ + NV40_VP_INST_CONST_SRC_MASK | \ + NV40_VP_INST_INPUT_SRC_MASK | \ + NV40_VP_INST_SRC0H_MASK \ + ) + +/* ---- OPCODE BITS 63:32 / data DWORD 2 --- */ +#define NV40_VP_INST_SRC0L_SHIFT 23 +#define NV40_VP_INST_SRC0L_MASK (0x1FF << 23) +#define NV40_VP_INST_SRC1_SHIFT 6 +#define NV40_VP_INST_SRC1_MASK (0x1FFFF << 6) +#define NV40_VP_INST_SRC2H_SHIFT 0 +#define NV40_VP_INST_SRC2H_MASK (0x3F << 0) +#define NV40_VP_INST_IADDRH_SHIFT 0 +#define NV40_VP_INST_IADDRH_MASK (0x1F << 0) + +/* ---- OPCODE BITS 31:0 / data DWORD 3 --- */ +#define NV40_VP_INST_IADDRL_SHIFT 29 +#define NV40_VP_INST_IADDRL_MASK (7 << 29) +#define NV40_VP_INST_SRC2L_SHIFT 21 +#define NV40_VP_INST_SRC2L_MASK (0x7FF << 21) +#define NV40_VP_INST_SCA_WRITEMASK_SHIFT 17 +#define NV40_VP_INST_SCA_WRITEMASK_MASK (0xF << 17) +# define NV40_VP_INST_SCA_WRITEMASK_X (1 << 20) +# define NV40_VP_INST_SCA_WRITEMASK_Y (1 << 19) +# define NV40_VP_INST_SCA_WRITEMASK_Z (1 << 18) +# define NV40_VP_INST_SCA_WRITEMASK_W (1 << 17) +#define NV40_VP_INST_VEC_WRITEMASK_SHIFT 13 +#define NV40_VP_INST_VEC_WRITEMASK_MASK (0xF << 13) +# define NV40_VP_INST_VEC_WRITEMASK_X (1 << 16) +# define NV40_VP_INST_VEC_WRITEMASK_Y (1 << 15) +# define NV40_VP_INST_VEC_WRITEMASK_Z (1 << 14) +# define NV40_VP_INST_VEC_WRITEMASK_W (1 << 13) +#define NV40_VP_INST_SCA_RESULT (1 << 12) +#define NV40_VP_INST_SCA_DEST_TEMP_SHIFT 7 +#define NV40_VP_INST_SCA_DEST_TEMP_MASK (0x1F << 7) +#define NV40_VP_INST_DEST_SHIFT 2 +#define NV40_VP_INST_DEST_MASK (31 << 2) +# define NV40_VP_INST_DEST_POS 0 +# define NV40_VP_INST_DEST_COL0 1 +# define NV40_VP_INST_DEST_COL1 2 +# define NV40_VP_INST_DEST_BFC0 3 +# define NV40_VP_INST_DEST_BFC1 4 +# define NV40_VP_INST_DEST_FOGC 5 +# define NV40_VP_INST_DEST_PSZ 6 +# define NV40_VP_INST_DEST_TC0 7 +# define NV40_VP_INST_DEST_TC(n) (7+n) +# define NV40_VP_INST_DEST_TEMP 0x1F +#define NV40_VP_INST_INDEX_CONST (1 << 1) +#define NV40_VP_INST_LAST (1 << 0) +#define NV40_VP_INST3_KNOWN ( \ + NV40_VP_INST_SRC2L_MASK |\ + NV40_VP_INST_SCA_WRITEMASK_MASK |\ + NV40_VP_INST_VEC_WRITEMASK_MASK |\ + NV40_VP_INST_SCA_DEST_TEMP_MASK |\ + NV40_VP_INST_DEST_MASK |\ + NV40_VP_INST_INDEX_CONST) + +/* Useful to split the source selection regs into their pieces */ +#define NV40_VP_SRC0_HIGH_SHIFT 9 +#define NV40_VP_SRC0_HIGH_MASK 0x0001FE00 +#define NV40_VP_SRC0_LOW_MASK 0x000001FF +#define NV40_VP_SRC2_HIGH_SHIFT 11 +#define NV40_VP_SRC2_HIGH_MASK 0x0001F800 +#define NV40_VP_SRC2_LOW_MASK 0x000007FF + +/* Source selection - these are the bits you fill NV40_VP_INST_SRCn with */ +#define NV40_VP_SRC_NEGATE (1 << 16) +#define NV40_VP_SRC_SWZ_X_SHIFT 14 +#define NV40_VP_SRC_SWZ_X_MASK (3 << 14) +#define NV40_VP_SRC_SWZ_Y_SHIFT 12 +#define NV40_VP_SRC_SWZ_Y_MASK (3 << 12) +#define NV40_VP_SRC_SWZ_Z_SHIFT 10 +#define NV40_VP_SRC_SWZ_Z_MASK (3 << 10) +#define NV40_VP_SRC_SWZ_W_SHIFT 8 +#define NV40_VP_SRC_SWZ_W_MASK (3 << 8) +#define NV40_VP_SRC_SWZ_ALL_SHIFT 8 +#define NV40_VP_SRC_SWZ_ALL_MASK (0xFF << 8) +#define NV40_VP_SRC_TEMP_SRC_SHIFT 2 +#define NV40_VP_SRC_TEMP_SRC_MASK (0x1F << 2) +#define NV40_VP_SRC_REG_TYPE_SHIFT 0 +#define NV40_VP_SRC_REG_TYPE_MASK (3 << 0) +# define NV40_VP_SRC_REG_TYPE_UNK0 0 +# define NV40_VP_SRC_REG_TYPE_TEMP 1 +# define NV40_VP_SRC_REG_TYPE_INPUT 2 +# define NV40_VP_SRC_REG_TYPE_CONST 3 + + +/* + * Each fragment program opcode appears to be comprised of 4 32-bit values. + * + * 0 - Opcode, output reg/mask, ATTRIB source + * 1 - Source 0 + * 2 - Source 1 + * 3 - Source 2 + * + * There appears to be no special difference between result regs and temp regs. + * result.color == R0.xyzw + * result.depth == R1.z + * When the fragprog contains instructions to write depth, + * NV30_TCL_PRIMITIVE_3D_UNK1D78=0 otherwise it is set to 1. + * + * Constants are inserted directly after the instruction that uses them. + * + * It appears that it's not possible to use two input registers in one + * instruction as the input sourcing is done in the instruction dword + * and not the source selection dwords. As such instructions such as: + * + * ADD result.color, fragment.color, fragment.texcoord[0]; + * + * must be split into two MOV's and then an ADD (nvidia does this) but + * I'm not sure why it's not just one MOV and then source the second input + * in the ADD instruction.. + * + * Negation of the full source is done with NV30_FP_REG_NEGATE, arbitrary + * negation requires multiplication with a const. + * + * Arbitrary swizzling is supported with the exception of SWIZZLE_ZERO and + * SWIZZLE_ONE. + * + * The temp/result regs appear to be initialised to (0.0, 0.0, 0.0, 0.0) as + * SWIZZLE_ZERO is implemented simply by not writing to the relevant components + * of the destination. + * + * Looping + * Loops appear to be fairly expensive on NV40 at least, the proprietary + * driver goes to a lot of effort to avoid using the native looping + * instructions. If the total number of *executed* instructions between + * REP/ENDREP or LOOP/ENDLOOP is <=500, the driver will unroll the loop. + * The maximum loop count is 255. + * + * Conditional execution + * TODO + * + * Non-native instructions: + * LIT + * LRP - MAD+MAD + * SUB - ADD, negate second source + * RSQ - LG2 + EX2 + * POW - LG2 + MUL + EX2 + * SCS - COS + SIN + * XPD + * DP2 - MUL + ADD + * NRM + */ + +//== Opcode / Destination selection == +#define NV40_FP_OP_PROGRAM_END (1 << 0) +#define NV40_FP_OP_OUT_REG_SHIFT 1 +#define NV40_FP_OP_OUT_REG_MASK (31 << 1) +/* Needs to be set when writing outputs to get expected result.. */ +#define NV40_FP_OP_UNK0_7 (1 << 7) +#define NV40_FP_OP_COND_WRITE_ENABLE (1 << 8) +#define NV40_FP_OP_OUTMASK_SHIFT 9 +#define NV40_FP_OP_OUTMASK_MASK (0xF << 9) +# define NV40_FP_OP_OUT_X (1 << 9) +# define NV40_FP_OP_OUT_Y (1 <<10) +# define NV40_FP_OP_OUT_Z (1 <<11) +# define NV40_FP_OP_OUT_W (1 <<12) +/* Uncertain about these, especially the input_src values.. it's possible that + * they can be dynamically changed. + */ +#define NV40_FP_OP_INPUT_SRC_SHIFT 13 +#define NV40_FP_OP_INPUT_SRC_MASK (15 << 13) +# define NV40_FP_OP_INPUT_SRC_POSITION 0x0 +# define NV40_FP_OP_INPUT_SRC_COL0 0x1 +# define NV40_FP_OP_INPUT_SRC_COL1 0x2 +# define NV40_FP_OP_INPUT_SRC_FOGC 0x3 +# define NV40_FP_OP_INPUT_SRC_TC0 0x4 +# define NV40_FP_OP_INPUT_SRC_TC(n) (0x4 + n) +# define NV40_FP_OP_INPUT_SRC_FACING 0xE +#define NV40_FP_OP_TEX_UNIT_SHIFT 17 +#define NV40_FP_OP_TEX_UNIT_MASK (0xF << 17) +#define NV40_FP_OP_PRECISION_SHIFT 22 +#define NV40_FP_OP_PRECISION_MASK (3 << 22) +# define NV40_FP_PRECISION_FP32 0 +# define NV40_FP_PRECISION_FP16 1 +# define NV40_FP_PRECISION_FX12 2 +#define NV40_FP_OP_OPCODE_SHIFT 24 +#define NV40_FP_OP_OPCODE_MASK (0x3F << 24) +# define NV40_FP_OP_OPCODE_NOP 0x00 +# define NV40_FP_OP_OPCODE_MOV 0x01 +# define NV40_FP_OP_OPCODE_MUL 0x02 +# define NV40_FP_OP_OPCODE_ADD 0x03 +# define NV40_FP_OP_OPCODE_MAD 0x04 +# define NV40_FP_OP_OPCODE_DP3 0x05 +# define NV40_FP_OP_OPCODE_DP4 0x06 +# define NV40_FP_OP_OPCODE_DST 0x07 +# define NV40_FP_OP_OPCODE_MIN 0x08 +# define NV40_FP_OP_OPCODE_MAX 0x09 +# define NV40_FP_OP_OPCODE_SLT 0x0A +# define NV40_FP_OP_OPCODE_SGE 0x0B +# define NV40_FP_OP_OPCODE_SLE 0x0C +# define NV40_FP_OP_OPCODE_SGT 0x0D +# define NV40_FP_OP_OPCODE_SNE 0x0E +# define NV40_FP_OP_OPCODE_SEQ 0x0F +# define NV40_FP_OP_OPCODE_FRC 0x10 +# define NV40_FP_OP_OPCODE_FLR 0x11 +# define NV40_FP_OP_OPCODE_KIL 0x12 +# define NV40_FP_OP_OPCODE_PK4B 0x13 +# define NV40_FP_OP_OPCODE_UP4B 0x14 +/* DDX/DDY can only write to XY */ +# define NV40_FP_OP_OPCODE_DDX 0x15 +# define NV40_FP_OP_OPCODE_DDY 0x16 +# define NV40_FP_OP_OPCODE_TEX 0x17 +# define NV40_FP_OP_OPCODE_TXP 0x18 +# define NV40_FP_OP_OPCODE_TXD 0x19 +# define NV40_FP_OP_OPCODE_RCP 0x1A +# define NV40_FP_OP_OPCODE_EX2 0x1C +# define NV40_FP_OP_OPCODE_LG2 0x1D +# define NV40_FP_OP_OPCODE_COS 0x22 +# define NV40_FP_OP_OPCODE_SIN 0x23 +# define NV40_FP_OP_OPCODE_PK2H 0x24 +# define NV40_FP_OP_OPCODE_UP2H 0x25 +# define NV40_FP_OP_OPCODE_PK4UB 0x27 +# define NV40_FP_OP_OPCODE_UP4UB 0x28 +# define NV40_FP_OP_OPCODE_PK2US 0x29 +# define NV40_FP_OP_OPCODE_UP2US 0x2A +# define NV40_FP_OP_OPCODE_DP2A 0x2E +# define NV40_FP_OP_OPCODE_TXL 0x2F +# define NV40_FP_OP_OPCODE_TXB 0x31 +# define NV40_FP_OP_OPCODE_DIV 0x3A +/* The use of these instructions appears to be indicated by bit 31 of DWORD 2.*/ +# define NV40_FP_OP_BRA_OPCODE_BRK 0x0 +# define NV40_FP_OP_BRA_OPCODE_CAL 0x1 +# define NV40_FP_OP_BRA_OPCODE_IF 0x2 +# define NV40_FP_OP_BRA_OPCODE_LOOP 0x3 +# define NV40_FP_OP_BRA_OPCODE_REP 0x4 +# define NV40_FP_OP_BRA_OPCODE_RET 0x5 +#define NV40_FP_OP_OUT_SAT (1 << 31) + +/* high order bits of SRC0 */ +#define NV40_FP_OP_OUT_ABS (1 << 29) +#define NV40_FP_OP_COND_SWZ_W_SHIFT 27 +#define NV40_FP_OP_COND_SWZ_W_MASK (3 << 27) +#define NV40_FP_OP_COND_SWZ_Z_SHIFT 25 +#define NV40_FP_OP_COND_SWZ_Z_MASK (3 << 25) +#define NV40_FP_OP_COND_SWZ_Y_SHIFT 23 +#define NV40_FP_OP_COND_SWZ_Y_MASK (3 << 23) +#define NV40_FP_OP_COND_SWZ_X_SHIFT 21 +#define NV40_FP_OP_COND_SWZ_X_MASK (3 << 21) +#define NV40_FP_OP_COND_SWZ_ALL_SHIFT 21 +#define NV40_FP_OP_COND_SWZ_ALL_MASK (0xFF << 21) +#define NV40_FP_OP_COND_SHIFT 18 +#define NV40_FP_OP_COND_MASK (0x07 << 18) +# define NV40_FP_OP_COND_FL 0 +# define NV40_FP_OP_COND_LT 1 +# define NV40_FP_OP_COND_EQ 2 +# define NV40_FP_OP_COND_LE 3 +# define NV40_FP_OP_COND_GT 4 +# define NV40_FP_OP_COND_NE 5 +# define NV40_FP_OP_COND_GE 6 +# define NV40_FP_OP_COND_TR 7 + +/* high order bits of SRC1 */ +#define NV40_FP_OP_OPCODE_IS_BRANCH (1<<31) +#define NV40_FP_OP_SRC_SCALE_SHIFT 28 +#define NV40_FP_OP_SRC_SCALE_MASK (3 << 28) + +/* SRC1 LOOP */ +#define NV40_FP_OP_LOOP_INCR_SHIFT 19 +#define NV40_FP_OP_LOOP_INCR_MASK (0xFF << 19) +#define NV40_FP_OP_LOOP_INDEX_SHIFT 10 +#define NV40_FP_OP_LOOP_INDEX_MASK (0xFF << 10) +#define NV40_FP_OP_LOOP_COUNT_SHIFT 2 +#define NV40_FP_OP_LOOP_COUNT_MASK (0xFF << 2) + +/* SRC1 IF */ +#define NV40_FP_OP_ELSE_ID_SHIFT 2 +#define NV40_FP_OP_ELSE_ID_MASK (0xFF << 2) + +/* SRC1 CAL */ +#define NV40_FP_OP_IADDR_SHIFT 2 +#define NV40_FP_OP_IADDR_MASK (0xFF << 2) + +/* SRC1 REP + * I have no idea why there are 3 count values here.. but they + * have always been filled with the same value in my tests so + * far.. + */ +#define NV40_FP_OP_REP_COUNT1_SHIFT 2 +#define NV40_FP_OP_REP_COUNT1_MASK (0xFF << 2) +#define NV40_FP_OP_REP_COUNT2_SHIFT 10 +#define NV40_FP_OP_REP_COUNT2_MASK (0xFF << 10) +#define NV40_FP_OP_REP_COUNT3_SHIFT 19 +#define NV40_FP_OP_REP_COUNT3_MASK (0xFF << 19) + +/* SRC2 REP/IF */ +#define NV40_FP_OP_END_ID_SHIFT 2 +#define NV40_FP_OP_END_ID_MASK (0xFF << 2) + +// SRC2 high-order +#define NV40_FP_OP_INDEX_INPUT (1 << 30) +#define NV40_FP_OP_ADDR_INDEX_SHIFT 19 +#define NV40_FP_OP_ADDR_INDEX_MASK (0xF << 19) + +//== Register selection == +#define NV40_FP_REG_TYPE_SHIFT 0 +#define NV40_FP_REG_TYPE_MASK (3 << 0) +# define NV40_FP_REG_TYPE_TEMP 0 +# define NV40_FP_REG_TYPE_INPUT 1 +# define NV40_FP_REG_TYPE_CONST 2 +#define NV40_FP_REG_SRC_SHIFT 2 +#define NV40_FP_REG_SRC_MASK (31 << 2) +#define NV40_FP_REG_UNK_0 (1 << 8) +#define NV40_FP_REG_SWZ_ALL_SHIFT 9 +#define NV40_FP_REG_SWZ_ALL_MASK (255 << 9) +#define NV40_FP_REG_SWZ_X_SHIFT 9 +#define NV40_FP_REG_SWZ_X_MASK (3 << 9) +#define NV40_FP_REG_SWZ_Y_SHIFT 11 +#define NV40_FP_REG_SWZ_Y_MASK (3 << 11) +#define NV40_FP_REG_SWZ_Z_SHIFT 13 +#define NV40_FP_REG_SWZ_Z_MASK (3 << 13) +#define NV40_FP_REG_SWZ_W_SHIFT 15 +#define NV40_FP_REG_SWZ_W_MASK (3 << 15) +# define NV40_FP_SWIZZLE_X 0 +# define NV40_FP_SWIZZLE_Y 1 +# define NV40_FP_SWIZZLE_Z 2 +# define NV40_FP_SWIZZLE_W 3 +#define NV40_FP_REG_NEGATE (1 << 17) + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nv40_vertprog.c b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c new file mode 100644 index 0000000000..111c6de71b --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c @@ -0,0 +1,647 @@ +#include "nouveau_shader.h" +#include "nouveau_msg.h" +#include "nv40_shader.h" + +extern nvsSwzComp NV20VP_TX_SWIZZLE[4]; +extern void NV20VPTXSwizzle(int hwswz, nvsSwzComp *swz); + +/***************************************************************************** + * Assembly routines + */ +static int +NV40VPSupportsOpcode(nvsFunc * shader, nvsOpcode op) +{ + if (shader->GetOPTXFromSOP(op, NULL)) + return 1; + return 0; +} + +static void +NV40VPSetOpcode(nvsFunc *shader, unsigned int opcode, int slot) +{ + if (slot) shader->inst[1] |= (opcode << NV40_VP_INST_SCA_OPCODE_SHIFT); + else shader->inst[1] |= (opcode << NV40_VP_INST_VEC_OPCODE_SHIFT); +} + +static void +NV40VPSetCCUpdate(nvsFunc *shader) +{ + shader->inst[0] |= NV40_VP_INST_COND_UPDATE_ENABLE; +} + +static void +NV40VPSetCondition(nvsFunc *shader, int on, nvsCond cond, int reg, + nvsSwzComp *swizzle) +{ + unsigned int hwcond; + + if (on ) shader->inst[0] |= NV40_VP_INST_COND_TEST_ENABLE; + if (reg) shader->inst[0] |= NV40_VP_INST_COND_REG_SELECT_1; + + switch (cond) { + case NVS_COND_TR: hwcond = NV40_VP_INST_COND_TR; break; + case NVS_COND_FL: hwcond = NV40_VP_INST_COND_FL; break; + case NVS_COND_LT: hwcond = NV40_VP_INST_COND_LT; break; + case NVS_COND_GT: hwcond = NV40_VP_INST_COND_GT; break; + case NVS_COND_NE: hwcond = NV40_VP_INST_COND_NE; break; + case NVS_COND_EQ: hwcond = NV40_VP_INST_COND_EQ; break; + case NVS_COND_GE: hwcond = NV40_VP_INST_COND_GE; break; + case NVS_COND_LE: hwcond = NV40_VP_INST_COND_LE; break; + default: + WARN_ONCE("unknown vp cond %d\n", cond); + hwcond = NV40_VP_INST_COND_TR; + break; + } + shader->inst[0] |= (hwcond << NV40_VP_INST_COND_SHIFT); + + shader->inst[0] |= (swizzle[NVS_SWZ_X] << NV40_VP_INST_COND_SWZ_X_SHIFT); + shader->inst[0] |= (swizzle[NVS_SWZ_Y] << NV40_VP_INST_COND_SWZ_Y_SHIFT); + shader->inst[0] |= (swizzle[NVS_SWZ_Z] << NV40_VP_INST_COND_SWZ_Z_SHIFT); + shader->inst[0] |= (swizzle[NVS_SWZ_W] << NV40_VP_INST_COND_SWZ_W_SHIFT); +} + +static void +NV40VPSetResult(nvsFunc *shader, nvsRegister * dest, unsigned int mask, + int slot) +{ + unsigned int hwmask = 0; + + if (mask & SMASK_X) hwmask |= (1 << 3); + if (mask & SMASK_Y) hwmask |= (1 << 2); + if (mask & SMASK_Z) hwmask |= (1 << 1); + if (mask & SMASK_W) hwmask |= (1 << 0); + + if (dest->file == NVS_FILE_RESULT) { + int hwidx; + + switch (dest->index) { + case NVS_FR_POSITION : hwidx = NV40_VP_INST_DEST_POS; break; + case NVS_FR_COL0 : hwidx = NV40_VP_INST_DEST_COL0; break; + case NVS_FR_COL1 : hwidx = NV40_VP_INST_DEST_COL1; break; + case NVS_FR_BFC0 : hwidx = NV40_VP_INST_DEST_BFC0; break; + case NVS_FR_BFC1 : hwidx = NV40_VP_INST_DEST_BFC1; break; + case NVS_FR_FOGCOORD : hwidx = NV40_VP_INST_DEST_FOGC; break; + case NVS_FR_POINTSZ : hwidx = NV40_VP_INST_DEST_PSZ; break; + case NVS_FR_TEXCOORD0: hwidx = NV40_VP_INST_DEST_TC(0); break; + case NVS_FR_TEXCOORD1: hwidx = NV40_VP_INST_DEST_TC(1); break; + case NVS_FR_TEXCOORD2: hwidx = NV40_VP_INST_DEST_TC(2); break; + case NVS_FR_TEXCOORD3: hwidx = NV40_VP_INST_DEST_TC(3); break; + case NVS_FR_TEXCOORD4: hwidx = NV40_VP_INST_DEST_TC(4); break; + case NVS_FR_TEXCOORD5: hwidx = NV40_VP_INST_DEST_TC(5); break; + case NVS_FR_TEXCOORD6: hwidx = NV40_VP_INST_DEST_TC(6); break; + case NVS_FR_TEXCOORD7: hwidx = NV40_VP_INST_DEST_TC(7); break; + default: + WARN_ONCE("unknown vtxprog output %d\n", dest->index); + hwidx = 0; + break; + } + shader->inst[3] |= (hwidx << NV40_VP_INST_DEST_SHIFT); + + if (slot) { + shader->inst[3] |= NV40_VP_INST_SCA_RESULT; + shader->inst[3] |= NV40_VP_INST_SCA_DEST_TEMP_MASK; + } else { + shader->inst[0] |= NV40_VP_INST_VEC_RESULT; + shader->inst[0] |= NV40_VP_INST_VEC_DEST_TEMP_MASK | (1<<20); + } + } else { + /* NVS_FILE_TEMP || NVS_FILE_ADDRESS */ + if (slot) + shader->inst[3] |= (dest->index << NV40_VP_INST_SCA_DEST_TEMP_SHIFT); + else + shader->inst[0] |= (dest->index << NV40_VP_INST_VEC_DEST_TEMP_SHIFT); + } + + if (slot) shader->inst[3] |= (hwmask << NV40_VP_INST_SCA_WRITEMASK_SHIFT); + else shader->inst[3] |= (hwmask << NV40_VP_INST_VEC_WRITEMASK_SHIFT); +} + +static void +NV40VPInsertSource(nvsFunc *shader, unsigned int hw, int pos) +{ + switch (pos) { + case 0: + shader->inst[1] |= ((hw & NV40_VP_SRC0_HIGH_MASK) >> + NV40_VP_SRC0_HIGH_SHIFT) + << NV40_VP_INST_SRC0H_SHIFT; + shader->inst[2] |= (hw & NV40_VP_SRC0_LOW_MASK) + << NV40_VP_INST_SRC0L_SHIFT; + break; + case 1: + shader->inst[2] |= hw + << NV40_VP_INST_SRC1_SHIFT; + break; + case 2: + shader->inst[2] |= ((hw & NV40_VP_SRC2_HIGH_MASK) >> + NV40_VP_SRC2_HIGH_SHIFT) + << NV40_VP_INST_SRC2H_SHIFT; + shader->inst[3] |= (hw & NV40_VP_SRC2_LOW_MASK) + << NV40_VP_INST_SRC2L_SHIFT; + break; + default: + assert(0); + break; + } +} + +static void +NV40VPSetSource(nvsFunc *shader, nvsRegister * src, int pos) +{ + unsigned int hw = 0; + + switch (src->file) { + case NVS_FILE_ADDRESS: + break; + case NVS_FILE_ATTRIB: + hw |= (NV40_VP_SRC_REG_TYPE_INPUT << NV40_VP_SRC_REG_TYPE_SHIFT); + + shader->inst[1] |= (src->index << NV40_VP_INST_INPUT_SRC_SHIFT); + if (src->indexed) { + shader->inst[0] |= NV40_VP_INST_INDEX_INPUT; + if (src->addr_reg) + shader->inst[0] |= NV40_VP_INST_ADDR_REG_SELECT_1; + shader->inst[0] |= (src->addr_comp << NV40_VP_INST_ADDR_SWZ_SHIFT); + } + break; + case NVS_FILE_CONST: + hw |= (NV40_VP_SRC_REG_TYPE_CONST << NV40_VP_SRC_REG_TYPE_SHIFT); + + shader->inst[1] |= (src->index << NV40_VP_INST_CONST_SRC_SHIFT); + if (src->indexed) { + shader->inst[3] |= NV40_VP_INST_INDEX_CONST; + if (src->addr_reg) + shader->inst[0] |= NV40_VP_INST_ADDR_REG_SELECT_1; + shader->inst[0] |= (src->addr_comp << NV40_VP_INST_ADDR_SWZ_SHIFT); + } + break; + case NVS_FILE_TEMP: + hw |= (NV40_VP_SRC_REG_TYPE_TEMP << NV40_VP_SRC_REG_TYPE_SHIFT); + hw |= (src->index << NV40_VP_SRC_TEMP_SRC_SHIFT); + break; + default: + fprintf(stderr, "unknown source file %d\n", src->file); + assert(0); + break; + } + + if (src->file != NVS_FILE_ADDRESS) { + if (src->negate) + hw |= NV40_VP_SRC_NEGATE; + if (src->abs) + shader->inst[0] |= (1 << (21 + pos)); + hw |= (src->swizzle[0] << NV40_VP_SRC_SWZ_X_SHIFT); + hw |= (src->swizzle[1] << NV40_VP_SRC_SWZ_Y_SHIFT); + hw |= (src->swizzle[2] << NV40_VP_SRC_SWZ_Z_SHIFT); + hw |= (src->swizzle[3] << NV40_VP_SRC_SWZ_W_SHIFT); + + NV40VPInsertSource(shader, hw, pos); + } +} + +static void +NV40VPSetUnusedSource(nvsFunc *shader, int pos) +{ + unsigned int hw; + + hw = ((NV40_VP_SRC_REG_TYPE_INPUT << NV40_VP_SRC_REG_TYPE_SHIFT) | + (NVS_SWZ_X << NV40_VP_SRC_SWZ_X_SHIFT) | + (NVS_SWZ_Y << NV40_VP_SRC_SWZ_Y_SHIFT) | + (NVS_SWZ_Z << NV40_VP_SRC_SWZ_Z_SHIFT) | + (NVS_SWZ_W << NV40_VP_SRC_SWZ_W_SHIFT)); + + NV40VPInsertSource(shader, hw, pos); +} + +static void +NV40VPSetLastInst(nvsFunc *shader, int pos) +{ + shader->inst[3] |= 1; +} + +/***************************************************************************** + * Disassembly routines + */ +static int +NV40VPHasMergedInst(nvsFunc * shader) +{ + if (shader->GetOpcodeHW(shader, 0) != NV40_VP_INST_OP_NOP && + shader->GetOpcodeHW(shader, 1) != NV40_VP_INST_OP_NOP) + return 1; + return 0; +} + +static unsigned int +NV40VPGetOpcodeHW(nvsFunc * shader, int slot) +{ + int op; + + if (slot) + op = (shader->inst[1] & NV40_VP_INST_SCA_OPCODE_MASK) + >> NV40_VP_INST_SCA_OPCODE_SHIFT; + else + op = (shader->inst[1] & NV40_VP_INST_VEC_OPCODE_MASK) + >> NV40_VP_INST_VEC_OPCODE_SHIFT; + + return op; +} + +static nvsRegFile +NV40VPGetDestFile(nvsFunc * shader, int merged) +{ + nvsOpcode op; + + op = shader->GetOpcode(shader, merged); + switch (op) { + case NVS_OP_ARL: + case NVS_OP_ARR: + case NVS_OP_ARA: + case NVS_OP_POPA: + return NVS_FILE_ADDRESS; + default: + if (shader->GetOpcodeSlot(shader, merged)) { + if (shader->inst[3] & NV40_VP_INST_SCA_RESULT) + return NVS_FILE_RESULT; + } + else { + if (shader->inst[0] & NV40_VP_INST_VEC_RESULT) + return NVS_FILE_RESULT; + } + return NVS_FILE_TEMP; + } + +} + +static unsigned int +NV40VPGetDestID(nvsFunc * shader, int merged) +{ + int id; + + switch (shader->GetDestFile(shader, merged)) { + case NVS_FILE_RESULT: + id = ((shader->inst[3] & NV40_VP_INST_DEST_MASK) + >> NV40_VP_INST_DEST_SHIFT); + switch (id) { + case NV40_VP_INST_DEST_POS : return NVS_FR_POSITION; + case NV40_VP_INST_DEST_COL0: return NVS_FR_COL0; + case NV40_VP_INST_DEST_COL1: return NVS_FR_COL1; + case NV40_VP_INST_DEST_BFC0: return NVS_FR_BFC0; + case NV40_VP_INST_DEST_BFC1: return NVS_FR_BFC1; + case NV40_VP_INST_DEST_FOGC: { + int mask = shader->GetDestMask(shader, merged); + switch (mask) { + case SMASK_X: return NVS_FR_FOGCOORD; + case SMASK_Y: return NVS_FR_CLIP0; + case SMASK_Z: return NVS_FR_CLIP1; + case SMASK_W: return NVS_FR_CLIP2; + default: + printf("more than 1 mask component set in FOGC writemask!\n"); + return NVS_FR_UNKNOWN; + } + } + case NV40_VP_INST_DEST_PSZ: + { + int mask = shader->GetDestMask(shader, merged); + switch (mask) { + case SMASK_X: return NVS_FR_POINTSZ; + case SMASK_Y: return NVS_FR_CLIP3; + case SMASK_Z: return NVS_FR_CLIP4; + case SMASK_W: return NVS_FR_CLIP5; + default: + printf("more than 1 mask component set in PSZ writemask!\n"); + return NVS_FR_UNKNOWN; + } + } + case NV40_VP_INST_DEST_TC(0): return NVS_FR_TEXCOORD0; + case NV40_VP_INST_DEST_TC(1): return NVS_FR_TEXCOORD1; + case NV40_VP_INST_DEST_TC(2): return NVS_FR_TEXCOORD2; + case NV40_VP_INST_DEST_TC(3): return NVS_FR_TEXCOORD3; + case NV40_VP_INST_DEST_TC(4): return NVS_FR_TEXCOORD4; + case NV40_VP_INST_DEST_TC(5): return NVS_FR_TEXCOORD5; + case NV40_VP_INST_DEST_TC(6): return NVS_FR_TEXCOORD6; + case NV40_VP_INST_DEST_TC(7): return NVS_FR_TEXCOORD7; + default: + return -1; + } + case NVS_FILE_ADDRESS: + /* Instructions that write address regs are encoded as if + * they would write temps. + */ + case NVS_FILE_TEMP: + if (shader->GetOpcodeSlot(shader, merged)) + id = ((shader->inst[3] & NV40_VP_INST_SCA_DEST_TEMP_MASK) + >> NV40_VP_INST_SCA_DEST_TEMP_SHIFT); + else + id = ((shader->inst[0] & NV40_VP_INST_VEC_DEST_TEMP_MASK) + >> NV40_VP_INST_VEC_DEST_TEMP_SHIFT); + return id; + default: + return -1; + } +} + +static unsigned int +NV40VPGetDestMask(nvsFunc * shader, int merged) +{ + unsigned int mask = 0; + + if (shader->GetOpcodeSlot(shader, merged)) { + if (shader->inst[3] & NV40_VP_INST_SCA_WRITEMASK_X) mask |= SMASK_X; + if (shader->inst[3] & NV40_VP_INST_SCA_WRITEMASK_Y) mask |= SMASK_Y; + if (shader->inst[3] & NV40_VP_INST_SCA_WRITEMASK_Z) mask |= SMASK_Z; + if (shader->inst[3] & NV40_VP_INST_SCA_WRITEMASK_W) mask |= SMASK_W; + } else { + if (shader->inst[3] & NV40_VP_INST_VEC_WRITEMASK_X) mask |= SMASK_X; + if (shader->inst[3] & NV40_VP_INST_VEC_WRITEMASK_Y) mask |= SMASK_Y; + if (shader->inst[3] & NV40_VP_INST_VEC_WRITEMASK_Z) mask |= SMASK_Z; + if (shader->inst[3] & NV40_VP_INST_VEC_WRITEMASK_W) mask |= SMASK_W; + } + + return mask; +} + +static unsigned int +NV40VPGetSourceHW(nvsFunc * shader, int merged, int pos) +{ + struct _op_xlat *opr; + unsigned int src; + + opr = shader->GetOPTXRec(shader, merged); + if (!opr) + return -1; + + switch (opr->srcpos[pos]) { + case 0: + src = ((shader->inst[1] & NV40_VP_INST_SRC0H_MASK) + >> NV40_VP_INST_SRC0H_SHIFT) + << NV40_VP_SRC0_HIGH_SHIFT; + src |= ((shader->inst[2] & NV40_VP_INST_SRC0L_MASK) + >> NV40_VP_INST_SRC0L_SHIFT); + break; + case 1: + src = ((shader->inst[2] & NV40_VP_INST_SRC1_MASK) + >> NV40_VP_INST_SRC1_SHIFT); + break; + case 2: + src = ((shader->inst[2] & NV40_VP_INST_SRC2H_MASK) + >> NV40_VP_INST_SRC2H_SHIFT) + << NV40_VP_SRC2_HIGH_SHIFT; + src |= ((shader->inst[3] & NV40_VP_INST_SRC2L_MASK) + >> NV40_VP_INST_SRC2L_SHIFT); + break; + default: + src = -1; + } + + return src; +} + +static nvsRegFile +NV40VPGetSourceFile(nvsFunc * shader, int merged, int pos) +{ + unsigned int src; + struct _op_xlat *opr; + int file; + + opr = shader->GetOPTXRec(shader, merged); + if (!opr || opr->srcpos[pos] == -1) + return -1; + + switch (opr->srcpos[pos]) { + case SPOS_ADDRESS: return NVS_FILE_ADDRESS; + default: + src = shader->GetSourceHW(shader, merged, pos); + file = (src & NV40_VP_SRC_REG_TYPE_MASK) >> NV40_VP_SRC_REG_TYPE_SHIFT; + + switch (file) { + case NV40_VP_SRC_REG_TYPE_TEMP : return NVS_FILE_TEMP; + case NV40_VP_SRC_REG_TYPE_INPUT: return NVS_FILE_ATTRIB; + case NV40_VP_SRC_REG_TYPE_CONST: return NVS_FILE_CONST; + default: + return NVS_FILE_UNKNOWN; + } + } +} + +static int +NV40VPGetSourceID(nvsFunc * shader, int merged, int pos) +{ + switch (shader->GetSourceFile(shader, merged, pos)) { + case NVS_FILE_ATTRIB: + switch ((shader->inst[1] & NV40_VP_INST_INPUT_SRC_MASK) + >> NV40_VP_INST_INPUT_SRC_SHIFT) { + case NV40_VP_INST_IN_POS: return NVS_FR_POSITION; + case NV40_VP_INST_IN_WEIGHT: return NVS_FR_WEIGHT; + case NV40_VP_INST_IN_NORMAL: return NVS_FR_NORMAL; + case NV40_VP_INST_IN_COL0: return NVS_FR_COL0; + case NV40_VP_INST_IN_COL1: return NVS_FR_COL1; + case NV40_VP_INST_IN_FOGC: return NVS_FR_FOGCOORD; + case NV40_VP_INST_IN_TC(0): return NVS_FR_TEXCOORD0; + case NV40_VP_INST_IN_TC(1): return NVS_FR_TEXCOORD1; + case NV40_VP_INST_IN_TC(2): return NVS_FR_TEXCOORD2; + case NV40_VP_INST_IN_TC(3): return NVS_FR_TEXCOORD3; + case NV40_VP_INST_IN_TC(4): return NVS_FR_TEXCOORD4; + case NV40_VP_INST_IN_TC(5): return NVS_FR_TEXCOORD5; + case NV40_VP_INST_IN_TC(6): return NVS_FR_TEXCOORD6; + case NV40_VP_INST_IN_TC(7): return NVS_FR_TEXCOORD7; + default: + return -1; + } + break; + case NVS_FILE_CONST: + return ((shader->inst[1] & NV40_VP_INST_CONST_SRC_MASK) + >> NV40_VP_INST_CONST_SRC_SHIFT); + case NVS_FILE_TEMP: + { + unsigned int src; + + src = shader->GetSourceHW(shader, merged, pos); + return ((src & NV40_VP_SRC_TEMP_SRC_MASK) >> + NV40_VP_SRC_TEMP_SRC_SHIFT); + } + default: + return -1; + } +} + +static int +NV40VPGetSourceNegate(nvsFunc * shader, int merged, int pos) +{ + unsigned int src; + + src = shader->GetSourceHW(shader, merged, pos); + + if (src == -1) + return -1; + return ((src & NV40_VP_SRC_NEGATE) ? 1 : 0); +} + +static void +NV40VPGetSourceSwizzle(nvsFunc * shader, int merged, int pos, nvsSwzComp *swz) +{ + unsigned int src; + int swzbits; + + src = shader->GetSourceHW(shader, merged, pos); + swzbits = (src & NV40_VP_SRC_SWZ_ALL_MASK) >> NV40_VP_SRC_SWZ_ALL_SHIFT; + NV20VPTXSwizzle(swzbits, swz); +} + +static int +NV40VPGetSourceIndexed(nvsFunc * shader, int merged, int pos) +{ + switch (shader->GetSourceFile(shader, merged, pos)) { + case NVS_FILE_ATTRIB: + return ((shader->inst[0] & NV40_VP_INST_INDEX_INPUT) ? 1 : 0); + case NVS_FILE_CONST: + return ((shader->inst[3] & NV40_VP_INST_INDEX_CONST) ? 1 : 0); + default: + return 0; + } +} + +static nvsSwzComp +NV40VPGetAddressRegSwizzle(nvsFunc * shader) +{ + nvsSwzComp swz; + + swz = NV20VP_TX_SWIZZLE[(shader->inst[0] & NV40_VP_INST_ADDR_SWZ_MASK) + >> NV40_VP_INST_ADDR_SWZ_SHIFT]; + return swz; +} + +static int +NV40VPSupportsConditional(nvsFunc * shader) +{ + /*FIXME: Is this true of all ops? */ + return 1; +} + +static int +NV40VPGetConditionUpdate(nvsFunc * shader) +{ + return ((shader->inst[0] & NV40_VP_INST_COND_UPDATE_ENABLE) ? 1 : 0); +} + +static int +NV40VPGetConditionTest(nvsFunc * shader) +{ + int op; + + /* The condition test is unconditionally enabled on some + * instructions. ie: the condition test bit does *NOT* have + * to be set. + * + * FIXME: check other relevant ops for this situation. + */ + op = shader->GetOpcodeHW(shader, 1); + switch (op) { + case NV40_VP_INST_OP_BRA: + return 1; + default: + return ((shader->inst[0] & NV40_VP_INST_COND_TEST_ENABLE) ? 1 : 0); + } +} + +static nvsCond +NV40VPGetCondition(nvsFunc * shader) +{ + int cond; + + cond = ((shader->inst[0] & NV40_VP_INST_COND_MASK) + >> NV40_VP_INST_COND_SHIFT); + + switch (cond) { + case NV40_VP_INST_COND_FL: return NVS_COND_FL; + case NV40_VP_INST_COND_LT: return NVS_COND_LT; + case NV40_VP_INST_COND_EQ: return NVS_COND_EQ; + case NV40_VP_INST_COND_LE: return NVS_COND_LE; + case NV40_VP_INST_COND_GT: return NVS_COND_GT; + case NV40_VP_INST_COND_NE: return NVS_COND_NE; + case NV40_VP_INST_COND_GE: return NVS_COND_GE; + case NV40_VP_INST_COND_TR: return NVS_COND_TR; + default: + return NVS_COND_UNKNOWN; + } +} + +static void +NV40VPGetCondRegSwizzle(nvsFunc * shader, nvsSwzComp *swz) +{ + int swzbits; + + swzbits = (shader->inst[0] & NV40_VP_INST_COND_SWZ_ALL_MASK) + >> NV40_VP_INST_COND_SWZ_ALL_SHIFT; + NV20VPTXSwizzle(swzbits, swz); +} + +static int +NV40VPGetCondRegID(nvsFunc * shader) +{ + return ((shader->inst[0] & NV40_VP_INST_COND_REG_SELECT_1) ? 1 : 0); +} + +static int +NV40VPGetBranch(nvsFunc * shader) +{ + int addr; + + addr = ((shader->inst[2] & NV40_VP_INST_IADDRH_MASK) + >> NV40_VP_INST_IADDRH_SHIFT) << 3; + addr |= ((shader->inst[3] & NV40_VP_INST_IADDRL_MASK) + >> NV40_VP_INST_IADDRL_SHIFT); + return addr; +} + +void +NV40VPInitShaderFuncs(nvsFunc * shader) +{ + /* Inherit NV30 VP code, we share some of it */ + NV30VPInitShaderFuncs(shader); + + /* Limits */ + shader->MaxInst = 4096; + shader->MaxAttrib = 16; + shader->MaxTemp = 32; + shader->MaxAddress = 2; + shader->MaxConst = 256; + shader->caps = SCAP_SRC_ABS; + + /* Add extra opcodes for NV40+ */ +// MOD_OPCODE(NVVP_TX_VOP, NV40_VP_INST_OP_TXWHAT, NVS_OP_TEX , 0, 4, -1); + MOD_OPCODE(NVVP_TX_SOP, NV40_VP_INST_OP_PUSHA, NVS_OP_PUSHA, 3, -1, -1); + MOD_OPCODE(NVVP_TX_SOP, NV40_VP_INST_OP_POPA , NVS_OP_POPA , -1, -1, -1); + + shader->SupportsOpcode = NV40VPSupportsOpcode; + shader->SetOpcode = NV40VPSetOpcode; + shader->SetCCUpdate = NV40VPSetCCUpdate; + shader->SetCondition = NV40VPSetCondition; + shader->SetResult = NV40VPSetResult; + shader->SetSource = NV40VPSetSource; + shader->SetUnusedSource = NV40VPSetUnusedSource; + shader->SetLastInst = NV40VPSetLastInst; + + shader->HasMergedInst = NV40VPHasMergedInst; + shader->GetOpcodeHW = NV40VPGetOpcodeHW; + + shader->GetDestFile = NV40VPGetDestFile; + shader->GetDestID = NV40VPGetDestID; + shader->GetDestMask = NV40VPGetDestMask; + + shader->GetSourceHW = NV40VPGetSourceHW; + shader->GetSourceFile = NV40VPGetSourceFile; + shader->GetSourceID = NV40VPGetSourceID; + shader->GetSourceNegate = NV40VPGetSourceNegate; + shader->GetSourceSwizzle = NV40VPGetSourceSwizzle; + shader->GetSourceIndexed = NV40VPGetSourceIndexed; + + shader->GetRelAddressSwizzle = NV40VPGetAddressRegSwizzle; + + shader->SupportsConditional = NV40VPSupportsConditional; + shader->GetConditionUpdate = NV40VPGetConditionUpdate; + shader->GetConditionTest = NV40VPGetConditionTest; + shader->GetCondition = NV40VPGetCondition; + shader->GetCondRegSwizzle = NV40VPGetCondRegSwizzle; + shader->GetCondRegID = NV40VPGetCondRegID; + + shader->GetBranch = NV40VPGetBranch; +} -- cgit v1.2.3 From 6ff3d2577ec1099a90cce9292118814c00ab0e6a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 26 Nov 2006 10:19:44 +0000 Subject: Fix progs/fp/tri-xpd Fragprog consts are inlined, so make sure we update *all* occurances of a param :) --- src/mesa/drivers/dri/nouveau/nouveau_shader.h | 6 +++++- src/mesa/drivers/dri/nouveau/nouveau_shader_2.c | 8 ++++++-- src/mesa/drivers/dri/nouveau/nv30_fragprog.c | 8 ++++++-- 3 files changed, 17 insertions(+), 5 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h index baf59d0259..fac8851a57 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -47,7 +47,11 @@ typedef struct _nouveauShader { struct { GLfloat *source_val; /* NULL if invariant */ float val[4]; - int hw_index; /* hw-specific value */ + /* Hardware-specific tracking, currently only nv30_fragprog + * makes use of it. + */ + int *hw_index; + int hw_index_cnt; } params[NVS_MAX_CONSTS]; struct { diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c index 1f09b6d453..1cb0ca490e 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c @@ -130,8 +130,12 @@ pass2_add_instruction(nvsPtr nvs, nvsInstruction *inst, nvs->inputs_read |= (1 << reg.index); shader->SetSource(shader, ®, op->srcpos[i]); srcpos_used |= (1<srcpos[i]); - if (reg.file == NVS_FILE_CONST && shader->GetSourceConstVal) - nvs->params[reg.index].hw_index = nvs->program_current + 4; + if (reg.file == NVS_FILE_CONST && shader->GetSourceConstVal) { + int idx_slot = nvs->params[reg.index].hw_index_cnt++; + nvs->params[reg.index].hw_index = realloc( + nvs->params[reg.index].hw_index, sizeof(int) * idx_slot+1); + nvs->params[reg.index].hw_index[idx_slot] = nvs->program_current + 4; + } } } for (i = 0; i < 3; i++) { diff --git a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c index 2e35d08c07..46391eb911 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c +++ b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c @@ -60,11 +60,15 @@ NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs) static void NV30FPUpdateConst(GLcontext *ctx, nouveauShader *nvs, int id) { - uint32_t *current = nvs->program + nvs->params[id].hw_index; uint32_t *new = nvs->params[id].source_val ? nvs->params[id].source_val : nvs->params[id].val; + uint32_t *current; + int i; - COPY_4V(current, new); + for (i=0; iparams[id].hw_index_cnt; i++) { + current = nvs->program + nvs->params[id].hw_index[i]; + COPY_4V(current, new); + } nvs->on_hardware = 0; } -- cgit v1.2.3 From 2f411b0a8bf9af96d7ef582564d8e462abd0f28d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 26 Nov 2006 13:18:41 +0000 Subject: Fix RSQ emulation --- .../drivers/dri/nouveau/nouveau_shader_0_arb.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0_arb.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0_arb.c index 8b5222d069..afb889d421 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0_arb.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0_arb.c @@ -125,6 +125,7 @@ struct pass0_rec { int next_temp; int swzconst_done; int swzconst_id; + nvsRegister const_half; }; #define X NVS_SWZ_X @@ -488,6 +489,7 @@ pass0_emulate_instruction(nouveauShader *nvs, struct prog_instruction *inst) nvsFunc *shader = nvs->func; nvsRegister src[3], dest, temp; nvsInstruction *nvsinst; + struct pass0_rec *rec = nvs->pass_rec; unsigned int mask = pass0_make_mask(inst->DstReg.WriteMask); int i, sat; @@ -561,11 +563,26 @@ pass0_emulate_instruction(nouveauShader *nvs, struct prog_instruction *inst) } break; case OPCODE_RSQ: + if (rec->const_half.file != NVS_FILE_CONST) { + GLfloat const_half[4] = { 0.5, 0.0, 0.0, 0.0 }; + pass0_make_reg(nvs, &rec->const_half, NVS_FILE_CONST, + _mesa_add_unnamed_constant(nvs->mesa.vp.Base.Parameters, + const_half, 4)); + COPY_4V(nvs->params[rec->const_half.index].val, const_half); + } pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); pass0_emit(nvs, NVS_OP_LG2, temp, SMASK_X, 0, - nvsAbs(nvsSwizzle(src[0], X, X, X, X)), nvr_unused, nvr_unused); + nvsAbs(nvsSwizzle(src[0], X, X, X, X)), + nvr_unused, + nvr_unused); + pass0_emit(nvs, NVS_OP_MUL, temp, SMASK_X, 0, + nvsSwizzle(temp, X, X, X, X), + nvsNegate(rec->const_half), + nvr_unused); pass0_emit(nvs, NVS_OP_EX2, dest, mask, sat, - nvsSwizzle(temp, X, X, X, X), nvr_unused, nvr_unused); + nvsSwizzle(temp, X, X, X, X), + nvr_unused, + nvr_unused); break; case OPCODE_SCS: if (mask & SMASK_X) @@ -607,7 +624,6 @@ static GLboolean pass0_translate_instructions(nouveauShader *nvs) { struct gl_program *prog = (struct gl_program *)&nvs->mesa.vp; - struct pass0_rec *rec = nvs->pass_rec; nvsFunc *shader = nvs->func; int ipos; -- cgit v1.2.3 From 98818f159baeaeba45d656d612b64b2f22c63753 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 27 Nov 2006 01:57:37 +0000 Subject: - Add InitInstruction to hw shader backend, and remove SetUnusedSource. - NV30FP/NV40VP: Clear any fields before we OR new values into them - NV40VP: It seems that it might be possible to write a result reg at the same time a temp is written. In InitInstruction, initialise OUT_DEST to OUT_DEST_TEMP so result regs don't get clobbered by default. --- src/mesa/drivers/dri/nouveau/nouveau_shader.h | 2 +- src/mesa/drivers/dri/nouveau/nouveau_shader_2.c | 16 ++--- src/mesa/drivers/dri/nouveau/nv30_fragprog.c | 50 ++++++++----- src/mesa/drivers/dri/nouveau/nv30_shader.h | 1 + src/mesa/drivers/dri/nouveau/nv40_vertprog.c | 95 ++++++++++++++++++------- 5 files changed, 109 insertions(+), 55 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h index fac8851a57..a1e7794487 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -256,6 +256,7 @@ struct _nvsFunc { struct _op_xlat*(*GetOPTXRec) (nvsFunc *, int merged); struct _op_xlat*(*GetOPTXFromSOP) (nvsOpcode, int *id); + void (*InitInstruction) (nvsFunc *); int (*SupportsOpcode) (nvsFunc *, nvsOpcode); void (*SetOpcode) (nvsFunc *, unsigned int opcode, int slot); @@ -265,7 +266,6 @@ struct _nvsFunc { void (*SetResult) (nvsFunc *, nvsRegister *, unsigned int mask, int slot); void (*SetSource) (nvsFunc *, nvsRegister *, int pos); - void (*SetUnusedSource) (nvsFunc *, int pos); void (*SetTexImageUnit) (nvsFunc *, int unit); void (*SetSaturate) (nvsFunc *); void (*SetLastInst) (nvsFunc *); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c index 1cb0ca490e..b39f4668b9 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c @@ -34,6 +34,8 @@ #include "macros.h" #include "enums.h" +#include "program.h" + #include "nouveau_shader.h" struct pass2_rec { @@ -100,7 +102,7 @@ pass2_add_instruction(nvsPtr nvs, nvsInstruction *inst, nvsSwzComp default_swz[4] = { NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W }; nvsFunc *shader = nvs->func; nvsRegister reg; - int i, srcpos_used = ~7; + int i; shader->SetOpcode(shader, op->NV, slot); if (inst->saturate ) shader->SetSaturate(shader); @@ -129,7 +131,6 @@ pass2_add_instruction(nvsPtr nvs, nvsInstruction *inst, if (reg.file == NVS_FILE_ATTRIB) nvs->inputs_read |= (1 << reg.index); shader->SetSource(shader, ®, op->srcpos[i]); - srcpos_used |= (1<srcpos[i]); if (reg.file == NVS_FILE_CONST && shader->GetSourceConstVal) { int idx_slot = nvs->params[reg.index].hw_index_cnt++; nvs->params[reg.index].hw_index = realloc( @@ -138,10 +139,6 @@ pass2_add_instruction(nvsPtr nvs, nvsInstruction *inst, } } } - for (i = 0; i < 3; i++) { - if (!(srcpos_used & (1<SetUnusedSource(shader, i); - } reg = pass2_mangle_reg(nvs, inst, inst->dest); if (reg.file == NVS_FILE_RESULT) @@ -153,9 +150,9 @@ static int pass2_assemble_instruction(nvsPtr nvs, nvsInstruction *inst, int last) { nvsFunc *shader = nvs->func; - struct _op_xlat *op, *op2; - unsigned int hw_inst[8] = {0,0,0,0,0,0,0,0,0}; - int slot, slot2; + struct _op_xlat *op; + unsigned int hw_inst[8]; + int slot; int instsz; int i; @@ -164,6 +161,7 @@ pass2_assemble_instruction(nvsPtr nvs, nvsInstruction *inst, int last) /* Assemble this instruction */ if (!(op = shader->GetOPTXFromSOP(inst->op, &slot))) return 0; + shader->InitInstruction(shader); pass2_add_instruction(nvs, inst, op, slot); if (last) shader->SetLastInst(shader); diff --git a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c index 46391eb911..1c2664ec70 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c +++ b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c @@ -61,7 +61,7 @@ static void NV30FPUpdateConst(GLcontext *ctx, nouveauShader *nvs, int id) { uint32_t *new = nvs->params[id].source_val ? - nvs->params[id].source_val : nvs->params[id].val; + (uint32_t*)nvs->params[id].source_val : (uint32_t*)nvs->params[id].val; uint32_t *current; int i; @@ -101,6 +101,7 @@ NV30FPSupportsOpcode(nvsFunc *shader, nvsOpcode op) static void NV30FPSetOpcode(nvsFunc *shader, unsigned int opcode, int slot) { + shader->inst[0] &= ~NV30_FP_OP_OPCODE_MASK; shader->inst[0] |= (opcode << NV30_FP_OP_OPCODE_SHIFT); } @@ -139,7 +140,10 @@ NV30FPSetCondition(nvsFunc *shader, int on, nvsCond cond, int reg, break; } + shader->inst[1] &= ~NV30_FP_OP_COND_MASK; shader->inst[1] |= (hwcond << NV30_FP_OP_COND_SHIFT); + + shader->inst[1] &= ~NV30_FP_OP_COND_SWZ_ALL_MASK; shader->inst[1] |= (swz[NVS_SWZ_X] << NV30_FP_OP_COND_SWZ_X_SHIFT); shader->inst[1] |= (swz[NVS_SWZ_Y] << NV30_FP_OP_COND_SWZ_Y_SHIFT); shader->inst[1] |= (swz[NVS_SWZ_Z] << NV30_FP_OP_COND_SWZ_Z_SHIFT); @@ -149,7 +153,7 @@ NV30FPSetCondition(nvsFunc *shader, int on, nvsCond cond, int reg, static void NV30FPSetResult(nvsFunc *shader, nvsRegister *reg, unsigned int mask, int slot) { - unsigned int hwreg, hwmask = 0; + unsigned int hwreg; if (mask & SMASK_X) shader->inst[0] |= NV30_FP_OP_OUT_X; if (mask & SMASK_Y) shader->inst[0] |= NV30_FP_OP_OUT_Y; @@ -160,8 +164,11 @@ NV30FPSetResult(nvsFunc *shader, nvsRegister *reg, unsigned int mask, int slot) hwreg = 0; /* FIXME: this is only fragment.color */ /* This is *not* correct, I have no idea what it is either */ shader->inst[0] |= NV30_FP_OP_UNK0_7; - } else + } else { + shader->inst[0] &= ~NV30_FP_OP_UNK0_7; hwreg = reg->index; + } + shader->inst[0] &= ~NV30_FP_OP_OUT_REG_SHIFT; shader->inst[0] |= (hwreg << NV30_FP_OP_OUT_REG_SHIFT); } @@ -197,6 +204,7 @@ NV30FPSetSource(nvsFunc *shader, nvsRegister *reg, int pos) hwin = NV30_FP_OP_INPUT_SRC_COL0; break; } + shader->inst[0] &= ~NV30_FP_OP_INPUT_SRC_MASK; shader->inst[0] |= (hwin << NV30_FP_OP_INPUT_SRC_SHIFT); hwsrc |= (hwin << NV30_FP_REG_SRC_SHIFT); } @@ -220,24 +228,14 @@ NV30FPSetSource(nvsFunc *shader, nvsRegister *reg, int pos) hwsrc |= (reg->swizzle[NVS_SWZ_Z] << NV30_FP_REG_SWZ_Z_SHIFT); hwsrc |= (reg->swizzle[NVS_SWZ_W] << NV30_FP_REG_SWZ_W_SHIFT); + shader->inst[pos+1] &= ~NV30_FP_REG_ALL_MASK; shader->inst[pos+1] |= hwsrc; } -static void -NV30FPSetUnusedSource(nvsFunc *shader, int pos) -{ - shader->inst[pos+1] |= ( - (NV30_FP_REG_TYPE_INPUT << NV30_FP_REG_TYPE_SHIFT) | - (NVS_SWZ_X << NV30_FP_REG_SWZ_X_SHIFT) | - (NVS_SWZ_Y << NV30_FP_REG_SWZ_Y_SHIFT) | - (NVS_SWZ_Z << NV30_FP_REG_SWZ_Z_SHIFT) | - (NVS_SWZ_W << NV30_FP_REG_SWZ_W_SHIFT) - ); -} - static void NV30FPSetTexImageUnit(nvsFunc *shader, int unit) { + shader->inst[0] &= ~NV30_FP_OP_TEX_UNIT_SHIFT; shader->inst[0] |= (unit << NV30_FP_OP_TEX_UNIT_SHIFT); } @@ -247,11 +245,27 @@ NV30FPSetSaturate(nvsFunc *shader) shader->inst[0] |= NV30_FP_OP_OUT_SAT; } +static void +NV30FPInitInstruction(nvsFunc *shader) +{ + unsigned int hwsrc; + + shader->inst[0] = 0; + + hwsrc = (NV30_FP_REG_TYPE_INPUT << NV30_FP_REG_TYPE_SHIFT) | + (NVS_SWZ_X << NV30_FP_REG_SWZ_X_SHIFT) | + (NVS_SWZ_Y << NV30_FP_REG_SWZ_Y_SHIFT) | + (NVS_SWZ_Z << NV30_FP_REG_SWZ_Z_SHIFT) | + (NVS_SWZ_W << NV30_FP_REG_SWZ_W_SHIFT); + shader->inst[1] = hwsrc; + shader->inst[2] = hwsrc; + shader->inst[3] = hwsrc; +} + static void NV30FPSetLastInst(nvsFunc *shader) { - shader->inst[0] |= 1; - + shader->inst[0] |= 1; } /******************************************************************************* @@ -669,13 +683,13 @@ NV30FPInitShaderFuncs(nvsFunc * shader) shader->UploadToHW = NV30FPUploadToHW; shader->UpdateConst = NV30FPUpdateConst; + shader->InitInstruction = NV30FPInitInstruction; shader->SupportsOpcode = NV30FPSupportsOpcode; shader->SetOpcode = NV30FPSetOpcode; shader->SetCCUpdate = NV30FPSetCCUpdate; shader->SetCondition = NV30FPSetCondition; shader->SetResult = NV30FPSetResult; shader->SetSource = NV30FPSetSource; - shader->SetUnusedSource = NV30FPSetUnusedSource; shader->SetTexImageUnit = NV30FPSetTexImageUnit; shader->SetSaturate = NV30FPSetSaturate; shader->SetLastInst = NV30FPSetLastInst; diff --git a/src/mesa/drivers/dri/nouveau/nv30_shader.h b/src/mesa/drivers/dri/nouveau/nv30_shader.h index d0bf639930..7a027dd427 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_shader.h +++ b/src/mesa/drivers/dri/nouveau/nv30_shader.h @@ -351,6 +351,7 @@ #define NV30_FP_OP_INDEX_INPUT (1 << 30) //== Register selection == +#define NV30_FP_REG_ALL_MASK (0x1FFFF<<0) #define NV30_FP_REG_TYPE_SHIFT 0 #define NV30_FP_REG_TYPE_MASK (3 << 0) # define NV30_FP_REG_TYPE_TEMP 0 diff --git a/src/mesa/drivers/dri/nouveau/nv40_vertprog.c b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c index 111c6de71b..f2cb3fb166 100644 --- a/src/mesa/drivers/dri/nouveau/nv40_vertprog.c +++ b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c @@ -19,8 +19,13 @@ NV40VPSupportsOpcode(nvsFunc * shader, nvsOpcode op) static void NV40VPSetOpcode(nvsFunc *shader, unsigned int opcode, int slot) { - if (slot) shader->inst[1] |= (opcode << NV40_VP_INST_SCA_OPCODE_SHIFT); - else shader->inst[1] |= (opcode << NV40_VP_INST_VEC_OPCODE_SHIFT); + if (slot) { + shader->inst[1] &= ~NV40_VP_INST_SCA_OPCODE_MASK; + shader->inst[1] |= (opcode << NV40_VP_INST_SCA_OPCODE_SHIFT); + } else { + shader->inst[1] &= ~NV40_VP_INST_VEC_OPCODE_MASK; + shader->inst[1] |= (opcode << NV40_VP_INST_VEC_OPCODE_SHIFT); + } } static void @@ -36,7 +41,9 @@ NV40VPSetCondition(nvsFunc *shader, int on, nvsCond cond, int reg, unsigned int hwcond; if (on ) shader->inst[0] |= NV40_VP_INST_COND_TEST_ENABLE; + else shader->inst[0] &= ~NV40_VP_INST_COND_TEST_ENABLE; if (reg) shader->inst[0] |= NV40_VP_INST_COND_REG_SELECT_1; + else shader->inst[0] &= ~NV40_VP_INST_COND_REG_SELECT_1; switch (cond) { case NVS_COND_TR: hwcond = NV40_VP_INST_COND_TR; break; @@ -52,8 +59,10 @@ NV40VPSetCondition(nvsFunc *shader, int on, nvsCond cond, int reg, hwcond = NV40_VP_INST_COND_TR; break; } + shader->inst[0] &= ~NV40_VP_INST_COND_MASK; shader->inst[0] |= (hwcond << NV40_VP_INST_COND_SHIFT); + shader->inst[0] &= ~NV40_VP_INST_COND_SWZ_ALL_MASK; shader->inst[0] |= (swizzle[NVS_SWZ_X] << NV40_VP_INST_COND_SWZ_X_SHIFT); shader->inst[0] |= (swizzle[NVS_SWZ_Y] << NV40_VP_INST_COND_SWZ_Y_SHIFT); shader->inst[0] |= (swizzle[NVS_SWZ_Z] << NV40_VP_INST_COND_SWZ_Z_SHIFT); @@ -95,25 +104,31 @@ NV40VPSetResult(nvsFunc *shader, nvsRegister * dest, unsigned int mask, hwidx = 0; break; } + shader->inst[3] &= ~NV40_VP_INST_DEST_MASK; shader->inst[3] |= (hwidx << NV40_VP_INST_DEST_SHIFT); - if (slot) { - shader->inst[3] |= NV40_VP_INST_SCA_RESULT; - shader->inst[3] |= NV40_VP_INST_SCA_DEST_TEMP_MASK; - } else { - shader->inst[0] |= NV40_VP_INST_VEC_RESULT; - shader->inst[0] |= NV40_VP_INST_VEC_DEST_TEMP_MASK | (1<<20); - } + if (slot) shader->inst[3] |= NV40_VP_INST_SCA_RESULT; + else shader->inst[0] |= NV40_VP_INST_VEC_RESULT; } else { /* NVS_FILE_TEMP || NVS_FILE_ADDRESS */ - if (slot) + if (slot) { + shader->inst[3] &= ~NV40_VP_INST_SCA_RESULT; + shader->inst[3] &= ~NV40_VP_INST_SCA_DEST_TEMP_MASK; shader->inst[3] |= (dest->index << NV40_VP_INST_SCA_DEST_TEMP_SHIFT); - else + } else { + shader->inst[0] &= ~NV40_VP_INST_VEC_RESULT; + shader->inst[0] &= ~(NV40_VP_INST_VEC_DEST_TEMP_MASK | (1<<20)); shader->inst[0] |= (dest->index << NV40_VP_INST_VEC_DEST_TEMP_SHIFT); + } } - if (slot) shader->inst[3] |= (hwmask << NV40_VP_INST_SCA_WRITEMASK_SHIFT); - else shader->inst[3] |= (hwmask << NV40_VP_INST_VEC_WRITEMASK_SHIFT); + if (slot) { + shader->inst[3] &= ~NV40_VP_INST_SCA_WRITEMASK_MASK; + shader->inst[3] |= (hwmask << NV40_VP_INST_SCA_WRITEMASK_SHIFT); + } else { + shader->inst[3] &= ~NV40_VP_INST_VEC_WRITEMASK_MASK; + shader->inst[3] |= (hwmask << NV40_VP_INST_VEC_WRITEMASK_SHIFT); + } } static void @@ -121,6 +136,8 @@ NV40VPInsertSource(nvsFunc *shader, unsigned int hw, int pos) { switch (pos) { case 0: + shader->inst[1] &= ~NV40_VP_INST_SRC0H_MASK; + shader->inst[2] &= ~NV40_VP_INST_SRC0L_MASK; shader->inst[1] |= ((hw & NV40_VP_SRC0_HIGH_MASK) >> NV40_VP_SRC0_HIGH_SHIFT) << NV40_VP_INST_SRC0H_SHIFT; @@ -128,10 +145,13 @@ NV40VPInsertSource(nvsFunc *shader, unsigned int hw, int pos) << NV40_VP_INST_SRC0L_SHIFT; break; case 1: + shader->inst[2] &= ~NV40_VP_INST_SRC1_MASK; shader->inst[2] |= hw << NV40_VP_INST_SRC1_SHIFT; break; case 2: + shader->inst[2] &= ~NV40_VP_INST_SRC2H_MASK; + shader->inst[3] &= ~NV40_VP_INST_SRC2L_MASK; shader->inst[2] |= ((hw & NV40_VP_SRC2_HIGH_MASK) >> NV40_VP_SRC2_HIGH_SHIFT) << NV40_VP_INST_SRC2H_SHIFT; @@ -155,24 +175,34 @@ NV40VPSetSource(nvsFunc *shader, nvsRegister * src, int pos) case NVS_FILE_ATTRIB: hw |= (NV40_VP_SRC_REG_TYPE_INPUT << NV40_VP_SRC_REG_TYPE_SHIFT); + shader->inst[1] &= ~NV40_VP_INST_INPUT_SRC_MASK; shader->inst[1] |= (src->index << NV40_VP_INST_INPUT_SRC_SHIFT); if (src->indexed) { shader->inst[0] |= NV40_VP_INST_INDEX_INPUT; if (src->addr_reg) shader->inst[0] |= NV40_VP_INST_ADDR_REG_SELECT_1; + else + shader->inst[0] &= ~NV40_VP_INST_ADDR_REG_SELECT_1; + shader->inst[0] &= ~NV40_VP_INST_ADDR_SWZ_SHIFT; shader->inst[0] |= (src->addr_comp << NV40_VP_INST_ADDR_SWZ_SHIFT); - } + } else + shader->inst[0] &= ~NV40_VP_INST_INDEX_INPUT; break; case NVS_FILE_CONST: hw |= (NV40_VP_SRC_REG_TYPE_CONST << NV40_VP_SRC_REG_TYPE_SHIFT); + shader->inst[1] &= ~NV40_VP_INST_CONST_SRC_MASK; shader->inst[1] |= (src->index << NV40_VP_INST_CONST_SRC_SHIFT); if (src->indexed) { shader->inst[3] |= NV40_VP_INST_INDEX_CONST; if (src->addr_reg) shader->inst[0] |= NV40_VP_INST_ADDR_REG_SELECT_1; + else + shader->inst[0] &= ~NV40_VP_INST_ADDR_REG_SELECT_1; + shader->inst[0] &= ~NV40_VP_INST_ADDR_SWZ_MASK; shader->inst[0] |= (src->addr_comp << NV40_VP_INST_ADDR_SWZ_SHIFT); - } + } else + shader->inst[3] &= ~NV40_VP_INST_INDEX_CONST; break; case NVS_FILE_TEMP: hw |= (NV40_VP_SRC_REG_TYPE_TEMP << NV40_VP_SRC_REG_TYPE_SHIFT); @@ -189,6 +219,8 @@ NV40VPSetSource(nvsFunc *shader, nvsRegister * src, int pos) hw |= NV40_VP_SRC_NEGATE; if (src->abs) shader->inst[0] |= (1 << (21 + pos)); + else + shader->inst[0] &= ~(1 << (21 + pos)); hw |= (src->swizzle[0] << NV40_VP_SRC_SWZ_X_SHIFT); hw |= (src->swizzle[1] << NV40_VP_SRC_SWZ_Y_SHIFT); hw |= (src->swizzle[2] << NV40_VP_SRC_SWZ_Z_SHIFT); @@ -199,21 +231,30 @@ NV40VPSetSource(nvsFunc *shader, nvsRegister * src, int pos) } static void -NV40VPSetUnusedSource(nvsFunc *shader, int pos) +NV40VPInitInstruction(nvsFunc *shader) { - unsigned int hw; - - hw = ((NV40_VP_SRC_REG_TYPE_INPUT << NV40_VP_SRC_REG_TYPE_SHIFT) | - (NVS_SWZ_X << NV40_VP_SRC_SWZ_X_SHIFT) | - (NVS_SWZ_Y << NV40_VP_SRC_SWZ_Y_SHIFT) | - (NVS_SWZ_Z << NV40_VP_SRC_SWZ_Z_SHIFT) | - (NVS_SWZ_W << NV40_VP_SRC_SWZ_W_SHIFT)); - - NV40VPInsertSource(shader, hw, pos); + unsigned int hwsrc = 0; + + shader->inst[0] = /*NV40_VP_INST_VEC_RESULT | */ + NV40_VP_INST_VEC_DEST_TEMP_MASK | (1<<20); + shader->inst[1] = 0; + shader->inst[2] = 0; + shader->inst[3] = NV40_VP_INST_SCA_RESULT | + NV40_VP_INST_SCA_DEST_TEMP_MASK | + NV40_VP_INST_DEST_MASK; + + hwsrc = (NV40_VP_SRC_REG_TYPE_INPUT << NV40_VP_SRC_REG_TYPE_SHIFT) | + (NVS_SWZ_X << NV40_VP_SRC_SWZ_X_SHIFT) | + (NVS_SWZ_Y << NV40_VP_SRC_SWZ_Y_SHIFT) | + (NVS_SWZ_Z << NV40_VP_SRC_SWZ_Z_SHIFT) | + (NVS_SWZ_W << NV40_VP_SRC_SWZ_W_SHIFT); + NV40VPInsertSource(shader, hwsrc, 0); + NV40VPInsertSource(shader, hwsrc, 1); + NV40VPInsertSource(shader, hwsrc, 2); } static void -NV40VPSetLastInst(nvsFunc *shader, int pos) +NV40VPSetLastInst(nvsFunc *shader) { shader->inst[3] |= 1; } @@ -611,13 +652,13 @@ NV40VPInitShaderFuncs(nvsFunc * shader) MOD_OPCODE(NVVP_TX_SOP, NV40_VP_INST_OP_PUSHA, NVS_OP_PUSHA, 3, -1, -1); MOD_OPCODE(NVVP_TX_SOP, NV40_VP_INST_OP_POPA , NVS_OP_POPA , -1, -1, -1); + shader->InitInstruction = NV40VPInitInstruction; shader->SupportsOpcode = NV40VPSupportsOpcode; shader->SetOpcode = NV40VPSetOpcode; shader->SetCCUpdate = NV40VPSetCCUpdate; shader->SetCondition = NV40VPSetCondition; shader->SetResult = NV40VPSetResult; shader->SetSource = NV40VPSetSource; - shader->SetUnusedSource = NV40VPSetUnusedSource; shader->SetLastInst = NV40VPSetLastInst; shader->HasMergedInst = NV40VPHasMergedInst; -- cgit v1.2.3 From b4dcb99cbc21ad1dafa12e31086f9e0d5fc05e81 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 3 Dec 2006 02:01:49 +0000 Subject: Fix a copy+paste'o that caused some *very* strange bugs.. --- src/mesa/drivers/dri/nouveau/nouveau_object.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.c b/src/mesa/drivers/dri/nouveau/nouveau_object.c index cd46feff7c..032cdee2f7 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.c @@ -33,7 +33,7 @@ static GLboolean nouveauCreateDmaObject(nouveauContextPtr nmesa, dma.target = target; dma.access = access; dma.offset = offset; - dma.handle = handle; + dma.size = size; ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_DMA_OBJECT_INIT, &dma, sizeof(dma)); return ret == 0; -- cgit v1.2.3 From d88d895e5a642cffaaf6b654b27686f2eac901d2 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sun, 3 Dec 2006 09:08:26 +0000 Subject: Merge the pciid work. Use lock step versioning with the drm. --- src/mesa/drivers/dri/nouveau/nouveau_card.c | 42 +---- src/mesa/drivers/dri/nouveau/nouveau_card_list.h | 229 +++++++++++++++++++++++ src/mesa/drivers/dri/nouveau/nouveau_context.c | 3 +- src/mesa/drivers/dri/nouveau/nouveau_context.h | 12 -- src/mesa/drivers/dri/nouveau/nouveau_fifo.c | 3 +- src/mesa/drivers/dri/nouveau/nouveau_fifo.h | 2 +- src/mesa/drivers/dri/nouveau/nouveau_reg.h | 10 +- src/mesa/drivers/dri/nouveau/nouveau_screen.c | 6 +- src/mesa/drivers/dri/nouveau/nouveau_shader.c | 3 +- src/mesa/drivers/dri/nouveau/nouveau_state.c | 2 +- 10 files changed, 253 insertions(+), 59 deletions(-) create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_card_list.h (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_card.c b/src/mesa/drivers/dri/nouveau/nouveau_card.c index 4a5d5eb9d7..a0628389bf 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_card.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_card.c @@ -1,48 +1,18 @@ #include "nouveau_card.h" #include "nouveau_reg.h" - -static nouveau_card nouveau_card_list[]={ -//{0x0010, "Riva 128", ????, NV_03, 0}, -{0x0020, "TNT/TNT2", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, -{0x00A0, "TNT2", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, -{0x0100, "GeForce", NV10_TCL_PRIMITIVE_3D, NV_10, 0}, -{0x0110, "GeForce 2 MX", NV15_TCL_PRIMITIVE_3D|0x1100, NV_10, 0}, -{0x01A0, "NForce", NV15_TCL_PRIMITIVE_3D|0x1100, NV_10, 0}, -{0x0150, "GeForce 2", NV15_TCL_PRIMITIVE_3D, NV_10, 0}, -{0x0170, "GeForce 4 MX", NV15_TCL_PRIMITIVE_3D|0x1700, NV_10, NV_HAS_LMA}, -{0x0180, "GeForce 4 MX", NV15_TCL_PRIMITIVE_3D|0x1700, NV_10, NV_HAS_LMA}, -{0x01F0, "NForce 2", NV15_TCL_PRIMITIVE_3D|0x1700, NV_10, NV_HAS_LMA}, -{0x0200, "GeForce 3", NV20_TCL_PRIMITIVE_3D|0x2000, NV_20, NV_HAS_LMA}, -{0x0250, "GeForce 4 Ti", NV20_TCL_PRIMITIVE_3D|0x2500, NV_20, NV_HAS_LMA}, -{0x0280, "GeForce 4 Ti", NV20_TCL_PRIMITIVE_3D|0x2500, NV_20, NV_HAS_LMA}, -{0x0320, "GeForce FX 5200/5500", NV30_TCL_PRIMITIVE_3D|0x3400, NV_30, NV_HAS_LMA}, -{0x0310, "GeForce FX 5600", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, NV_HAS_LMA}, -{0x0340, "GeForce FX 5700", NV30_TCL_PRIMITIVE_3D|0x3500, NV_30, NV_HAS_LMA}, -{0x0300, "GeForce FX 5800", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, NV_HAS_LMA}, -{0x0330, "GeForce FX 5900", NV30_TCL_PRIMITIVE_3D|0x3500, NV_30, NV_HAS_LMA}, -{0x0240, "GeForce 6100", NV30_TCL_PRIMITIVE_3D|0x4400, NV_40, NV_HAS_LMA}, -{0x0160, "GeForce 6200", NV30_TCL_PRIMITIVE_3D|0x4400, NV_40, NV_HAS_LMA}, -{0x0220, "GeForce 6200", NV30_TCL_PRIMITIVE_3D|0x4400, NV_40, NV_HAS_LMA}, -{0x0140, "GeForce 6200/6600", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, NV_HAS_LMA}, -{0x0040, "GeForce 6800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, NV_HAS_LMA}, -{0x00C0, "GeForce 6800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, NV_HAS_LMA}, -{0x0210, "GeForce 6800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, NV_HAS_LMA}, -{0x01D0, "GeForce 7200/7300/7400", NV30_TCL_PRIMITIVE_3D|0x4400, NV_40, NV_HAS_LMA}, -{0x0390, "GeForce 7300/7600", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, NV_HAS_LMA}, -{0x02E0, "GeForce 7300/7600", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, NV_HAS_LMA}, -{0x0090, "GeForce 7800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, NV_HAS_LMA}, -{0x0290, "GeForce 7900", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, NV_HAS_LMA}, -/* catchall */ -{0x0000, "Unknown card", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, NV_HAS_LMA}, -}; +#include "nouveau_drm.h" +// FIXME hack for now +#define NV15_TCL_PRIMITIVE_3D 0x0096 +#define NV17_TCL_PRIMITIVE_3D 0x0099 +#include "nouveau_card_list.h" nouveau_card* nouveau_card_lookup(uint32_t device_id) { int i; for(i=0;iDriverCtx)) -/* Flags for what context state needs to be updated: */ -#define NOUVEAU_NEW_ALPHA 0x0001 -#define NOUVEAU_NEW_DEPTH 0x0002 -#define NOUVEAU_NEW_FOG 0x0004 -#define NOUVEAU_NEW_CLIP 0x0008 -#define NOUVEAU_NEW_CULL 0x0010 -#define NOUVEAU_NEW_MASKS 0x0020 -#define NOUVEAU_NEW_RENDER_NOT 0x0040 -#define NOUVEAU_NEW_WINDOW 0x0080 -#define NOUVEAU_NEW_CONTEXT 0x0100 -#define NOUVEAU_NEW_ALL 0x01ff - /* Flags for software fallback cases: */ #define NOUVEAU_FALLBACK_TEXTURE 0x0001 #define NOUVEAU_FALLBACK_DRAW_BUFFER 0x0002 diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c index 9fac6a48df..0b745e1e74 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c @@ -90,7 +90,8 @@ void nouveauWaitForIdleLocked(nouveauContextPtr nmesa) case NV_20: case NV_30: case NV_40: - case G_70: + case NV_44: + case NV_50: default: status=NV_READ(NV04_STATUS); break; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h index 44b9f356d1..51993cf556 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h @@ -60,7 +60,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define OUT_RINGp(ptr,sz) do { \ uint32_t* p=(uint32_t*)(ptr); \ -int i; printf("OUT_RINGp: (size 0x%x dwords)\n",sz); for(i=0;ipatch) + return NULL; + psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, ddx_version, dri_version, drm_version, frame_buffer, pSAREA, fd, diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.c b/src/mesa/drivers/dri/nouveau/nouveau_shader.c index 97ea1ee547..63da8420b2 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.c @@ -173,10 +173,11 @@ nouveauShaderInitFuncs(GLcontext * ctx) NV30FPInitShaderFuncs(&nmesa->FPfunc); break; case NV_40: - case G_70: + case NV_44: NV40VPInitShaderFuncs(&nmesa->VPfunc); NV40FPInitShaderFuncs(&nmesa->FPfunc); break; + case NV_50: default: return; } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c index 1445ee7449..88a8c9ed59 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -168,7 +168,7 @@ void nouveauDDInitState(nouveauContextPtr nmesa) break; case NV_30: case NV_40: - case G_70: + case NV_50: nv30InitStateFuncs(&nmesa->glCtx->Driver); break; default: -- cgit v1.2.3 From f95fe81fffa42be756b0fa53b5f3b240006158d2 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 3 Dec 2006 10:08:04 +0000 Subject: Remove duplicate nv10 tcl defines --- src/mesa/drivers/dri/nouveau/nouveau_reg.h | 225 +---------------------------- 1 file changed, 5 insertions(+), 220 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_reg.h b/src/mesa/drivers/dri/nouveau/nouveau_reg.h index 077f06e02b..200e770903 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_reg.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_reg.h @@ -290,226 +290,11 @@ Object NV_IMAGE_BLIT used on: NV04 NV10 NV15 NV20 NV40 Object NV10_TCL_PRIMITIVE_3D used on: NV10 */ #define NV10_TCL_PRIMITIVE_3D 0x00000056 -# define NV10_TCL_PRIMITIVE_3D_NOP 0x00000100 -# define NV10_TCL_PRIMITIVE_3D_NOTIFY 0x00000104 -# define NV10_TCL_PRIMITIVE_3D_SET_DMA_NOTIFY 0x00000180 -# define NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY0 0x00000184 -# define NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY1 0x00000188 -# define NV10_TCL_PRIMITIVE_3D_SET_DISPLAY_LIST 0x0000018c -# define NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY2 0x00000194 -# define NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY3 0x00000198 -# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ 0x00000200 /* Parameters: width x */ -# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_VERT 0x00000204 /* Parameters: height y */ -# define NV10_TCL_PRIMITIVE_3D_BUFFER_FORMAT 0x00000208 /* Parameters: type color */ -# define NV10_TCL_PRIMITIVE_3D_BUFFER_PITCH 0x0000020c /* Parameters: depth/stencil buffer pitch color buffer pitch */ -# define NV10_TCL_PRIMITIVE_3D_COLOR_OFFSET 0x00000210 -# define NV10_TCL_PRIMITIVE_3D_DEPTH_OFFSET 0x00000214 -# define NV10_TCL_PRIMITIVE_3D_TX_OFFSET(d) (0x00000218 + d * 0x0004) -# define NV10_TCL_PRIMITIVE_3D_TX_FORMAT(d) (0x00000220 + d * 0x0004) /* Parameters: wrap_t wrap_s log2(height) log2(width) lod npot format cube_map */ -# define NV10_TCL_PRIMITIVE_3D_TX_ENABLE(d) (0x00000228 + d * 0x0004) /* Parameters: enable anisotropy */ -# define NV10_TCL_PRIMITIVE_3D_TX_NPOT_PITCH(d) (0x00000230 + d * 0x0004) /* Parameters: pitch */ -# define NV10_TCL_PRIMITIVE_3D_TX_NPOT_SIZE(d) (0x00000240 + d * 0x0004) /* Parameters: width height */ -# define NV10_TCL_PRIMITIVE_3D_TX_FILTER(d) (0x00000248 + d * 0x0004) /* Parameters: mag_filter min_filter */ -# define NV10_TCL_PRIMITIVE_3D_RC_IN_ALPHA(d) (0x00000260 + d * 0x0004) /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ -# define NV10_TCL_PRIMITIVE_3D_RC_IN_RGB(d) (0x00000268 + d * 0x0004) /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ -# define NV10_TCL_PRIMITIVE_3D_RC_OUT_ALPHA(d) (0x00000278 + d * 0x0004) /* Parameters: scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ -# define NV10_TCL_PRIMITIVE_3D_RC_OUT_RGB(d) (0x00000280 + d * 0x0004) /* Parameters: rc1_tx_units_enabled rc1_rc_enabled scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ -# define NV10_TCL_PRIMITIVE_3D_TX_MATRIX_ENABLE(d) (0x000003e0 + d * 0x0004) -# define NV10_TCL_PRIMITIVE_3D_TX_MATRIX(x,y) (0x00000540 + y * 0x0010 + x * 0x0004) -# define NV10_TCL_PRIMITIVE_3D_RC_COLOR0 0x00000270 /* Parameters: a r g b */ -# define NV10_TCL_PRIMITIVE_3D_RC_COLOR1 0x00000274 /* Parameters: a r g b */ -# define NV10_TCL_PRIMITIVE_3D_RC_FINAL0 0x00000288 /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ -# define NV10_TCL_PRIMITIVE_3D_RC_FINAL1 0x0000028c /* Parameters: vare_mapping vare_component_usage vare_input varf_mapping varf_component_usage varf_input varg_mapping varg_component_usage varg_input color_sum_clamp */ -# define NV10_TCL_PRIMITIVE_3D_LIGHT_MODEL 0x00000294 /* Parameters: local_viewer color_control */ -# define NV10_TCL_PRIMITIVE_3D_COLOR_MATERIAL 0x00000298 /* Parameters: specular diffuse ambient emission */ -# define NV10_TCL_PRIMITIVE_3D_FOG_MODE 0x0000029c -# define NV10_TCL_PRIMITIVE_3D_FOG_COORD_DIST 0x000002a0 -# define NV10_TCL_PRIMITIVE_3D_FOG_ENABLE 0x000002a4 -# define NV10_TCL_PRIMITIVE_3D_FOG_COLOR 0x000002a8 /* Parameters: a b g r */ -# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(d) (0x000002c0 + d * 0x0004) /* Parameters: x2 x1 */ -# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(d) (0x000002e0 + d * 0x0004) /* Parameters: y2 y1 */ -# define NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE 0x00000300 -# define NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE 0x00000304 -# define NV10_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE 0x00000308 -# define NV10_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE 0x0000030c -# define NV10_TCL_PRIMITIVE_3D_DITHER_ENABLE 0x00000310 -# define NV10_TCL_PRIMITIVE_3D_LIGHTING_ENABLE 0x00000314 -# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETERS_ENABLE 0x00000318 -# define NV10_TCL_PRIMITIVE_3D_POINT_SMOOTH_ENABLE 0x0000031c -# define NV10_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE 0x00000320 -# define NV10_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE 0x00000324 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_WEIGHT_ENABLE 0x00000328 -# define NV10_TCL_PRIMITIVE_3D_STENCIL_ENABLE 0x0000032c -# define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE 0x00000330 -# define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE 0x00000334 -# define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE 0x00000338 -# define NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC 0x0000033c -# define NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF 0x00000340 -# define NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC 0x00000344 -# define NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_DST 0x00000348 -# define NV10_TCL_PRIMITIVE_3D_BLEND_COLOR 0x0000034c /* Parameters: a r g b */ -# define NV10_TCL_PRIMITIVE_3D_BLEND_EQUATION 0x00000350 -# define NV10_TCL_PRIMITIVE_3D_DEPTH_FUNC 0x00000354 -# define NV10_TCL_PRIMITIVE_3D_COLOR_MASK 0x00000358 /* Parameters: r g b */ -# define NV10_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE 0x0000035c -# define NV10_TCL_PRIMITIVE_3D_STENCIL_MASK 0x00000360 -# define NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC 0x00000364 -# define NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_REF 0x00000368 -# define NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_MASK 0x0000036c -# define NV10_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL 0x00000370 -# define NV10_TCL_PRIMITIVE_3D_STENCIL_OP_ZFAIL 0x00000374 -# define NV10_TCL_PRIMITIVE_3D_STENCIL_OP_ZPASS 0x00000378 -# define NV10_TCL_PRIMITIVE_3D_SHADE_MODEL 0x0000037c -# define NV10_TCL_PRIMITIVE_3D_LINE_WIDTH 0x00000380 -# define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR 0x00000384 -# define NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_UNITS 0x00000388 -# define NV10_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT 0x0000038c -# define NV10_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK 0x00000390 -# define NV10_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR 0x00000394 -# define NV10_TCL_PRIMITIVE_3D_DEPTH_RANGE_FAR 0x00000398 -# define NV10_TCL_PRIMITIVE_3D_CULL_FACE 0x0000039c -# define NV10_TCL_PRIMITIVE_3D_FRONT_FACE 0x000003a0 -# define NV10_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE 0x000003a4 -# define NV10_TCL_PRIMITIVE_3D_MATERIAL_DIFFUSE_ALPHA_FRONT 0x000003b4 -# define NV10_TCL_PRIMITIVE_3D_COLOR_CONTROL 0x000003b8 /* Parameters: color_control */ -# define NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS 0x000003bc /* Parameters: light 7 light 6 light 5 light 4 light 3 light 2 light 1 light 0 */ -# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE( d) (0x000003c0 + d * 0x0004) -# define NV10_TCL_PRIMITIVE_3D_VIEW_MATRIX_ENABLE 0x000003e8 /* Parameters: projection modelview0 modelview1 */ -# define NV10_TCL_PRIMITIVE_3D_POINT_SIZE 0x000003ec -# define NV10_TCL_PRIMITIVE_3D_MODELVIEW0_MATRIX( d) (0x00000400 + d * 0x0004) -# define NV10_TCL_PRIMITIVE_3D_MODELVIEW1_MATRIX( d) (0x00000440 + d * 0x0004) -# define NV10_TCL_PRIMITIVE_3D_INVERSE_MODELVIEW0_MATRIX( d) (0x00000480 + d * 0x0004) -# define NV10_TCL_PRIMITIVE_3D_INVERSE_MODELVIEW1_MATRIX( d) (0x000004c0 + d * 0x0004) -# define NV10_TCL_PRIMITIVE_3D_PROJECTION_MATRIX( d) (0x00000500 + d * 0x0004) -# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_A(d) (0x00000600 + d * 0x0010) -# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_B(d) (0x00000604 + d * 0x0010) -# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_C(d) (0x00000608 + d * 0x0010) -# define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_D(d) (0x0000060c + d * 0x0010) -# define NV10_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT 0x00000680 -# define NV10_TCL_PRIMITIVE_3D_FOG_EQUATION_LINEAR 0x00000684 -# define NV10_TCL_PRIMITIVE_3D_FOG_EQUATION_QUADRATIC 0x00000688 -# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_A 0x000006a0 -# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_B 0x000006a4 -# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_C 0x000006a8 -# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_D 0x000006ac -# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_E 0x000006b0 -# define NV10_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_F 0x000006b4 -# define NV10_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R 0x000006c4 -# define NV10_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_G 0x000006c8 -# define NV10_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_B 0x000006cc -# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X 0x000006e8 -# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_Y 0x000006ec -# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_Z 0x000006f0 -# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_W 0x000006f4 -# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_A 0x000006f8 -# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_B 0x000006fc -# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_C 0x00000700 -# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_D 0x00000704 -# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_E 0x00000708 -# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_F 0x0000070c -# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_G 0x00000710 -# define NV10_TCL_PRIMITIVE_3D_POINT_PARAMETER_H 0x00000714 -# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_R(d) (0x00000800 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_G(d) (0x00000804 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_AMBIENT_B(d) (0x00000808 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_R(d) (0x0000080c + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_G(d) (0x00000810 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_DIFFUSE_B(d) (0x00000814 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_R(d) (0x00000818 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_G(d) (0x0000081c + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_FRONT_SIDE_PRODUCT_SPECULAR_B(d) (0x00000820 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_X(d) (0x00000828 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_Y(d) (0x0000082c + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_HALF_VECTOR_Z(d) (0x00000830 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_X(d) (0x00000834 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_Y(d) (0x00000838 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_DIRECTION_Z(d) (0x0000083c + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(d) (0x00000840 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(d) (0x00000844 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(d) (0x00000848 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(d) (0x0000084c + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_Y(d) (0x00000850 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_Z(d) (0x00000854 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(d) (0x00000858 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(d) (0x0000085c + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_Y(d) (0x00000860 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_Z(d) (0x00000864 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(d) (0x00000868 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_LINEAR_ATTENUATION(d) (0x0000086c + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_LIGHT_QUADRATIC_ATTENUATION(d) (0x00000870 + d * 0x0080) -# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_X 0x00000c00 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_Y 0x00000c04 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_3F_Z 0x00000c08 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_4F_X 0x00000c18 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_4F_Y 0x00000c1c -# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_4F_Z 0x00000c20 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_POS_4F_W 0x00000c24 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_X 0x00000c30 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_Y 0x00000c34 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_Z 0x00000c38 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_XY 0x00000c40 /* Parameters: y x */ -# define NV10_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_Z 0x00000c44 /* Parameters: z */ -# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4F_R 0x00000c50 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4F_G 0x00000c54 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4F_B 0x00000c58 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4F_A 0x00000c5c -# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_3F_R 0x00000c60 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_3F_G 0x00000c64 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_3F_B 0x00000c68 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL_4I 0x00000c6c /* Parameters: a b g r */ -# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_R 0x00000c80 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_G 0x00000c84 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_B 0x00000c88 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_COL2_3I 0x00000c8c /* Parameters: a b g r */ -# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_S 0x00000c90 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_T 0x00000c94 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_2I 0x00000c98 /* Parameters: t s */ -# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_S 0x00000ca0 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_T 0x00000ca4 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_R 0x00000ca8 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_Q 0x00000cac -# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_ST 0x00000cb0 /* Parameters: t s */ -# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_RQ 0x00000cb4 /* Parameters: q r */ -# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_S 0x00000cb8 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_T 0x00000cbc -# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_2I 0x00000cc0 /* Parameters: t s */ -# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_S 0x00000cc8 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_T 0x00000ccc -# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_R 0x00000cd0 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_Q 0x00000cd4 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_ST 0x00000cd8 /* Parameters: t s */ -# define NV10_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_RQ 0x00000cdc /* Parameters: q r */ -# define NV10_TCL_PRIMITIVE_3D_VERTEX_FOG_1F 0x00000ce0 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_WGH_1F 0x00000ce4 -# define NV10_TCL_PRIMITIVE_3D_EDGEFLAG_ENABLE 0x00000cec -# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_VALIDATE 0x00000cf0 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_POS 0x00000d00 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_POS 0x00000d04 /* Parameters: stride fields type */ -# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_COL 0x00000d08 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_COL 0x00000d0c /* Parameters: stride fields type */ -# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_COL2 0x00000d10 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_COL2 0x00000d14 /* Parameters: stride fields type */ -# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_TX0 0x00000d18 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_TX0 0x00000d1c /* Parameters: stride fields type */ -# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_TX1 0x00000d20 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_TX1 0x00000d24 /* Parameters: stride fields type */ -# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_NOR 0x00000d28 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_NOR 0x00000d2c /* Parameters: stride fields type */ -# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_WGH 0x00000d30 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_WGH 0x00000d34 /* Parameters: stride fields type */ -# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_FOG 0x00000d38 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_FOG 0x00000d3c /* Parameters: stride fields type */ -# define NV10_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE 0x00000d40 -# define NV10_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP 0x00000d44 -# define NV10_TCL_PRIMITIVE_3D_BEGIN_END 0x00000dfc -# define NV10_TCL_PRIMITIVE_3D_INDEX_DATA 0x00000e00 /* Parameters: index1 index0 */ -# define NV10_TCL_PRIMITIVE_3D_VERTEX_BUFFER_BEGIN_END 0x000013fc -# define NV10_TCL_PRIMITIVE_3D_VERTEX_BUFFER_DRAW_ARRAYS 0x00001400 /* Parameters: count-1 first */ -# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X 0x00001638 -# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_Y 0x0000163c -# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_Z 0x00001640 -# define NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_W 0x00001644 -# define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_DATA 0x00001800 + +/****************************************** +Object NV17_TCL_PRIMITIVE_3D used on: NV15 +*/ +#define NV17_TCL_PRIMITIVE_3D 0x00000099 /****************************************** Object NV11_TCL_PRIMITIVE_3D used on: NV15 -- cgit v1.2.3 From 3867bc97800ef3072a70565559c11badba3ed55a Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sun, 3 Dec 2006 11:46:18 +0000 Subject: Fix the swtcl module. --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 4d05a439bb..07b3e666df 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -61,7 +61,6 @@ static void nv10ResetLineStipple( GLcontext *ctx ); static inline void nv10StartPrimitive(struct nouveau_context* nmesa,uint32_t primitive,uint32_t size) { - // FIXME the primitive type can probably go trough the caching system as well if (nmesa->screen->card->type==NV_10) BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_BEGIN_END,1); else if (nmesa->screen->card->type==NV_20) @@ -80,7 +79,6 @@ static inline void nv10StartPrimitive(struct nouveau_context* nmesa,uint32_t pri inline void nv10FinishPrimitive(struct nouveau_context *nmesa) { - // FIXME this is probably not needed if (nmesa->screen->card->type==NV_10) BEGIN_RING_SIZE(NvSub3D,NV10_TCL_PRIMITIVE_3D_BEGIN_END,1); else if (nmesa->screen->card->type==NV_20) @@ -156,11 +154,11 @@ static inline void nv10_render_generic_primitive_verts(GLcontext *ctx,GLuint sta struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); GLubyte *vertptr = (GLubyte *)nmesa->verts; GLuint vertsize = nmesa->vertex_size; - GLuint size_dword = vertsize*(count-start); + GLuint size_dword = vertsize*(count-start)/4; nv10ExtendPrimitive(nmesa, size_dword); nv10StartPrimitive(nmesa,prim+1,size_dword); - OUT_RINGp((nouveauVertex*)(vertptr+(start*vertsize*4)),size_dword); + OUT_RINGp((nouveauVertex*)(vertptr+(start*vertsize)),size_dword); nv10FinishPrimitive(nmesa); } @@ -242,14 +240,14 @@ static inline void nv10_render_generic_primitive_elts(GLcontext *ctx,GLuint star struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); GLubyte *vertptr = (GLubyte *)nmesa->verts; GLuint vertsize = nmesa->vertex_size; - GLuint size_dword = vertsize*(count-start); + GLuint size_dword = vertsize*(count-start)/4; const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; GLuint j; nv10ExtendPrimitive(nmesa, size_dword); nv10StartPrimitive(nmesa,prim+1,size_dword); for (j=start; j Date: Fri, 8 Dec 2006 03:01:33 +0000 Subject: Some work on buffer handling, most likely not entirely correct and incomplete. But, it works well enough that windows can be moved/resized. --- src/mesa/drivers/dri/nouveau/Makefile | 1 + src/mesa/drivers/dri/nouveau/nouveau_buffers.c | 331 +++++++++++++++++++++++++ src/mesa/drivers/dri/nouveau/nouveau_buffers.h | 41 +++ src/mesa/drivers/dri/nouveau/nouveau_context.c | 79 +++++- src/mesa/drivers/dri/nouveau/nouveau_context.h | 20 ++ src/mesa/drivers/dri/nouveau/nouveau_driver.c | 29 +++ src/mesa/drivers/dri/nouveau/nouveau_driver.h | 5 +- src/mesa/drivers/dri/nouveau/nouveau_lock.c | 18 ++ src/mesa/drivers/dri/nouveau/nouveau_object.c | 23 +- src/mesa/drivers/dri/nouveau/nouveau_object.h | 9 +- src/mesa/drivers/dri/nouveau/nouveau_screen.c | 128 +++++----- src/mesa/drivers/dri/nouveau/nouveau_shader.c | 2 + src/mesa/drivers/dri/nouveau/nouveau_shader.h | 2 + src/mesa/drivers/dri/nouveau/nouveau_span.c | 14 +- src/mesa/drivers/dri/nouveau/nouveau_span.h | 3 +- src/mesa/drivers/dri/nouveau/nouveau_state.c | 42 ++-- src/mesa/drivers/dri/nouveau/nouveau_state.h | 6 +- src/mesa/drivers/dri/nouveau/nv30_fragprog.c | 29 +-- src/mesa/drivers/dri/nouveau/nv30_state.c | 152 +++++++++++- 19 files changed, 784 insertions(+), 150 deletions(-) create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_buffers.c create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_buffers.h (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile index 384713eeeb..1a76169156 100644 --- a/src/mesa/drivers/dri/nouveau/Makefile +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -8,6 +8,7 @@ LIBNAME = nouveau_dri.so MINIGLX_SOURCES = DRIVER_SOURCES = \ + nouveau_buffers.c \ nouveau_card.c \ nouveau_context.c \ nouveau_driver.c \ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c new file mode 100644 index 0000000000..a356fd1212 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c @@ -0,0 +1,331 @@ +#include "utils.h" +#include "framebuffer.h" +#include "renderbuffer.h" +#include "fbobject.h" + +#include "nouveau_context.h" +#include "nouveau_buffers.h" + +void +nouveau_mem_free(GLcontext *ctx, nouveau_mem *mem) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + drm_nouveau_mem_free_t memf; + + if (mem->map) + drmUnmap(mem->map, mem->size); + memf.flags = mem->type; + memf.region_offset = mem->offset; + drmCommandWrite(nmesa->driFd, DRM_NOUVEAU_MEM_FREE, &memf, sizeof(memf)); + FREE(mem); +} + +nouveau_mem * +nouveau_mem_alloc(GLcontext *ctx, int type, GLuint size, GLuint align) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + drm_nouveau_mem_alloc_t mema; + nouveau_mem *mem; + int ret; + + mem = CALLOC(sizeof(nouveau_mem)); + if (!mem) + return NULL; + + mema.flags = mem->type = type; + mema.size = mem->size = size; + mema.alignment = align; + mem->map = NULL; + ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_MEM_ALLOC, + &mema, sizeof(mema)); + if (ret) { + FREE(mem); + return NULL; + } + mem->offset = mema.region_offset; + + if (type & NOUVEAU_MEM_MAPPED) + ret = drmMap(nmesa->driFd, mem->offset, mem->size, &mem->map); + if (ret) { + mem->map = NULL; + nouveau_mem_free(ctx, mem); + mem = NULL; + } + + return mem; +} + +uint32_t +nouveau_mem_gpu_offset_get(GLcontext *ctx, nouveau_mem *mem) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (mem->type & NOUVEAU_MEM_FB) + return (uint32_t)mem->offset - nmesa->vram_phys; + else if (mem->type & NOUVEAU_MEM_AGP) + return (uint32_t)mem->offset - nmesa->agp_phys; + else + return 0xDEADF00D; +} + +static GLboolean +nouveau_renderbuffer_pixelformat(nouveau_renderbuffer *nrb, + GLenum internalFormat) +{ + nrb->mesa.InternalFormat = internalFormat; + + /*TODO: We probably want to extend this a bit, and maybe make + * card-specific? + */ + switch (internalFormat) { + case GL_RGBA: + case GL_RGBA8: + nrb->mesa._BaseFormat = GL_RGBA; + nrb->mesa._ActualFormat= GL_RGBA8; + nrb->mesa.DataType = GL_UNSIGNED_BYTE; + nrb->mesa.RedBits = 8; + nrb->mesa.GreenBits = 8; + nrb->mesa.BlueBits = 8; + nrb->mesa.AlphaBits = 8; + nrb->cpp = 4; + break; + case GL_RGB5: + nrb->mesa._BaseFormat = GL_RGB; + nrb->mesa._ActualFormat= GL_RGB5; + nrb->mesa.DataType = GL_UNSIGNED_BYTE; + nrb->mesa.RedBits = 5; + nrb->mesa.GreenBits = 6; + nrb->mesa.BlueBits = 5; + nrb->mesa.AlphaBits = 0; + nrb->cpp = 2; + break; + case GL_DEPTH_COMPONENT16: + nrb->mesa._BaseFormat = GL_DEPTH_COMPONENT; + nrb->mesa._ActualFormat= GL_DEPTH_COMPONENT16; + nrb->mesa.DataType = GL_UNSIGNED_SHORT; + nrb->mesa.DepthBits = 16; + nrb->cpp = 2; + break; + case GL_DEPTH_COMPONENT24: + nrb->mesa._BaseFormat = GL_DEPTH_COMPONENT; + nrb->mesa._ActualFormat= GL_DEPTH24_STENCIL8_EXT; + nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT; + nrb->mesa.DepthBits = 24; + nrb->cpp = 4; + break; + case GL_STENCIL_INDEX8_EXT: + nrb->mesa._BaseFormat = GL_STENCIL_INDEX; + nrb->mesa._ActualFormat= GL_DEPTH24_STENCIL8_EXT; + nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT; + nrb->mesa.StencilBits = 8; + nrb->cpp = 4; + break; + case GL_DEPTH24_STENCIL8_EXT: + nrb->mesa._BaseFormat = GL_DEPTH_STENCIL_EXT; + nrb->mesa._ActualFormat= GL_DEPTH24_STENCIL8_EXT; + nrb->mesa.DataType = GL_UNSIGNED_INT_24_8_EXT; + nrb->mesa.DepthBits = 24; + nrb->mesa.StencilBits = 8; + nrb->cpp = 4; + break; + default: + return GL_FALSE; + break; + } + + return GL_TRUE; +} + +static GLboolean +nouveau_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, + GLuint height) +{ + nouveau_renderbuffer *nrb = (nouveau_renderbuffer*)rb; + + if (!nouveau_renderbuffer_pixelformat(nrb, internalFormat)) { + fprintf(stderr, "%s: unknown internalFormat\n", __func__); + return GL_FALSE; + } + + /* If this buffer isn't statically alloc'd, we may need to ask the + * drm for more memory */ + if (!nrb->map && (rb->Width != width || rb->Height != height)) { + GLuint pitch; + + /* align pitches to 64 bytes */ + pitch = ((width * nrb->cpp) + 63) & ~63; + + if (nrb->mem) + nouveau_mem_free(ctx, nrb->mem); + nrb->mem = nouveau_mem_alloc(ctx, + NOUVEAU_MEM_FB | NOUVEAU_MEM_MAPPED, + pitch*height, + 0); + if (!nrb->mem) + return GL_FALSE; + + /* update nouveau_renderbuffer info */ + nrb->offset = nouveau_mem_gpu_offset_get(ctx, nrb->mem); + nrb->pitch = pitch; + } + + rb->Width = width; + rb->Height = height; + rb->InternalFormat = internalFormat; + return GL_TRUE; +} + +static void +nouveau_renderbuffer_delete(struct gl_renderbuffer *rb) +{ + GET_CURRENT_CONTEXT(ctx); + nouveau_renderbuffer *nrb = (nouveau_renderbuffer*)rb; + + if (nrb->mem) + nouveau_mem_free(ctx, nrb->mem); + FREE(nrb); +} + +nouveau_renderbuffer * +nouveau_renderbuffer_new(GLenum internalFormat, GLvoid *map, + GLuint offset, GLuint pitch, + __DRIdrawablePrivate *dPriv) +{ + nouveau_renderbuffer *nrb; + + nrb = CALLOC_STRUCT(nouveau_renderbuffer_t); + if (nrb) { + _mesa_init_renderbuffer(&nrb->mesa, 0); + + nouveau_renderbuffer_pixelformat(nrb, internalFormat); + + nrb->mesa.AllocStorage = nouveau_renderbuffer_storage; + nrb->mesa.Delete = nouveau_renderbuffer_delete; + + nrb->dPriv = dPriv; + nrb->offset = offset; + nrb->pitch = pitch; + nrb->map = map; + } + + return nrb; +} + +void +nouveau_window_moved(GLcontext *ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + /* Viewport depends on window size/position, nouveauCalcViewport + * will take care of calling the hw-specific WindowMoved + */ + ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y, + ctx->Viewport.Width, ctx->Viewport.Height); + /* Scissor depends on window position */ + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); +} + +GLboolean +nouveau_build_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_renderbuffer *color[MAX_DRAW_BUFFERS]; + nouveau_renderbuffer *depth; + + _mesa_update_framebuffer(ctx); + _mesa_update_draw_buffer_bounds(ctx); + + color[0] = (nouveau_renderbuffer *)fb->_ColorDrawBuffers[0][0]; + depth = (nouveau_renderbuffer *)fb->_DepthBuffer; + + if (!nmesa->hw_func.BindBuffers(nmesa, 1, color, depth)) + return GL_FALSE; + nouveau_window_moved(ctx); + + return GL_TRUE; +} + +nouveau_renderbuffer * +nouveau_current_draw_buffer(GLcontext *ctx) +{ + struct gl_framebuffer *fb = ctx->DrawBuffer; + nouveau_renderbuffer *nrb; + + if (!fb) + return NULL; + + if (fb->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT) + nrb = (nouveau_renderbuffer *) + fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + else if (fb->_ColorDrawBufferMask[0] == BUFFER_BIT_BACK_LEFT) + nrb = (nouveau_renderbuffer *) + fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + else + nrb = NULL; + return nrb; +} + +static struct gl_framebuffer * +nouveauNewFramebuffer(GLcontext *ctx, GLuint name) +{ + return _mesa_new_framebuffer(ctx, name); +} + +static struct gl_renderbuffer * +nouveauNewRenderbuffer(GLcontext *ctx, GLuint name) +{ + nouveau_renderbuffer *nrb; + + nrb = CALLOC_STRUCT(nouveau_renderbuffer_t); + if (nrb) { + _mesa_init_renderbuffer(&nrb->mesa, name); + + nrb->mesa.AllocStorage = nouveau_renderbuffer_storage; + nrb->mesa.Delete = nouveau_renderbuffer_delete; + } + return &nrb->mesa; +} + +static void +nouveauBindFramebuffer(GLcontext *ctx, GLenum target, struct gl_framebuffer *fb) +{ + nouveau_build_framebuffer(ctx, fb); +} + +static void +nouveauFramebufferRenderbuffer(GLcontext *ctx, + struct gl_framebuffer *fb, + GLenum attachment, + struct gl_renderbuffer *rb) +{ + _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb); + nouveau_build_framebuffer(ctx, fb); +} + +static void +nouveauRenderTexture(GLcontext *ctx, + struct gl_framebuffer *fb, + struct gl_renderbuffer_attachment *att) +{ +} + +static void +nouveauFinishRenderTexture(GLcontext *ctx, + struct gl_renderbuffer_attachment *att) +{ +} + +void +nouveauInitBufferFuncs(struct dd_function_table *func) +{ + func->NewFramebuffer = nouveauNewFramebuffer; + func->NewRenderbuffer = nouveauNewRenderbuffer; + func->BindFramebuffer = nouveauBindFramebuffer; + func->FramebufferRenderbuffer = nouveauFramebufferRenderbuffer; + func->RenderTexture = nouveauRenderTexture; + func->FinishRenderTexture = nouveauFinishRenderTexture; +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.h b/src/mesa/drivers/dri/nouveau/nouveau_buffers.h new file mode 100644 index 0000000000..bb297ad558 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_buffers.h @@ -0,0 +1,41 @@ +#ifndef __NOUVEAU_BUFFERS_H__ +#define __NOUVEAU_BUFFERS_H__ + +#include +#include "mtypes.h" +#include "utils.h" +#include "renderbuffer.h" + +typedef struct nouveau_mem_t { + int type; + uint64_t offset; + uint64_t size; + void* map; +} nouveau_mem; + +extern nouveau_mem *nouveau_mem_alloc(GLcontext *ctx, int type, + GLuint size, GLuint align); +extern void nouveau_mem_free(GLcontext *ctx, nouveau_mem *mem); +extern uint32_t nouveau_mem_gpu_offset_get(GLcontext *ctx, nouveau_mem *mem); + +typedef struct nouveau_renderbuffer_t { + struct gl_renderbuffer mesa; /* must be first! */ + __DRIdrawablePrivate *dPriv; + + nouveau_mem *mem; + void * map; + + int cpp; + uint32_t offset; + uint32_t pitch; +} nouveau_renderbuffer; + +extern nouveau_renderbuffer *nouveau_renderbuffer_new(GLenum internalFormat, + GLvoid *map, GLuint offset, GLuint pitch, __DRIdrawablePrivate *dPriv); +extern void nouveau_window_moved(GLcontext *ctx); +extern GLboolean nouveau_build_framebuffer(GLcontext *, struct gl_framebuffer *); +extern nouveau_renderbuffer *nouveau_current_draw_buffer(GLcontext *ctx); + +extern void nouveauInitBufferFuncs(struct dd_function_table *func); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index b208d6c9f5..f48c54416a 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -32,6 +32,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "array_cache/acache.h" +#include "framebuffer.h" #include "tnl/tnl.h" #include "tnl/t_pipeline.h" @@ -47,6 +48,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_fifo.h" #include "nouveau_tex.h" #include "nouveau_msg.h" +#include "nouveau_reg.h" #include "nv10_swtcl.h" #include "vblank.h" @@ -96,10 +98,17 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, screen=nmesa->screen; /* Create the hardware context */ + if (!nouveauDRMGetParam(nmesa, NOUVEAU_GETPARAM_FB_PHYSICAL, + &nmesa->vram_phys)) + return GL_FALSE; + if (!nouveauDRMGetParam(nmesa, NOUVEAU_GETPARAM_AGP_PHYSICAL, + &nmesa->agp_phys)) + return GL_FALSE; if (!nouveauFifoInit(nmesa)) return GL_FALSE; nouveauObjectInit(nmesa); + /* Init default driver functions then plug in our nouveau-specific functions * (the texture functions are especially important) */ @@ -169,6 +178,7 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, break; } + nmesa->hw_func.InitCard(nmesa); nouveauInitState(ctx); driContextPriv->driverPrivate = (void *)nmesa; @@ -208,17 +218,26 @@ GLboolean nouveauMakeCurrent( __DRIcontextPrivate *driContextPriv, __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->vblank_seq ); - newNOUVEAUCtx->driDrawable = driDrawPriv; - - _mesa_make_current( newNOUVEAUCtx->glCtx, - (GLframebuffer *) driDrawPriv->driverPrivate, - (GLframebuffer *) driReadPriv->driverPrivate ); - + nouveauContextPtr nmesa = (nouveauContextPtr) driContextPriv->driverPrivate; + struct gl_framebuffer *draw_fb = + (struct gl_framebuffer*)driDrawPriv->driverPrivate; + struct gl_framebuffer *read_fb = + (struct gl_framebuffer*)driReadPriv->driverPrivate; + + driDrawableInitVBlank(driDrawPriv, nmesa->vblank_flags, &nmesa->vblank_seq ); + nmesa->driDrawable = driDrawPriv; + + _mesa_resize_framebuffer(nmesa->glCtx, draw_fb, + driDrawPriv->w, driDrawPriv->h); + if (draw_fb != read_fb) { + _mesa_resize_framebuffer(nmesa->glCtx, draw_fb, + driReadPriv->w, + driReadPriv->h); + } + _mesa_make_current(nmesa->glCtx, draw_fb, read_fb); + + nouveau_build_framebuffer(nmesa->glCtx, + driDrawPriv->driverPrivate); } else { _mesa_make_current( NULL, NULL, NULL ); } @@ -234,8 +253,46 @@ GLboolean nouveauUnbindContext( __DRIcontextPrivate *driContextPriv ) return GL_TRUE; } +static void nouveauDoSwapBuffers(nouveauContextPtr nmesa, + __DRIdrawablePrivate *dPriv) +{ + struct gl_framebuffer *fb; + nouveau_renderbuffer *src, *dst; + + fb = (struct gl_framebuffer *)dPriv->driverPrivate; + dst = (nouveau_renderbuffer*) + fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + src = (nouveau_renderbuffer*) + fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + +#ifdef ALLOW_MULTI_SUBCHANNEL + /* Ignore this.. it's a hack to test double-buffering, and not how + * SwapBuffers should look :) + */ + BEGIN_RING_SIZE(NvSubCtxSurf2D, NV10_CONTEXT_SURFACES_2D_FORMAT, 4); + OUT_RING (6); /* X8R8G8B8 */ + OUT_RING ((dst->pitch << 16) | src->pitch); + OUT_RING (src->offset); + OUT_RING (dst->offset); + + BEGIN_RING_SIZE(NvSubImageBlit, NV10_IMAGE_BLIT_SET_POINT, 3); + OUT_RING ((0 << 16) | 0); /* src point */ + OUT_RING ((0 << 16) | 0); /* dst point */ + OUT_RING ((fb->Height << 16) | fb->Width); /* width/height */ +#endif +} + void nouveauSwapBuffers(__DRIdrawablePrivate *dPriv) { + if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { + nouveauContextPtr nmesa = dPriv->driContextPriv->driverPrivate; + + if (nmesa->glCtx->Visual.doubleBufferMode) { + _mesa_notifySwapBuffers(nmesa->glCtx); + nouveauDoSwapBuffers(nmesa, dPriv); + } + + } } void nouveauCopySubBuffer(__DRIdrawablePrivate *dPriv, diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 947e95d18b..211d4e0a6d 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -38,6 +38,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_screen.h" #include "nouveau_state_cache.h" +#include "nouveau_buffers.h" #include "nouveau_shader.h" #include "xmlconfig.h" @@ -75,6 +76,17 @@ typedef void (*nouveau_line_func)( struct nouveau_context*, typedef void (*nouveau_point_func)( struct nouveau_context*, nouveauVertex * ); +typedef struct nouveau_hw_func_t { + /* Initialise any card-specific non-GL related state */ + GLboolean (*InitCard)(struct nouveau_context *); + /* Update buffer offset/pitch/format */ + GLboolean (*BindBuffers)(struct nouveau_context *, int num_color, + nouveau_renderbuffer **color, + nouveau_renderbuffer *depth); + /* Update anything that depends on the window position/size */ + void (*WindowMoved)(struct nouveau_context *); +} nouveau_hw_func; + typedef struct nouveau_context { /* Mesa context */ GLcontext *glCtx; @@ -85,6 +97,13 @@ typedef struct nouveau_context { /* The read-only regs */ volatile unsigned char* mmio; + /* Physical addresses of AGP/VRAM apertures */ + uint64_t vram_phys; + uint64_t agp_phys; + + /* Additional hw-specific functions */ + nouveau_hw_func hw_func; + /* FIXME : do we want to put all state into a separate struct ? */ /* State for tris */ GLuint color_offset; @@ -132,6 +151,7 @@ typedef struct nouveau_context { __DRIcontextPrivate *driContext; /* DRI context */ __DRIscreenPrivate *driScreen; /* DRI screen */ __DRIdrawablePrivate *driDrawable; /* DRI drawable bound to this ctx */ + GLint lastStamp; drm_context_t hHWContext; drm_hw_lock_t *driHwLock; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_driver.c b/src/mesa/drivers/dri/nouveau/nouveau_driver.c index a45530e451..f85dc62e74 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_driver.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_driver.c @@ -36,6 +36,35 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "utils.h" +/* Wrapper for DRM_NOUVEAU_GETPARAM ioctl */ +GLboolean nouveauDRMGetParam(nouveauContextPtr nmesa, + unsigned int param, + uint64_t* value) +{ + drm_nouveau_getparam_t getp; + + getp.param = param; + if (!value || drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_GETPARAM, + &getp, sizeof(getp))) + return GL_FALSE; + *value = getp.value; + return GL_TRUE; +} + +/* Wrapper for DRM_NOUVEAU_GETPARAM ioctl */ +GLboolean nouveauDRMSetParam(nouveauContextPtr nmesa, + unsigned int param, + uint64_t value) +{ + drm_nouveau_setparam_t setp; + + setp.param = param; + setp.value = value; + if (drmCommandWrite(nmesa->driFd, DRM_NOUVEAU_SETPARAM, &setp, + sizeof(setp))) + return GL_FALSE; + return GL_TRUE; +} /* Return the width and height of the current color buffer */ static void nouveauGetBufferSize( GLframebuffer *buffer, diff --git a/src/mesa/drivers/dri/nouveau/nouveau_driver.h b/src/mesa/drivers/dri/nouveau/nouveau_driver.h index e1541aa3c5..6164012b5b 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_driver.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_driver.h @@ -33,7 +33,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define DRIVER_AUTHOR "Stephane Marchesin" extern void nouveauDriverInitFunctions( struct dd_function_table *functions ); - +extern GLboolean nouveauDRMGetParam(nouveauContextPtr nmesa, unsigned int param, + uint64_t *value); +extern GLboolean nouveauDRMSetParam(nouveauContextPtr nmesa, unsigned int param, + uint64_t value); #endif /* __NOUVEAU_DRIVER_H__ */ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_lock.c b/src/mesa/drivers/dri/nouveau/nouveau_lock.c index 7dd67a143a..c119d14dd7 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_lock.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_lock.c @@ -29,6 +29,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_lock.h" #include "drirenderbuffer.h" +#include "framebuffer.h" /* Update the hardware state. This is called if another context has @@ -57,6 +58,23 @@ void nouveauGetLock( nouveauContextPtr nmesa, GLuint flags ) */ DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv ); + /* If timestamps don't match, the window has been changed */ + if (nmesa->lastStamp != dPriv->lastStamp) { + struct gl_framebuffer *fb = (struct gl_framebuffer *)dPriv->driverPrivate; + + /* _mesa_resize_framebuffer will take care of calling the renderbuffer's + * AllocStorage function if we need more memory to hold it */ + if (fb->Width != dPriv->w || fb->Height != dPriv->h) { + _mesa_resize_framebuffer(nmesa->glCtx, fb, dPriv->w, dPriv->h); + /* resize buffers, will call nouveau_window_moved */ + nouveau_build_framebuffer(nmesa->glCtx, fb); + } else { + nouveau_window_moved(nmesa->glCtx); + } + + nmesa->lastStamp = dPriv->lastStamp; + } + nmesa->numClipRects = dPriv->numClipRects; nmesa->pClipRects = dPriv->pClipRects; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.c b/src/mesa/drivers/dri/nouveau/nouveau_object.c index 032cdee2f7..ef8a428c22 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.c @@ -1,6 +1,7 @@ #include "nouveau_fifo.h" #include "nouveau_object.h" +#include "nouveau_reg.h" static GLboolean nouveauCreateContextObject(nouveauContextPtr nmesa, int handle, int class, uint32_t flags, uint32_t dma_in, uint32_t dma_out, uint32_t dma_notifier) @@ -51,14 +52,30 @@ void nouveauObjectInit(nouveauContextPtr nmesa) return; #endif - nouveauCreateContextObject(nmesa, Nv3D, nmesa->screen->card->class_3d, 0, 0, 0, 0); - nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); /* We need to know vram size.. */ -#if 0 nouveauCreateDmaObject( nmesa, NvDmaFB, 0, (256*1024*1024), 0 /*NV_DMA_TARGET_FB*/, 0 /*NV_DMA_ACCESS_RW*/); + + nouveauCreateContextObject(nmesa, Nv3D, nmesa->screen->card->class_3d, + 0, 0, 0, 0); + nouveauCreateContextObject(nmesa, NvCtxSurf2D, NV10_CONTEXT_SURFACES_2D, + 0, 0, 0, 0); + nouveauCreateContextObject(nmesa, NvImageBlit, NV10_IMAGE_BLIT, + NV_DMA_CONTEXT_FLAGS_PATCH_SRCCOPY, 0, 0, 0); + +#ifdef ALLOW_MULTI_SUBCHANNEL + nouveauObjectOnSubchannel(nmesa, NvSubCtxSurf2D, NvCtxSurf2D); + BEGIN_RING_SIZE(NvSubCtxSurf2D, NV10_CONTEXT_SURFACES_2D_SET_DMA_IN_MEMORY0, 2); + OUT_RING(NvDmaFB); + OUT_RING(NvDmaFB); + + nouveauObjectOnSubchannel(nmesa, NvSubImageBlit, NvImageBlit); + BEGIN_RING_SIZE(NvSubImageBlit, NV10_IMAGE_BLIT_SET_CONTEXT_SURFACES_2D, 1); + OUT_RING(NvCtxSurf2D); #endif + + nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.h b/src/mesa/drivers/dri/nouveau/nouveau_object.h index 8386f923c3..f555eba9b4 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.h @@ -3,14 +3,21 @@ #include "nouveau_context.h" +#define ALLOW_MULTI_SUBCHANNEL + void nouveauObjectInit(nouveauContextPtr nmesa); enum DMAObjects { Nv3D = 0x80000019, - NvDmaFB = 0xD0FB0001 + NvCtxSurf2D = 0x80000020, + NvImageBlit = 0x80000021, + NvDmaFB = 0xD0FB0001, + NvDmaAGP = 0xD0AA0001 }; enum DMASubchannel { + NvSubCtxSurf2D = 0, + NvSubImageBlit = 1, NvSub3D = 7, }; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index 51f9fb1487..15c1c40925 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -120,86 +120,69 @@ nouveauCreateBuffer(__DRIscreenPrivate *driScrnPriv, GLboolean isPixmap) { nouveauScreenPtr screen = (nouveauScreenPtr) driScrnPriv->private; + nouveau_renderbuffer *nrb; + struct gl_framebuffer *fb; + const GLboolean swAccum = mesaVis->accumRedBits > 0; + const GLboolean swStencil = mesaVis->stencilBits > 0 && mesaVis->depthBits != 24; - if (isPixmap) { + if (isPixmap) return GL_FALSE; /* not implemented */ - } - else { - const GLboolean swDepth = GL_FALSE; - const GLboolean swAlpha = GL_FALSE; - const GLboolean swAccum = mesaVis->accumRedBits > 0; - const GLboolean swStencil = mesaVis->stencilBits > 0 && mesaVis->depthBits != 24; - struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis); - - /* front color renderbuffer */ - { - driRenderbuffer *frontRb - = driNewRenderbuffer(GL_RGBA, - driScrnPriv->pFB + screen->frontOffset, - screen->fbFormat, - screen->frontOffset, screen->frontPitch, - driDrawPriv); - nouveauSpanSetFunctions(frontRb, mesaVis); - _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base); - } - /* back color renderbuffer */ - if (mesaVis->doubleBufferMode) { - driRenderbuffer *backRb - = driNewRenderbuffer(GL_RGBA, - driScrnPriv->pFB + screen->backOffset, - screen->fbFormat, - screen->backOffset, screen->backPitch, - driDrawPriv); - nouveauSpanSetFunctions(backRb, mesaVis); - _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base); - } + fb = _mesa_create_framebuffer(mesaVis); + if (!fb) + return GL_FALSE; - /* depth renderbuffer */ - if (mesaVis->depthBits == 16) { - driRenderbuffer *depthRb - = driNewRenderbuffer(GL_DEPTH_COMPONENT16, - driScrnPriv->pFB + screen->depthOffset, - screen->fbFormat, - screen->depthOffset, screen->depthPitch, - driDrawPriv); - nouveauSpanSetFunctions(depthRb, mesaVis); - _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base); - } - else if (mesaVis->depthBits == 24) { - driRenderbuffer *depthRb - = driNewRenderbuffer(GL_DEPTH_COMPONENT24, - driScrnPriv->pFB + screen->depthOffset, - screen->fbFormat, - screen->depthOffset, screen->depthPitch, - driDrawPriv); - nouveauSpanSetFunctions(depthRb, mesaVis); - _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base); + /* Front buffer */ + nrb = nouveau_renderbuffer_new(GL_RGBA, + driScrnPriv->pFB + screen->frontOffset, + screen->frontOffset, + screen->frontPitch * 4, + driDrawPriv); + nouveauSpanSetFunctions(nrb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &nrb->mesa); + + if (0 /* unified buffers if we choose to support them.. */) { + } else { + if (mesaVis->doubleBufferMode) { + nrb = nouveau_renderbuffer_new(GL_RGBA, NULL, + 0, 0, + driDrawPriv); + nouveauSpanSetFunctions(nrb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &nrb->mesa); } - /* stencil renderbuffer */ - if (mesaVis->stencilBits > 0 && !swStencil) { - driRenderbuffer *stencilRb - = driNewRenderbuffer(GL_STENCIL_INDEX8_EXT, - driScrnPriv->pFB + screen->depthOffset, - screen->fbFormat, - screen->depthOffset, screen->depthPitch, - driDrawPriv); - nouveauSpanSetFunctions(stencilRb, mesaVis); - _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base); + if (mesaVis->depthBits == 24 && mesaVis->stencilBits == 8) { + nrb = nouveau_renderbuffer_new(GL_DEPTH24_STENCIL8_EXT, NULL, + 0, 0, + driDrawPriv); + nouveauSpanSetFunctions(nrb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &nrb->mesa); + _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &nrb->mesa); + } else if (mesaVis->depthBits == 24) { + nrb = nouveau_renderbuffer_new(GL_DEPTH_COMPONENT24, NULL, + 0, 0, + driDrawPriv); + nouveauSpanSetFunctions(nrb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &nrb->mesa); + } else if (mesaVis->depthBits == 16) { + nrb = nouveau_renderbuffer_new(GL_DEPTH_COMPONENT16, NULL, + 0, 0, + driDrawPriv); + nouveauSpanSetFunctions(nrb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &nrb->mesa); } + } - _mesa_add_soft_renderbuffers(fb, - GL_FALSE, /* color */ - swDepth, - swStencil, - swAccum, - swAlpha, - GL_FALSE /* aux */); - driDrawPriv->driverPrivate = (void *) fb; + _mesa_add_soft_renderbuffers(fb, + GL_FALSE, /* color */ + GL_FALSE, /* depth */ + swStencil, + swAccum, + GL_FALSE, /* alpha */ + GL_FALSE /* aux */); - return (driDrawPriv->driverPrivate != NULL); - } + driDrawPriv->driverPrivate = (void *) fb; + return (driDrawPriv->driverPrivate != NULL); } @@ -363,7 +346,8 @@ void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIsc *driver_modes = nouveauFillInModes(dri_priv->bpp, (dri_priv->bpp == 16) ? 16 : 24, (dri_priv->bpp == 16) ? 0 : 8, - (dri_priv->back_offset != dri_priv->depth_offset)); + 1 + ); /* Calling driInitExtensions here, with a NULL context pointer, does not actually * enable the extensions. It just makes sure that all the dispatch offsets for all diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.c b/src/mesa/drivers/dri/nouveau/nouveau_shader.c index 63da8420b2..4dedefe5a3 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.c @@ -132,6 +132,8 @@ nvsUpdateShader(GLcontext *ctx, nouveauShader *nvs) */ nvs->func->UpdateConst(ctx, nvs, i); } else if (plist->Parameters[i].Type == PROGRAM_STATE_VAR) { + if (!nvs->params[i].source_val) /* this is a workaround when consts aren't alloc'd from id=0.. */ + continue; /* update any changed state parameters */ if (!TEST_EQ_4V(nvs->params[i].val, nvs->params[i].source_val)) nvs->func->UpdateConst(ctx, nvs, i); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h index a1e7794487..dce2e23f46 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -2,6 +2,7 @@ #define __SHADER_COMMON_H__ #include "mtypes.h" +#include "nouveau_buffers.h" typedef struct _nvsFunc nvsFunc; @@ -40,6 +41,7 @@ typedef struct _nouveauShader { unsigned int program_alloc_size; unsigned int program_start_id; unsigned int program_current; + nouveau_mem *program_buffer; unsigned int inputs_read; unsigned int outputs_written; int inst_count; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_span.c b/src/mesa/drivers/dri/nouveau/nouveau_span.c index 1763b37e53..6d99728b85 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_span.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_span.c @@ -109,14 +109,10 @@ void nouveauSpanInitFunctions( GLcontext *ctx ) * Plug in the Get/Put routines for the given driRenderbuffer. */ void -nouveauSpanSetFunctions(driRenderbuffer *drb, const GLvisual *vis) +nouveauSpanSetFunctions(nouveau_renderbuffer *nrb, 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); - } - } + if (nrb->mesa._ActualFormat == GL_RGBA8) + nouveauInitPointers_ARGB8888(&nrb->mesa); + else if (nrb->mesa._ActualFormat == GL_RGB5) + nouveauInitPointers_RGB565(&nrb->mesa); } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_span.h b/src/mesa/drivers/dri/nouveau/nouveau_span.h index f5e5733ba8..bc39ecd17b 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_span.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_span.h @@ -30,9 +30,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define __NOUVEAU_SPAN_H__ #include "drirenderbuffer.h" +#include "nouveau_buffers.h" extern void nouveauSpanInitFunctions( GLcontext *ctx ); -extern void nouveauSpanSetFunctions(driRenderbuffer *rb, const GLvisual *vis); +extern void nouveauSpanSetFunctions(nouveau_renderbuffer *nrb, const GLvisual *vis); #endif /* __NOUVEAU_SPAN_H__ */ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c index 88a8c9ed59..6406b2d9cd 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -59,20 +59,33 @@ static void nouveauCalcViewport(GLcontext *ctx) /* Calculate the Viewport Matrix */ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_renderbuffer *nrb; const GLfloat *v = ctx->Viewport._WindowMap.m; GLfloat *m = nmesa->viewport.m; + GLfloat xoffset, yoffset; GLint h = 0; - - if (nmesa->driDrawable) - h = nmesa->driDrawable->h + SUBPIXEL_Y; - + + nrb = nouveau_current_draw_buffer(ctx); + nmesa->depth_scale = 1.0 / ctx->DrawBuffer->_DepthMaxF; + + if (nrb && nrb->map) { + /* Window */ + xoffset = nrb->dPriv->x; + yoffset = nrb->dPriv->y; + } else { + /* Offscreen or back buffer */ + xoffset = 0.0; + yoffset = 0.0; + } + m[MAT_SX] = v[MAT_SX]; - m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X; + m[MAT_TX] = v[MAT_TX] + xoffset + SUBPIXEL_X; m[MAT_SY] = - v[MAT_SY]; - m[MAT_TY] = - v[MAT_TY] + h; + m[MAT_TY] = v[MAT_TY] + yoffset + SUBPIXEL_Y; m[MAT_SZ] = v[MAT_SZ] * nmesa->depth_scale; m[MAT_TZ] = v[MAT_TZ] * nmesa->depth_scale; + nmesa->hw_func.WindowMoved(nmesa); } static void nouveauViewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) @@ -96,7 +109,7 @@ static void nouveauViewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei nouveauCalcViewport(ctx); } -static void nouveauDepthRange(GLcontext *ctx) +static void nouveauDepthRange(GLcontext *ctx, GLclampd near, GLclampd far) { nouveauCalcViewport(ctx); } @@ -161,15 +174,15 @@ void nouveauDDInitState(nouveauContextPtr nmesa) /* No TCL engines for these ones */ break; case NV_10: - nv10InitStateFuncs(&nmesa->glCtx->Driver); + nv10InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver); break; case NV_20: - nv20InitStateFuncs(&nmesa->glCtx->Driver); + nv20InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver); break; case NV_30: case NV_40: case NV_50: - nv30InitStateFuncs(&nmesa->glCtx->Driver); + nv30InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver); break; default: break; @@ -270,7 +283,6 @@ void nouveauInitState(GLcontext *ctx) STATE_INIT(CullFace)( ctx, ctx->Polygon.CullFaceMode ); STATE_INIT(DepthFunc)( ctx, ctx->Depth.Func ); STATE_INIT(DepthMask)( ctx, ctx->Depth.Mask ); - STATE_INIT(DepthRange)( ctx, ctx->Viewport.Near, ctx->Viewport.Far ); STATE_INIT(Enable)( ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled ); STATE_INIT(Enable)( ctx, GL_BLEND, ctx->Color.BlendEnabled ); @@ -320,8 +332,6 @@ void nouveauInitState(GLcontext *ctx) ctx->Polygon.OffsetFactor, ctx->Polygon.OffsetUnits ); STATE_INIT(PolygonStipple)( ctx, (const GLubyte *)ctx->PolygonStipple ); - STATE_INIT(Scissor)( ctx, ctx->Scissor.X, ctx->Scissor.Y, - ctx->Scissor.Width, ctx->Scissor.Height ); STATE_INIT(ShadeModel)( ctx, ctx->Light.ShadeModel ); STATE_INIT(StencilFuncSeparate)( ctx, GL_FRONT, ctx->Stencil.Function[0], @@ -341,10 +351,4 @@ void nouveauInitState(GLcontext *ctx) ctx->Stencil.FailFunc[1], ctx->Stencil.ZFailFunc[1], ctx->Stencil.ZPassFunc[1]); - - STATE_INIT(Viewport)( ctx, - ctx->Viewport.X, ctx->Viewport.Y, - ctx->Viewport.Width, ctx->Viewport.Height ); - - STATE_INIT(DrawBuffer)( ctx, ctx->Color.DrawBuffer[0] ); } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.h b/src/mesa/drivers/dri/nouveau/nouveau_state.h index 37f04f41bd..16d63a6ac2 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.h @@ -32,9 +32,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. extern void nouveauDDInitState(nouveauContextPtr nmesa); extern void nouveauDDInitStateFuncs(GLcontext *ctx); -extern void nv10InitStateFuncs(struct dd_function_table *func); -extern void nv20InitStateFuncs(struct dd_function_table *func); -extern void nv30InitStateFuncs(struct dd_function_table *func); +extern void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func); +extern void nv20InitStateFuncs(GLcontext *ctx, struct dd_function_table *func); +extern void nv30InitStateFuncs(GLcontext *ctx, struct dd_function_table *func); extern void nouveauInitState(GLcontext *ctx); diff --git a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c index 1c2664ec70..98aa27ea9c 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c +++ b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c @@ -10,6 +10,7 @@ #include "nouveau_shader.h" #include "nouveau_object.h" #include "nouveau_msg.h" +#include "nouveau_buffers.h" #include "nv30_shader.h" unsigned int NVFP_TX_AOP_COUNT = 64; @@ -19,31 +20,22 @@ struct _op_xlat NVFP_TX_AOP[64]; * Support routines */ -/*XXX: bad bad bad bad */ -static uint64_t fragprog_ofs; -static uint32_t *fragprog_buf = NULL; - static void NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); drm_nouveau_mem_alloc_t mem; - if (!fragprog_buf) { - mem.flags = NOUVEAU_MEM_FB|NOUVEAU_MEM_MAPPED; - mem.size = nvs->program_size * sizeof(uint32_t); - mem.alignment = 0; - mem.region_offset = &fragprog_ofs; - if (drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_MEM_ALLOC, &mem, - sizeof(mem))) { - fprintf(stderr, "MEM_ALLOC fail\n"); - return; - } + if (!nvs->program_buffer) { + nouveau_mem *fpbuf; - if (drmMap(nmesa->driFd, fragprog_ofs, mem.size, &fragprog_buf)) { - fprintf(stderr, "MEM_MAP fail\n"); + fpbuf = nouveau_mem_alloc(ctx, NOUVEAU_MEM_FB|NOUVEAU_MEM_MAPPED, + nvs->program_size * sizeof(uint32_t), 0); + if (!fpbuf) { + fprintf(stderr, "fragprog vram alloc fail!\n"); return; } + nvs->program_buffer = fpbuf; } /*XXX: should do a DMA.. and not copy over a possibly in-use program.. */ @@ -52,9 +44,10 @@ NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs) * caches the program somewhere? so, maybe not so bad to just clobber the * old program in vram.. */ - memcpy(fragprog_buf, nvs->program, nvs->program_size * sizeof(uint32_t)); + memcpy(nvs->program_buffer->map, nvs->program, + nvs->program_size * sizeof(uint32_t)); BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM, 1); - OUT_RING(((uint32_t)fragprog_ofs-0xE0000000)|1); + OUT_RING(nouveau_mem_gpu_offset_get(ctx, nvs->program_buffer) | 1); } static void diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 3ffb5d3a41..3228320623 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -304,10 +304,16 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) // case GL_POST_COLOR_MATRIX_COLOR_TABLE: // case GL_POST_CONVOLUTION_COLOR_TABLE: // case GL_RESCALE_NORMAL: -// case GL_SCISSOR_TEST: + case GL_SCISSOR_TEST: + /* No enable bit, nv30Scissor will adjust to max range */ + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); + break; // case GL_SEPARABLE_2D: case GL_STENCIL_TEST: // TODO BACK and FRONT ? + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_ENABLE, 1); + OUT_RING_CACHE(state); BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_ENABLE, 1); OUT_RING_CACHE(state); break; @@ -514,9 +520,26 @@ void (*RenderMode)(GLcontext *ctx, GLenum mode ); static void nv30Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_renderbuffer *nrb; + + /* Adjust offsets if drawing to a window */ + nrb = nouveau_current_draw_buffer(ctx); + if (nrb && nrb->map) { + x += nrb->dPriv->x; + y += nrb->dPriv->y; + } + + /* There's no scissor enable bit, so adjust the scissor to cover the + * maximum draw buffer bounds + */ + if (!ctx->Scissor.Enabled) { + x = y = 0; + w = h = 4095; + } + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS, 2); - OUT_RING_CACHE((w << 16) | x); - OUT_RING_CACHE((h << 16) | y); + OUT_RING_CACHE(((w) << 16) | x); + OUT_RING_CACHE(((h) << 16) | y); } /** Select flat or smooth shading */ @@ -602,18 +625,117 @@ static void nv30TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) OUT_RING_CACHEp(mat->m, 16); } -/** Set the viewport */ -static void nv30Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +static void nv30WindowMoved(nouveauContextPtr nmesa) { - /* TODO: Where do the VIEWPORT_XFRM_* regs come in? */ - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLcontext *ctx = nmesa->glCtx; + nouveau_renderbuffer *nrb; + GLfloat *v = nmesa->viewport.m; + GLuint w = ctx->Viewport.Width; + GLuint h = ctx->Viewport.Height; + GLuint x = ctx->Viewport.X; + GLuint y = ctx->Viewport.Y; + + /* Adjust offsets if drawing to a window */ + nrb = nouveau_current_draw_buffer(ctx); + if (nrb && nrb->map) { + x += nrb->dPriv->x; + y += nrb->dPriv->y; + } + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_0, 2); OUT_RING_CACHE((w << 16) | x); OUT_RING_CACHE((h << 16) | y); -} - -void nv30InitStateFuncs(struct dd_function_table *func) + /* something to do with clears, possibly doesn't belong here */ + BEGIN_RING_CACHE(NvSub3D, + NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_OFS0, 2); + OUT_RING_CACHE(((w+x) << 16) | x); + OUT_RING_CACHE(((h+y) << 16) | y); + /* viewport transform */ + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_OX, 8); + OUT_RING_CACHEf (v[MAT_TX]); + OUT_RING_CACHEf (v[MAT_TY]); + OUT_RING_CACHEf (v[MAT_TZ]); + OUT_RING_CACHEf (0.0); + OUT_RING_CACHEf (v[MAT_SX]); + OUT_RING_CACHEf (v[MAT_SY]); + OUT_RING_CACHEf (v[MAT_SZ]); + OUT_RING_CACHEf (0.0); + + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); +} + +static GLboolean nv30InitCard(nouveauContextPtr nmesa) +{ + /* Need some love.. */ + return GL_FALSE; +} + +static GLboolean nv40InitCard(nouveauContextPtr nmesa) +{ + nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); + + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT1, 2); + OUT_RING(NvDmaFB); + OUT_RING(NvDmaFB); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT8, 1); + OUT_RING(NvDmaFB); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT4, 2); + OUT_RING(NvDmaFB); + OUT_RING(NvDmaFB); + BEGIN_RING_SIZE(NvSub3D, 0x0220, 1); + OUT_RING(1); + BEGIN_RING_SIZE(NvSub3D, 0x1fc8, 2); + OUT_RING(0xedcba987); + OUT_RING(0x00000021); + BEGIN_RING_SIZE(NvSub3D, 0x1d60, 1); + OUT_RING(0x03008000); + + return GL_TRUE; +} + +static GLboolean nv30BindBuffers(nouveauContextPtr nmesa, int num_color, + nouveau_renderbuffer **color, + nouveau_renderbuffer *depth) +{ + nouveau_renderbuffer *nrb; + GLuint x, y, w, h; + + /* Adjust offsets if drawing to a window */ + nrb = nouveau_current_draw_buffer(nmesa->glCtx); + w = nrb->mesa.Width; + h = nrb->mesa.Height; + if (nrb && nrb->map) { + x = nrb->dPriv->x; + y = nrb->dPriv->y; + } else { + x = 0; + y = 0; + } + + if (num_color != 1) + return GL_FALSE; + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_DIM0, 5); + OUT_RING (((w+x)<<16)|x); + OUT_RING (((h+y)<<16)|y); + OUT_RING (0x148); + OUT_RING (color[0]->pitch); + OUT_RING (color[0]->offset); + + if (depth) { + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_OFFSET, 1); + OUT_RING (depth->offset); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH, 1); + OUT_RING (depth->pitch); + } + + return GL_TRUE; +} + +void nv30InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) { + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + func->AlphaFunc = nv30AlphaFunc; func->BlendColor = nv30BlendColor; func->BlendEquationSeparate = nv30BlendEquationSeparate; @@ -628,7 +750,6 @@ void nv30InitStateFuncs(struct dd_function_table *func) func->FrontFace = nv30FrontFace; func->DepthFunc = nv30DepthFunc; func->DepthMask = nv30DepthMask; - func->DepthRange = nv30DepthRange; func->Enable = nv30Enable; func->Fogfv = nv30Fogfv; func->Hint = nv30Hint; @@ -656,6 +777,13 @@ void nv30InitStateFuncs(struct dd_function_table *func) func->TexParameter = nv30TexParameter; #endif func->TextureMatrix = nv30TextureMatrix; - func->Viewport = nv30Viewport; + + + if (nmesa->screen->card->type >= NV_40) + nmesa->hw_func.InitCard = nv40InitCard; + else + nmesa->hw_func.InitCard = nv30InitCard; + nmesa->hw_func.BindBuffers = nv30BindBuffers; + nmesa->hw_func.WindowMoved = nv30WindowMoved; } -- cgit v1.2.3 From 1d6f13986c40c014708175ed3289811d03a8c724 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 8 Dec 2006 03:04:10 +0000 Subject: oops, we don't want this by default just yet... --- src/mesa/drivers/dri/nouveau/nouveau_object.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.h b/src/mesa/drivers/dri/nouveau/nouveau_object.h index f555eba9b4..a49a39719b 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.h @@ -3,7 +3,7 @@ #include "nouveau_context.h" -#define ALLOW_MULTI_SUBCHANNEL +//#define ALLOW_MULTI_SUBCHANNEL void nouveauObjectInit(nouveauContextPtr nmesa); -- cgit v1.2.3 From 011377622fa78d141486ba0536a1546cea8cb8c6 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 8 Dec 2006 07:15:43 +0000 Subject: Create visuals for modes the ddx provides --- src/mesa/drivers/dri/nouveau/nouveau_screen.c | 82 +++++++++++++-------------- 1 file changed, 38 insertions(+), 44 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index 15c1c40925..18ca37918f 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -226,8 +226,17 @@ nouveauFillInModes( unsigned pixel_bits, unsigned depth_bits, unsigned num_modes; unsigned depth_buffer_factor; unsigned back_buffer_factor; - GLenum fb_format; - GLenum fb_type; + unsigned fb_format_factor; + int i; + + static const struct { + GLenum format; + GLenum type; + } fb_format_array[] = { + { GL_RGB , GL_UNSIGNED_SHORT_5_6_5 }, + { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV }, + { GL_RGB , GL_UNSIGNED_INT_8_8_8_8_REV }, + }; /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't * support pageflipping at all. @@ -236,58 +245,43 @@ nouveauFillInModes( unsigned pixel_bits, unsigned depth_bits, GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML }; - u_int8_t depth_bits_array[3]; - u_int8_t stencil_bits_array[3]; - - depth_bits_array[0] = 0; - depth_bits_array[1] = depth_bits; - depth_bits_array[2] = depth_bits; - - /* Just like with the accumulation buffer, always provide some modes - * with a stencil buffer. It will be a sw fallback, but some apps won't - * care about that. - */ - stencil_bits_array[0] = 0; - stencil_bits_array[1] = 0; - stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits; + u_int8_t depth_bits_array[4] = { 0, 16, 24, 24 }; + u_int8_t stencil_bits_array[4] = { 0, 0, 0, 8 }; - depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1; + depth_buffer_factor = 4; back_buffer_factor = (have_back_buffer) ? 3 : 1; - num_modes = depth_buffer_factor * back_buffer_factor * 4; - - if ( pixel_bits == 16 ) { - fb_format = GL_RGB; - fb_type = GL_UNSIGNED_SHORT_5_6_5; - } else { - fb_format = GL_BGRA; - fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; - } - - modes = (*dri_interface->createContextModes)( num_modes, sizeof( __GLcontextModes ) ); + num_modes = ((pixel_bits==16) ? 1 : 2) * + depth_buffer_factor * back_buffer_factor * 4; + modes = (*dri_interface->createContextModes)(num_modes, + sizeof(__GLcontextModes)); m = modes; - if (!driFillInModes(&m, fb_format, fb_type, - depth_bits_array, stencil_bits_array, depth_buffer_factor, - back_buffer_modes, back_buffer_factor, - GLX_TRUE_COLOR)) { + + for (i=((pixel_bits==16)?0:1);i<((pixel_bits==16)?1:3);i++) { + if (!driFillInModes(&m, fb_format_array[i].format, + fb_format_array[i].type, + depth_bits_array, + stencil_bits_array, + depth_buffer_factor, + back_buffer_modes, + back_buffer_factor, + GLX_TRUE_COLOR)) { fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__ ); return NULL; - } - if (!driFillInModes(&m, fb_format, fb_type, - depth_bits_array, stencil_bits_array, depth_buffer_factor, - back_buffer_modes, back_buffer_factor, - GLX_DIRECT_COLOR)) { + } + + if (!driFillInModes(&m, fb_format_array[i].format, + fb_format_array[i].type, + depth_bits_array, + stencil_bits_array, + depth_buffer_factor, + back_buffer_modes, + back_buffer_factor, + GLX_DIRECT_COLOR)) { fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__ ); return NULL; - } - - /* Mark the visual as slow if there are "fake" stencil bits. - */ - for ( m = modes ; m != NULL ; m = m->next ) { - if ( (m->stencilBits != 0) && (m->stencilBits != stencil_bits) ) { - m->visualRating = GLX_SLOW_CONFIG; } } -- cgit v1.2.3 From bda66ac426e7ebd0c9383c665a43bc9dbe3154f7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 8 Dec 2006 07:27:39 +0000 Subject: oops, typo --- src/mesa/drivers/dri/nouveau/nouveau_screen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index 18ca37918f..93f66826e8 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -234,8 +234,8 @@ nouveauFillInModes( unsigned pixel_bits, unsigned depth_bits, GLenum type; } fb_format_array[] = { { GL_RGB , GL_UNSIGNED_SHORT_5_6_5 }, - { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV }, - { GL_RGB , GL_UNSIGNED_INT_8_8_8_8_REV }, + { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV }, + { GL_BGR , GL_UNSIGNED_INT_8_8_8_8_REV }, }; /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't -- cgit v1.2.3 From e62b2f9c2ec083db40abcf2991201e9e108861f1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 8 Dec 2006 11:45:39 +0000 Subject: Implement a simple nv30Clear, and make sure we get a nouveau_renderbuffer for the depth buffer and not a Mesa renderbuffer adaptor --- src/mesa/drivers/dri/nouveau/nouveau_buffers.c | 5 ++++- src/mesa/drivers/dri/nouveau/nv30_state.c | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c index a356fd1212..42d8691752 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c @@ -239,7 +239,10 @@ nouveau_build_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb) _mesa_update_draw_buffer_bounds(ctx); color[0] = (nouveau_renderbuffer *)fb->_ColorDrawBuffers[0][0]; - depth = (nouveau_renderbuffer *)fb->_DepthBuffer; + if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) + depth = (nouveau_renderbuffer *)fb->_DepthBuffer->Wrapped; + else + depth = (nouveau_renderbuffer *)fb->_DepthBuffer; if (!nmesa->hw_func.BindBuffers(nmesa, 1, color, depth)) return GL_FALSE; diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 3228320623..aab0bd9fda 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -79,6 +79,23 @@ static void nv30BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfac OUT_RING_CACHE((dfactorA<<16) | dfactorRGB); } +static void nv30Clear(GLcontext *ctx, GLbitfield mask) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLuint hw_bufs = 0; + + if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT)) + hw_bufs |= 0xf0; + if (mask & (BUFFER_BIT_DEPTH)) + hw_bufs |= 0x03; + + if (hw_bufs) { + /* should we flush the state cache before this? */ + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_WHICH_BUFFERS, 1); + OUT_RING(hw_bufs); + } +} + static void nv30ClearColor(GLcontext *ctx, const GLfloat color[4]) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); @@ -740,6 +757,7 @@ void nv30InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) func->BlendColor = nv30BlendColor; func->BlendEquationSeparate = nv30BlendEquationSeparate; func->BlendFuncSeparate = nv30BlendFuncSeparate; + func->Clear = nv30Clear; func->ClearColor = nv30ClearColor; func->ClearDepth = nv30ClearDepth; func->ClearStencil = nv30ClearStencil; -- cgit v1.2.3 From 046ece3a2da89c30c8d1bfa25389b19caad0a64c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 8 Dec 2006 11:51:50 +0000 Subject: state cache is automagically flushed on a normal BEGIN_RING_SIZE --- src/mesa/drivers/dri/nouveau/nv30_state.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index aab0bd9fda..f0b37a76f5 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -90,7 +90,6 @@ static void nv30Clear(GLcontext *ctx, GLbitfield mask) hw_bufs |= 0x03; if (hw_bufs) { - /* should we flush the state cache before this? */ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLEAR_WHICH_BUFFERS, 1); OUT_RING(hw_bufs); } -- cgit v1.2.3 From fe91d00e332b42d0aea9f7aa266f8cc28ac9ec39 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 8 Dec 2006 12:36:26 +0000 Subject: NV_44 uses nv30InitStateFuncs too --- src/mesa/drivers/dri/nouveau/nouveau_state.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c index 6406b2d9cd..cec7120d43 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -181,6 +181,7 @@ void nouveauDDInitState(nouveauContextPtr nmesa) break; case NV_30: case NV_40: + case NV_44: case NV_50: nv30InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver); break; -- cgit v1.2.3 From c04c74bc5da454478fd0dbf3b25dd54190ac0942 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 8 Dec 2006 14:12:47 +0000 Subject: Skeletal extension handling across chipsets. --- src/mesa/drivers/dri/nouveau/nouveau_context.c | 45 ++++++++++++++++++++++++++ src/mesa/drivers/dri/nouveau/nouveau_screen.c | 10 ++++++ src/mesa/drivers/dri/nouveau/nouveau_shader.c | 3 -- 3 files changed, 55 insertions(+), 3 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index f48c54416a..53d26e0d74 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -65,11 +65,44 @@ static const struct dri_debug_control debug_control[] = { NULL, 0 } }; +#define need_GL_ARB_vertex_program +#include "extension_helper.h" + const struct dri_extension common_extensions[] = { { NULL, 0 } }; +const struct dri_extension nv10_extensions[] = +{ + { NULL, 0 } +}; + +const struct dri_extension nv20_extensions[] = +{ + { NULL, 0 } +}; + +const struct dri_extension nv30_extensions[] = +{ + { "GL_ARB_fragment_program", NULL }, + { NULL, 0 } +}; + +const struct dri_extension nv40_extensions[] = +{ + /* ARB_vp can be moved to nv20/30 once the shader backend has been + * written for those cards. + */ + { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions }, + { NULL, 0 } +}; + +const struct dri_extension nv50_extensions[] = +{ + { NULL, 0 } +}; + /* Create the device specific context. */ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, @@ -137,6 +170,18 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, nmesa->sarea = (drm_nouveau_sarea_t *)((char *)sPriv->pSAREA + screen->sarea_priv_offset); + /* Enable any supported extensions */ + driInitExtensions(ctx, common_extensions, GL_TRUE); + if (nmesa->screen->card->type >= NV_10) + driInitExtensions(ctx, nv10_extensions, GL_FALSE); + if (nmesa->screen->card->type >= NV_20) + driInitExtensions(ctx, nv20_extensions, GL_FALSE); + if (nmesa->screen->card->type >= NV_30) + driInitExtensions(ctx, nv30_extensions, GL_FALSE); + if (nmesa->screen->card->type >= NV_40) + driInitExtensions(ctx, nv40_extensions, GL_FALSE); + if (nmesa->screen->card->type >= NV_50) + driInitExtensions(ctx, nv50_extensions, GL_FALSE); nmesa->current_primitive = -1; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index 93f66826e8..8e548dbcbd 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -53,6 +53,11 @@ DRI_CONF_END; static const GLuint __driNConfigOptions = 1; extern const struct dri_extension common_extensions[]; +extern const struct dri_extension nv10_extensions[]; +extern const struct dri_extension nv20_extensions[]; +extern const struct dri_extension nv30_extensions[]; +extern const struct dri_extension nv40_extensions[]; +extern const struct dri_extension nv50_extensions[]; static nouveauScreenPtr nouveauCreateScreen(__DRIscreenPrivate *sPriv) { @@ -352,6 +357,11 @@ void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIsc * Hello chicken. Hello egg. How are you two today? */ driInitExtensions( NULL, common_extensions, GL_FALSE ); + driInitExtensions( NULL, nv10_extensions, GL_FALSE ); + driInitExtensions( NULL, nv10_extensions, GL_FALSE ); + driInitExtensions( NULL, nv30_extensions, GL_FALSE ); + driInitExtensions( NULL, nv40_extensions, GL_FALSE ); + driInitExtensions( NULL, nv50_extensions, GL_FALSE ); } return (void *) psp; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.c b/src/mesa/drivers/dri/nouveau/nouveau_shader.c index 4dedefe5a3..e3082ebc69 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.c @@ -184,7 +184,6 @@ nouveauShaderInitFuncs(GLcontext * ctx) return; } - _mesa_enable_extension(ctx, "GL_ARB_vertex_program"); ctx->Const.VertexProgram.MaxNativeInstructions = nmesa->VPfunc.MaxInst; ctx->Const.VertexProgram.MaxNativeAluInstructions = nmesa->VPfunc.MaxInst; ctx->Const.VertexProgram.MaxNativeTexInstructions = nmesa->VPfunc.MaxInst; @@ -196,8 +195,6 @@ nouveauShaderInitFuncs(GLcontext * ctx) ctx->Const.VertexProgram.MaxNativeParameters = nmesa->VPfunc.MaxConst; if (nmesa->screen->card->type >= NV_30) { - _mesa_enable_extension(ctx, "GL_ARB_fragment_program"); - ctx->Const.FragmentProgram.MaxNativeInstructions = nmesa->FPfunc.MaxInst; ctx->Const.FragmentProgram.MaxNativeAluInstructions = nmesa->FPfunc.MaxInst; ctx->Const.FragmentProgram.MaxNativeTexInstructions = nmesa->FPfunc.MaxInst; -- cgit v1.2.3 From 65c54a685a0ac7d08ad608c25d0e3c318f8be43f Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 8 Dec 2006 16:39:12 +0000 Subject: Resend spot light parameters when part of it changes --- src/mesa/drivers/dri/nouveau/nv10_state.c | 87 ++++++++++++++++++++++--------- 1 file changed, 61 insertions(+), 26 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index da26ccba87..bb9abe9867 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -326,11 +326,18 @@ static void nv10Hint(GLcontext *ctx, GLenum target, GLenum mode) // void (*IndexMask)(GLcontext *ctx, GLuint mask); +enum { + SPOTLIGHT_UPDATE_EXPONENT, + SPOTLIGHT_UPDATE_DIRECTION, + SPOTLIGHT_UPDATE_ALL +}; + static void nv10Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params ) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); GLint p = light - GL_LIGHT0; struct gl_light *l = &ctx->Light.Light[p]; + int spotlightUpdate = -1; switch(pname) { @@ -352,41 +359,20 @@ static void nv10Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; - case GL_SPOT_DIRECTION: - { - GLfloat x,y,z; - x = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[0]; - y = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[1]; - z = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[2]; - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p), 3); - OUT_RING_CACHEf(x); - OUT_RING_CACHEf(y); - OUT_RING_CACHEf(z); - } - break; case GL_POSITION: BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(p), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; + case GL_SPOT_DIRECTION: + spotlightUpdate = SPOTLIGHT_UPDATE_DIRECTION; + break; case GL_SPOT_EXPONENT: - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(p), 1); - OUT_RING_CACHEf(*params); + spotlightUpdate = SPOTLIGHT_UPDATE_DIRECTION; break; case GL_SPOT_CUTOFF: - /* you can't factor these */ - { - GLfloat c; - c = -2.0 * (0.5 + l->_CosCutoff); - - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 1); - OUT_RING_CACHEf(params[0]); - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(p), 1); - OUT_RING_CACHEf(params[1]); - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(p), 1); - OUT_RING_CACHEf(c); - } + spotlightUpdate = SPOTLIGHT_UPDATE_ALL; break; case GL_CONSTANT_ATTENUATION: BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p), 1); @@ -403,6 +389,55 @@ static void nv10Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa default: break; } + + switch(spotlightUpdate) { + case SPOTLIGHT_UPDATE_DIRECTION: + { + GLfloat x,y,z; + x = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[0]; + y = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[1]; + z = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[2]; + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p), 3); + OUT_RING_CACHEf(x); + OUT_RING_CACHEf(y); + OUT_RING_CACHEf(z); + } + break; + case SPOTLIGHT_UPDATE_EXPONENT: + { + GLfloat cc,lc,qc; + cc = 1.0; /* These need to be correctly computed */ + lc = 0.0; + qc = 2.0; + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 3); + OUT_RING_CACHEf(cc); + OUT_RING_CACHEf(lc); + OUT_RING_CACHEf(qc); + } + break; + case SPOTLIGHT_UPDATE_ALL: + { + GLfloat cc,lc,qc, x,y,z, c; + cc = 1.0; /* These need to be correctly computed */ + lc = 0.0; + qc = 2.0; + x = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[0]; + y = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[1]; + z = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[2]; + c = -2.0 * (0.5 + l->_CosCutoff); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 7); + OUT_RING_CACHEf(cc); + OUT_RING_CACHEf(lc); + OUT_RING_CACHEf(qc); + OUT_RING_CACHEf(x); + OUT_RING_CACHEf(y); + OUT_RING_CACHEf(z); + OUT_RING_CACHEf(c); + } + break; + default: + break; + } } /** Set the lighting model parameters */ -- cgit v1.2.3 From 5c80270b91a3054a00a3c95f7b15b7398c8dccab Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 8 Dec 2006 16:40:34 +0000 Subject: grr, always check twice before commit --- src/mesa/drivers/dri/nouveau/nv10_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index bb9abe9867..ed688a076b 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -369,7 +369,7 @@ static void nv10Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa spotlightUpdate = SPOTLIGHT_UPDATE_DIRECTION; break; case GL_SPOT_EXPONENT: - spotlightUpdate = SPOTLIGHT_UPDATE_DIRECTION; + spotlightUpdate = SPOTLIGHT_UPDATE_EXPONENT; break; case GL_SPOT_CUTOFF: spotlightUpdate = SPOTLIGHT_UPDATE_ALL; -- cgit v1.2.3 From aadcf1a9ff7e3f92977380d16b4ad2e676d7eb18 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 8 Dec 2006 18:56:51 +0000 Subject: Update spot light params also for nv20 and nv30 --- src/mesa/drivers/dri/nouveau/nv10_state.c | 4 +- src/mesa/drivers/dri/nouveau/nv20_state.c | 87 ++++++++++++++++++++++--------- src/mesa/drivers/dri/nouveau/nv30_state.c | 87 ++++++++++++++++++++++--------- 3 files changed, 124 insertions(+), 54 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index ed688a076b..e88ac2bfe6 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -406,7 +406,7 @@ static void nv10Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa case SPOTLIGHT_UPDATE_EXPONENT: { GLfloat cc,lc,qc; - cc = 1.0; /* These need to be correctly computed */ + cc = 1.0; /* FIXME: These need to be correctly computed */ lc = 0.0; qc = 2.0; BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 3); @@ -418,7 +418,7 @@ static void nv10Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa case SPOTLIGHT_UPDATE_ALL: { GLfloat cc,lc,qc, x,y,z, c; - cc = 1.0; /* These need to be correctly computed */ + cc = 1.0; /* FIXME: These need to be correctly computed */ lc = 0.0; qc = 2.0; x = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[0]; diff --git a/src/mesa/drivers/dri/nouveau/nv20_state.c b/src/mesa/drivers/dri/nouveau/nv20_state.c index 082dc64b83..ff06d481ee 100644 --- a/src/mesa/drivers/dri/nouveau/nv20_state.c +++ b/src/mesa/drivers/dri/nouveau/nv20_state.c @@ -337,11 +337,18 @@ static void nv20Hint(GLcontext *ctx, GLenum target, GLenum mode) // void (*IndexMask)(GLcontext *ctx, GLuint mask); +enum { + SPOTLIGHT_UPDATE_EXPONENT, + SPOTLIGHT_UPDATE_DIRECTION, + SPOTLIGHT_UPDATE_ALL +}; + static void nv20Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params ) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); GLint p = light - GL_LIGHT0; struct gl_light *l = &ctx->Light.Light[p]; + int spotlightUpdate = -1; /* not sure where the fourth param value goes...*/ switch(pname) @@ -364,41 +371,20 @@ static void nv20Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; - case GL_SPOT_DIRECTION: - { - GLfloat x,y,z; - x = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[0]; - y = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[1]; - z = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[2]; - BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p), 3); - OUT_RING_CACHEf(x); - OUT_RING_CACHEf(y); - OUT_RING_CACHEf(z); - } - break; case GL_POSITION: BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(p), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; + case GL_SPOT_DIRECTION: + spotlightUpdate = SPOTLIGHT_UPDATE_DIRECTION; + break; case GL_SPOT_EXPONENT: - BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(p), 1); - OUT_RING_CACHEf(*params); + spotlightUpdate = SPOTLIGHT_UPDATE_EXPONENT; break; case GL_SPOT_CUTOFF: - /* you can't factor these */ - { - GLfloat c; - c = -2.0 * (0.5 + l->_CosCutoff); - - BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 1); - OUT_RING_CACHEf(params[0]); - BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(p), 1); - OUT_RING_CACHEf(params[1]); - BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(p), 1); - OUT_RING_CACHEf(c); - } + spotlightUpdate = SPOTLIGHT_UPDATE_ALL; break; case GL_CONSTANT_ATTENUATION: BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p), 1); @@ -415,6 +401,55 @@ static void nv20Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa default: break; } + + switch(spotlightUpdate) { + case SPOTLIGHT_UPDATE_DIRECTION: + { + GLfloat x,y,z; + x = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[0]; + y = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[1]; + z = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[2]; + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p), 3); + OUT_RING_CACHEf(x); + OUT_RING_CACHEf(y); + OUT_RING_CACHEf(z); + } + break; + case SPOTLIGHT_UPDATE_EXPONENT: + { + GLfloat cc,lc,qc; + cc = 1.0; /* FIXME: These need to be correctly computed */ + lc = 0.0; + qc = 2.0; + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 3); + OUT_RING_CACHEf(cc); + OUT_RING_CACHEf(lc); + OUT_RING_CACHEf(qc); + } + break; + case SPOTLIGHT_UPDATE_ALL: + { + GLfloat cc,lc,qc, x,y,z, c; + cc = 1.0; /* FIXME: These need to be correctly computed */ + lc = 0.0; + qc = 2.0; + x = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[0]; + y = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[1]; + z = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[2]; + c = -2.0 * (0.5 + l->_CosCutoff); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 7); + OUT_RING_CACHEf(cc); + OUT_RING_CACHEf(lc); + OUT_RING_CACHEf(qc); + OUT_RING_CACHEf(x); + OUT_RING_CACHEf(y); + OUT_RING_CACHEf(z); + OUT_RING_CACHEf(c); + } + break; + default: + break; + } } /** Set the lighting model parameters */ diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index f0b37a76f5..e30dc8a37c 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -366,11 +366,18 @@ static void nv30Hint(GLcontext *ctx, GLenum target, GLenum mode) // void (*IndexMask)(GLcontext *ctx, GLuint mask); +enum { + SPOTLIGHT_UPDATE_EXPONENT, + SPOTLIGHT_UPDATE_DIRECTION, + SPOTLIGHT_UPDATE_ALL +}; + static void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params ) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); GLint p = light - GL_LIGHT0; struct gl_light *l = &ctx->Light.Light[p]; + int spotlightUpdate = -1; if (NOUVEAU_CARD_USING_SHADERS) return; @@ -396,41 +403,20 @@ static void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; - case GL_SPOT_DIRECTION: - { - GLfloat x,y,z; - x = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[0]; - y = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[1]; - z = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[2]; - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p), 3); - OUT_RING_CACHEf(x); - OUT_RING_CACHEf(y); - OUT_RING_CACHEf(z); - } - break; case GL_POSITION: BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(p), 3); OUT_RING_CACHEf(params[0]); OUT_RING_CACHEf(params[1]); OUT_RING_CACHEf(params[2]); break; + case GL_SPOT_DIRECTION: + spotlightUpdate = SPOTLIGHT_UPDATE_DIRECTION; + break; case GL_SPOT_EXPONENT: - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_EXPONENT(p), 1); - OUT_RING_CACHEf(*params); + spotlightUpdate = SPOTLIGHT_UPDATE_EXPONENT; break; case GL_SPOT_CUTOFF: - /* you can't factor these */ - { - GLfloat c; - c = -2.0 * (0.5 + l->_CosCutoff); - - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 1); - OUT_RING_CACHEf(params[0]); - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_B(p), 1); - OUT_RING_CACHEf(params[1]); - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_C(p), 1); - OUT_RING_CACHEf(c); - } + spotlightUpdate = SPOTLIGHT_UPDATE_ALL; break; case GL_CONSTANT_ATTENUATION: BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p), 1); @@ -447,6 +433,55 @@ static void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa default: break; } + + switch(spotlightUpdate) { + case SPOTLIGHT_UPDATE_DIRECTION: + { + GLfloat x,y,z; + x = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[0]; + y = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[1]; + z = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[2]; + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p), 3); + OUT_RING_CACHEf(x); + OUT_RING_CACHEf(y); + OUT_RING_CACHEf(z); + } + break; + case SPOTLIGHT_UPDATE_EXPONENT: + { + GLfloat cc,lc,qc; + cc = 1.0; /* FIXME: These need to be correctly computed */ + lc = 0.0; + qc = 2.0; + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 3); + OUT_RING_CACHEf(cc); + OUT_RING_CACHEf(lc); + OUT_RING_CACHEf(qc); + } + break; + case SPOTLIGHT_UPDATE_ALL: + { + GLfloat cc,lc,qc, x,y,z, c; + cc = 1.0; /* FIXME: These need to be correctly computed */ + lc = 0.0; + qc = 2.0; + x = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[0]; + y = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[1]; + z = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[2]; + c = -2.0 * (0.5 + l->_CosCutoff); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 7); + OUT_RING_CACHEf(cc); + OUT_RING_CACHEf(lc); + OUT_RING_CACHEf(qc); + OUT_RING_CACHEf(x); + OUT_RING_CACHEf(y); + OUT_RING_CACHEf(z); + OUT_RING_CACHEf(c); + } + break; + default: + break; + } } /** Set the lighting model parameters */ -- cgit v1.2.3 From 2956a0c8a8395e4d9ae00888aeb88ea5c38b89ad Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Thu, 14 Dec 2006 00:34:44 +0100 Subject: submit vertex weights to make World of Warcraft maybe happy (bug 8250) submit the vertex weights to hw, which will enable broken vertex programs errorneously using them to work. Note however that this will only work if glWeight is used, there is no code in mesa at all to deal with weight vertex array (glWeightPointerARB). --- src/mesa/drivers/dri/r200/r200_context.h | 1 + src/mesa/drivers/dri/r200/r200_maos_arrays.c | 19 ++++++++++++++++++- src/mesa/drivers/dri/r200/r200_vertprog.c | 1 - 3 files changed, 19 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h index fa38a78e26..44c67b68cb 100644 --- a/src/mesa/drivers/dri/r200/r200_context.h +++ b/src/mesa/drivers/dri/r200/r200_context.h @@ -735,6 +735,7 @@ struct r200_tcl_info { GLuint *Elts; struct r200_dma_region indexed_verts; + struct r200_dma_region weight; struct r200_dma_region obj; struct r200_dma_region rgba; struct r200_dma_region spec; diff --git a/src/mesa/drivers/dri/r200/r200_maos_arrays.c b/src/mesa/drivers/dri/r200/r200_maos_arrays.c index 39c1f68911..270dc35a46 100644 --- a/src/mesa/drivers/dri/r200/r200_maos_arrays.c +++ b/src/mesa/drivers/dri/r200/r200_maos_arrays.c @@ -423,7 +423,21 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs ) count ); } component[nr++] = &rmesa->tcl.generic[geninput]; - vfmt0 |= R200_VTX_W0 | R200_VTX_Z0; + vfmt0 |= R200_VTX_W0 | R200_VTX_Z0; + } + + if (inputs & VERT_BIT_WEIGHT) { + if (!rmesa->tcl.weight.buf) + emit_vector( ctx, + &rmesa->tcl.weight, + (char *)VB->AttribPtr[VERT_ATTRIB_WEIGHT]->data, + VB->AttribPtr[VERT_ATTRIB_WEIGHT]->size, + VB->AttribPtr[VERT_ATTRIB_WEIGHT]->stride, + count); + + assert(VB->AttribPtr[VERT_ATTRIB_WEIGHT]->size <= 4); + vfmt0 |= VB->AttribPtr[VERT_ATTRIB_WEIGHT]->size << R200_VTX_WEIGHT_COUNT_SHIFT; + component[nr++] = &rmesa->tcl.weight; } if (inputs & VERT_BIT_NORMAL) { @@ -672,6 +686,9 @@ void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs ) if (newinputs & VERT_BIT_POS) r200ReleaseDmaRegion( rmesa, &rmesa->tcl.obj, __FUNCTION__ ); + if (newinputs & VERT_BIT_WEIGHT) + r200ReleaseDmaRegion( rmesa, &rmesa->tcl.weight, __FUNCTION__ ); + if (newinputs & VERT_BIT_NORMAL) r200ReleaseDmaRegion( rmesa, &rmesa->tcl.norm, __FUNCTION__ ); diff --git a/src/mesa/drivers/dri/r200/r200_vertprog.c b/src/mesa/drivers/dri/r200/r200_vertprog.c index 899e84caa0..491701b796 100644 --- a/src/mesa/drivers/dri/r200/r200_vertprog.c +++ b/src/mesa/drivers/dri/r200/r200_vertprog.c @@ -503,7 +503,6 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte array_count++; } if (mesa_vp->Base.InputsRead & VERT_BIT_WEIGHT) { - /* we don't actually handle that later. Then again, we don't have to... */ vp->inputs[VERT_ATTRIB_WEIGHT] = 12; array_count++; } -- cgit v1.2.3 From 15c7e8896ba4c0fedbe3510cb04c44ba3e8d644b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 14 Dec 2006 03:24:57 +0000 Subject: Some more voodoo to get 3D going with a minimal initial context. --- src/mesa/drivers/dri/nouveau/nouveau_object.c | 2 ++ src/mesa/drivers/dri/nouveau/nv30_state.c | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.c b/src/mesa/drivers/dri/nouveau/nouveau_object.c index ef8a428c22..dda547c916 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.c @@ -73,6 +73,8 @@ void nouveauObjectInit(nouveauContextPtr nmesa) nouveauObjectOnSubchannel(nmesa, NvSubImageBlit, NvImageBlit); BEGIN_RING_SIZE(NvSubImageBlit, NV10_IMAGE_BLIT_SET_CONTEXT_SURFACES_2D, 1); OUT_RING(NvCtxSurf2D); + BEGIN_RING_SIZE(NvSubImageBlit, NV10_IMAGE_BLIT_SET_OPERATION, 1); + OUT_RING(3); /* SRCCOPY */ #endif nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index e30dc8a37c..eb3606b6e1 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -736,9 +736,28 @@ static GLboolean nv40InitCard(nouveauContextPtr nmesa) OUT_RING(NvDmaFB); BEGIN_RING_SIZE(NvSub3D, 0x0220, 1); OUT_RING(1); + + BEGIN_RING_SIZE(NvSub3D, 0x1ea4, 3); + OUT_RING(0x00000010); + OUT_RING(0x01000100); + OUT_RING(0xff800006); + BEGIN_RING_SIZE(NvSub3D, 0x1fc4, 1); + OUT_RING(0x06144321); BEGIN_RING_SIZE(NvSub3D, 0x1fc8, 2); OUT_RING(0xedcba987); OUT_RING(0x00000021); + BEGIN_RING_SIZE(NvSub3D, 0x1fd0, 1); + OUT_RING(0x00171615); + BEGIN_RING_SIZE(NvSub3D, 0x1fd4, 1); + OUT_RING(0x001b1a19); + + BEGIN_RING_SIZE(NvSub3D, 0x1ef8, 1); + OUT_RING(0x0020ffff); + BEGIN_RING_SIZE(NvSub3D, 0x1d64, 1); + OUT_RING(0x00d30000); + BEGIN_RING_SIZE(NvSub3D, 0x1e94, 1); + OUT_RING(0x00000001); + BEGIN_RING_SIZE(NvSub3D, 0x1d60, 1); OUT_RING(0x03008000); -- cgit v1.2.3 From c95557f48beb132f96cf103822bb433e00131829 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 14 Dec 2006 04:12:05 +0000 Subject: 0x4497 doesn't have NV30_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE --- src/mesa/drivers/dri/nouveau/nv30_state.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index eb3606b6e1..7592c3fa0a 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -293,8 +293,10 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) // case GL_MAP2_VERTEX_4: // case GL_MINMAX: case GL_NORMALIZE: - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1); - OUT_RING_CACHE(state); + if (nmesa->screen->card->type != NV_44) { + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE, 1); + OUT_RING_CACHE(state); + } break; // case GL_POINT_SMOOTH: case GL_POLYGON_OFFSET_POINT: -- cgit v1.2.3 From 99878298daf37d02fbabb2dded3f7e7b52cd42fe Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 14 Dec 2006 04:34:38 +0000 Subject: Improve SwapBuffers a bit. --- src/mesa/drivers/dri/nouveau/nouveau_context.c | 39 +++++++++++++++++--------- 1 file changed, 26 insertions(+), 13 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 53d26e0d74..1e25062c1d 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -49,6 +49,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_tex.h" #include "nouveau_msg.h" #include "nouveau_reg.h" +#include "nouveau_lock.h" #include "nv10_swtcl.h" #include "vblank.h" @@ -303,6 +304,8 @@ static void nouveauDoSwapBuffers(nouveauContextPtr nmesa, { struct gl_framebuffer *fb; nouveau_renderbuffer *src, *dst; + drm_clip_rect_t *box; + int nbox, i; fb = (struct gl_framebuffer *)dPriv->driverPrivate; dst = (nouveau_renderbuffer*) @@ -311,19 +314,29 @@ static void nouveauDoSwapBuffers(nouveauContextPtr nmesa, fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; #ifdef ALLOW_MULTI_SUBCHANNEL - /* Ignore this.. it's a hack to test double-buffering, and not how - * SwapBuffers should look :) - */ - BEGIN_RING_SIZE(NvSubCtxSurf2D, NV10_CONTEXT_SURFACES_2D_FORMAT, 4); - OUT_RING (6); /* X8R8G8B8 */ - OUT_RING ((dst->pitch << 16) | src->pitch); - OUT_RING (src->offset); - OUT_RING (dst->offset); - - BEGIN_RING_SIZE(NvSubImageBlit, NV10_IMAGE_BLIT_SET_POINT, 3); - OUT_RING ((0 << 16) | 0); /* src point */ - OUT_RING ((0 << 16) | 0); /* dst point */ - OUT_RING ((fb->Height << 16) | fb->Width); /* width/height */ + LOCK_HARDWARE(nmesa); + nbox = dPriv->numClipRects; + box = dPriv->pClipRects; + + if (nbox) { + BEGIN_RING_SIZE(NvSubCtxSurf2D, + NV10_CONTEXT_SURFACES_2D_FORMAT, 4); + OUT_RING (6); /* X8R8G8B8 */ + OUT_RING ((dst->pitch << 16) | src->pitch); + OUT_RING (src->offset); + OUT_RING (dst->offset); + } + + for (i=0; iy1 - dPriv->y) << 16) | + (box->x1 - dPriv->x)); + OUT_RING ((box->y1 << 16) | box->x1); + OUT_RING (((box->y2 - box->y1) << 16) | + (box->x2 - box->x1)); + } + + UNLOCK_HARDWARE(nmesa); #endif } -- cgit v1.2.3 From 4cb09df015068f6d75e6457b6c98836dd58aaf29 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Thu, 14 Dec 2006 10:24:09 +0100 Subject: intelTexSubimage: Fix last parameter for intel_miptree_image_map(). --- src/mesa/drivers/dri/i915tex/intel_tex_subimage.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_subimage.c b/src/mesa/drivers/dri/i915tex/intel_tex_subimage.c index 25a2dca685..3935787806 100644 --- a/src/mesa/drivers/dri/i915tex/intel_tex_subimage.c +++ b/src/mesa/drivers/dri/i915tex/intel_tex_subimage.c @@ -50,7 +50,6 @@ intelTexSubimage(GLcontext * ctx, { struct intel_context *intel = intel_context(ctx); struct intel_texture_image *intelImage = intel_texture_image(texImage); - GLuint dstImageStride; GLuint dstRowStride; DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__, @@ -79,7 +78,7 @@ intelTexSubimage(GLcontext * ctx, intelImage->face, intelImage->level, &dstRowStride, - &dstImageStride); + texImage->ImageOffsets); assert(dstRowStride); -- cgit v1.2.3 From 5f8a3e586f21219d02912635a93ce312bcf5987c Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Thu, 14 Dec 2006 10:49:26 +0100 Subject: intel_batchbuffer_flush: Don't assert cliprects when lock is not held. This is a legitimate situation when copying texture data between mipmap trees. --- src/mesa/drivers/dri/i915tex/intel_batchbuffer.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c index b4e0b74f16..be2750d041 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c @@ -252,6 +252,7 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch) { struct intel_context *intel = batch->intel; GLuint used = batch->ptr - batch->map; + GLboolean was_locked = intel->locked; if (used == 0) return batch->last_fence; @@ -278,17 +279,14 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch) /* TODO: Just pass the relocation list and dma buffer up to the * kernel. */ - if (!intel->locked) { - assert(!(batch->flags & INTEL_BATCH_NO_CLIPRECTS)); - + if (!was_locked) LOCK_HARDWARE(intel); - do_flush_locked(batch, used, GL_FALSE, GL_TRUE); + + do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS), + GL_FALSE); + + if (!was_locked) UNLOCK_HARDWARE(intel); - } - else { - GLboolean ignore_cliprects = !(batch->flags & INTEL_BATCH_CLIPRECTS); - do_flush_locked(batch, used, ignore_cliprects, GL_FALSE); - } /* Reset the buffer: */ -- cgit v1.2.3 From cc1afed6718882d13ab66ba0bbeaab6334e0629c Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Thu, 14 Dec 2006 10:56:10 +0100 Subject: intel_finalize_mipmap_tree: Add more conditions for rebuilding mipmap trees. These are taken from the i965 driver and fix corruption of some mipmap levels under some circumsances with 945 chipsets at least. Also flush the batchbuffer after copying data between trees, or some apps fail an assertion elsewhere. --- src/mesa/drivers/dri/i915tex/intel_tex_validate.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_validate.c b/src/mesa/drivers/dri/i915tex/intel_tex_validate.c index 5f82dfa19e..e73c9c2f21 100644 --- a/src/mesa/drivers/dri/i915tex/intel_tex_validate.c +++ b/src/mesa/drivers/dri/i915tex/intel_tex_validate.c @@ -2,6 +2,7 @@ #include "macros.h" #include "intel_context.h" +#include "intel_batchbuffer.h" #include "intel_mipmap_tree.h" #include "intel_tex.h" @@ -155,9 +156,15 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) * leaving the tree alone. */ if (intelObj->mt && - ((intelObj->mt->first_level > intelObj->firstLevel) || - (intelObj->mt->last_level < intelObj->lastLevel) || - (intelObj->mt->internal_format != firstImage->base.InternalFormat))) { + (intelObj->mt->target != intelObj->base.Target || + intelObj->mt->internal_format != firstImage->base.InternalFormat || + intelObj->mt->first_level != intelObj->firstLevel || + intelObj->mt->last_level != intelObj->lastLevel || + intelObj->mt->width0 != firstImage->base.Width || + intelObj->mt->height0 != firstImage->base.Height || + intelObj->mt->depth0 != firstImage->base.Depth || + intelObj->mt->cpp != firstImage->base.TexFormat->TexelBytes || + intelObj->mt->compressed != firstImage->base.IsCompressed)) { intel_miptree_release(intel, &intelObj->mt); } @@ -198,6 +205,8 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) } } + intel_batchbuffer_flush(intel->batch); + return GL_TRUE; } -- cgit v1.2.3 From 3416ef303af633668cece0b199b4a8b2388c1e2f Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Thu, 14 Dec 2006 12:32:41 +0100 Subject: Share code to lay out >= 945 style 2D mipmaps between i915tex and i965 drivers. Use the i965 version as it has some fixes over the i915tex version. --- src/mesa/drivers/dri/i915tex/Makefile | 5 +- src/mesa/drivers/dri/i915tex/i915_tex_layout.c | 54 +--------------- src/mesa/drivers/dri/i915tex/intel_tex_layout.c | 1 + src/mesa/drivers/dri/i965/Makefile | 5 +- src/mesa/drivers/dri/i965/brw_tex_layout.c | 55 +---------------- src/mesa/drivers/dri/i965/intel_tex_layout.c | 1 + src/mesa/drivers/dri/intel/intel_tex_layout.c | 82 +++++++++++++++++++++++++ src/mesa/drivers/dri/intel/intel_tex_layout.h | 41 +++++++++++++ 8 files changed, 139 insertions(+), 105 deletions(-) create mode 120000 src/mesa/drivers/dri/i915tex/intel_tex_layout.c create mode 120000 src/mesa/drivers/dri/i965/intel_tex_layout.c create mode 100644 src/mesa/drivers/dri/intel/intel_tex_layout.c create mode 100644 src/mesa/drivers/dri/intel/intel_tex_layout.h (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/Makefile b/src/mesa/drivers/dri/i915tex/Makefile index 94879d209f..3b3f3f5a3f 100644 --- a/src/mesa/drivers/dri/i915tex/Makefile +++ b/src/mesa/drivers/dri/i915tex/Makefile @@ -20,6 +20,7 @@ DRIVER_SOURCES = \ intel_batchbuffer.c \ intel_mipmap_tree.c \ i915_tex_layout.c \ + intel_tex_layout.c \ intel_tex_image.c \ intel_tex_subimage.c \ intel_tex_copy.c \ @@ -59,8 +60,10 @@ C_SOURCES = \ ASM_SOURCES = - +DRIVER_DEFINES = -I../intel include ../Makefile.template +intel_tex_layout.o: ../intel/intel_tex_layout.c + symlinks: diff --git a/src/mesa/drivers/dri/i915tex/i915_tex_layout.c b/src/mesa/drivers/dri/i915tex/i915_tex_layout.c index e9360ecea8..fc98611d31 100644 --- a/src/mesa/drivers/dri/i915tex/i915_tex_layout.c +++ b/src/mesa/drivers/dri/i915tex/i915_tex_layout.c @@ -30,6 +30,7 @@ */ #include "intel_mipmap_tree.h" +#include "intel_tex_layout.h" #include "macros.h" #include "intel_context.h" @@ -52,12 +53,6 @@ static GLint step_offsets[6][2] = { {0, 2}, {-1, 1} }; -static GLuint -minify(GLuint d) -{ - return MAX2(1, d >> 1); -} - GLboolean i915_miptree_layout(struct intel_mipmap_tree * mt) { @@ -322,52 +317,9 @@ i945_miptree_layout(struct intel_mipmap_tree * mt) case GL_TEXTURE_1D: case GL_TEXTURE_2D: - case GL_TEXTURE_RECTANGLE_ARB:{ - GLuint x = 0; - GLuint y = 0; - GLuint width = mt->width0; - GLuint height = mt->height0; - GLint align_h = 2; - - mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; - mt->total_height = 0; - - for (level = mt->first_level; level <= mt->last_level; level++) { - GLuint img_height; - - intel_miptree_set_level_info(mt, level, 1, - x, y, - width, - mt->compressed ? height/4 : height, 1); - - - if (mt->compressed) - img_height = MAX2(1, height / 4); - else - img_height = MAX2(align_h, height); - - /* LPT change: step right after second mipmap. - */ - if (level == mt->first_level + 1) { - x += mt->pitch / 2; - x = (x + 3) & ~3; - } - else { - y += img_height; - y += align_h - 1; - y &= ~(align_h - 1); - } - - /* Because the images are packed better, the final offset - * might not be the maximal one: - */ - mt->total_height = MAX2(mt->total_height, y); - - width = minify(width); - height = minify(height); - } + case GL_TEXTURE_RECTANGLE_ARB: + i945_miptree_layout_2d(mt); break; - } default: _mesa_problem(NULL, "Unexpected tex target in i945_miptree_layout()"); } diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_layout.c b/src/mesa/drivers/dri/i915tex/intel_tex_layout.c new file mode 120000 index 0000000000..fe61b44194 --- /dev/null +++ b/src/mesa/drivers/dri/i915tex/intel_tex_layout.c @@ -0,0 +1 @@ +../intel/intel_tex_layout.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile index 213eac895c..f0a6fa5740 100644 --- a/src/mesa/drivers/dri/i965/Makefile +++ b/src/mesa/drivers/dri/i965/Makefile @@ -20,6 +20,7 @@ DRIVER_SOURCES = \ intel_pixel_bitmap.c \ intel_state.c \ intel_tex.c \ + intel_tex_layout.c \ intel_tex_validate.c \ brw_aub.c \ brw_aub_playback.c \ @@ -92,8 +93,10 @@ C_SOURCES = \ ASM_SOURCES = - +DRIVER_DEFINES = -I../intel include ../Makefile.template +intel_tex_layout.o: ../intel/intel_tex_layout.c + symlinks: diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c index 1353325aff..af1ad0f1ef 100644 --- a/src/mesa/drivers/dri/i965/brw_tex_layout.c +++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c @@ -34,21 +34,15 @@ */ #include "intel_mipmap_tree.h" +#include "intel_tex_layout.h" #include "macros.h" -static GLuint minify( GLuint d ) -{ - return MAX2(1, d>>1); -} - GLboolean brw_miptree_layout( struct intel_mipmap_tree *mt ) { /* XXX: these vary depending on image format: */ /* GLint align_w = 4; */ - GLint align_h = 2; - switch (mt->target) { case GL_TEXTURE_CUBE_MAP: @@ -107,53 +101,10 @@ GLboolean brw_miptree_layout( struct intel_mipmap_tree *mt ) break; } - default: { - GLuint level; - GLuint x = 0; - GLuint y = 0; - GLuint width = mt->width0; - GLuint height = mt->height0; - - mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; - mt->total_height = 0; - - for ( level = mt->first_level ; level <= mt->last_level ; level++ ) { - GLuint img_height; - - intel_miptree_set_level_info(mt, level, 1, - x, y, - width, - mt->compressed ? height/4 : height, 1); - - if (mt->compressed) - img_height = MAX2(1, height/4); - else - img_height = MAX2(align_h, height); - - - /* Because the images are packed better, the final offset - * might not be the maximal one: - */ - mt->total_height = MAX2(mt->total_height, y + img_height); - - /* Layout_below: step right after second mipmap. - */ - if (level == mt->first_level + 1) { - x += mt->pitch / 2; - x = (x + 3) & ~ 3; - } - else { - y += img_height; - y += align_h - 1; - y &= ~(align_h - 1); - } - - width = minify(width); - height = minify(height); - } + default: + i945_miptree_layout_2d(mt); break; } - } DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__, mt->pitch, mt->total_height, diff --git a/src/mesa/drivers/dri/i965/intel_tex_layout.c b/src/mesa/drivers/dri/i965/intel_tex_layout.c new file mode 120000 index 0000000000..fe61b44194 --- /dev/null +++ b/src/mesa/drivers/dri/i965/intel_tex_layout.c @@ -0,0 +1 @@ +../intel/intel_tex_layout.c \ No newline at end of file diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.c b/src/mesa/drivers/dri/intel/intel_tex_layout.c new file mode 100644 index 0000000000..6b9e1de2ed --- /dev/null +++ b/src/mesa/drivers/dri/intel/intel_tex_layout.c @@ -0,0 +1,82 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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. + * + **************************************************************************/ + /* + * Authors: + * Keith Whitwell + * Michel Dänzer + */ + +#include "intel_mipmap_tree.h" +#include "intel_tex_layout.h" +#include "macros.h" + + +void i945_miptree_layout_2d( struct intel_mipmap_tree *mt ) +{ + GLint align_h = 2; + GLuint level; + GLuint x = 0; + GLuint y = 0; + GLuint width = mt->width0; + GLuint height = mt->height0; + + mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; + mt->total_height = 0; + + for ( level = mt->first_level ; level <= mt->last_level ; level++ ) { + GLuint img_height; + + intel_miptree_set_level_info(mt, level, 1, x, y, width, + mt->compressed ? height/4 : height, 1); + + if (mt->compressed) + img_height = MAX2(1, height/4); + else + img_height = MAX2(align_h, height); + + + /* Because the images are packed better, the final offset + * might not be the maximal one: + */ + mt->total_height = MAX2(mt->total_height, y + img_height); + + /* Layout_below: step right after second mipmap. + */ + if (level == mt->first_level + 1) { + x += mt->pitch / 2; + x = (x + 3) & ~ 3; + } + else { + y += img_height; + y += align_h - 1; + y &= ~(align_h - 1); + } + + width = minify(width); + height = minify(height); + } +} diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.h b/src/mesa/drivers/dri/intel/intel_tex_layout.h new file mode 100644 index 0000000000..e685d474ec --- /dev/null +++ b/src/mesa/drivers/dri/intel/intel_tex_layout.h @@ -0,0 +1,41 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * 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 TUNGSTEN 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. + * + **************************************************************************/ + /* + * Authors: + * Keith Whitwell + * Michel Dänzer + */ + +#include "macros.h" + + +static GLuint minify( GLuint d ) +{ + return MAX2(1, d>>1); +} + +extern void i945_miptree_layout_2d( struct intel_mipmap_tree *mt ); -- cgit v1.2.3 From 81855f22cd8d8df5bd96fdbd76ff975b6cf4150b Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Thu, 14 Dec 2006 12:42:51 +0100 Subject: Fix some corner cases in i945_miptree_layout_2d(). Based on a patch from Keith Whitwell, with some further fixes. --- src/mesa/drivers/dri/intel/intel_tex_layout.c | 34 +++++++++++++++++++++------ 1 file changed, 27 insertions(+), 7 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.c b/src/mesa/drivers/dri/intel/intel_tex_layout.c index 6b9e1de2ed..b503175001 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_layout.c +++ b/src/mesa/drivers/dri/intel/intel_tex_layout.c @@ -35,16 +35,39 @@ #include "macros.h" +static int align(int value, int alignment) +{ + return (value + alignment - 1) & ~(alignment - 1); +} + void i945_miptree_layout_2d( struct intel_mipmap_tree *mt ) { - GLint align_h = 2; + GLint align_h = 2, align_w = 4; GLuint level; GLuint x = 0; GLuint y = 0; GLuint width = mt->width0; GLuint height = mt->height0; - mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; + mt->pitch = mt->width0; + + /* May need to adjust pitch to accomodate the placement of + * the 2nd mipmap. This occurs when the alignment + * constraints of mipmap placement push the right edge of the + * 2nd mipmap out past the width of its parent. + */ + if (mt->first_level != mt->last_level) { + GLuint mip1_width = align(minify(mt->width0), align_w) + + minify(minify(mt->width0)); + + if (mip1_width > mt->width0) + mt->pitch = mip1_width; + } + + /* Pitch must be a whole number of dwords, even though we + * express it in texels. + */ + mt->pitch = align(mt->pitch * mt->cpp, 4) / mt->cpp; mt->total_height = 0; for ( level = mt->first_level ; level <= mt->last_level ; level++ ) { @@ -56,7 +79,7 @@ void i945_miptree_layout_2d( struct intel_mipmap_tree *mt ) if (mt->compressed) img_height = MAX2(1, height/4); else - img_height = MAX2(align_h, height); + img_height = align(height, align_h); /* Because the images are packed better, the final offset @@ -67,13 +90,10 @@ void i945_miptree_layout_2d( struct intel_mipmap_tree *mt ) /* Layout_below: step right after second mipmap. */ if (level == mt->first_level + 1) { - x += mt->pitch / 2; - x = (x + 3) & ~ 3; + x += align(width, align_w); } else { y += img_height; - y += align_h - 1; - y &= ~(align_h - 1); } width = minify(width); -- cgit v1.2.3 From e0c9361a7cd16cc008220cf1933fba4371f46753 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Thu, 14 Dec 2006 12:47:44 +0100 Subject: Avoid failing assertion in intel_miptree_set_image_offset() with cube maps. Cube maps still aren't working quite correctly though. --- src/mesa/drivers/dri/i915tex/i915_tex_layout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/i915_tex_layout.c b/src/mesa/drivers/dri/i915tex/i915_tex_layout.c index fc98611d31..333fefef85 100644 --- a/src/mesa/drivers/dri/i915tex/i915_tex_layout.c +++ b/src/mesa/drivers/dri/i915tex/i915_tex_layout.c @@ -212,7 +212,7 @@ i945_miptree_layout(struct intel_mipmap_tree * mt) y = mt->total_height - 4; x = (face - 4) * 8; } - else if (dim < 4) { + else if (dim < 4 && (face > 0 || mt->first_level > 0)) { y = mt->total_height - 4; x = face * 8; } -- cgit v1.2.3 From fde908444af5c826bce84203a9cb4273d8341ed0 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Thu, 14 Dec 2006 12:57:59 +0100 Subject: Fix copy-and-paste-o of my e-mail address. --- src/mesa/drivers/dri/intel/intel_tex_layout.c | 2 +- src/mesa/drivers/dri/intel/intel_tex_layout.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.c b/src/mesa/drivers/dri/intel/intel_tex_layout.c index b503175001..f356480217 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_layout.c +++ b/src/mesa/drivers/dri/intel/intel_tex_layout.c @@ -27,7 +27,7 @@ /* * Authors: * Keith Whitwell - * Michel Dänzer + * Michel Dänzer */ #include "intel_mipmap_tree.h" diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.h b/src/mesa/drivers/dri/intel/intel_tex_layout.h index e685d474ec..1e37f8f525 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_layout.h +++ b/src/mesa/drivers/dri/intel/intel_tex_layout.h @@ -27,7 +27,7 @@ /* * Authors: * Keith Whitwell - * Michel Dänzer + * Michel Dänzer */ #include "macros.h" -- cgit v1.2.3 From c340dd7d842b3f20a6d3d2bec1ebb0d1de15728e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 15 Dec 2006 21:02:23 +0000 Subject: NV1x/2x hw_func stubs. --- src/mesa/drivers/dri/nouveau/nv10_state.c | 34 ++++++++++++++++++++++++++++--- src/mesa/drivers/dri/nouveau/nv20_state.c | 34 ++++++++++++++++++++++++++++--- 2 files changed, 62 insertions(+), 6 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index e88ac2bfe6..be5f5f6e42 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -500,8 +500,11 @@ void (*PolygonStipple)(GLcontext *ctx, const GLubyte *mask ); void (*ReadBuffer)( GLcontext *ctx, GLenum buffer ); /** Set rasterization mode */ void (*RenderMode)(GLcontext *ctx, GLenum mode ); + /** Define the scissor box */ -void (*Scissor)(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h); +static void nv10Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ +} /** Select flat or smooth shading */ static void nv10ShadeModel(GLcontext *ctx, GLenum mode) @@ -567,8 +570,29 @@ static void nv10Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) OUT_RING_CACHE((h << 16) | y); } -void nv10InitStateFuncs(struct dd_function_table *func) +/* Initialise any card-specific non-GL related state */ +static GLboolean nv10InitCard(nouveauContextPtr nmesa) +{ + return GL_TRUE; +} + +/* Update buffer offset/pitch/format */ +static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color, + nouveau_renderbuffer **color, + nouveau_renderbuffer *depth) +{ + return GL_TRUE; +} + +/* Update anything that depends on the window position/size */ +static void nv10WindowMoved(nouveauContextPtr nmesa) { +} + +void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + func->AlphaFunc = nv10AlphaFunc; func->BlendColor = nv10BlendColor; func->BlendEquationSeparate = nv10BlendEquationSeparate; @@ -602,8 +626,8 @@ void nv10InitStateFuncs(struct dd_function_table *func) func->PolygonStipple = nv10PolygonStipple; func->ReadBuffer = nv10ReadBuffer; func->RenderMode = nv10RenderMode; - func->Scissor = nv10Scissor; #endif + func->Scissor = nv10Scissor; func->ShadeModel = nv10ShadeModel; func->StencilFuncSeparate = nv10StencilFuncSeparate; func->StencilMaskSeparate = nv10StencilMaskSeparate; @@ -614,5 +638,9 @@ void nv10InitStateFuncs(struct dd_function_table *func) func->TextureMatrix = nv10TextureMatrix; #endif func->Viewport = nv10Viewport; + + nmesa->hw_func.InitCard = nv10InitCard; + nmesa->hw_func.BindBuffers = nv10BindBuffers; + nmesa->hw_func.WindowMoved = nv10WindowMoved; } diff --git a/src/mesa/drivers/dri/nouveau/nv20_state.c b/src/mesa/drivers/dri/nouveau/nv20_state.c index ff06d481ee..6bfac8466b 100644 --- a/src/mesa/drivers/dri/nouveau/nv20_state.c +++ b/src/mesa/drivers/dri/nouveau/nv20_state.c @@ -515,8 +515,11 @@ void (*PolygonStipple)(GLcontext *ctx, const GLubyte *mask ); void (*ReadBuffer)( GLcontext *ctx, GLenum buffer ); /** Set rasterization mode */ void (*RenderMode)(GLcontext *ctx, GLenum mode ); + /** Define the scissor box */ -void (*Scissor)(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h); +static void nv20Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ +} /** Select flat or smooth shading */ static void nv20ShadeModel(GLcontext *ctx, GLenum mode) @@ -582,8 +585,33 @@ static void nv20Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) OUT_RING_CACHE((h << 16) | y); } -void nv20InitStateFuncs(struct dd_function_table *func) +/* Initialise any card-specific non-GL related state */ +static GLboolean nv20InitCard(nouveauContextPtr nmesa) +{ + return GL_TRUE; +} + +/* Update buffer offset/pitch/format */ +static GLboolean nv20BindBuffers(nouveauContextPtr nmesa, int num_color, + nouveau_renderbuffer **color, + nouveau_renderbuffer *depth) +{ + return GL_TRUE; +} + +/* Update anything that depends on the window position/size */ +static void nv20WindowMoved(nouveauContextPtr nmesa) { +} + +void nv20InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + nmesa->hw_func.InitCard = nv20InitCard; + nmesa->hw_func.BindBuffers = nv20BindBuffers; + nmesa->hw_func.WindowMoved = nv20WindowMoved; + func->AlphaFunc = nv20AlphaFunc; func->BlendColor = nv20BlendColor; func->BlendEquationSeparate = nv20BlendEquationSeparate; @@ -615,8 +643,8 @@ void nv20InitStateFuncs(struct dd_function_table *func) func->PolygonStipple = nv20PolygonStipple; func->ReadBuffer = nv20ReadBuffer; func->RenderMode = nv20RenderMode; - func->Scissor = nv20Scissor; #endif + func->Scissor = nv20Scissor; func->ShadeModel = nv20ShadeModel; func->StencilFuncSeparate = nv20StencilFuncSeparate; func->StencilMaskSeparate = nv20StencilMaskSeparate; -- cgit v1.2.3 From de947e8a5b2f10eb3fd2bdeacc54209e55447e86 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 16 Dec 2006 12:32:11 +0000 Subject: Get nv10_swtcl.c working enough for glxgears on NV40. --- src/mesa/drivers/dri/nouveau/nouveau_context.c | 6 +-- src/mesa/drivers/dri/nouveau/nouveau_context.h | 1 + src/mesa/drivers/dri/nouveau/nouveau_shader.c | 65 +++++++++++++++++++++++++- src/mesa/drivers/dri/nouveau/nouveau_shader.h | 3 ++ src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 27 ++++++++++- 5 files changed, 96 insertions(+), 6 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 1e25062c1d..22c1f58874 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -187,11 +187,9 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, nmesa->current_primitive = -1; nouveauShaderInitFuncs(ctx); - /* Install Mesa's fixed-function shader support */ - if (nmesa->screen->card->type >= NV_40) { - ctx->_MaintainTnlProgram = GL_TRUE; + /* Install Mesa's fixed-function texenv shader support */ + if (nmesa->screen->card->type >= NV_40) ctx->_MaintainTexEnvProgram = GL_TRUE; - } /* Initialize the swrast */ _swrast_CreateContext( ctx ); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 211d4e0a6d..d7730bd796 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -144,6 +144,7 @@ typedef struct nouveau_context { nvsFunc FPfunc; nouveauShader *current_fragprog; nouveauShader *current_vertprog; + nouveauShader *passthrough_vp; nouveauScreenRec *screen; drm_nouveau_sarea_t *sarea; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.c b/src/mesa/drivers/dri/nouveau/nouveau_shader.c index e3082ebc69..9a09f43d58 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.c @@ -37,6 +37,7 @@ #include "program.h" #include "tnl/tnl.h" +#include "shader/arbprogparse.h" #include "nouveau_context.h" #include "nouveau_shader.h" @@ -161,6 +162,63 @@ nvsUpdateShader(GLcontext *ctx, nouveauShader *nvs) return GL_TRUE; } +nouveauShader * +nvsBuildTextShader(GLcontext *ctx, GLenum target, const char *text) +{ + nouveauShader *nvs; + + nvs = CALLOC_STRUCT(_nouveauShader); + if (!nvs) + return NULL; + + if (target == GL_VERTEX_PROGRAM_ARB) { + _mesa_init_vertex_program(ctx, &nvs->mesa.vp, GL_VERTEX_PROGRAM_ARB, 0); + _mesa_parse_arb_vertex_program(ctx, + GL_VERTEX_PROGRAM_ARB, + text, + strlen(text), + &nvs->mesa.vp); + } else if (target == GL_FRAGMENT_PROGRAM_ARB) { + _mesa_init_fragment_program(ctx, &nvs->mesa.fp, GL_VERTEX_PROGRAM_ARB, 0); + _mesa_parse_arb_fragment_program(ctx, + GL_FRAGMENT_PROGRAM_ARB, + text, + strlen(text), + &nvs->mesa.fp); + } + + nouveau_shader_pass0_arb(ctx, nvs); + nouveau_shader_pass1(nvs); + nouveau_shader_pass2(nvs); + + return nvs; +} + +static void +nvsBuildPassthroughVP(GLcontext *ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + const char *vp_text = + "!!ARBvp1.0\n" + "OPTION ARB_position_invariant;" + "" + "MOV result.color, vertex.color;\n" + "MOV result.texcoord[0], vertex.texcoord[0];\n" + "MOV result.texcoord[1], vertex.texcoord[1];\n" + "MOV result.texcoord[2], vertex.texcoord[2];\n" + "MOV result.texcoord[3], vertex.texcoord[3];\n" + "MOV result.texcoord[4], vertex.texcoord[4];\n" + "MOV result.texcoord[5], vertex.texcoord[5];\n" + "MOV result.texcoord[6], vertex.texcoord[6];\n" + "MOV result.texcoord[7], vertex.texcoord[7];\n" + "END"; + + nmesa->passthrough_vp = nvsBuildTextShader(ctx, + GL_VERTEX_PROGRAM_ARB, + vp_text); +} + void nouveauShaderInitFuncs(GLcontext * ctx) { @@ -184,6 +242,11 @@ nouveauShaderInitFuncs(GLcontext * ctx) return; } + /* Build a vertex program that simply passes through all attribs. + * Needed to do swtcl on nv40 + */ + nvsBuildPassthroughVP(ctx); + ctx->Const.VertexProgram.MaxNativeInstructions = nmesa->VPfunc.MaxInst; ctx->Const.VertexProgram.MaxNativeAluInstructions = nmesa->VPfunc.MaxInst; ctx->Const.VertexProgram.MaxNativeTexInstructions = nmesa->VPfunc.MaxInst; @@ -446,7 +509,7 @@ nvsDumpReg(nvsInstruction * inst, nvsRegister * reg) printf(")"); } -void +static void nvsDumpInstruction(nvsInstruction * inst, int slot, int lvl) { struct _opcode_info *opr = &ops[inst->op]; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h index dce2e23f46..652775e6c2 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -349,6 +349,9 @@ nvsSwizzle(nvsRegister reg, nvsSwzComp x, nvsSwzComp y, extern GLboolean nvsUpdateShader(GLcontext *ctx, nouveauShader *nvs); extern void nvsDisasmHWShader(nvsPtr); +extern void nvsDumpFragmentList(nvsFragmentList *f, int lvl); +extern nouveauShader *nvsBuildTextShader(GLcontext *ctx, GLenum target, + const char *text); extern void NV20VPInitShaderFuncs(nvsFunc *); extern void NV30VPInitShaderFuncs(nvsFunc *); diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 07b3e666df..37d9f001d1 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -366,6 +366,15 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa) int i; int slots=0; int total_size=0; + /* t_vertex_generic dereferences a NULL pointer if we + * pass NULL as the vp transform... + */ + const GLfloat ident_vp[16] = { + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + }; RENDERINPUTS_COPY(index, nmesa->render_inputs_bitset); @@ -425,10 +434,11 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa) total_size+=attr_size[i]; } } + nmesa->vertex_size=_tnl_install_attrs( ctx, nmesa->vertex_attrs, nmesa->vertex_attr_count, - NULL, 0 ); + ident_vp, 0 ); assert(nmesa->vertex_size==total_size*4); /* @@ -467,6 +477,8 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa) OUT_RING_CACHE(NV_VERTEX_ATTRIBUTE_TYPE_FLOAT|(size*0x10)); } } else { + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DO_VERTICES, 1); + OUT_RING(0); BEGIN_RING_CACHE(NvSub3D,NV30_TCL_PRIMITIVE_3D_VERTEX_ATTR0_POS,slots); for(i=0;irender_inputs_bitset, index); nv10OutputVertexFormat(nmesa); } + + if (nmesa->screen->card->type >= NV_40) { + /* Ensure passthrough shader is being used, and mvp matrix + * is up to date + */ + nvsUpdateShader(ctx, nmesa->passthrough_vp); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_IN_REG, 2); + OUT_RING_CACHE (0xff09); /*IN : POS, COL, TC0-7 */ + OUT_RING_CACHE (0x3fc001); /*OUT: COL, TC0-7, POS implied */ + + /* Update texenv shader / user fragprog */ + nvsUpdateShader(ctx, (nouveauShader*)ctx->FragmentProgram._Current); + } } -- cgit v1.2.3 From 53d40646bdac2deb7954794e213154e0a4596278 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 17 Dec 2006 03:38:21 +0000 Subject: Don't build passthrough shader on screen->card->type >= NV_40) + nvsBuildPassthroughVP(ctx); ctx->Const.VertexProgram.MaxNativeInstructions = nmesa->VPfunc.MaxInst; ctx->Const.VertexProgram.MaxNativeAluInstructions = nmesa->VPfunc.MaxInst; -- cgit v1.2.3 From 1dd6759c059e054a9a2279d2339a5bd8bb83f6b4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 23 Dec 2006 10:56:19 +1100 Subject: nouveau: get 16bpp working --- src/mesa/drivers/dri/nouveau/nouveau_buffers.c | 1 + src/mesa/drivers/dri/nouveau/nouveau_context.c | 5 ++++- src/mesa/drivers/dri/nouveau/nouveau_screen.c | 7 ++++--- src/mesa/drivers/dri/nouveau/nv30_state.c | 5 ++++- 4 files changed, 13 insertions(+), 5 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c index 42d8691752..f30e59323d 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c @@ -89,6 +89,7 @@ nouveau_renderbuffer_pixelformat(nouveau_renderbuffer *nrb, nrb->mesa.AlphaBits = 8; nrb->cpp = 4; break; + case GL_RGB: case GL_RGB5: nrb->mesa._BaseFormat = GL_RGB; nrb->mesa._ActualFormat= GL_RGB5; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 22c1f58874..ac940ac595 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -319,7 +319,10 @@ static void nouveauDoSwapBuffers(nouveauContextPtr nmesa, if (nbox) { BEGIN_RING_SIZE(NvSubCtxSurf2D, NV10_CONTEXT_SURFACES_2D_FORMAT, 4); - OUT_RING (6); /* X8R8G8B8 */ + if (src->mesa._ActualFormat == GL_RGBA8) + OUT_RING (6); /* X8R8G8B8 */ + else + OUT_RING (4); /* R5G6B5 */ OUT_RING ((dst->pitch << 16) | src->pitch); OUT_RING (src->offset); OUT_RING (dst->offset); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index 8e548dbcbd..140db496b2 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -129,6 +129,7 @@ nouveauCreateBuffer(__DRIscreenPrivate *driScrnPriv, struct gl_framebuffer *fb; const GLboolean swAccum = mesaVis->accumRedBits > 0; const GLboolean swStencil = mesaVis->stencilBits > 0 && mesaVis->depthBits != 24; + GLenum color_format = screen->fbFormat == 4 ? GL_RGBA8 : GL_RGB5; if (isPixmap) return GL_FALSE; /* not implemented */ @@ -138,10 +139,10 @@ nouveauCreateBuffer(__DRIscreenPrivate *driScrnPriv, return GL_FALSE; /* Front buffer */ - nrb = nouveau_renderbuffer_new(GL_RGBA, + nrb = nouveau_renderbuffer_new(color_format, driScrnPriv->pFB + screen->frontOffset, screen->frontOffset, - screen->frontPitch * 4, + screen->frontPitch * screen->fbFormat, driDrawPriv); nouveauSpanSetFunctions(nrb, mesaVis); _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &nrb->mesa); @@ -149,7 +150,7 @@ nouveauCreateBuffer(__DRIscreenPrivate *driScrnPriv, if (0 /* unified buffers if we choose to support them.. */) { } else { if (mesaVis->doubleBufferMode) { - nrb = nouveau_renderbuffer_new(GL_RGBA, NULL, + nrb = nouveau_renderbuffer_new(color_format, NULL, 0, 0, driDrawPriv); nouveauSpanSetFunctions(nrb, mesaVis); diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 7592c3fa0a..4169dad661 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -790,7 +790,10 @@ static GLboolean nv30BindBuffers(nouveauContextPtr nmesa, int num_color, BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_DIM0, 5); OUT_RING (((w+x)<<16)|x); OUT_RING (((h+y)<<16)|y); - OUT_RING (0x148); + if (color[0]->mesa._ActualFormat == GL_RGBA8) + OUT_RING (0x148); + else + OUT_RING (0x143); OUT_RING (color[0]->pitch); OUT_RING (color[0]->offset); -- cgit v1.2.3 From ae8d8d132600cc544b7295c9554e6531bdbd8094 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 23 Dec 2006 23:03:55 +1100 Subject: nouveau: Don't fill nrb->dPriv for private buffers --- src/mesa/drivers/dri/nouveau/nouveau_buffers.c | 2 +- src/mesa/drivers/dri/nouveau/nouveau_screen.c | 8 ++++---- src/mesa/drivers/dri/nouveau/nouveau_state.c | 2 +- src/mesa/drivers/dri/nouveau/nv30_state.c | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c index f30e59323d..0a5efa8c2e 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c @@ -152,7 +152,7 @@ nouveau_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, /* If this buffer isn't statically alloc'd, we may need to ask the * drm for more memory */ - if (!nrb->map && (rb->Width != width || rb->Height != height)) { + if (!nrb->dPriv && (rb->Width != width || rb->Height != height)) { GLuint pitch; /* align pitches to 64 bytes */ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index 140db496b2..99992b838a 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -152,7 +152,7 @@ nouveauCreateBuffer(__DRIscreenPrivate *driScrnPriv, if (mesaVis->doubleBufferMode) { nrb = nouveau_renderbuffer_new(color_format, NULL, 0, 0, - driDrawPriv); + NULL); nouveauSpanSetFunctions(nrb, mesaVis); _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &nrb->mesa); } @@ -160,20 +160,20 @@ nouveauCreateBuffer(__DRIscreenPrivate *driScrnPriv, if (mesaVis->depthBits == 24 && mesaVis->stencilBits == 8) { nrb = nouveau_renderbuffer_new(GL_DEPTH24_STENCIL8_EXT, NULL, 0, 0, - driDrawPriv); + NULL); nouveauSpanSetFunctions(nrb, mesaVis); _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &nrb->mesa); _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &nrb->mesa); } else if (mesaVis->depthBits == 24) { nrb = nouveau_renderbuffer_new(GL_DEPTH_COMPONENT24, NULL, 0, 0, - driDrawPriv); + NULL); nouveauSpanSetFunctions(nrb, mesaVis); _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &nrb->mesa); } else if (mesaVis->depthBits == 16) { nrb = nouveau_renderbuffer_new(GL_DEPTH_COMPONENT16, NULL, 0, 0, - driDrawPriv); + NULL); nouveauSpanSetFunctions(nrb, mesaVis); _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &nrb->mesa); } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c index cec7120d43..d3c233eb13 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -68,7 +68,7 @@ static void nouveauCalcViewport(GLcontext *ctx) nrb = nouveau_current_draw_buffer(ctx); nmesa->depth_scale = 1.0 / ctx->DrawBuffer->_DepthMaxF; - if (nrb && nrb->map) { + if (nrb && nrb->dPriv) { /* Window */ xoffset = nrb->dPriv->x; yoffset = nrb->dPriv->y; diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 4169dad661..35b428b37c 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -577,7 +577,7 @@ static void nv30Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) /* Adjust offsets if drawing to a window */ nrb = nouveau_current_draw_buffer(ctx); - if (nrb && nrb->map) { + if (nrb && nrb->dPriv) { x += nrb->dPriv->x; y += nrb->dPriv->y; } @@ -690,7 +690,7 @@ static void nv30WindowMoved(nouveauContextPtr nmesa) /* Adjust offsets if drawing to a window */ nrb = nouveau_current_draw_buffer(ctx); - if (nrb && nrb->map) { + if (nrb && nrb->dPriv) { x += nrb->dPriv->x; y += nrb->dPriv->y; } @@ -777,7 +777,7 @@ static GLboolean nv30BindBuffers(nouveauContextPtr nmesa, int num_color, nrb = nouveau_current_draw_buffer(nmesa->glCtx); w = nrb->mesa.Width; h = nrb->mesa.Height; - if (nrb && nrb->map) { + if (nrb && nrb->dPriv) { x = nrb->dPriv->x; y = nrb->dPriv->y; } else { -- cgit v1.2.3 From cb6a400dcd26089101c8a29a4eee198bd7ad9a58 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 23 Dec 2006 23:51:24 +1100 Subject: nouveau: maintain numClipRects/pClipRects in context. --- src/mesa/drivers/dri/nouveau/nouveau_buffers.c | 56 +++++++++++++++++--------- src/mesa/drivers/dri/nouveau/nouveau_context.h | 2 + src/mesa/drivers/dri/nouveau/nouveau_state.c | 13 +----- src/mesa/drivers/dri/nouveau/nv30_state.c | 32 ++++----------- 4 files changed, 46 insertions(+), 57 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c index 0a5efa8c2e..e3e2a8099e 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c @@ -214,10 +214,46 @@ nouveau_renderbuffer_new(GLenum internalFormat, GLvoid *map, return nrb; } +static void +nouveau_cliprects_drawable_set(nouveauContextPtr nmesa, + nouveau_renderbuffer *nrb) +{ + __DRIdrawablePrivate *dPriv = nrb->dPriv; + + nmesa->numClipRects = dPriv->numClipRects; + nmesa->pClipRects = dPriv->pClipRects; + nmesa->drawX = dPriv->x; + nmesa->drawY = dPriv->y; +} + +static void +nouveau_cliprects_renderbuffer_set(nouveauContextPtr nmesa, + nouveau_renderbuffer *nrb) +{ + nmesa->numClipRects = 1; + nmesa->pClipRects = &nmesa->osClipRect; + nmesa->osClipRect.x1 = 0; + nmesa->osClipRect.y1 = 0; + nmesa->osClipRect.x2 = nrb->mesa.Width; + nmesa->osClipRect.y2 = nrb->mesa.Height; + nmesa->drawX = 0; + nmesa->drawY = 0; +} + void nouveau_window_moved(GLcontext *ctx) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_renderbuffer *nrb; + + nrb = (nouveau_renderbuffer *)ctx->DrawBuffer->_ColorDrawBuffers[0][0]; + if (!nrb) + return; + + if (!nrb->dPriv) + nouveau_cliprects_renderbuffer_set(nmesa, nrb); + else + nouveau_cliprects_drawable_set(nmesa, nrb); /* Viewport depends on window size/position, nouveauCalcViewport * will take care of calling the hw-specific WindowMoved @@ -252,26 +288,6 @@ nouveau_build_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb) return GL_TRUE; } -nouveau_renderbuffer * -nouveau_current_draw_buffer(GLcontext *ctx) -{ - struct gl_framebuffer *fb = ctx->DrawBuffer; - nouveau_renderbuffer *nrb; - - if (!fb) - return NULL; - - if (fb->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT) - nrb = (nouveau_renderbuffer *) - fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; - else if (fb->_ColorDrawBufferMask[0] == BUFFER_BIT_BACK_LEFT) - nrb = (nouveau_renderbuffer *) - fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer; - else - nrb = NULL; - return nrb; -} - static struct gl_framebuffer * nouveauNewFramebuffer(GLcontext *ctx, GLuint name) { diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index d7730bd796..ea28506b74 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -134,6 +134,8 @@ typedef struct nouveau_context { /* Cliprects information */ GLuint numClipRects; drm_clip_rect_t *pClipRects; + drm_clip_rect_t osClipRect; + GLuint drawX, drawY; /* The rendering context information */ GLenum current_primitive; /* the current primitive enum */ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c index d3c233eb13..8df334d700 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -62,22 +62,11 @@ static void nouveauCalcViewport(GLcontext *ctx) nouveau_renderbuffer *nrb; const GLfloat *v = ctx->Viewport._WindowMap.m; GLfloat *m = nmesa->viewport.m; - GLfloat xoffset, yoffset; + GLfloat xoffset = nmesa->drawX, yoffset = nmesa->drawY; GLint h = 0; - nrb = nouveau_current_draw_buffer(ctx); nmesa->depth_scale = 1.0 / ctx->DrawBuffer->_DepthMaxF; - if (nrb && nrb->dPriv) { - /* Window */ - xoffset = nrb->dPriv->x; - yoffset = nrb->dPriv->y; - } else { - /* Offscreen or back buffer */ - xoffset = 0.0; - yoffset = 0.0; - } - m[MAT_SX] = v[MAT_SX]; m[MAT_TX] = v[MAT_TX] + xoffset + SUBPIXEL_X; m[MAT_SY] = - v[MAT_SY]; diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 35b428b37c..7ccf5f9875 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -575,19 +575,15 @@ static void nv30Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); nouveau_renderbuffer *nrb; - /* Adjust offsets if drawing to a window */ - nrb = nouveau_current_draw_buffer(ctx); - if (nrb && nrb->dPriv) { - x += nrb->dPriv->x; - y += nrb->dPriv->y; - } - /* There's no scissor enable bit, so adjust the scissor to cover the * maximum draw buffer bounds */ if (!ctx->Scissor.Enabled) { x = y = 0; w = h = 4095; + } else { + x += nmesa->drawX; + y += nmesa->drawY; } BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS, 2); @@ -685,15 +681,8 @@ static void nv30WindowMoved(nouveauContextPtr nmesa) GLfloat *v = nmesa->viewport.m; GLuint w = ctx->Viewport.Width; GLuint h = ctx->Viewport.Height; - GLuint x = ctx->Viewport.X; - GLuint y = ctx->Viewport.Y; - - /* Adjust offsets if drawing to a window */ - nrb = nouveau_current_draw_buffer(ctx); - if (nrb && nrb->dPriv) { - x += nrb->dPriv->x; - y += nrb->dPriv->y; - } + GLuint x = ctx->Viewport.X + nmesa->drawX; + GLuint y = ctx->Viewport.Y + nmesa->drawY; BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_0, 2); OUT_RING_CACHE((w << 16) | x); @@ -773,17 +762,10 @@ static GLboolean nv30BindBuffers(nouveauContextPtr nmesa, int num_color, nouveau_renderbuffer *nrb; GLuint x, y, w, h; - /* Adjust offsets if drawing to a window */ - nrb = nouveau_current_draw_buffer(nmesa->glCtx); w = nrb->mesa.Width; h = nrb->mesa.Height; - if (nrb && nrb->dPriv) { - x = nrb->dPriv->x; - y = nrb->dPriv->y; - } else { - x = 0; - y = 0; - } + x = nmesa->drawX; + y = nmesa->drawY; if (num_color != 1) return GL_FALSE; -- cgit v1.2.3 From f54c725497cac19294e1465413d21a9416d4245f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 24 Dec 2006 00:13:34 +1100 Subject: nouveau: Modify span routines to use nouveau_renderbuffer instead of driRenderbuffer --- src/mesa/drivers/dri/nouveau/nouveau_buffers.c | 8 ++++++++ src/mesa/drivers/dri/nouveau/nouveau_fifo.c | 7 +++++++ src/mesa/drivers/dri/nouveau/nouveau_span.c | 23 +++++++++++++++-------- 3 files changed, 30 insertions(+), 8 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c index e3e2a8099e..f6a03ecd9c 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c @@ -288,6 +288,12 @@ nouveau_build_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb) return GL_TRUE; } +static void +nouveauDrawBuffer(GLcontext *ctx, GLenum buffer) +{ + nouveau_build_framebuffer(ctx, ctx->DrawBuffer); +} + static struct gl_framebuffer * nouveauNewFramebuffer(GLcontext *ctx, GLuint name) { @@ -341,6 +347,8 @@ nouveauFinishRenderTexture(GLcontext *ctx, void nouveauInitBufferFuncs(struct dd_function_table *func) { + func->DrawBuffer = nouveauDrawBuffer; + func->NewFramebuffer = nouveauNewFramebuffer; func->NewRenderbuffer = nouveauNewRenderbuffer; func->BindFramebuffer = nouveauBindFramebuffer; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c index 0b745e1e74..fcfc0ebe14 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c @@ -77,6 +77,12 @@ void nouveauWaitForIdleLocked(nouveauContextPtr nmesa) FIRE_RING(); while(RING_AHEAD()>0); + /* We can't wait on PGRAPH going idle.. + * 1) We don't have the regs mapped + * 2) PGRAPH may not go idle with multiple channels active + * Look into replacing this with a NOTIFY/NOP + wait notifier sequence. + */ +#if 0 for(i=0;i<1000000;i++) /* 1 second */ { switch(nmesa->screen->card->type) @@ -100,6 +106,7 @@ void nouveauWaitForIdleLocked(nouveauContextPtr nmesa) return; DO_USLEEP(1); } +#endif } void nouveauWaitForIdle(nouveauContextPtr nmesa) diff --git a/src/mesa/drivers/dri/nouveau/nouveau_span.c b/src/mesa/drivers/dri/nouveau/nouveau_span.c index 6d99728b85..74dec66afc 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_span.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_span.c @@ -37,12 +37,21 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define HAVE_HW_STENCIL_SPANS 0 #define HAVE_HW_STENCIL_PIXELS 0 +#define HW_CLIPLOOP() \ + do { \ + int _nc = nmesa->numClipRects; \ + while ( _nc-- ) { \ + int minx = nmesa->pClipRects[_nc].x1 - nmesa->drawX; \ + int miny = nmesa->pClipRects[_nc].y1 - nmesa->drawY; \ + int maxx = nmesa->pClipRects[_nc].x2 - nmesa->drawX; \ + int maxy = nmesa->pClipRects[_nc].y2 - nmesa->drawY; + #define LOCAL_VARS \ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); \ - __DRIscreenPrivate *sPriv = nmesa->driScreen; \ - __DRIdrawablePrivate *dPriv = nmesa->driDrawable; \ - driRenderbuffer *drb = (driRenderbuffer *) rb; \ - GLuint height = dPriv->h; \ + nouveau_renderbuffer *nrb = (nouveau_renderbuffer *)rb; \ + GLuint height = nrb->mesa.Height; \ + GLubyte *map = (GLubyte *)(nrb->map ? nrb->map : nrb->mem->map) + \ + (nmesa->drawY * nrb->pitch) + (nmesa->drawX * nrb->cpp); \ GLuint p; \ (void) p; @@ -64,8 +73,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #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) +#define GET_PTR(X,Y) (map + (Y)*nrb->pitch + (X)*nrb->cpp) #include "spantmp2.h" @@ -75,8 +83,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #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) +#define GET_PTR(X,Y) (map + (Y)*nrb->pitch + (X)*nrb->cpp) #include "spantmp2.h" static void -- cgit v1.2.3 From d79323bd42864fc4768874f56734bad9dc6d8a9c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 24 Dec 2006 00:50:13 +1100 Subject: nouveau: Kill some compile warnings. --- src/mesa/drivers/dri/nouveau/nouveau_driver.c | 3 +-- src/mesa/drivers/dri/nouveau/nouveau_fifo.c | 10 ++++++---- src/mesa/drivers/dri/nouveau/nouveau_fifo.h | 1 + src/mesa/drivers/dri/nouveau/nouveau_screen.c | 1 - src/mesa/drivers/dri/nouveau/nouveau_shader.h | 3 +++ src/mesa/drivers/dri/nouveau/nouveau_state.c | 2 -- src/mesa/drivers/dri/nouveau/nv30_fragprog.c | 1 - src/mesa/drivers/dri/nouveau/nv30_state.c | 7 ++----- src/mesa/drivers/dri/nouveau/nv30_vertprog.c | 3 --- src/mesa/drivers/dri/nouveau/nv40_vertprog.c | 3 --- 10 files changed, 13 insertions(+), 21 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_driver.c b/src/mesa/drivers/dri/nouveau/nouveau_driver.c index f85dc62e74..00956aa8f8 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_driver.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_driver.c @@ -129,8 +129,7 @@ static void nouveauFinish( GLcontext *ctx ) } /* glClear */ -static void nouveauClear( GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint cx, GLint cy, GLint cw, GLint ch ) +static void nouveauClear( GLcontext *ctx, GLbitfield mask ) { // XXX we really should do something here... } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c index fcfc0ebe14..5c2b2c7552 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c @@ -133,12 +133,14 @@ GLboolean nouveauFifoInit(nouveauContextPtr nmesa) return GL_FALSE; } - if (drmMap(nmesa->driFd, fifo_init.cmdbuf, fifo_init.cmdbuf_size, &nmesa->fifo.buffer)) { - FATAL("Unable to map the fifo\n",ret); + ret = drmMap(nmesa->driFd, fifo_init.cmdbuf, fifo_init.cmdbuf_size, &nmesa->fifo.buffer); + if (ret) { + FATAL("Unable to map the fifo (returned %d)\n",ret); return GL_FALSE; } - if (drmMap(nmesa->driFd, fifo_init.ctrl, fifo_init.ctrl_size, &nmesa->fifo.mmio)) { - FATAL("Unable to map the control regs\n",ret); + ret = drmMap(nmesa->driFd, fifo_init.ctrl, fifo_init.ctrl_size, &nmesa->fifo.mmio); + if (ret) { + FATAL("Unable to map the control regs (returned %d)\n",ret); return GL_FALSE; } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h index 51993cf556..05d00d4769 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h @@ -145,6 +145,7 @@ int i; for(i=0;iViewport._WindowMap.m; GLfloat *m = nmesa->viewport.m; GLfloat xoffset = nmesa->drawX, yoffset = nmesa->drawY; - GLint h = 0; nmesa->depth_scale = 1.0 / ctx->DrawBuffer->_DepthMaxF; diff --git a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c index 98aa27ea9c..b11bc1809e 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c +++ b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c @@ -24,7 +24,6 @@ static void NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - drm_nouveau_mem_alloc_t mem; if (!nvs->program_buffer) { nouveau_mem *fpbuf; diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 7ccf5f9875..45befd0e77 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -573,7 +573,6 @@ void (*RenderMode)(GLcontext *ctx, GLenum mode ); static void nv30Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - nouveau_renderbuffer *nrb; /* There's no scissor enable bit, so adjust the scissor to cover the * maximum draw buffer bounds @@ -677,7 +676,6 @@ static void nv30TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) static void nv30WindowMoved(nouveauContextPtr nmesa) { GLcontext *ctx = nmesa->glCtx; - nouveau_renderbuffer *nrb; GLfloat *v = nmesa->viewport.m; GLuint w = ctx->Viewport.Width; GLuint h = ctx->Viewport.Height; @@ -759,11 +757,10 @@ static GLboolean nv30BindBuffers(nouveauContextPtr nmesa, int num_color, nouveau_renderbuffer **color, nouveau_renderbuffer *depth) { - nouveau_renderbuffer *nrb; GLuint x, y, w, h; - w = nrb->mesa.Width; - h = nrb->mesa.Height; + w = color[0]->mesa.Width; + h = color[0]->mesa.Height; x = nmesa->drawX; y = nmesa->drawY; diff --git a/src/mesa/drivers/dri/nouveau/nv30_vertprog.c b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c index e60422dad1..6ba8e35d55 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_vertprog.c +++ b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c @@ -6,9 +6,6 @@ #include "nouveau_shader.h" #include "nv30_shader.h" -extern nvsSwzComp NV20VP_TX_SWIZZLE[4]; -extern void NV20VPTXSwizzle(int hwswz, nvsSwzComp *swz); - /***************************************************************************** * Support routines */ diff --git a/src/mesa/drivers/dri/nouveau/nv40_vertprog.c b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c index f2cb3fb166..0493e18403 100644 --- a/src/mesa/drivers/dri/nouveau/nv40_vertprog.c +++ b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c @@ -2,9 +2,6 @@ #include "nouveau_msg.h" #include "nv40_shader.h" -extern nvsSwzComp NV20VP_TX_SWIZZLE[4]; -extern void NV20VPTXSwizzle(int hwswz, nvsSwzComp *swz); - /***************************************************************************** * Assembly routines */ -- cgit v1.2.3 From b8769f318ff9c2e4a74fbb1d4b058eb521e36dda Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Mon, 25 Dec 2006 23:34:56 +0100 Subject: Rework r300 fragprog avoid using bitfield structure. It seems that bitfield structure lead to some strange problem on 64bits arch, don't want to waste time debugging strange things like that so converted pfs_reg_t structure to a GLuint and use good old masking and shifting spell. (cherry picked from 2a7de9d095d8e60da12b11aaa1efe664b87b11d3 commit) --- src/mesa/drivers/dri/r300/r300_fragprog.c | 753 ++++++++++++++++++------------ src/mesa/drivers/dri/r300/r300_fragprog.h | 3 +- 2 files changed, 466 insertions(+), 290 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c index 32c0128eaa..f00162a6dc 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog.c @@ -51,18 +51,110 @@ #include "r300_fragprog.h" #include "r300_reg.h" +/* + * Usefull macros and values + */ +#define ERROR(fmt, args...) do { \ + fprintf(stderr, "%s::%s(): " fmt "\n", \ + __FILE__, __func__, ##args); \ + rp->error = GL_TRUE; \ + } while(0) + #define PFS_INVAL 0xFFFFFFFF #define COMPILE_STATE struct r300_pfs_compile_state *cs = rp->cs -static void dump_program(struct r300_fragment_program *rp); -static void emit_arith(struct r300_fragment_program *rp, int op, - pfs_reg_t dest, int mask, - pfs_reg_t src0, pfs_reg_t src1, pfs_reg_t src2, - int flags); +#define SWIZZLE_XYZ 0 +#define SWIZZLE_XXX 1 +#define SWIZZLE_YYY 2 +#define SWIZZLE_ZZZ 3 +#define SWIZZLE_WWW 4 +#define SWIZZLE_YZX 5 +#define SWIZZLE_ZXY 6 +#define SWIZZLE_WZY 7 +#define SWIZZLE_111 8 +#define SWIZZLE_000 9 +#define SWIZZLE_HHH 10 + +#define swizzle(r, x, y, z, w) do_swizzle(rp, r, \ + ((SWIZZLE_##x<<0)| \ + (SWIZZLE_##y<<3)| \ + (SWIZZLE_##z<<6)| \ + (SWIZZLE_##w<<9)), \ + 0) + +#define REG_TYPE_INPUT 0 +#define REG_TYPE_OUTPUT 1 +#define REG_TYPE_TEMP 2 +#define REG_TYPE_CONST 3 + +#define REG_TYPE_SHIFT 0 +#define REG_INDEX_SHIFT 2 +#define REG_VSWZ_SHIFT 8 +#define REG_SSWZ_SHIFT 13 +#define REG_NEGV_SHIFT 18 +#define REG_NEGS_SHIFT 19 +#define REG_ABS_SHIFT 20 +#define REG_NO_USE_SHIFT 21 +#define REG_VALID_SHIFT 22 + +#define REG_TYPE_MASK (0x03 << REG_TYPE_SHIFT) +#define REG_INDEX_MASK (0x3F << REG_INDEX_SHIFT) +#define REG_VSWZ_MASK (0x1F << REG_VSWZ_SHIFT) +#define REG_SSWZ_MASK (0x1F << REG_SSWZ_SHIFT) +#define REG_NEGV_MASK (0x01 << REG_NEGV_SHIFT) +#define REG_NEGS_MASK (0x01 << REG_NEGS_SHIFT) +#define REG_ABS_MASK (0x01 << REG_ABS_SHIFT) +#define REG_NO_USE_MASK (0x01 << REG_NO_USE_SHIFT) +#define REG_VALID_MASK (0x01 << REG_VALID_SHIFT) + +#define REG(type, index, vswz, sswz, nouse, valid) \ + (((type << REG_TYPE_SHIFT) & REG_TYPE_MASK) | \ + ((index << REG_INDEX_SHIFT) & REG_INDEX_MASK) | \ + ((nouse << REG_NO_USE_SHIFT) & REG_NO_USE_MASK) | \ + ((valid << REG_VALID_SHIFT) & REG_VALID_MASK) | \ + ((vswz << REG_VSWZ_SHIFT) & REG_VSWZ_MASK) | \ + ((sswz << REG_SSWZ_SHIFT) & REG_SSWZ_MASK)) +#define REG_GET_TYPE(reg) \ + ((reg & REG_TYPE_MASK) >> REG_TYPE_SHIFT) +#define REG_GET_INDEX(reg) \ + ((reg & REG_INDEX_MASK) >> REG_INDEX_SHIFT) +#define REG_GET_VSWZ(reg) \ + ((reg & REG_VSWZ_MASK) >> REG_VSWZ_SHIFT) +#define REG_GET_SSWZ(reg) \ + ((reg & REG_SSWZ_MASK) >> REG_SSWZ_SHIFT) +#define REG_GET_NO_USE(reg) \ + ((reg & REG_NO_USE_MASK) >> REG_NO_USE_SHIFT) +#define REG_GET_VALID(reg) \ + ((reg & REG_VALID_MASK) >> REG_VALID_SHIFT) +#define REG_SET_TYPE(reg, type) \ + reg = ((reg & ~REG_TYPE_MASK) | \ + ((type << REG_TYPE_SHIFT) & REG_TYPE_MASK)) +#define REG_SET_INDEX(reg, index) \ + reg = ((reg & ~REG_INDEX_MASK) | \ + ((index << REG_INDEX_SHIFT) & REG_INDEX_MASK)) +#define REG_SET_VSWZ(reg, vswz) \ + reg = ((reg & ~REG_VSWZ_MASK) | \ + ((vswz << REG_VSWZ_SHIFT) & REG_VSWZ_MASK)) +#define REG_SET_SSWZ(reg, sswz) \ + reg = ((reg & ~REG_SSWZ_MASK) | \ + ((sswz << REG_SSWZ_SHIFT) & REG_SSWZ_MASK)) +#define REG_SET_NO_USE(reg, nouse) \ + reg = ((reg & ~REG_NO_USE_MASK) | \ + ((nouse << REG_NO_USE_SHIFT) & REG_NO_USE_MASK)) +#define REG_SET_VALID(reg, valid) \ + reg = ((reg & ~REG_VALID_MASK) | \ + ((valid << REG_VALID_SHIFT) & REG_VALID_MASK)) +#define REG_ABS(reg) \ + reg = (reg | REG_ABS_MASK) +#define REG_NEGV(reg) \ + reg = (reg | REG_NEGV_MASK) +#define REG_NEGS(reg) \ + reg = (reg | REG_NEGS_MASK) -/*************************************** - * begin: useful data structions for fragment program generation - ***************************************/ + +/* + * Datas structures for fragment program generation + */ /* description of r300 native hw instructions */ static const struct { @@ -86,20 +178,19 @@ static const struct { { "CMPH", 3, R300_FPI0_OUTC_CMPH, PFS_INVAL }, }; -#define MAKE_SWZ3(x, y, z) (MAKE_SWIZZLE4(SWIZZLE_##x, \ - SWIZZLE_##y, \ - SWIZZLE_##z, \ - SWIZZLE_ZERO)) - -#define SLOT_VECTOR (1<<0) -#define SLOT_SCALAR (1<<3) -#define SLOT_BOTH (SLOT_VECTOR|SLOT_SCALAR) /* vector swizzles r300 can support natively, with a couple of * cases we handle specially * - * pfs_reg_t.v_swz/pfs_reg_t.s_swz is an index into this table - **/ + * REG_VSWZ/REG_SSWZ is an index into this table + */ +#define SLOT_VECTOR (1<<0) +#define SLOT_SCALAR (1<<3) +#define SLOT_BOTH (SLOT_VECTOR | SLOT_SCALAR) +#define MAKE_SWZ3(x, y, z) (MAKE_SWIZZLE4(SWIZZLE_##x, \ + SWIZZLE_##y, \ + SWIZZLE_##z, \ + SWIZZLE_ZERO)) static const struct r300_pfs_swizzle { GLuint hash; /* swizzle value this matches */ GLuint base; /* base value for hw swizzle */ @@ -120,39 +211,29 @@ static const struct r300_pfs_swizzle { { PFS_INVAL, R300_FPI0_ARGC_HALF, 0, 0}, { PFS_INVAL, 0, 0, 0}, }; -#define SWIZZLE_XYZ 0 -#define SWIZZLE_XXX 1 -#define SWIZZLE_YYY 2 -#define SWIZZLE_ZZZ 3 -#define SWIZZLE_WWW 4 -#define SWIZZLE_YZX 5 -#define SWIZZLE_ZXY 6 -#define SWIZZLE_WZY 7 -#define SWIZZLE_111 8 -#define SWIZZLE_000 9 -#define SWIZZLE_HHH 10 +/* used during matching of non-native swizzles */ #define SWZ_X_MASK (7 << 0) #define SWZ_Y_MASK (7 << 3) #define SWZ_Z_MASK (7 << 6) #define SWZ_W_MASK (7 << 9) -/* used during matching of non-native swizzles */ static const struct { - GLuint hash; /* used to mask matching swizzle components */ + GLuint hash; /* used to mask matching swizzle components */ int mask; /* actual outmask */ int count; /* count of components matched */ } s_mask[] = { - { SWZ_X_MASK|SWZ_Y_MASK|SWZ_Z_MASK, 1|2|4, 3}, - { SWZ_X_MASK|SWZ_Y_MASK, 1|2, 2}, - { SWZ_X_MASK|SWZ_Z_MASK, 1|4, 2}, - { SWZ_Y_MASK|SWZ_Z_MASK, 2|4, 2}, - { SWZ_X_MASK, 1, 1}, - { SWZ_Y_MASK, 2, 1}, - { SWZ_Z_MASK, 4, 1}, - { PFS_INVAL, PFS_INVAL, PFS_INVAL} + { SWZ_X_MASK|SWZ_Y_MASK|SWZ_Z_MASK, 1|2|4, 3}, + { SWZ_X_MASK|SWZ_Y_MASK, 1|2, 2}, + { SWZ_X_MASK|SWZ_Z_MASK, 1|4, 2}, + { SWZ_Y_MASK|SWZ_Z_MASK, 2|4, 2}, + { SWZ_X_MASK, 1, 1}, + { SWZ_Y_MASK, 2, 1}, + { SWZ_Z_MASK, 4, 1}, + { PFS_INVAL, PFS_INVAL, PFS_INVAL} }; /* mapping from SWIZZLE_* to r300 native values for scalar insns */ +#define SWIZZLE_HALF 6 static const struct { int base; /* hw value of swizzle */ int stride; /* difference between SRC0/1/2 */ @@ -166,58 +247,51 @@ static const struct { { R300_FPI2_ARGA_ONE , 0, 0 }, { R300_FPI2_ARGA_HALF , 0, 0 } }; -#define SWIZZLE_HALF 6 /* boiler-plate reg, for convenience */ -static const pfs_reg_t undef = { - type: REG_TYPE_TEMP, - index: 0, - v_swz: SWIZZLE_XYZ, - s_swz: SWIZZLE_W, - negate_v: 0, - negate_s: 0, - absolute: 0, - no_use: GL_FALSE, - valid: GL_FALSE -}; +static const GLuint undef = REG(REG_TYPE_TEMP, + 0, + SWIZZLE_XYZ, + SWIZZLE_W, + GL_FALSE, + GL_FALSE); /* constant one source */ -static const pfs_reg_t pfs_one = { - type: REG_TYPE_CONST, - index: 0, - v_swz: SWIZZLE_111, - s_swz: SWIZZLE_ONE, - valid: GL_TRUE -}; +static const GLuint pfs_one = REG(REG_TYPE_TEMP, + 0, + SWIZZLE_111, + SWIZZLE_ONE, + GL_FALSE, + GL_TRUE); /* constant half source */ -static const pfs_reg_t pfs_half = { - type: REG_TYPE_CONST, - index: 0, - v_swz: SWIZZLE_HHH, - s_swz: SWIZZLE_HALF, - valid: GL_TRUE -}; +static const GLuint pfs_half = REG(REG_TYPE_TEMP, + 0, + SWIZZLE_HHH, + SWIZZLE_HALF, + GL_FALSE, + GL_TRUE); /* constant zero source */ -static const pfs_reg_t pfs_zero = { - type: REG_TYPE_CONST, - index: 0, - v_swz: SWIZZLE_000, - s_swz: SWIZZLE_ZERO, - valid: GL_TRUE -}; - -/*************************************** - * end: data structures - ***************************************/ +static const GLuint pfs_zero = REG(REG_TYPE_TEMP, + 0, + SWIZZLE_000, + SWIZZLE_ZERO, + GL_FALSE, + GL_TRUE); -#define ERROR(fmt, args...) do { \ - fprintf(stderr, "%s::%s(): " fmt "\n",\ - __FILE__, __func__, ##args); \ - rp->error = GL_TRUE; \ -} while(0) +/* + * Common functions prototypes + */ +static void dump_program(struct r300_fragment_program *rp); +static void emit_arith(struct r300_fragment_program *rp, int op, + GLuint dest, int mask, + GLuint src0, GLuint src1, GLuint src2, + int flags); +/* + * Helper functions prototypes + */ static int get_hw_temp(struct r300_fragment_program *rp) { COMPILE_STATE; @@ -256,263 +330,338 @@ static void free_hw_temp(struct r300_fragment_program *rp, int idx) cs->hwreg_in_use &= ~(1<temp_in_use); - if (!r.index) { + index = ffs(~cs->temp_in_use); + if (!index) { ERROR("Out of program temps\n"); return r; } - cs->temp_in_use |= (1 << --r.index); - - cs->temps[r.index].refcount = 0xFFFFFFFF; - cs->temps[r.index].reg = -1; - r.valid = GL_TRUE; + + cs->temp_in_use |= (1 << --index); + cs->temps[index].refcount = 0xFFFFFFFF; + cs->temps[index].reg = -1; + + REG_SET_TYPE(r, REG_TYPE_TEMP); + REG_SET_INDEX(r, index); + REG_SET_VALID(r, GL_TRUE); return r; } -static pfs_reg_t get_temp_reg_tex(struct r300_fragment_program *rp) +static GLuint get_temp_reg_tex(struct r300_fragment_program *rp) { COMPILE_STATE; - pfs_reg_t r = undef; + GLuint r = undef; + GLuint index; - r.index = ffs(~cs->temp_in_use); - if (!r.index) { + index = ffs(~cs->temp_in_use); + if (!index) { ERROR("Out of program temps\n"); return r; } - cs->temp_in_use |= (1 << --r.index); - - cs->temps[r.index].refcount = 0xFFFFFFFF; - cs->temps[r.index].reg = get_hw_temp_tex(rp); - r.valid = GL_TRUE; + + cs->temp_in_use |= (1 << --index); + cs->temps[index].refcount = 0xFFFFFFFF; + cs->temps[index].reg = get_hw_temp_tex(rp); + + REG_SET_TYPE(r, REG_TYPE_TEMP); + REG_SET_INDEX(r, index); + REG_SET_VALID(r, GL_TRUE); return r; } -static void free_temp(struct r300_fragment_program *rp, pfs_reg_t r) +static void free_temp(struct r300_fragment_program *rp, GLuint r) { COMPILE_STATE; - if (!(cs->temp_in_use & (1<temp_in_use & (1 << index))) + return; - if (r.type == REG_TYPE_TEMP) { - free_hw_temp(rp, cs->temps[r.index].reg); - cs->temps[r.index].reg = -1; - cs->temp_in_use &= ~(1<inputs[r.index].reg); - cs->inputs[r.index].reg = -1; + if (REG_GET_TYPE(r) == REG_TYPE_TEMP) { + free_hw_temp(rp, cs->temps[index].reg); + cs->temps[index].reg = -1; + cs->temp_in_use &= ~(1 << index); + } else if (REG_GET_TYPE(r) == REG_TYPE_INPUT) { + free_hw_temp(rp, cs->inputs[index].reg); + cs->inputs[index].reg = -1; } } -static pfs_reg_t emit_param4fv(struct r300_fragment_program *rp, - GLfloat *values) +static GLuint emit_param4fv(struct r300_fragment_program *rp, + GLfloat *values) { - pfs_reg_t r = undef; - r.type = REG_TYPE_CONST; + GLuint r = undef; + GLuint index; int pidx; pidx = rp->param_nr++; - r.index = rp->const_nr++; - if (pidx >= PFS_NUM_CONST_REGS || r.index >= PFS_NUM_CONST_REGS) { + index = rp->const_nr++; + if (pidx >= PFS_NUM_CONST_REGS || index >= PFS_NUM_CONST_REGS) { ERROR("Out of const/param slots!\n"); return r; } - - rp->param[pidx].idx = r.index; + + rp->param[pidx].idx = index; rp->param[pidx].values = values; rp->params_uptodate = GL_FALSE; - r.valid = GL_TRUE; + REG_SET_TYPE(r, REG_TYPE_CONST); + REG_SET_INDEX(r, index); + REG_SET_VALID(r, GL_TRUE); return r; } -static pfs_reg_t emit_const4fv(struct r300_fragment_program *rp, GLfloat *cp) +static GLuint emit_const4fv(struct r300_fragment_program *rp, GLfloat *cp) { - pfs_reg_t r = undef; - r.type = REG_TYPE_CONST; + GLuint r = undef; + GLuint index; - r.index = rp->const_nr++; - if (r.index >= PFS_NUM_CONST_REGS) { + index = rp->const_nr++; + if (index >= PFS_NUM_CONST_REGS) { ERROR("Out of hw constants!\n"); return r; } - COPY_4V(rp->constant[r.index], cp); - r.valid = GL_TRUE; + COPY_4V(rp->constant[index], cp); + + REG_SET_TYPE(r, REG_TYPE_CONST); + REG_SET_INDEX(r, index); + REG_SET_VALID(r, GL_TRUE); return r; } -static __inline pfs_reg_t negate(pfs_reg_t r) +static inline GLuint negate(GLuint r) { - r.negate_v = 1; - r.negate_s = 1; + REG_NEGS(r); + REG_NEGV(r); return r; } /* Hack, to prevent clobbering sources used multiple times when * emulating non-native instructions */ -static __inline pfs_reg_t keep(pfs_reg_t r) +static inline GLuint keep(GLuint r) { - r.no_use = GL_TRUE; + REG_SET_NO_USE(r, GL_TRUE); return r; } -static __inline pfs_reg_t absolute(pfs_reg_t r) +static inline GLuint absolute(GLuint r) { - r.absolute = 1; + REG_ABS(r); return r; } static int swz_native(struct r300_fragment_program *rp, - pfs_reg_t src, pfs_reg_t *r, GLuint arbneg) + GLuint src, + GLuint *r, + GLuint arbneg) { - /* Native swizzle, nothing to see here */ - src.negate_s = (arbneg >> 3) & 1; + /* Native swizzle, handle negation */ + src |= ((arbneg >> 3) & 1) << REG_NEGS_SHIFT; if ((arbneg & 0x7) == 0x0) { - src.negate_v = 0; + src = src & ~REG_NEGV_MASK; *r = src; } else if ((arbneg & 0x7) == 0x7) { - src.negate_v = 1; + src |= REG_NEGV_MASK; *r = src; } else { - if (!r->valid) + if (!REG_GET_VALID(*r)) *r = get_temp_reg(rp); - src.negate_v = 1; - emit_arith(rp, PFS_OP_MAD, *r, arbneg & 0x7, - keep(src), pfs_one, pfs_zero, 0); - src.negate_v = 0; - emit_arith(rp, PFS_OP_MAD, *r, + src |= REG_NEGV_MASK; + emit_arith(rp, + PFS_OP_MAD, + *r, + arbneg & 0x7, + keep(src), + pfs_one, + pfs_zero, + 0); + src = src & ~REG_NEGV_MASK; + emit_arith(rp, + PFS_OP_MAD, + *r, (arbneg ^ 0x7) | WRITEMASK_W, - src, pfs_one, pfs_zero, 0); + src, + pfs_one, + pfs_zero, + 0); } return 3; } -static int swz_emit_partial(struct r300_fragment_program *rp, pfs_reg_t src, - pfs_reg_t *r, int mask, int mc, GLuint arbneg) +static int swz_emit_partial(struct r300_fragment_program *rp, + GLuint src, + GLuint *r, + int mask, + int mc, + GLuint arbneg) { GLuint tmp; GLuint wmask = 0; - if (!r->valid) + if (!REG_GET_VALID(*r)) *r = get_temp_reg(rp); - /* A partial match, src.v_swz/mask define what parts of the - * desired swizzle we match */ + /* A partial match, VSWZ/mask define what parts of the + * desired swizzle we match + */ if (mc + s_mask[mask].count == 3) { wmask = WRITEMASK_W; - src.negate_s = (arbneg >> 3) & 1; + src |= ((arbneg >> 3) & 1) << REG_NEGS_SHIFT; } tmp = arbneg & s_mask[mask].mask; if (tmp) { tmp = tmp ^ s_mask[mask].mask; if (tmp) { - src.negate_v = 1; - emit_arith(rp, PFS_OP_MAD, *r, + emit_arith(rp, + PFS_OP_MAD, + *r, arbneg & s_mask[mask].mask, - keep(src), pfs_one, pfs_zero, 0); - src.negate_v = 0; - if (!wmask) src.no_use = GL_TRUE; - else src.no_use = GL_FALSE; - emit_arith(rp, PFS_OP_MAD, *r, tmp | wmask, - src, pfs_one, pfs_zero, 0); + keep(src) | REG_NEGV_MASK, + pfs_one, + pfs_zero, + 0); + if (!wmask) { + REG_SET_NO_USE(src, GL_TRUE); + } else { + REG_SET_NO_USE(src, GL_FALSE); + } + emit_arith(rp, + PFS_OP_MAD, + *r, + tmp | wmask, + src, + pfs_one, + pfs_zero, + 0); } else { - src.negate_v = 1; - if (!wmask) src.no_use = GL_TRUE; - else src.no_use = GL_FALSE; - emit_arith(rp, PFS_OP_MAD, *r, + if (!wmask) { + REG_SET_NO_USE(src, GL_TRUE); + } else { + REG_SET_NO_USE(src, GL_FALSE); + } + emit_arith(rp, + PFS_OP_MAD, + *r, (arbneg & s_mask[mask].mask) | wmask, - src, pfs_one, pfs_zero, 0); - src.negate_v = 0; + src | REG_NEGV_MASK, + pfs_one, + pfs_zero, + 0); } } else { - if (!wmask) src.no_use = GL_TRUE; - else src.no_use = GL_FALSE; - emit_arith(rp, PFS_OP_MAD, *r, + if (!wmask) { + REG_SET_NO_USE(src, GL_TRUE); + } else { + REG_SET_NO_USE(src, GL_FALSE); + } + emit_arith(rp, PFS_OP_MAD, + *r, s_mask[mask].mask | wmask, - src, pfs_one, pfs_zero, 0); + src, + pfs_one, + pfs_zero, + 0); } return s_mask[mask].count; } -#define swizzle(r, x, y, z, w) do_swizzle(rp, r, \ - ((SWIZZLE_##x<<0)| \ - (SWIZZLE_##y<<3)| \ - (SWIZZLE_##z<<6)| \ - (SWIZZLE_##w<<9)), \ - 0) - -static pfs_reg_t do_swizzle(struct r300_fragment_program *rp, - pfs_reg_t src, GLuint arbswz, GLuint arbneg) +static GLuint do_swizzle(struct r300_fragment_program *rp, + GLuint src, + GLuint arbswz, + GLuint arbneg) { - pfs_reg_t r = undef; - + GLuint r = undef; + GLuint vswz; int c_mask = 0; - int v_matched = 0; + int v_match = 0; /* If swizzling from something without an XYZW native swizzle, * emit result to a temp, and do new swizzle from the temp. */ - if (src.v_swz != SWIZZLE_XYZ || src.s_swz != SWIZZLE_W) { - pfs_reg_t temp = get_temp_reg(rp); - emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_XYZW, src, pfs_one, - pfs_zero, 0); + if (REG_GET_VSWZ(src) != SWIZZLE_XYZ || + REG_GET_SSWZ(src) != SWIZZLE_W) { + GLuint temp = get_temp_reg(rp); + emit_arith(rp, + PFS_OP_MAD, + temp, + WRITEMASK_XYZW, + src, + pfs_one, + pfs_zero, + 0); src = temp; } - src.s_swz = GET_SWZ(arbswz, 3); + + /* set scalar swizzling */ + REG_SET_SSWZ(src, GET_SWZ(arbswz, 3)); do { + vswz = REG_GET_VSWZ(src); do { -#define CUR_HASH (v_swiz[src.v_swz].hash & s_mask[c_mask].hash) - if (CUR_HASH == (arbswz & s_mask[c_mask].hash)) { - if (s_mask[c_mask].count == 3) - v_matched += swz_native(rp, src, &r, + int chash; + + REG_SET_VSWZ(src, vswz); + chash = v_swiz[REG_GET_VSWZ(src)].hash & + s_mask[c_mask].hash; + + if (chash == (arbswz & s_mask[c_mask].hash)) { + if (s_mask[c_mask].count == 3) { + v_match += swz_native(rp, + src, + &r, arbneg); - else - v_matched += swz_emit_partial(rp, src, - &r, - c_mask, - v_matched, - arbneg); - - if (v_matched == 3) + } else { + v_match += swz_emit_partial(rp, + src, + &r, + c_mask, + v_match, + arbneg); + } + + if (v_match == 3) return r; /* Fill with something invalid.. all 0's was * wrong before, matched SWIZZLE_X. So all - * 1's will be okay for now */ + * 1's will be okay for now + */ arbswz |= (PFS_INVAL & s_mask[c_mask].hash); } - } while(v_swiz[++src.v_swz].hash != PFS_INVAL); - src.v_swz = SWIZZLE_XYZ; + } while(v_swiz[++vswz].hash != PFS_INVAL); + REG_SET_VSWZ(src, SWIZZLE_XYZ); } while (s_mask[++c_mask].hash != PFS_INVAL); ERROR("should NEVER get here\n"); return r; } - -static pfs_reg_t t_src(struct r300_fragment_program *rp, - struct prog_src_register fpsrc) + +static GLuint t_src(struct r300_fragment_program *rp, + struct prog_src_register fpsrc) { - pfs_reg_t r = undef; + GLuint r = undef; switch (fpsrc.File) { case PROGRAM_TEMPORARY: - r.index = fpsrc.Index; - r.valid = GL_TRUE; + REG_SET_INDEX(r, fpsrc.Index); + REG_SET_VALID(r, GL_TRUE); + REG_SET_TYPE(r, REG_TYPE_TEMP); break; case PROGRAM_INPUT: - r.index = fpsrc.Index; - r.type = REG_TYPE_INPUT; - r.valid = GL_TRUE; + REG_SET_INDEX(r, fpsrc.Index); + REG_SET_VALID(r, GL_TRUE); + REG_SET_TYPE(r, REG_TYPE_INPUT); break; case PROGRAM_LOCAL_PARAM: r = emit_param4fv(rp, @@ -533,13 +682,13 @@ static pfs_reg_t t_src(struct r300_fragment_program *rp, } /* no point swizzling ONE/ZERO/HALF constants... */ - if (r.v_swz < SWIZZLE_111 || r.s_swz < SWIZZLE_ZERO) + if (REG_GET_VSWZ(r) < SWIZZLE_111 || REG_GET_SSWZ(r) < SWIZZLE_ZERO) r = do_swizzle(rp, r, fpsrc.Swizzle, fpsrc.NegateBase); return r; } -static pfs_reg_t t_scalar_src(struct r300_fragment_program *rp, - struct prog_src_register fpsrc) +static GLuint t_scalar_src(struct r300_fragment_program *rp, + struct prog_src_register fpsrc) { struct prog_src_register src = fpsrc; int sc = GET_SWZ(fpsrc.Swizzle, 0); /* X */ @@ -549,22 +698,24 @@ static pfs_reg_t t_scalar_src(struct r300_fragment_program *rp, return t_src(rp, src); } -static pfs_reg_t t_dst(struct r300_fragment_program *rp, - struct prog_dst_register dest) { - pfs_reg_t r = undef; +static GLuint t_dst(struct r300_fragment_program *rp, + struct prog_dst_register dest) +{ + GLuint r = undef; switch (dest.File) { case PROGRAM_TEMPORARY: - r.index = dest.Index; - r.valid = GL_TRUE; + REG_SET_INDEX(r, dest.Index); + REG_SET_VALID(r, GL_TRUE); + REG_SET_TYPE(r, REG_TYPE_TEMP); return r; case PROGRAM_OUTPUT: - r.type = REG_TYPE_OUTPUT; + REG_SET_TYPE(r, REG_TYPE_OUTPUT); switch (dest.Index) { case FRAG_RESULT_COLR: case FRAG_RESULT_DEPR: - r.index = dest.Index; - r.valid = GL_TRUE; + REG_SET_INDEX(r, dest.Index); + REG_SET_VALID(r, GL_TRUE); return r; default: ERROR("Bad DstReg->Index 0x%x\n", dest.Index); @@ -576,66 +727,77 @@ static pfs_reg_t t_dst(struct r300_fragment_program *rp, } } -static int t_hw_src(struct r300_fragment_program *rp, pfs_reg_t src, +static int t_hw_src(struct r300_fragment_program *rp, + GLuint src, GLboolean tex) { COMPILE_STATE; int idx; + int index = REG_GET_INDEX(src); - switch (src.type) { + switch(REG_GET_TYPE(src)) { case REG_TYPE_TEMP: /* NOTE: if reg==-1 here, a source is being read that - * hasn't been written to. Undefined results */ - if (cs->temps[src.index].reg == -1) - cs->temps[src.index].reg = get_hw_temp(rp); - idx = cs->temps[src.index].reg; + * hasn't been written to. Undefined results + */ + if (cs->temps[index].reg == -1) + cs->temps[index].reg = get_hw_temp(rp); - if (!src.no_use && (--cs->temps[src.index].refcount == 0)) + idx = cs->temps[index].reg; + + if (!REG_GET_NO_USE(src) && + (--cs->temps[index].refcount == 0)) free_temp(rp, src); break; case REG_TYPE_INPUT: - idx = cs->inputs[src.index].reg; + idx = cs->inputs[index].reg; - if (!src.no_use && (--cs->inputs[src.index].refcount == 0)) - free_hw_temp(rp, cs->inputs[src.index].reg); + if (!REG_GET_NO_USE(src) && + (--cs->inputs[index].refcount == 0)) + free_hw_temp(rp, cs->inputs[index].reg); break; case REG_TYPE_CONST: - return (src.index | SRC_CONST); + return (index | SRC_CONST); default: ERROR("Invalid type for source reg\n"); return (0 | SRC_CONST); } - if (!tex) cs->used_in_node |= (1 << idx); + if (!tex) + cs->used_in_node |= (1 << idx); return idx; } -static int t_hw_dst(struct r300_fragment_program *rp, pfs_reg_t dest, +static int t_hw_dst(struct r300_fragment_program *rp, + GLuint dest, GLboolean tex) { COMPILE_STATE; int idx; - assert(dest.valid); + GLuint index = REG_GET_INDEX(dest); + assert(REG_GET_VALID(dest)); - switch (dest.type) { + switch(REG_GET_TYPE(dest)) { case REG_TYPE_TEMP: - if (cs->temps[dest.index].reg == -1) { - if (!tex) - cs->temps[dest.index].reg = get_hw_temp(rp); - else - cs->temps[dest.index].reg = get_hw_temp_tex(rp); + if (cs->temps[REG_GET_INDEX(dest)].reg == -1) { + if (!tex) { + cs->temps[index].reg = get_hw_temp(rp); + } else { + cs->temps[index].reg = get_hw_temp_tex(rp); + } } - idx = cs->temps[dest.index].reg; + idx = cs->temps[index].reg; - if (!dest.no_use && (--cs->temps[dest.index].refcount == 0)) + if (!REG_GET_NO_USE(dest) && + (--cs->temps[index].refcount == 0)) free_temp(rp, dest); cs->dest_in_node |= (1 << idx); cs->used_in_node |= (1 << idx); break; case REG_TYPE_OUTPUT: - switch (dest.index) { + switch(index) { case FRAG_RESULT_COLR: rp->node[rp->cur_node].flags |= R300_PFS_NODE_OUTPUT_COLOR; break; @@ -643,17 +805,18 @@ static int t_hw_dst(struct r300_fragment_program *rp, pfs_reg_t dest, rp->node[rp->cur_node].flags |= R300_PFS_NODE_OUTPUT_DEPTH; break; } - return dest.index; + return index; break; default: - ERROR("invalid dest reg type %d\n", dest.type); + ERROR("invalid dest reg type %d\n", REG_GET_TYPE(dest)); return 0; } return idx; } -static void emit_nop(struct r300_fragment_program *rp, GLuint mask, +static void emit_nop(struct r300_fragment_program *rp, + GLuint mask, GLboolean sync) { COMPILE_STATE; @@ -679,8 +842,8 @@ static void emit_tex(struct r300_fragment_program *rp, int opcode) { COMPILE_STATE; - pfs_reg_t coord = t_src(rp, fpi->SrcReg[0]); - pfs_reg_t dest = undef, rdest = undef; + GLuint coord = t_src(rp, fpi->SrcReg[0]); + GLuint dest = undef, rdest = undef; GLuint din = cs->dest_in_node, uin = cs->used_in_node; int unit = fpi->TexSrcUnit; int hwsrc, hwdest; @@ -691,7 +854,7 @@ static void emit_tex(struct r300_fragment_program *rp, dest = t_dst(rp, fpi->DstReg); /* r300 doesn't seem to be able to do TEX->output reg */ - if (dest.type == REG_TYPE_OUTPUT) { + if (REG_GET_TYPE(dest) == REG_TYPE_OUTPUT) { rdest = dest; dest = get_temp_reg_tex(rp); } @@ -703,7 +866,7 @@ static void emit_tex(struct r300_fragment_program *rp, if (uin & (1 << hwdest)) { free_hw_temp(rp, hwdest); hwdest = get_hw_temp_tex(rp); - cs->temps[dest.index].reg = hwdest; + cs->temps[REG_GET_INDEX(dest)].reg = hwdest; } } else { hwdest = 0; @@ -713,8 +876,8 @@ static void emit_tex(struct r300_fragment_program *rp, /* Indirection if source has been written in this node, or if the * dest has been read/written in this node */ - if ((coord.type != REG_TYPE_CONST && (din & (1<v_pos = cs->s_pos = MAX2(cs->v_pos, cs->s_pos); @@ -754,13 +917,13 @@ static void emit_tex(struct r300_fragment_program *rp, | (opcode << R300_FPITX_OPCODE_SHIFT); cs->dest_in_node |= (1 << hwdest); - if (coord.type != REG_TYPE_CONST) + if (REG_GET_TYPE(coord) != REG_TYPE_CONST) cs->used_in_node |= (1 << hwsrc); rp->node[rp->cur_node].tex_end++; /* Copy from temp to output if needed */ - if (rdest.valid) { + if (REG_GET_VALID(rdest)) { emit_arith(rp, PFS_OP_MAD, rdest, WRITEMASK_XYZW, dest, pfs_one, pfs_zero, 0); free_temp(rp, dest); @@ -770,7 +933,9 @@ static void emit_tex(struct r300_fragment_program *rp, /* Add sources to FPI1/FPI3 lists. If source is already on list, * reuse the index instead of wasting a source. */ -static int add_src(struct r300_fragment_program *rp, int reg, int pos, +static int add_src(struct r300_fragment_program *rp, + int reg, + int pos, int srcmask) { COMPILE_STATE; @@ -819,9 +984,12 @@ static int add_src(struct r300_fragment_program *rp, int reg, int pos, * It's not necessary to force the first case, but it makes disassembled * shaders easier to read. */ -static GLboolean force_same_slot(int vop, int sop, - GLboolean emit_vop, GLboolean emit_sop, - int argc, pfs_reg_t *src) +static GLboolean force_same_slot(int vop, + int sop, + GLboolean emit_vop, + GLboolean emit_sop, + int argc, + GLuint *src) { int i; @@ -833,20 +1001,24 @@ static GLboolean force_same_slot(int vop, int sop, if (emit_vop) { for (i=0;ialu.inst[vpos].inst1 |= hwdest << R300_FPI1_DSTC_SHIFT; - if (dest.type == REG_TYPE_OUTPUT) { - if (dest.index == FRAG_RESULT_COLR) { + if (REG_GET_TYPE(dest) == REG_TYPE_OUTPUT) { + if (REG_GET_INDEX(dest) == FRAG_RESULT_COLR) { rp->alu.inst[vpos].inst1 |= (mask & WRITEMASK_XYZ) << R300_FPI1_DSTC_OUTPUT_MASK_SHIFT; } else assert(0); @@ -968,11 +1143,11 @@ static void emit_arith(struct r300_fragment_program *rp, int op, sswz[2] << R300_FPI2_ARG2A_SHIFT; if (mask & WRITEMASK_W) { - if (dest.type == REG_TYPE_OUTPUT) { - if (dest.index == FRAG_RESULT_COLR) { + if (REG_GET_TYPE(dest) == REG_TYPE_OUTPUT) { + if (REG_GET_INDEX(dest) == FRAG_RESULT_COLR) { rp->alu.inst[spos].inst3 |= (hwdest << R300_FPI3_DSTA_SHIFT) | R300_FPI3_DSTA_OUTPUT; - } else if (dest.index == FRAG_RESULT_DEPR) { + } else if (REG_GET_INDEX(dest) == FRAG_RESULT_DEPR) { rp->alu.inst[spos].inst3 |= R300_FPI3_DSTA_DEPTH; } else assert(0); } else { @@ -985,22 +1160,22 @@ static void emit_arith(struct r300_fragment_program *rp, int op, rp->alu.inst[vpos].inst2 = NOP_INST2; return; -}; +} #if 0 -static pfs_reg_t get_attrib(struct r300_fragment_program *rp, GLuint attr) +static GLuint get_attrib(struct r300_fragment_program *rp, GLuint attr) { struct gl_fragment_program *mp = &rp->mesa_program; - pfs_reg_t r = undef; + GLuint r = undef; if (!(mp->Base.InputsRead & (1<mesa_program; const struct prog_instruction *inst = mp->Base.Instructions; struct prog_instruction *fpi; - pfs_reg_t src[3], dest, temp; - pfs_reg_t cnst; + GLuint src[3], dest, temp; + GLuint cnst; int flags, mask = 0; GLfloat cnstv[4] = {0.0, 0.0, 0.0, 0.0}; @@ -1167,7 +1342,7 @@ static GLboolean parse_program(struct r300_fragment_program *rp) /* result.x = 1.0 * result.w = src1.w */ if (mask & WRITEMASK_XW) { - src[1].v_swz = SWIZZLE_111; /* Cheat.. */ + REG_SET_VSWZ(src[1], SWIZZLE_111); /*Cheat*/ emit_arith(rp, PFS_OP_MAD, dest, mask & WRITEMASK_XW, src[1], pfs_one, pfs_zero, diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.h b/src/mesa/drivers/dri/r300/r300_fragprog.h index 4bbaa07e01..b0cebe60bb 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.h +++ b/src/mesa/drivers/dri/r300/r300_fragprog.h @@ -41,6 +41,7 @@ #include "r300_context.h" #include "program_instruction.h" +#if 0 /* representation of a register for emit_arith/swizzle */ typedef struct _pfs_reg_t { enum { @@ -58,7 +59,7 @@ typedef struct _pfs_reg_t { GLboolean no_use:1; GLboolean valid:1; } pfs_reg_t; - +#endif typedef struct r300_fragment_program_swizzle { GLuint length; GLuint src[4]; -- cgit v1.2.3 From c0a63d8e5e33b7fe3057e32f04c22969ac2adc1d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 26 Dec 2006 20:59:49 +1100 Subject: nouveau: Add notifier support functions --- src/mesa/drivers/dri/nouveau/Makefile | 1 + src/mesa/drivers/dri/nouveau/nouveau_context.c | 1 + src/mesa/drivers/dri/nouveau/nouveau_context.h | 4 + src/mesa/drivers/dri/nouveau/nouveau_object.c | 14 +-- src/mesa/drivers/dri/nouveau/nouveau_object.h | 16 +++- src/mesa/drivers/dri/nouveau/nouveau_sync.c | 115 +++++++++++++++++++++++++ src/mesa/drivers/dri/nouveau/nouveau_sync.h | 36 ++++++++ 7 files changed, 179 insertions(+), 8 deletions(-) create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_sync.c create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_sync.h (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile index 1a76169156..962978dc7f 100644 --- a/src/mesa/drivers/dri/nouveau/Makefile +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -24,6 +24,7 @@ DRIVER_SOURCES = \ nouveau_shader_2.c \ nouveau_tex.c \ nouveau_swtcl.c \ + nouveau_sync.c \ nv10_swtcl.c \ nv10_state.c \ nv20_state.c \ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index ac940ac595..7aca31d0d3 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -222,6 +222,7 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, break; } + nouveauSyncInitFuncs(ctx); nmesa->hw_func.InitCard(nmesa); nouveauInitState(ctx); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index ea28506b74..f54ac9a7c8 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -40,6 +40,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_state_cache.h" #include "nouveau_buffers.h" #include "nouveau_shader.h" +#include "nouveau_sync.h" #include "xmlconfig.h" @@ -101,6 +102,9 @@ typedef struct nouveau_context { uint64_t vram_phys; uint64_t agp_phys; + /* Channel synchronisation */ + nouveau_notifier *syncNotifier; + /* Additional hw-specific functions */ nouveau_hw_func hw_func; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.c b/src/mesa/drivers/dri/nouveau/nouveau_object.c index dda547c916..cf7284d2d5 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.c @@ -4,7 +4,7 @@ #include "nouveau_reg.h" -static GLboolean nouveauCreateContextObject(nouveauContextPtr nmesa, int handle, int class, uint32_t flags, uint32_t dma_in, uint32_t dma_out, uint32_t dma_notifier) +GLboolean nouveauCreateContextObject(nouveauContextPtr nmesa, int handle, int class, uint32_t flags, uint32_t dma_in, uint32_t dma_out, uint32_t dma_notifier) { drm_nouveau_object_init_t cto; int ret; @@ -20,12 +20,12 @@ static GLboolean nouveauCreateContextObject(nouveauContextPtr nmesa, int handle, return ret == 0; } -static GLboolean nouveauCreateDmaObject(nouveauContextPtr nmesa, - uint32_t handle, - uint32_t offset, - uint32_t size, - int target, - int access) +GLboolean nouveauCreateDmaObject(nouveauContextPtr nmesa, + uint32_t handle, + uint32_t offset, + uint32_t size, + int target, + int access) { drm_nouveau_dma_object_init_t dma; int ret; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.h b/src/mesa/drivers/dri/nouveau/nouveau_object.h index a49a39719b..87f2dc9ae7 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.h @@ -12,7 +12,8 @@ enum DMAObjects { NvCtxSurf2D = 0x80000020, NvImageBlit = 0x80000021, NvDmaFB = 0xD0FB0001, - NvDmaAGP = 0xD0AA0001 + NvDmaAGP = 0xD0AA0001, + NvSyncNotify = 0xD0000001 }; enum DMASubchannel { @@ -22,4 +23,17 @@ enum DMASubchannel { }; extern void nouveauObjectOnSubchannel(nouveauContextPtr nmesa, int subchannel, int handle); + +extern GLboolean nouveauCreateContextObject(nouveauContextPtr nmesa, + int handle, int class, + uint32_t flags, + uint32_t dma_in, + uint32_t dma_out, + uint32_t dma_notifier); +extern GLboolean nouveauCreateDmaObject(nouveauContextPtr nmesa, + uint32_t handle, + uint32_t offset, + uint32_t size, + int target, + int access); #endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.c b/src/mesa/drivers/dri/nouveau/nouveau_sync.c new file mode 100644 index 0000000000..698f778c4b --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.c @@ -0,0 +1,115 @@ +#include "vblank.h" /* for DO_USLEEP */ + +#include "nouveau_context.h" +#include "nouveau_buffers.h" +#include "nouveau_object.h" +#include "nouveau_fifo.h" +#include "nouveau_reg.h" +#include "nouveau_msg.h" +#include "nouveau_sync.h" + +nouveau_notifier * +nouveau_notifier_new(GLcontext *ctx, GLuint handle) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_notifier *notifier; + + notifier = CALLOC_STRUCT(nouveau_notifier_t); + if (!notifier) + return NULL; + + notifier->mem = nouveau_mem_alloc(ctx, NOUVEAU_MEM_FB, 32, 0); + if (!notifier->mem) { + FREE(notifier); + return NULL; + } + + if (!nouveauCreateDmaObject(nmesa, handle, notifier->mem->offset, + notifier->mem->size, + 0 /* NV_DMA_TARGET_FB */, + 0 /* NV_DMA_ACCESS_RW */)) { + nouveau_mem_free(ctx, notifier->mem); + FREE(notifier); + return NULL; + } + + notifier->handle = handle; + return notifier; +} + +void +nouveau_notifier_destroy(GLcontext *ctx, nouveau_notifier *notifier) +{ + /*XXX: free DMA object.. */ + nouveau_mem_free(ctx, notifier->mem); + FREE(notifier); +} + +void +nouveau_notifier_reset(nouveau_notifier *notifier) +{ + volatile GLuint *n = notifier->mem->map; + + n[NV_NOTIFY_TIME_0 /4] = 0x00000000; + n[NV_NOTIFY_TIME_1 /4] = 0x00000000; + n[NV_NOTIFY_RETURN_VALUE/4] = 0x00000000; + n[NV_NOTIFY_STATE /4] = (NV_NOTIFY_STATE_STATUS_IN_PROCESS << + NV_NOTIFY_STATE_STATUS_SHIFT); +} + +GLboolean +nouveau_notifier_wait_status(nouveau_notifier *notifier, GLuint status, + GLuint timeout) +{ + volatile GLuint *n = notifier->mem->map; + unsigned int time = 0; + + while (time <= timeout) { + if (n[NV_NOTIFY_STATE] & NV_NOTIFY_STATE_ERROR_CODE_MASK) { + MESSAGE("Notifier returned error: 0x%04x\n", + n[NV_NOTIFY_STATE] & + NV_NOTIFY_STATE_ERROR_CODE_MASK); + return GL_FALSE; + } + + if (((n[NV_NOTIFY_STATE] & NV_NOTIFY_STATE_STATUS_MASK) >> + NV_NOTIFY_STATE_STATUS_SHIFT) == status) + return GL_TRUE; + + if (timeout) { + DO_USLEEP(1); + time++; + } + } + + MESSAGE("Notifier timed out\n"); + return GL_FALSE; +} + +void +nouveau_notifier_wait_nop(GLcontext *ctx, nouveau_notifier *notifier, + GLuint subc) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLboolean ret; + + nouveau_notifier_reset(notifier); + + BEGIN_RING_SIZE(subc, NV_NOTIFY, 1); + OUT_RING (NV_NOTIFY_STYLE_WRITE_ONLY); + BEGIN_RING_SIZE(subc, NV_NOP, 1); + OUT_RING (0); + + ret = nouveau_notifier_wait_status(notifier, + NV_NOTIFY_STATE_STATUS_COMPLETED, + 0 /* no timeout */); + if (ret) MESSAGE("wait on notifier failed\n"); +} + +void nouveauSyncInitFuncs(GLcontext *ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + nmesa->syncNotifier = nouveau_notifier_new(ctx, NvSyncNotify); +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.h b/src/mesa/drivers/dri/nouveau/nouveau_sync.h new file mode 100644 index 0000000000..b20c2565ca --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.h @@ -0,0 +1,36 @@ +#ifndef __NOUVEAU_SYNC_H__ +#define __NOUVEAU_SYNC_H__ + +#include "nouveau_buffers.h" + +#define NV_NOTIFY_TIME_0 0x00000000 +#define NV_NOTIFY_TIME_1 0x00000004 +#define NV_NOTIFY_RETURN_VALUE 0x00000008 +#define NV_NOTIFY_STATE 0x0000000C +#define NV_NOTIFY_STATE_STATUS_MASK 0xFF000000 +#define NV_NOTIFY_STATE_STATUS_SHIFT 24 +#define NV_NOTIFY_STATE_STATUS_COMPLETED 0x00 +#define NV_NOTIFY_STATE_STATUS_IN_PROCESS 0x01 +#define NV_NOTIFY_STATE_ERROR_CODE_MASK 0x0000FFFF +#define NV_NOTIFY_STATE_ERROR_CODE_SHIFT 0 + +/* Methods that (hopefully) all objects have */ +#define NV_NOP 0x00000100 +#define NV_NOTIFY 0x00000104 +#define NV_NOTIFY_STYLE_WRITE_ONLY 0 + +typedef struct nouveau_notifier_t { + GLuint handle; + nouveau_mem *mem; +} nouveau_notifier; + +extern nouveau_notifier *nouveau_notifier_new(GLcontext *, GLuint handle); +extern void nouveau_notifier_destroy(GLcontext *, nouveau_notifier *); +extern void nouveau_notifier_reset(nouveau_notifier *); +extern GLboolean nouveau_notifier_wait_status(nouveau_notifier *r, + GLuint status, GLuint timeout); +extern void nouveau_notifier_wait_nop(GLcontext *ctx, + nouveau_notifier *, GLuint subc); + +extern void nouveauSyncInitFuncs(GLcontext *ctx); +#endif -- cgit v1.2.3 From 0b2b2de6cff23bc224f5471cc8d0812661a0d363 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 26 Dec 2006 21:10:38 +1100 Subject: nouveau: Wait on notifier to check for completion of previous commands. We can't wait on NV_PGRAPH_STATUS. We don't have the regs mapped, and there's no guarantee that we'll catch PGRAPH idle when multiple channels are active. --- src/mesa/drivers/dri/nouveau/nouveau_context.c | 3 +- src/mesa/drivers/dri/nouveau/nouveau_fifo.c | 39 +++++--------------------- src/mesa/drivers/dri/nouveau/nouveau_sync.c | 14 ++++++++- src/mesa/drivers/dri/nouveau/nouveau_sync.h | 2 +- 4 files changed, 23 insertions(+), 35 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 7aca31d0d3..d68f4e77e7 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -222,7 +222,8 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, break; } - nouveauSyncInitFuncs(ctx); + if (!nouveauSyncInitFuncs(ctx)) + return GL_FALSE; nmesa->hw_func.InitCard(nmesa); nouveauInitState(ctx); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c index 5c2b2c7552..7af9f1e3c2 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c @@ -35,6 +35,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_msg.h" #include "nouveau_fifo.h" #include "nouveau_lock.h" +#include "nouveau_object.h" +#include "nouveau_sync.h" #define RING_SKIPS 8 @@ -68,45 +70,18 @@ void WAIT_RING(nouveauContextPtr nmesa,u_int32_t size) } /* - * Wait for the card to be idle + * Wait for the channel to be idle */ void nouveauWaitForIdleLocked(nouveauContextPtr nmesa) { - int i,status; - + /* Wait for FIFO idle */ FIRE_RING(); while(RING_AHEAD()>0); - /* We can't wait on PGRAPH going idle.. - * 1) We don't have the regs mapped - * 2) PGRAPH may not go idle with multiple channels active - * Look into replacing this with a NOTIFY/NOP + wait notifier sequence. + /* Wait on notifier to indicate all commands in the channel have + * been completed. */ -#if 0 - 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 NV_44: - case NV_50: - default: - status=NV_READ(NV04_STATUS); - break; - } - if (status) - return; - DO_USLEEP(1); - } -#endif + nouveau_notifier_wait_nop(nmesa->glCtx, nmesa->syncNotifier, NvSub3D); } void nouveauWaitForIdle(nouveauContextPtr nmesa) diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.c b/src/mesa/drivers/dri/nouveau/nouveau_sync.c index 698f778c4b..5c1c030913 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.c @@ -106,10 +106,22 @@ nouveau_notifier_wait_nop(GLcontext *ctx, nouveau_notifier *notifier, if (ret) MESSAGE("wait on notifier failed\n"); } -void nouveauSyncInitFuncs(GLcontext *ctx) +GLboolean nouveauSyncInitFuncs(GLcontext *ctx) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); nmesa->syncNotifier = nouveau_notifier_new(ctx, NvSyncNotify); + if (!nmesa->syncNotifier) { + MESSAGE("Failed to create channel sync notifier\n"); + return GL_FALSE; + } + + /* 0x180 is SET_DMA_NOTIFY, should be correct for all supported 3D + * object classes + */ + BEGIN_RING_CACHE(NvSub3D, 0x180, 1); + OUT_RING_CACHE (NvSyncNotify); + + return GL_TRUE; } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.h b/src/mesa/drivers/dri/nouveau/nouveau_sync.h index b20c2565ca..d9e3d4b80c 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.h @@ -32,5 +32,5 @@ extern GLboolean nouveau_notifier_wait_status(nouveau_notifier *r, extern void nouveau_notifier_wait_nop(GLcontext *ctx, nouveau_notifier *, GLuint subc); -extern void nouveauSyncInitFuncs(GLcontext *ctx); +extern GLboolean nouveauSyncInitFuncs(GLcontext *ctx); #endif -- cgit v1.2.3 From 3fcb7d388d71c6ab147769d35feab29b7f511521 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 26 Dec 2006 21:33:58 +1100 Subject: nouveau: Make the notifier stuff actually work.. --- src/mesa/drivers/dri/nouveau/nouveau_sync.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.c b/src/mesa/drivers/dri/nouveau/nouveau_sync.c index 5c1c030913..e27101d868 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.c @@ -18,7 +18,10 @@ nouveau_notifier_new(GLcontext *ctx, GLuint handle) if (!notifier) return NULL; - notifier->mem = nouveau_mem_alloc(ctx, NOUVEAU_MEM_FB, 32, 0); + notifier->mem = nouveau_mem_alloc(ctx, + NOUVEAU_MEM_FB | NOUVEAU_MEM_MAPPED, + 32, + 0); if (!notifier->mem) { FREE(notifier); return NULL; @@ -65,14 +68,14 @@ nouveau_notifier_wait_status(nouveau_notifier *notifier, GLuint status, unsigned int time = 0; while (time <= timeout) { - if (n[NV_NOTIFY_STATE] & NV_NOTIFY_STATE_ERROR_CODE_MASK) { + if (n[NV_NOTIFY_STATE/4] & NV_NOTIFY_STATE_ERROR_CODE_MASK) { MESSAGE("Notifier returned error: 0x%04x\n", n[NV_NOTIFY_STATE] & NV_NOTIFY_STATE_ERROR_CODE_MASK); return GL_FALSE; } - if (((n[NV_NOTIFY_STATE] & NV_NOTIFY_STATE_STATUS_MASK) >> + if (((n[NV_NOTIFY_STATE/4] & NV_NOTIFY_STATE_STATUS_MASK) >> NV_NOTIFY_STATE_STATUS_SHIFT) == status) return GL_TRUE; @@ -99,11 +102,12 @@ nouveau_notifier_wait_nop(GLcontext *ctx, nouveau_notifier *notifier, OUT_RING (NV_NOTIFY_STYLE_WRITE_ONLY); BEGIN_RING_SIZE(subc, NV_NOP, 1); OUT_RING (0); + FIRE_RING(); ret = nouveau_notifier_wait_status(notifier, NV_NOTIFY_STATE_STATUS_COMPLETED, 0 /* no timeout */); - if (ret) MESSAGE("wait on notifier failed\n"); + if (ret == GL_FALSE) MESSAGE("wait on notifier failed\n"); } GLboolean nouveauSyncInitFuncs(GLcontext *ctx) -- cgit v1.2.3 From 257e3d1d5953a94892a31d71bd2e200204d7968f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 26 Dec 2006 22:03:12 +1100 Subject: nouveau: Make use of NOUVEAU_DEBUG for shader disasm --- src/mesa/drivers/dri/nouveau/nouveau_context.c | 1 + src/mesa/drivers/dri/nouveau/nouveau_context.h | 5 ++++ src/mesa/drivers/dri/nouveau/nouveau_shader_2.c | 33 ++++++++++++++----------- 3 files changed, 24 insertions(+), 15 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index d68f4e77e7..3718900b62 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -63,6 +63,7 @@ int NOUVEAU_DEBUG = 0; static const struct dri_debug_control debug_control[] = { + { "shaders", DEBUG_SHADERS }, { NULL, 0 } }; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index f54ac9a7c8..0efbcce129 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -213,5 +213,10 @@ extern void nouveauSwapBuffers(__DRIdrawablePrivate *dPriv); extern void nouveauCopySubBuffer(__DRIdrawablePrivate *dPriv, int x, int y, int w, int h); +/* Debugging utils: */ +extern int NOUVEAU_DEBUG; + +#define DEBUG_SHADERS 0x00000001 + #endif /* __NOUVEAU_CONTEXT_H__ */ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c index b39f4668b9..2177413b66 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c @@ -36,6 +36,7 @@ #include "program.h" +#include "nouveau_context.h" #include "nouveau_shader.h" struct pass2_rec { @@ -219,21 +220,23 @@ nouveau_shader_pass2(nvsPtr nvs) nvs->translated = 1; nvs->on_hardware = 0; -#if 1 - fflush(stdout); fflush(stderr); - fprintf(stderr, "----------------MESA PROGRAM\n"); - fflush(stdout); fflush(stderr); - _mesa_print_program(&nvs->mesa.vp.Base); - fflush(stdout); fflush(stderr); - fprintf(stderr, "^^^^^^^^^^^^^^^^MESA PROGRAM\n"); - fflush(stdout); fflush(stderr); - fprintf(stderr, "----------------NV40 PROGRAM\n"); - fflush(stdout); fflush(stderr); - nvsDisasmHWShader(nvs); - fflush(stdout); fflush(stderr); - fprintf(stderr, "^^^^^^^^^^^^^^^^NV40 PROGRAM\n"); - fflush(stdout); fflush(stderr); -#endif + if (NOUVEAU_DEBUG & DEBUG_SHADERS) { + fflush(stdout); fflush(stderr); + fprintf(stderr, "----------------MESA PROGRAM target=%s, id=0x%x\n", + _mesa_lookup_enum_by_nr(nvs->mesa.vp.Base.Target), + nvs->mesa.vp.Base.Id); + fflush(stdout); fflush(stderr); + _mesa_print_program(&nvs->mesa.vp.Base); + fflush(stdout); fflush(stderr); + fprintf(stderr, "^^^^^^^^^^^^^^^^MESA PROGRAM\n"); + fflush(stdout); fflush(stderr); + fprintf(stderr, "----------------NV PROGRAM\n"); + fflush(stdout); fflush(stderr); + nvsDisasmHWShader(nvs); + fflush(stdout); fflush(stderr); + fprintf(stderr, "^^^^^^^^^^^^^^^^NV PROGRAM\n"); + fflush(stdout); fflush(stderr); + } return GL_TRUE; } -- cgit v1.2.3 From 2dccca57e4325e77d7b2f0a08835eeccc11892cb Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Tue, 26 Dec 2006 18:39:21 +0100 Subject: Deleted unused file which likely have be reintroduced during git move. This file was deleted longtime ago, guess that git migration created it again. --- src/mesa/drivers/dri/r300/r300_fragprog_swz.c | 1328 ------------------------- 1 file changed, 1328 deletions(-) delete mode 100644 src/mesa/drivers/dri/r300/r300_fragprog_swz.c (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_swz.c b/src/mesa/drivers/dri/r300/r300_fragprog_swz.c deleted file mode 100644 index b29331d7bd..0000000000 --- a/src/mesa/drivers/dri/r300/r300_fragprog_swz.c +++ /dev/null @@ -1,1328 +0,0 @@ -/* - * Copyright (C) 2005 Jerome Glisse. 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, 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. - * - */ -#include "r300_fragprog.h" -#include "r300_reg.h" - - -#define I0_000 ( (R300_FPI0_OUTC_MAD) | \ - (R300_FPI0_ARGC_ZERO) | \ - (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG1C_SHIFT) | \ - (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT) ) -#define I0_111 ( (R300_FPI0_OUTC_MAD) | \ - (R300_FPI0_ARGC_ZERO) | \ - (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG1C_SHIFT) | \ - (R300_FPI0_ARGC_ONE << R300_FPI0_ARG2C_SHIFT) ) -#define I0_XXX ( (R300_FPI0_OUTC_MAD) | \ - (R300_FPI0_ARGC_SRC0C_XXX) | \ - (R300_FPI0_ARGC_ONE << R300_FPI0_ARG1C_SHIFT) | \ - (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT) ) -#define I0_YYY ( (R300_FPI0_OUTC_MAD) | \ - (R300_FPI0_ARGC_SRC0C_YYY) | \ - (R300_FPI0_ARGC_ONE << R300_FPI0_ARG1C_SHIFT) | \ - (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT) ) -#define I0_ZZZ ( (R300_FPI0_OUTC_MAD) | \ - (R300_FPI0_ARGC_SRC0C_ZZZ) | \ - (R300_FPI0_ARGC_ONE << R300_FPI0_ARG1C_SHIFT) | \ - (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT) ) -#define I0_XYZ ( (R300_FPI0_OUTC_MAD) | \ - (R300_FPI0_ARGC_SRC0C_XYZ) | \ - (R300_FPI0_ARGC_ONE << R300_FPI0_ARG1C_SHIFT) | \ - (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT) ) -#define I0_YZX ( (R300_FPI0_OUTC_MAD) | \ - (R300_FPI0_ARGC_SRC0C_YZX) | \ - (R300_FPI0_ARGC_ONE << R300_FPI0_ARG1C_SHIFT) | \ - (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT) ) -#define I0_ZXY ( (R300_FPI0_OUTC_MAD) | \ - (R300_FPI0_ARGC_SRC0C_ZXY) | \ - (R300_FPI0_ARGC_ONE << R300_FPI0_ARG1C_SHIFT) | \ - (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT) ) -#define I0_WZY ( (R300_FPI0_OUTC_MAD) | \ - (R300_FPI0_ARGC_SRC0CA_WZY) | \ - (R300_FPI0_ARGC_ONE << R300_FPI0_ARG1C_SHIFT) | \ - (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT) ) -#define I0_WWW ( (R300_FPI0_OUTC_MAD) | \ - (R300_FPI0_ARGC_SRC0A) | \ - (R300_FPI0_ARGC_ONE << R300_FPI0_ARG1C_SHIFT) | \ - (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT) ) - -#define IEMPTY 0 - -#define I1_XYZ ( R300_FPI1_SRC1C_CONST | \ - R300_FPI1_SRC2C_CONST | \ - R300_FPI1_DSTC_REG_X | \ - R300_FPI1_DSTC_REG_Y | \ - R300_FPI1_DSTC_REG_Z ) -#define I1_XY_ ( R300_FPI1_SRC1C_CONST | \ - R300_FPI1_SRC2C_CONST | \ - R300_FPI1_DSTC_REG_X | \ - R300_FPI1_DSTC_REG_Y ) -#define I1_X_Z ( R300_FPI1_SRC1C_CONST | \ - R300_FPI1_SRC2C_CONST | \ - R300_FPI1_DSTC_REG_X | \ - R300_FPI1_DSTC_REG_Z ) -#define I1__YZ ( R300_FPI1_SRC1C_CONST | \ - R300_FPI1_SRC2C_CONST | \ - R300_FPI1_DSTC_REG_Y | \ - R300_FPI1_DSTC_REG_Z ) -#define I1_X__ ( R300_FPI1_SRC1C_CONST | \ - R300_FPI1_SRC2C_CONST | \ - R300_FPI1_DSTC_REG_X ) -#define I1__Y_ ( R300_FPI1_SRC1C_CONST | \ - R300_FPI1_SRC2C_CONST | \ - R300_FPI1_DSTC_REG_Y ) -#define I1___Z ( R300_FPI1_SRC1C_CONST | \ - R300_FPI1_SRC2C_CONST | \ - R300_FPI1_DSTC_REG_Z ) - -#define SEMPTY {0,{0,0,0,0},{0,0,0,0,0,0,0,0}} - -struct r300_fragment_program_swizzle r300_swizzle [512] = { - /* XXX */ - {1,{0,0,0,0},{ I0_XXX, I1_XYZ, - 0, 0, 0, 0, 0, 0 } }, - /* YXX */ - {2,{0,0,0,0},{ I0_YZX, I1_X_Z, - I0_XXX, I1__Y_, - 0,0, - 0,0 } }, - /* ZXX */ - {2,{0,0,0,0},{ I0_ZZZ, I1_X__, - I0_XXX, I1__YZ, - 0,0, - 0,0 } }, - /* WXX */ - {2,{0,0,0,0},{ I0_WZY, I1_X__, - I0_XXX, I1__YZ, - 0,0, - 0,0} }, - /* 0XX */ - {2,{0,2,0,0},{ I0_XXX, I1__YZ, - I0_000, I1_X__, - 0,0, - 0,0 } }, - /* 1XX */ - {2,{0,2,0,0},{ I0_XXX, I1__YZ, - I0_111, I1_X__, - 0,0,0,0}}, - SEMPTY,SEMPTY, - /* XYX */ - {2,{0,0,0,0},{ I0_YYY, I1__Y_, - I0_XXX, I1_X_Z, - 0,0,0,0}}, - /* YYX */ - {2,{0,0,0,0},{ I0_YYY, I1_XY_, - I0_XXX, I1___Z, - 0,0,0,0}}, - /* ZYX */ - {3,{0,0,0,0},{ I0_ZZZ, I1_X__, - I0_YYY, I1__Y_, - I0_XXX, I1___Z, - 0,0}}, - /* WYX */ - {3,{0,0,0,0},{ I0_WZY, I1_X__, - I0_YYY, I1__Y_, - I0_XXX, I1___Z, - 0,0}}, - /* 0YX */ - {3,{0,0,2,0},{ I0_YYY, I1__Y_, - I0_XXX, I1___Z, - I0_000, I1_X__, - 0,0}}, - /* 1YX */ - {3,{0,0,2,0},{ I0_YYY, I1__Y_, - I0_XXX, I1___Z, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* XZX */ - {2,{0,0,0,0},{ I0_YZX, I1__YZ, - I0_XXX, I1_X__, - 0,0,0,0}}, - /* YZX */ - {1,{0,0,0,0},{ I0_YZX, I1_XYZ, - 0, 0, 0, 0, 0, 0 } }, - /* ZZX */ - {2,{0,0,0,0},{ I0_YZX, I1__YZ, - I0_ZZZ, I1_X__,0,0,0,0}}, - /* WZX */ - {2,{0,0,0,0},{ I0_WZY, I1_XY_, - I0_XXX, I1___Z,0,0,0,0}}, - /* 0ZX */ - {2,{0,2,0,0},{ I0_YZX, I1__YZ, - I0_000, I1_X__, - 0,0,0,0}}, - /* 1ZX */ - {2,{0,2,0,0},{ I0_YZX, I1__YZ, - I0_111, I1_X__, - 0,0,0,0}}, - SEMPTY,SEMPTY, - /* XWX */ - {2,{0,0,0,0},{ I0_WWW, I1__Y_, - I0_XXX, I1_X_Z, - 0,0,0,0}}, - /* YWX */ - {2,{0,0,0,0},{ I0_WWW, I1__Y_, - I0_YZX, I1_X_Z, - 0,0,0,0}}, - /* ZWX */ - {3,{0,0,0,0},{ I0_WWW, I1__Y_, - I0_ZZZ, I1_X__, - I0_XXX, I1___Z, - 0,0}}, - /* WWX */ - {2,{0,0,0,0},{ I0_WWW, I1_XY_, - I0_YZX, I1___Z, - 0,0,0,0}}, - /* 0WX */ - {3,{0,0,2,0},{ I0_WWW, I1__Y_, - I0_XXX, I1___Z, - I0_000, I1_X__, - 0,0}}, - /* 1WX */ - {3,{0,0,2,0},{ I0_WWW, I1__Y_, - I0_XXX, I1___Z, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* X0X */ - {2,{0,2,0,0},{ I0_XXX, I1_X_Z, - I0_000, I1__Y_, - 0,0,0,0}}, - /* Y0X */ - {2,{0,2,0,0},{ I0_YZX, I1_X_Z, - I0_000, I1__Y_, - 0,0,0,0}}, - /* Z0X */ - {3,{0,2,0,0},{ I0_XXX, I1___Z, - I0_000, I1__Y_, - I0_ZZZ, I1_X__, - 0,0}}, - /* W0X */ - {3,{0,0,2,0},{ I0_WZY, I1_XYZ, - I0_XXX, I1___Z, - I0_000, I1__Y_, - 0,0}}, - /* 00X */ - {2,{0,2,0,0},{ I0_XXX, I1___Z, - I0_000, I1_XY_, - 0,0,0,0}}, - /* 10X */ - {3,{0,2,0,0},{ I0_XXX, I1___Z, - I0_000, I1__Y_, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* X1X */ - {2,{0,2,0,0},{ I0_XXX, I1_X_Z, - I0_111, I1__Y_, - 0,0,0,0}}, - /* Y1X */ - {2,{0,2,0,0},{ I0_YZX, I1_X_Z, - I0_111, I1__Y_, - 0,0,0,0}}, - /* Z1X */ - {3,{0,2,0,0},{ I0_XXX, I1___Z, - I0_111, I1__Y_, - I0_ZZZ, I1_X__, - 0,0}}, - /* W1X */ - {3,{0,0,2,0},{ I0_WZY, I1_XYZ, - I0_XXX, I1___Z, - I0_111, I1__Y_, - 0,0}}, - /* 01X */ - {3,{0,2,0,0},{ I0_XXX, I1___Z, - I0_111, I1__Y_, - I0_000, I1_X__, - 0,0}}, - /* 11X */ - {2,{0,2,0,0},{ I0_XXX, I1___Z, - I0_111, I1_XY_, - 0,0,0,0}}, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - /* XXY */ - {2,{0,0,0,0},{ I0_YYY, I1___Z, - I0_XXX, I1_XY_, - 0,0,0,0}}, - /* YXY */ - {2,{0,0,0,0},{ I0_YYY, I1_X_Z, - I0_XXX, I1__Y_, - 0,0,0,0}}, - /* ZXY */ - {1,{0,0,0,0},{ I0_ZXY, I1_XYZ, - 0, 0, 0, 0, 0, 0 } }, - /* WXY */ - {2,{0,0,0,0},{ I0_WZY, I1_X__, - I0_ZXY, I1__YZ, - 0,0,0,0}}, - /* 0XY */ - {2,{0,0,0,0},{ I0_ZXY, I1__YZ, - I0_000, I1_X__, - 0,0,0,0}}, - /* 1XY */ - {2,{0,0,0,0},{ I0_ZXY, I1__YZ, - I0_111, I1_X__, - 0,0,0,0}}, - SEMPTY,SEMPTY, - /* XYY */ - {2,{0,0,0,0},{ I0_YYY, I1__YZ, - I0_XXX, I1_X__, - 0,0,0,0}}, - /* YYY */ - {1,{0,0,0,0},{ I0_YYY, I1_XYZ, - 0, 0, 0, 0, 0, 0 } }, - /* ZYY */ - {2,{0,0,0,0},{ I0_YYY, I1__YZ, - I0_ZZZ, I1_X__, - 0,0,0,0}}, - /* WYY */ - {2,{0,0,0,0},{ I0_WZY, I1_XYZ, - I0_YYY, I1__YZ, - 0,0,0,0}}, - /* 0YY */ - {2,{0,0,0,0},{ I0_YYY, I1__YZ, - I0_000, I1_X__, - 0,0,0,0}}, - /* 1YY */ - {2,{0,0,0,0},{ I0_YYY, I1__YZ, - I0_111, I1_X__, - 0,0,0,0}}, - SEMPTY,SEMPTY, - /* XZY */ - {2,{0,0,0,0},{ I0_WZY, I1__YZ, - I0_XXX, I1_X__, - 0,0,0,0}}, - /* YZY */ - {2,{0,0,0,0},{ I0_WZY, I1__YZ, - I0_YYY, I1_X__, - 0,0,0,0}}, - /* ZZY */ - {2,{0,0,0,0},{ I0_WZY, I1__YZ, - I0_ZZZ, I1_X__, - 0,0,0,0}}, - /* WZY */ - {1,{0,0,0,0},{ I0_WZY, I1_XYZ, - 0, 0, 0, 0, 0, 0 } }, - /* 0ZY */ - {2,{0,0,0,0},{ I0_WZY, I1__YZ, - I0_000, I1_X__, - 0,0,0,0}}, - /* 1ZY */ - {2,{0,0,0,0},{ I0_WZY, I1__YZ, - I0_111, I1_X__, - 0,0,0,0}}, - SEMPTY,SEMPTY, - /* XWY */ - {3,{0,0,0,0},{ I0_WWW, I1__Y_, - I0_XXX, I1_X__, - I0_YYY, I1___Z, - 0,0}}, - /* YWY */ - {2,{0,0,0,0},{ I0_WWW, I1__Y_, - I0_YYY, I1_X_Z, - 0,0,0,0}}, - /* ZWY */ - {2,{0,0,0,0},{ I0_WWW, I1__Y_, - I0_ZXY, I1_X_Z, - 0,0,0,0}}, - /* WWY */ - {2,{0,0,0,0},{ I0_WWW, I1_XY_, - I0_ZXY, I1___Z, - 0,0,0,0}}, - /* 0WY */ - {3,{0,0,2,0},{ I0_WWW, I1__Y_, - I0_ZXY, I1___Z, - I0_000, I1_X__, - 0,0}}, - /* 1WY */ - {3,{0,0,0,0},{ I0_WWW, I1__Y_, - I0_ZXY, I1___Z, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* X0Y */ - {3,{0,2,0,0},{ I0_XXX, I1_X__, - I0_000, I1__Y_, - I0_YYY, I1___Z, - 0,0}}, - /* Y0Y */ - {2,{0,2,0,0},{ I0_YYY, I1_X_Z, - I0_000, I1__Y_, - 0,0,0,0}}, - /* Z0Y */ - {2,{0,2,0,0},{ I0_ZXY, I1_X_Z, - I0_000, I1__Y_, - 0,0,0,0}}, - /* W0Y */ - {2,{0,2,0,0},{ I0_WZY, I1_X_Z, - I0_000, I1__Y_, - 0,0,0,0}}, - /* 00Y */ - {2,{0,2,0,0},{ I0_YYY, I1___Z, - I0_000, I1_XY_, - 0,0,0,0}}, - /* 10Y */ - {3,{0,2,0,0},{ I0_YYY, I1___Z, - I0_000, I1__Y_, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* X1Y */ - {3,{0,2,0,0},{ I0_XXX, I1_X__, - I0_111, I1__Y_, - I0_YYY, I1___Z, - 0,0}}, - /* Y1Y */ - {2,{0,2,0,0},{ I0_YYY, I1_X_Z, - I0_111, I1__Y_, - 0,0,0,0}}, - /* Z1Y */ - {2,{0,2,0,0},{ I0_ZXY, I1_X_Z, - I0_111, I1__Y_, - 0,0,0,0}}, - /* W1Y */ - {3,{0,2,0,0},{ I0_WZY, I1_X_Z, - I0_111, I1__Y_, - 0,0,0,0}}, - /* 01Y */ - {3,{0,2,0,0},{ I0_YYY, I1___Z, - I0_111, I1__Y_, - I0_000, I1_X__, - 0,0}}, - /* 11Y */ - {2,{0,2,0,0},{ I0_YYY, I1___Z, - I0_111, I1_XY_, - 0,0,0,0}}, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - /* XXZ */ - {2,{0,0,0,0},{ I0_XXX, I1_XY_, - I0_ZZZ, I1___Z, - 0,0,0,0}}, - /* YXZ */ - {3,{0,0,0,0},{ I0_XXX, I1__Y_, - I0_YYY, I1_X__, - I0_ZZZ, I1___Z, - 0,0}}, - /* ZXZ */ - {2,{0,0,0,0},{ I0_XXX, I1__Y_, - I0_ZZZ, I1_X_Z, - 0,0,0,0}}, - /* WXZ */ - {3,{0,0,0,0},{ I0_WZY, I1_XYZ, - I0_XXX, I1__Y_, - I0_ZZZ, I1___Z, - 0,0}}, - /* 0XZ */ - {3,{0,0,2,0},{ I0_XXX, I1__Y_, - I0_ZZZ, I1___Z, - I0_000, I1_X__, - 0,0}}, - /* 1XZ */ - {3,{0,0,2,0},{ I0_XXX, I1__Y_, - I0_ZZZ, I1___Z, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* XYZ */ - {1,{0,0,0,0},{ I0_XYZ, I1_XYZ, - 0, 0, 0, 0, 0, 0 } }, - /* YYZ */ - {2,{0,0,0,0},{ I0_ZZZ, I1___Z, - I0_YYY, I1_XY_, - 0,0,0,0}}, - /* ZYZ */ - {2,{0,0,0,0},{ I0_ZZZ, I1_X_Z, - I0_YYY, I1__Y_, - 0,0,0,0}}, - /* WYZ */ - {2,{0,0,0,0},{ I0_WZY, I1_XYZ, - I0_XYZ, I1__YZ, - 0,0,0,0}}, - /* 0YZ */ - {2,{0,2,0,0},{ I0_XYZ, I1__YZ, - I0_000, I1_X__, - 0,0,0,0}}, - /* 1YZ */ - {2,{0,2,0,0},{ I0_XYZ, I1__YZ, - I0_111, I1_X__, - 0,0,0,0}}, - SEMPTY,SEMPTY, - /* XZZ */ - {2,{0,0,0,0},{ I0_ZZZ, I1__YZ, - I0_XXX, I1_X__, - 0,0,0,0}}, - /* YZZ */ - {2,{0,0,0,0},{ I0_ZZZ, I1__YZ, - I0_YYY, I1_X__, - 0,0,0,0}}, - /* ZZZ */ - {1,{0,0,0,0},{ I0_ZZZ, I1_XYZ, - 0, 0, 0, 0, 0, 0 } }, - /* WZZ */ - {2,{0,0,0,0},{ I0_WZY, I1_XYZ, - I0_ZZZ, I1__YZ, - 0,0,0,0}}, - /* 0ZZ */ - {2,{0,2,0,0},{ I0_ZZZ, I1__YZ, - I0_000, I1_X__, - 0,0,0,0}}, - /* 1ZZ */ - {2,{0,2,0,0},{ I0_ZZZ, I1__YZ, - I0_111, I1_X__, - 0,0,0,0}}, - SEMPTY,SEMPTY, - /* XWZ */ - {2,{0,0,0,0},{ I0_WWW, I1__Y_, - I0_XYZ, I1_X_Z, - 0,0,0,0}}, - /* YWZ */ - {3,{0,0,0,0},{ I0_WWW, I1__Y_, - I0_YYY, I1_X__, - I0_XYZ, I1___Z, - 0,0}}, - /* ZWZ */ - {2,{0,0,0,0},{ I0_WWW, I1__Y_, - I0_ZZZ, I1_X_Z, - 0,0,0,0}}, - /* WWZ */ - {2,{0,0,0,0},{ I0_WWW, I1_XY_, - I0_XYZ, I1___Z, - 0,0,0,0}}, - /* 0WZ */ - {3,{0,0,2,0},{ I0_WWW, I1__Y_, - I0_XYZ, I1___Z, - I0_000, I1_X__, - 0,0}}, - /* 1WZ */ - {3,{0,0,2,0},{ I0_WWW, I1__Y_, - I0_XYZ, I1___Z, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* X0Z */ - {2,{0,2,0,0},{ I0_XYZ, I1_X_Z, - I0_000, I1__Y_, - 0,0,0,0}}, - /* Y0Z */ - {3,{0,2,0,0},{ I0_ZZZ, I1___Z, - I0_000, I1__Y_, - I0_YYY, I1_X__, - 0,0}}, - /* Z0Z */ - {2,{0,2,0,0},{ I0_ZZZ, I1_X_Z, - I0_000, I1__Y_, - 0,0,0,0}}, - /* W0Z */ - {3,{0,0,2,0},{ I0_WZY, I1_X_Z, - I0_ZZZ, I1___Z, - I0_000, I1__Y_, - 0,0}}, - /* 00Z */ - {2,{0,2,0,0},{ I0_ZZZ, I1___Z, - I0_000, I1_XY_, - 0,0,0,0}}, - /* 10Z */ - {3,{0,2,2,0},{ I0_ZZZ, I1___Z, - I0_000, I1__Y_, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* X1Z */ - {2,{0,2,0,0},{ I0_XYZ, I1_X_Z, - I0_111, I1__Y_, - 0,0,0,0}}, - /* Y1Z */ - {3,{0,2,0,0},{ I0_ZZZ, I1___Z, - I0_111, I1__Y_, - I0_YYY, I1_X__, - 0,0}}, - /* Z1Z */ - {2,{0,2,0,0},{ I0_ZZZ, I1_X_Z, - I0_111, I1__Y_, - 0,0,0,0}}, - /* W1Z */ - {3,{0,0,2,0},{ I0_WZY, I1_XYZ, - I0_ZZZ, I1___Z, - I0_111, I1__Y_, - 0,0}}, - /* 01Z */ - {3,{0,2,2,0},{ I0_ZZZ, I1___Z, - I0_111, I1__Y_, - I0_000, I1_X__, - 0,0}}, - /* 11Z */ - {2,{0,2,0,0},{ I0_ZZZ, I1___Z, - I0_111, I1_XY_, - 0,0,0,0}}, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - /* XXW */ - {2,{0,0,0,0},{ I0_WWW, I1___Z, - I0_XXX, I1_XY_, - 0,0,0,0}}, - /* YXW */ - {3,{0,0,0,0},{ I0_WWW, I1___Z, - I0_XXX, I1__Y_, - I0_YYY, I1_X__, - 0,0}}, - /* ZXW */ - {2,{0,0,0,0},{ I0_WWW, I1___Z, - I0_ZXY, I1_XY_, - 0,0,0,0}}, - /* WXW */ - {2,{0,0,0,0},{ I0_WWW, I1_X_Z, - I0_XXX, I1__Y_, - 0,0,0,0}}, - /* 0XW */ - {3,{0,0,2,0},{ I0_WWW, I1___Z, - I0_XXX, I1__Y_, - I0_000, I1_X__, - 0,0}}, - /* 1XW */ - {3,{0,0,2,0},{ I0_WWW, I1___Z, - I0_XXX, I1__Y_, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* XYW */ - {2,{0,0,0,0},{ I0_WWW, I1___Z, - I0_XYZ, I1_XY_, - 0,0,0,0}}, - /* YYW */ - {2,{0,0,0,0},{ I0_WWW, I1___Z, - I0_YYY, I1_XY_, - 0,0}}, - /* ZYW */ - {3,{0,0,0,0},{ I0_WWW, I1___Z, - I0_XYZ, I1__Y_, - I0_ZZZ, I1_X__, - 0,0}}, - /* WYW */ - {2,{0,0,0,0},{ I0_WWW, I1_X_Z, - I0_YYY, I1__Y_, - 0,0,0,0}}, - /* 0YW */ - {3,{0,0,2,0},{ I0_WWW, I1___Z, - I0_YYY, I1__Y_, - I0_000, I1_X__, - 0,0}}, - /* 1YW */ - {3,{0,0,2,0},{ I0_WWW, I1___Z, - I0_YYY, I1__Y_, - I0_111, I1_X__, - 0,0}}, - - SEMPTY,SEMPTY, - /* XZW */ - {3,{0,0,0,0},{ I0_WWW, I1___Z, - I0_XYZ, I1_X__, - I0_ZZZ, I1__Y_, - 0,0}}, - /* YZW */ - {2,{0,0,0,0},{ I0_WWW, I1___Z, - I0_YZX, I1_XY_, - 0,0,0,0}}, - /* ZZW */ - {2,{0,0,0,0},{ I0_WWW, I1___Z, - I0_ZZZ, I1_XY_, - 0,0,0,0}}, - /* WZW */ - {2,{0,0,0,0},{ I0_WWW, I1_X_Z, - I0_ZZZ, I1__Y_, - 0,0,0,0}}, - /* 0ZW */ - {3,{0,0,2,0},{ I0_WWW, I1___Z, - I0_ZZZ, I1__Y_, - I0_000, I1_X__, - 0,0}}, - /* 1ZW */ - {3,{0,0,2,0},{ I0_WWW, I1___Z, - I0_ZZZ, I1__Y_, - I0_111, I1_X__, - 0,0}}, - - SEMPTY,SEMPTY, - /* XWW */ - {2,{0,0,0,0},{ I0_WWW, I1__YZ, - I0_XYZ, I1_X__, - 0,0,0,0}}, - /* YWW */ - {2,{0,0,0,0},{ I0_WWW, I1__YZ, - I0_YYY, I1_X__, - 0,0,0,0}}, - /* ZWW */ - {2,{0,0,0,0},{ I0_WWW, I1__YZ, - I0_ZZZ, I1_X__, - 0,0,0,0}}, - /* WWW */ - {1,{0,0,0,0},{ I0_WWW, I1_XYZ, - 0,0,0,0,0,0}}, - /* 0WW */ - {2,{0,2,0,0},{ I0_WWW, I1__YZ, - I0_000, I1_X__, - 0,0,0,0}}, - /* 1WW */ - {2,{0,2,0,0},{ I0_WWW, I1__YZ, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* X0W */ - {3,{0,0,2,0},{ I0_WWW, I1___Z, - I0_XYZ, I1_X__, - I0_000, I1__Y_, - 0,0}}, - /* Y0W */ - {3,{0,0,2,0},{ I0_WWW, I1___Z, - I0_YYY, I1_X__, - I0_000, I1__Y_, - 0,0}}, - /* Z0W */ - {3,{0,0,2,0},{ I0_WWW, I1___Z, - I0_ZZZ, I1_X__, - I0_000, I1__Y_, - 0,0}}, - /* W0W */ - {2,{0,2,0,0},{ I0_WWW, I1_X_Z, - I0_000, I1__Y_, - 0,0,0,0}}, - /* 00W */ - {2,{0,2,0,0},{ I0_WWW, I1___Z, - I0_000, I1_XY_, - 0,0,0,0}}, - /* 10W */ - {3,{0,2,2,0},{ I0_WWW, I1___Z, - I0_111, I1_X__, - I0_000, I1__Y_, - 0,0}}, - SEMPTY,SEMPTY, - /* X1W */ - {3,{0,0,2,0},{ I0_WWW, I1___Z, - I0_XYZ, I1_X__, - I0_111, I1__Y_, - 0,0}}, - /* Y1W */ - {3,{0,0,2,0},{ I0_WWW, I1___Z, - I0_YYY, I1_X__, - I0_111, I1__Y_, - 0,0}}, - /* Z1W */ - {3,{0,0,2,0},{ I0_WWW, I1___Z, - I0_ZZZ, I1_X__, - I0_111, I1__Y_, - 0,0}}, - /* W1W */ - {2,{0,2,0,0},{ I0_WWW, I1_XYZ, - I0_111, I1__Y_, - 0,0,0,0}}, - /* 01W */ - {3,{0,2,2,0},{ I0_WWW, I1___Z, - I0_000, I1_X__, - I0_111, I1__Y_, - 0,0}}, - /* 11W */ - {2,{0,2,0,0},{ I0_WWW, I1___Z, - I0_111, I1_XY_, - 0,0,0,0}}, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - /* XX0 */ - {2,{0,2,0,0},{ I0_XXX, I1_XY_, - I0_000, I1___Z, - 0,0,0,0}}, - /* YX0 */ - {3,{0,0,2,0},{ I0_YYY, I1_X__, - I0_XXX, I1__Y_, - I0_000, I1___Z, - 0,0}}, - /* ZX0 */ - {2,{0,2,0,0},{ I0_ZXY, I1_XY_, - I0_000, I1___Z, - 0,0,0,0}}, - /* WX0 */ - {3,{0,0,2,0},{ I0_WZY, I1_X__, - I0_XXX, I1__Y_, - I0_000, I1___Z, - 0,0}}, - /* 0X0 */ - {2,{0,2,0,0},{ I0_XXX, I1__Y_, - I0_000, I1_X_Z, - 0,0,0,0}}, - /* 1X0 */ - {3,{0,2,2,0},{ I0_XXX, I1__Y_, - I0_000, I1___Z, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* XY0 */ - {2,{0,2,0,0},{ I0_XYZ, I1_XY_, - I0_000, I1___Z, - 0,0,0,0}}, - /* YY0 */ - {2,{0,2,0,0},{ I0_YYY, I1_XY_, - I0_000, I1___Z, - 0,0,0,0}}, - /* ZY0 */ - {3,{0,0,2,0},{ I0_YYY, I1__Y_, - I0_ZZZ, I1_X__, - I0_000, I1___Z, - 0,0}}, - /* WY0 */ - {3,{0,0,2,0},{ I0_WZY, I1_X__, - I0_XYZ, I1__Y_, - I0_000, I1___Z, - 0,0}}, - /* 0Y0 */ - {2,{0,2,0,0},{ I0_XYZ, I1__Y_, - I0_000, I1_X_Z, - 0,0,0,0}}, - /* 1Y0 */ - {3,{0,2,2,0},{ I0_XYZ, I1__Y_, - I0_000, I1___Z, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* XZ0 */ - {3,{0,0,2,0},{ I0_ZZZ, I1__Y_, - I0_XYZ, I1_X__, - I0_000, I1___Z, - 0,0}}, - /* YZ0 */ - {2,{0,2,0,0},{ I0_YZX, I1_XY_, - I0_000, I1___Z, - 0,0,0,0}}, - /* ZZ0 */ - {2,{0,2,0,0},{ I0_ZZZ, I1_XY_, - I0_000, I1___Z, - 0,0,0,0}}, - /* WZ0 */ - {3,{0,0,2,0},{ I0_XYZ, I1_XYZ, - I0_WZY, I1_XY_, - I0_000, I1___Z, - 0,0}}, - /* 0Z0 */ - {2,{0,2,0,0},{ I0_ZZZ, I1__Y_, - I0_000, I1_X_Z, - 0,0,0,0}}, - /* 1Z0 */ - {3,{0,2,2,0},{ I0_ZZZ, I1__Y_, - I0_000, I1___Z, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* XW0 */ - {3,{0,0,2,0},{ I0_WWW, I1__Y_, - I0_XYZ, I1_X__, - I0_000, I1___Z, - 0,0}}, - /* YW0 */ - {3,{0,2,0,0},{ I0_WWW, I1__Y_, - I0_000, I1___Z, - I0_YYY, I1_X__, - 0,0}}, - /* ZW0 */ - {3,{0,2,0,0},{ I0_WWW, I1__Y_, - I0_000, I1___Z, - I0_ZZZ, I1_X__, - 0,0}}, - /* WW0 */ - {2,{0,2,0,0},{ I0_WWW, I1_XY_, - I0_000, I1___Z, - 0,0,0,0}}, - /* 0W0 */ - {2,{0,2,0,0},{ I0_WWW, I1__Y_, - I0_000, I1_X_Z, - 0,0,0,0}}, - /* 1W0 */ - {3,{0,2,2,0},{ I0_WWW, I1__Y_, - I0_000, I1___Z, - I0_111, I1_X__, - 0,0}}, - SEMPTY,SEMPTY, - /* X00 */ - {2,{0,2,0,0},{ I0_XYZ, I1_X__, - I0_000, I1__YZ, - 0,0,0,0}}, - /* Y00 */ - {2,{0,2,0,0},{ I0_YYY, I1_X__, - I0_000, I1__YZ, - 0,0,0,0}}, - /* Z00 */ - {2,{0,2,0,0},{ I0_ZZZ, I1_X__, - I0_000, I1__YZ, - 0,0,0,0}}, - /* W00 */ - {2,{2,0,0,0},{ I0_WZY, I1_X__, - I0_000, I1__YZ, - 0,0,0,0}}, - /* 000 */ - {1,{2,0,0,0},{ I0_000, I1_XYZ, - 0, 0, 0, 0, 0, 0 } }, - /* 100 */ - {2,{2,2,0,0},{ I0_000, I1__YZ, - I0_111, I1_X__, - 0,0,0,0}}, - SEMPTY,SEMPTY, - /* X10 */ - {3,{0,2,2,0},{ I0_XYZ, I1_XYZ, - I0_000, I1___Z, - I0_111, I1__Y_, - 0,0}}, - /* Y10 */ - {3,{0,2,2,0},{ I0_YYY, I1_XYZ, - I0_000, I1___Z, - I0_111, I1__Y_, - 0,0}}, - /* Z10 */ - {3,{0,2,2,0},{ I0_ZZZ, I1_XYZ, - I0_000, I1___Z, - I0_111, I1__Y_, - 0,0}}, - /* W10 */ - {3,{0,2,2,0},{ I0_WZY, I1_XYZ, - I0_000, I1___Z, - I0_111, I1__Y_, - 0,0}}, - /* 010 */ - {2,{2,2,0,0},{ I0_000, I1_X_Z, - I0_111, I1__Y_, - 0, 0, 0, 0 } }, - /* 110 */ - {2,{2,2,0,0},{ I0_000, I1___Z, - I0_111, I1_XY_, - 0,0,0,0}}, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - - - - /* XX1 */ - {2,{0,2,0,0},{ I0_XXX, I1_XY_, - I0_111, I1___Z, - 0,0,0,0}}, - /* YX1 */ - {3,{0,0,2,0},{ I0_YYY, I1_X__, - I0_XXX, I1__Y_, - I0_111, I1___Z, - 0,0}}, - /* ZX1 */ - {2,{0,2,0,0},{ I0_ZXY, I1_XY_, - I0_111, I1___Z, - 0,0,0,0}}, - /* WX1 */ - {3,{0,0,2,0},{ I0_WZY, I1_XYZ, - I0_XXX, I1__Y_, - I0_111, I1___Z, - 0,0}}, - /* 0X1 */ - {3,{0,2,2,0},{ I0_XXX, I1__Y_, - I0_111, I1___Z, - I0_000, I1_X__, - 0,0}}, - /* 1X1 */ - {2,{0,2,0,0},{ I0_XXX, I1__Y_, - I0_111, I1_X_Z, - 0,0,0,0}}, - SEMPTY,SEMPTY, - /* XY1 */ - {2,{0,2,0,0},{ I0_XYZ, I1_XY_, - I0_111, I1___Z, - 0,0,0,0}}, - /* YY1 */ - {2,{0,2,0,0},{ I0_YYY, I1_XY_, - I0_111, I1___Z, - 0,0,0,0}}, - /* ZY1 */ - {3,{0,0,2,0},{ I0_YYY, I1__Y_, - I0_ZZZ, I1_X__, - I0_111, I1___Z, - 0,0}}, - /* WY1 */ - {3,{0,0,2,0},{ I0_WZY, I1_XYZ, - I0_XYZ, I1__Y_, - I0_111, I1___Z, - 0,0}}, - /* 0Y1 */ - {3,{0,2,2,0},{ I0_XYZ, I1__Y_, - I0_111, I1___Z, - I0_000, I1_X__, - 0,0}}, - /* 1Y1 */ - {2,{0,2,0,0},{ I0_XYZ, I1__Y_, - I0_111, I1_X_Z, - 0,0,0,0}}, - SEMPTY,SEMPTY, - /* XZ1 */ - {3,{0,0,2,0},{ I0_ZZZ, I1__Y_, - I0_XYZ, I1_X__, - I0_111, I1___Z, - 0,0}}, - /* YZ1 */ - {2,{0,2,0,0},{ I0_YZX, I1_XY_, - I0_111, I1___Z, - 0,0,0,0}}, - /* ZZ1 */ - {2,{0,2,0,0},{ I0_ZZZ, I1_XYZ, - I0_111, I1___Z, - 0,0,0,0}}, - /* WZ1 */ - {2,{0,2,0,0},{ I0_WZY, I1_XY_, - I0_111, I1___Z, - 0,0,0,0}}, - /* 0Z1 */ - {3,{0,2,2,0},{ I0_ZZZ, I1_XYZ, - I0_111, I1___Z, - I0_000, I1_X__, - 0,0}}, - /* 1Z1 */ - {2,{0,2,0,0},{ I0_ZZZ, I1__Y_, - I0_111, I1_X_Z, - 0,0,0,0}}, - SEMPTY,SEMPTY, - /* XW1 */ - {3,{0,0,2,0},{ I0_WWW, I1__Y_, - I0_XYZ, I1_X__, - I0_111, I1___Z, - 0,0}}, - /* YW1 */ - {3,{0,2,0,0},{ I0_WWW, I1__Y_, - I0_111, I1___Z, - I0_YYY, I1_X__, - 0,0}}, - /* ZW1 */ - {3,{0,2,0,0},{ I0_WWW, I1__Y_, - I0_111, I1___Z, - I0_ZZZ, I1_X__, - 0,0}}, - /* WW1 */ - {2,{0,2,0,0},{ I0_WWW, I1_XY_, - I0_111, I1___Z, - 0,0,0,0}}, - /* 0W1 */ - {3,{0,2,2,0},{ I0_WWW, I1__Y_, - I0_111, I1___Z, - I0_000, I1_X__, - 0,0}}, - /* 1W1 */ - {2,{0,2,0,0},{ I0_WWW, I1__Y_, - I0_111, I1_X_Z, - 0,0,0,0}}, - SEMPTY,SEMPTY, - /* X01 */ - {3,{0,2,2,0},{ I0_XYZ, I1_X__, - I0_111, I1___Z, - I0_000, I1__Y_, - 0,0}}, - /* Y01 */ - {3,{0,2,2,0},{ I0_YYY, I1_X__, - I0_111, I1___Z, - I0_000, I1__Y_, - 0,0}}, - /* Z01 */ - {3,{0,2,2,0},{ I0_ZZZ, I1_X__, - I0_111, I1___Z, - I0_000, I1__Y_, - 0,0}}, - /* W01 */ - {3,{0,2,2,0},{ I0_WZY, I1_XYZ, - I0_111, I1___Z, - I0_000, I1__Y_, - 0,0}}, - /* 001 */ - {2,{2,2,0,0},{ I0_111, I1___Z, - I0_000, I1_XY_, - 0,0,0,0}}, - /* 101 */ - {2,{2,2,0,0},{ I0_111, I1_X_Z, - I0_000, I1__Y_, - 0, 0, 0, 0 } }, - SEMPTY,SEMPTY, - /* X11 */ - {2,{0,2,0,0},{ I0_XYZ, I1_X__, - I0_111, I1__YZ, - 0,0,0,0}}, - /* Y11 */ - {2,{0,2,0,0},{ I0_YYY, I1_X__, - I0_111, I1__YZ, - 0,0,0,0}}, - /* Z11 */ - {2,{0,2,0,0},{ I0_ZZZ, I1_X__, - I0_111, I1__YZ, - 0,0,0,0}}, - /* W11 */ - {2,{0,2,0,0},{ I0_WZY, I1_XYZ, - I0_111, I1__YZ, - 0,0,0,0}}, - /* 011 */ - {2,{2,2,0,0},{ I0_111, I1__YZ, - I0_000, I1_X__, - 0,0,0,0}}, - /* 111 */ - {1,{2,0,0,0},{ I0_111, I1_XYZ, - 0, 0, 0, 0, 0, 0 } }, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY, - SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY,SEMPTY -}; - -/****************************************************************************** -* Color source mask table -******************************************************************************/ - -#define S_111 R300_FPI0_ARGC_ONE -#define S_000 R300_FPI0_ARGC_ZERO - -#define S0XXX R300_FPI0_ARGC_SRC0C_XXX -#define S0YYY R300_FPI0_ARGC_SRC0C_YYY -#define S0ZZZ R300_FPI0_ARGC_SRC0C_ZZZ -#define S0WWW R300_FPI0_ARGC_SRC0A -#define S0XYZ R300_FPI0_ARGC_SRC0C_XYZ -#define S0ZXY R300_FPI0_ARGC_SRC0C_ZXY -#define S0YZX R300_FPI0_ARGC_SRC0C_YZX -#define S0WZY R300_FPI0_ARGC_SRC0CA_WZY -#define S0WZY R300_FPI0_ARGC_SRC0CA_WZY - -#define S1XXX R300_FPI0_ARGC_SRC1C_XXX -#define S1YYY R300_FPI0_ARGC_SRC1C_YYY -#define S1ZZZ R300_FPI0_ARGC_SRC1C_ZZZ -#define S1WWW R300_FPI0_ARGC_SRC1A -#define S1XYZ R300_FPI0_ARGC_SRC1C_XYZ -#define S1ZXY R300_FPI0_ARGC_SRC1C_ZXY -#define S1YZX R300_FPI0_ARGC_SRC1C_YZX -#define S1WZY R300_FPI0_ARGC_SRC1CA_WZY - -#define S2XXX R300_FPI0_ARGC_SRC2C_XXX -#define S2YYY R300_FPI0_ARGC_SRC2C_YYY -#define S2ZZZ R300_FPI0_ARGC_SRC2C_ZZZ -#define S2WWW R300_FPI0_ARGC_SRC2A -#define S2XYZ R300_FPI0_ARGC_SRC2C_XYZ -#define S2ZXY R300_FPI0_ARGC_SRC2C_ZXY -#define S2YZX R300_FPI0_ARGC_SRC2C_YZX -#define S2WZY R300_FPI0_ARGC_SRC2CA_WZY - -#define ntnat 32 - -const GLuint r300_swz_srcc_mask[3][512] = { - { - S0XXX,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S0YZX,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S0ZXY,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,S0YYY,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,S0WZY,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S0XYZ,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S0ZZZ,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S0WWW, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,S_000,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,S_111,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat - }, - { - S1XXX,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S1YZX,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S1ZXY,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,S1YYY,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,S1WZY,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S1XYZ,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S1ZZZ,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S1WWW, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,S_000,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,S_111,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat - }, - { - S2XXX,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S2YZX,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S2ZXY,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,S2YYY,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,S2WZY,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S2XYZ,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S2ZZZ,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,S2WWW, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,S_000,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,S_111,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat,ntnat, - ntnat,ntnat - } -}; - -/****************************************************************************** -* Alpha source mask table -******************************************************************************/ - -GLuint r300_swz_srca_mask[3][6] = { - { R300_FPI2_ARGA_SRC0C_X, - R300_FPI2_ARGA_SRC0C_Y, - R300_FPI2_ARGA_SRC0C_Z, - R300_FPI2_ARGA_SRC0A, - R300_FPI2_ARGA_ZERO, - R300_FPI2_ARGA_ONE }, - { R300_FPI2_ARGA_SRC1C_X, - R300_FPI2_ARGA_SRC1C_Y, - R300_FPI2_ARGA_SRC1C_Z, - R300_FPI2_ARGA_SRC1A, - R300_FPI2_ARGA_ZERO, - R300_FPI2_ARGA_ONE }, - { R300_FPI2_ARGA_SRC2C_X, - R300_FPI2_ARGA_SRC2C_Y, - R300_FPI2_ARGA_SRC2C_Z, - R300_FPI2_ARGA_SRC2A, - R300_FPI2_ARGA_ZERO, - R300_FPI2_ARGA_ONE }, -}; -- cgit v1.2.3 From 297a35eb69382193a4cc9ba4b51619984a8969db Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 27 Dec 2006 00:02:38 +1100 Subject: nouveau: Add simple wrapper for NV_MEMORY_TO_MEMORY_FORMAT. --- src/mesa/drivers/dri/nouveau/nouveau_buffers.c | 59 ++++++++++++++++++++++++++ src/mesa/drivers/dri/nouveau/nouveau_buffers.h | 5 +++ src/mesa/drivers/dri/nouveau/nouveau_object.c | 10 ++++- src/mesa/drivers/dri/nouveau/nouveau_object.h | 2 + 4 files changed, 75 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c index f6a03ecd9c..92329e514f 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c @@ -5,6 +5,65 @@ #include "nouveau_context.h" #include "nouveau_buffers.h" +#include "nouveau_object.h" +#include "nouveau_fifo.h" +#include "nouveau_reg.h" +#include "nouveau_msg.h" + +#define MAX_MEMFMT_LENGTH 32768 + +/* Unstrided blit using NV_MEMORY_TO_MEMORY_FORMAT */ +GLboolean +nouveau_memformat_flat_emit(GLcontext *ctx, + nouveau_mem *dst, nouveau_mem *src, + GLuint dst_offset, GLuint src_offset, + GLuint size) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + uint32_t src_handle, dst_handle; + GLuint count; + + if (src_offset + size > src->size) { + MESSAGE("src out of nouveau_mem bounds\n"); + return GL_FALSE; + } + if (dst_offset + size > dst->size) { + MESSAGE("dst out of nouveau_mem bounds\n"); + return GL_FALSE; + } + + src_handle = (src->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaAGP; + dst_handle = (src->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaAGP; + src_offset += nouveau_mem_gpu_offset_get(ctx, src); + dst_offset += nouveau_mem_gpu_offset_get(ctx, dst); + + BEGIN_RING_SIZE(NvSubMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_OBJECT_IN, 2); + OUT_RING (src_handle); + OUT_RING (dst_handle); + + count = (size / MAX_MEMFMT_LENGTH) + ((size % MAX_MEMFMT_LENGTH) ? 1 : 0); + + while (count--) { + GLuint length = (size > MAX_MEMFMT_LENGTH) ? MAX_MEMFMT_LENGTH : size; + + BEGIN_RING_SIZE(NvSubMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); + OUT_RING (src_offset); + OUT_RING (dst_offset); + OUT_RING (0); /* pitch in */ + OUT_RING (0); /* pitch out */ + OUT_RING (length); /* line length */ + OUT_RING (1); /* number of lines */ + OUT_RING ((1 << 8) /* dst_inc */ | (1 << 0) /* src_inc */); + OUT_RING (0); /* buffer notify? */ + FIRE_RING(); + + src_offset += length; + dst_offset += length; + size -= length; + } + + return GL_TRUE; +} void nouveau_mem_free(GLcontext *ctx, nouveau_mem *mem) diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.h b/src/mesa/drivers/dri/nouveau/nouveau_buffers.h index bb297ad558..a8d85b279b 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_buffers.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_buffers.h @@ -18,6 +18,11 @@ extern nouveau_mem *nouveau_mem_alloc(GLcontext *ctx, int type, extern void nouveau_mem_free(GLcontext *ctx, nouveau_mem *mem); extern uint32_t nouveau_mem_gpu_offset_get(GLcontext *ctx, nouveau_mem *mem); +extern GLboolean nouveau_memformat_flat_emit(GLcontext *ctx, + nouveau_mem *dst, nouveau_mem *src, + GLuint dst_offset, GLuint src_offset, + GLuint size); + typedef struct nouveau_renderbuffer_t { struct gl_renderbuffer mesa; /* must be first! */ __DRIdrawablePrivate *dPriv; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.c b/src/mesa/drivers/dri/nouveau/nouveau_object.c index cf7284d2d5..1558f2963d 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.c @@ -52,10 +52,13 @@ void nouveauObjectInit(nouveauContextPtr nmesa) return; #endif -/* We need to know vram size.. */ +/* We need to know vram size.. and AGP size (and even if the card is AGP..) */ nouveauCreateDmaObject( nmesa, NvDmaFB, 0, (256*1024*1024), 0 /*NV_DMA_TARGET_FB*/, 0 /*NV_DMA_ACCESS_RW*/); + nouveauCreateDmaObject( nmesa, NvDmaAGP, + nmesa->agp_phys, (128*1024*1024), + 3 /* AGP */, 0 /* RW */); nouveauCreateContextObject(nmesa, Nv3D, nmesa->screen->card->class_3d, 0, 0, 0, 0); @@ -63,6 +66,9 @@ void nouveauObjectInit(nouveauContextPtr nmesa) 0, 0, 0, 0); nouveauCreateContextObject(nmesa, NvImageBlit, NV10_IMAGE_BLIT, NV_DMA_CONTEXT_FLAGS_PATCH_SRCCOPY, 0, 0, 0); + nouveauCreateContextObject(nmesa, NvMemFormat, + NV_MEMORY_TO_MEMORY_FORMAT, + 0, 0, 0, 0); #ifdef ALLOW_MULTI_SUBCHANNEL nouveauObjectOnSubchannel(nmesa, NvSubCtxSurf2D, NvCtxSurf2D); @@ -75,6 +81,8 @@ void nouveauObjectInit(nouveauContextPtr nmesa) OUT_RING(NvCtxSurf2D); BEGIN_RING_SIZE(NvSubImageBlit, NV10_IMAGE_BLIT_SET_OPERATION, 1); OUT_RING(3); /* SRCCOPY */ + + nouveauObjectOnSubchannel(nmesa, NvSubMemFormat, NvMemFormat); #endif nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.h b/src/mesa/drivers/dri/nouveau/nouveau_object.h index 87f2dc9ae7..d5fcc6df8d 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.h @@ -11,6 +11,7 @@ enum DMAObjects { Nv3D = 0x80000019, NvCtxSurf2D = 0x80000020, NvImageBlit = 0x80000021, + NvMemFormat = 0x80000022, NvDmaFB = 0xD0FB0001, NvDmaAGP = 0xD0AA0001, NvSyncNotify = 0xD0000001 @@ -19,6 +20,7 @@ enum DMAObjects { enum DMASubchannel { NvSubCtxSurf2D = 0, NvSubImageBlit = 1, + NvSubMemFormat = 2, NvSub3D = 7, }; -- cgit v1.2.3 From 7b59a424b519c37b7c94e4ea8c420794c6a0eb4c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 27 Dec 2006 15:38:09 +1100 Subject: nouveau: Typo --- src/mesa/drivers/dri/nouveau/nouveau_buffers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c index 92329e514f..6d73e9ff51 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c @@ -33,7 +33,7 @@ nouveau_memformat_flat_emit(GLcontext *ctx, } src_handle = (src->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaAGP; - dst_handle = (src->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaAGP; + dst_handle = (dst->type & NOUVEAU_MEM_FB) ? NvDmaFB : NvDmaAGP; src_offset += nouveau_mem_gpu_offset_get(ctx, src); dst_offset += nouveau_mem_gpu_offset_get(ctx, dst); -- cgit v1.2.3 From 2dd37534506e85351fb114c79fd6c994a9c355c0 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 27 Dec 2006 15:39:52 +1100 Subject: nouveau: record *actual* type of memory that was alloc'd, not the requested types. --- src/mesa/drivers/dri/nouveau/nouveau_buffers.c | 3 ++- src/mesa/drivers/dri/nouveau/nouveau_buffers.h | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c index 6d73e9ff51..e628dd5b3c 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c @@ -91,7 +91,7 @@ nouveau_mem_alloc(GLcontext *ctx, int type, GLuint size, GLuint align) if (!mem) return NULL; - mema.flags = mem->type = type; + mema.flags = type; mema.size = mem->size = size; mema.alignment = align; mem->map = NULL; @@ -102,6 +102,7 @@ nouveau_mem_alloc(GLcontext *ctx, int type, GLuint size, GLuint align) return NULL; } mem->offset = mema.region_offset; + mem->type = mema.flags; if (type & NOUVEAU_MEM_MAPPED) ret = drmMap(nmesa->driFd, mem->offset, mem->size, &mem->map); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.h b/src/mesa/drivers/dri/nouveau/nouveau_buffers.h index a8d85b279b..d86455184c 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_buffers.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_buffers.h @@ -19,8 +19,10 @@ extern void nouveau_mem_free(GLcontext *ctx, nouveau_mem *mem); extern uint32_t nouveau_mem_gpu_offset_get(GLcontext *ctx, nouveau_mem *mem); extern GLboolean nouveau_memformat_flat_emit(GLcontext *ctx, - nouveau_mem *dst, nouveau_mem *src, - GLuint dst_offset, GLuint src_offset, + nouveau_mem *dst, + nouveau_mem *src, + GLuint dst_offset, + GLuint src_offset, GLuint size); typedef struct nouveau_renderbuffer_t { -- cgit v1.2.3 From 885a7cc38d80366396f463a54ef4af00c9fd07ff Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 27 Dec 2006 15:50:59 +1100 Subject: nouveau: add nouveau_mem_alloc/free debugging --- src/mesa/drivers/dri/nouveau/nouveau_buffers.c | 15 +++++++++++++++ src/mesa/drivers/dri/nouveau/nouveau_context.c | 5 +++-- src/mesa/drivers/dri/nouveau/nouveau_context.h | 3 ++- 3 files changed, 20 insertions(+), 3 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c index e628dd5b3c..b54f68f402 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_buffers.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_buffers.c @@ -71,6 +71,11 @@ nouveau_mem_free(GLcontext *ctx, nouveau_mem *mem) nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); drm_nouveau_mem_free_t memf; + if (NOUVEAU_DEBUG & DEBUG_MEM) { + fprintf(stderr, "%s: type=0x%x, offset=0x%x, size=0x%x\n", + __func__, mem->type, (GLuint)mem->offset, (GLuint)mem->size); + } + if (mem->map) drmUnmap(mem->map, mem->size); memf.flags = mem->type; @@ -87,6 +92,11 @@ nouveau_mem_alloc(GLcontext *ctx, int type, GLuint size, GLuint align) nouveau_mem *mem; int ret; + if (NOUVEAU_DEBUG & DEBUG_MEM) { + fprintf(stderr, "%s: requested: type=0x%x, size=0x%x, align=0x%x\n", + __func__, type, (GLuint)size, align); + } + mem = CALLOC(sizeof(nouveau_mem)); if (!mem) return NULL; @@ -104,6 +114,11 @@ nouveau_mem_alloc(GLcontext *ctx, int type, GLuint size, GLuint align) mem->offset = mema.region_offset; mem->type = mema.flags; + if (NOUVEAU_DEBUG & DEBUG_MEM) { + fprintf(stderr, "%s: actual: type=0x%x, offset=0x%x, size=0x%x\n", + __func__, mem->type, (GLuint)mem->offset, (GLuint)mem->size); + } + if (type & NOUVEAU_MEM_MAPPED) ret = drmMap(nmesa->driFd, mem->offset, mem->size, &mem->map); if (ret) { diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 3718900b62..bb67f72f4a 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -63,8 +63,9 @@ int NOUVEAU_DEBUG = 0; static const struct dri_debug_control debug_control[] = { - { "shaders", DEBUG_SHADERS }, - { NULL, 0 } + { "shaders" , DEBUG_SHADERS }, + { "mem" , DEBUG_MEM }, + { NULL , 0 } }; #define need_GL_ARB_vertex_program diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 0efbcce129..b0952070c7 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -216,7 +216,8 @@ extern void nouveauCopySubBuffer(__DRIdrawablePrivate *dPriv, /* Debugging utils: */ extern int NOUVEAU_DEBUG; -#define DEBUG_SHADERS 0x00000001 +#define DEBUG_SHADERS 0x00000001 +#define DEBUG_MEM 0x00000002 #endif /* __NOUVEAU_CONTEXT_H__ */ -- cgit v1.2.3 From 1780fd4eeeef2358e929c23cfae2c348cb4a709e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 27 Dec 2006 15:54:30 +1100 Subject: nouveau: We'll need syncNotifier for NV_MEMORY_TO_MEMORY_FORMAT too. --- src/mesa/drivers/dri/nouveau/nouveau_sync.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.c b/src/mesa/drivers/dri/nouveau/nouveau_sync.c index e27101d868..0bf20e723b 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.c @@ -125,6 +125,11 @@ GLboolean nouveauSyncInitFuncs(GLcontext *ctx) */ BEGIN_RING_CACHE(NvSub3D, 0x180, 1); OUT_RING_CACHE (NvSyncNotify); +#ifdef ALLOW_MULTI_SUBCHANNEL + BEGIN_RING_SIZE(NvSubMemFormat, + NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); + OUT_RING (NvSyncNotify); +#endif return GL_TRUE; } -- cgit v1.2.3 From 9a20ae70ecda2e78ea6b52c3fd829d283434c1ad Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 27 Dec 2006 23:30:34 +1100 Subject: nouveau: Initial buffer object support --- src/mesa/drivers/dri/nouveau/Makefile | 1 + src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c | 272 +++++++++++++++++++++++ src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h | 27 +++ src/mesa/drivers/dri/nouveau/nouveau_context.c | 2 + src/mesa/drivers/dri/nouveau/nouveau_context.h | 1 + 5 files changed, 303 insertions(+) create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile index 962978dc7f..d31b42a568 100644 --- a/src/mesa/drivers/dri/nouveau/Makefile +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -8,6 +8,7 @@ LIBNAME = nouveau_dri.so MINIGLX_SOURCES = DRIVER_SOURCES = \ + nouveau_bufferobj.c \ nouveau_buffers.c \ nouveau_card.c \ nouveau_context.c \ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c new file mode 100644 index 0000000000..d36196aeef --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c @@ -0,0 +1,272 @@ +#include "bufferobj.h" +#include "enums.h" + +#include "nouveau_bufferobj.h" +#include "nouveau_buffers.h" +#include "nouveau_context.h" +#include "nouveau_drm.h" +#include "nouveau_object.h" +#include "nouveau_msg.h" + +#define DEBUG(fmt,args...) do { \ + if (NOUVEAU_DEBUG & DEBUG_BUFFEROBJ) { \ + fprintf(stderr, "%s: "fmt, __func__, ##args); \ + } \ +} while(0) + +/* Wrapper for nouveau_mem_gpu_offset_get() that marks the bufferobj dirty + * if the GPU modifies the data. + */ +uint32_t +nouveau_bufferobj_gpu_ref(GLcontext *ctx, GLenum access, + struct gl_buffer_object *obj) +{ + nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj; + + DEBUG("obj=%p, access=%s\n", obj, _mesa_lookup_enum_by_nr(access)); + + if (access == GL_WRITE_ONLY_ARB || access == GL_READ_WRITE_ARB) + nbo->gpu_dirty = GL_TRUE; + + return nouveau_mem_gpu_offset_get(ctx, nbo->gpu_mem); +} + +static void +nouveauBindBuffer(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj) +{ +} + +static struct gl_buffer_object * +nouveauNewBufferObject(GLcontext *ctx, GLuint buffer, GLenum target) +{ + nouveau_buffer_object *nbo; + + nbo = CALLOC_STRUCT(nouveau_buffer_object_t); + DEBUG("name=0x%08x, target=%s, obj=%p\n", + buffer, _mesa_lookup_enum_by_nr(target), nbo); + _mesa_initialize_buffer_object(&nbo->mesa, buffer, target); + return &nbo->mesa; +} + +static void +nouveauDeleteBuffer(GLcontext *ctx, struct gl_buffer_object *obj) +{ + nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj; + + DEBUG("obj=%p\n", obj); + + if (nbo->gpu_mem) { + nouveau_mem_free(ctx, nbo->gpu_mem); + } + _mesa_delete_buffer_object(ctx, obj); +} + +static void +nouveauBufferData(GLcontext *ctx, GLenum target, GLsizeiptrARB size, + const GLvoid *data, GLenum usage, + struct gl_buffer_object *obj) +{ + nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj; + + DEBUG("obj=%p, target=%s, usage=%s, size=%d, data=%p\n", + obj, + _mesa_lookup_enum_by_nr(target), + _mesa_lookup_enum_by_nr(usage), + (unsigned int)size, + data); + + if (nbo->gpu_mem && nbo->gpu_mem->size != size) + nouveau_mem_free(ctx, nbo->gpu_mem); + + /* Always have the GPU access the data from VRAM if possible. For + * some "usage" values it may be better from AGP be default? + * + * TODO: At some point we should drop the NOUVEAU_MEM_MAPPED flag. + * TODO: Use the NOUVEAU_MEM_AGP_ACCEPTABLE flag. + * TODO: What about PCI-E and shared system memory? + */ + if (!nbo->gpu_mem) + nbo->gpu_mem = nouveau_mem_alloc(ctx, + NOUVEAU_MEM_FB | + NOUVEAU_MEM_MAPPED, + size, + 0); + + if (!nbo->gpu_mem) { + MESSAGE("AIII bufferobj malloc failed\n"); + return; + } + + obj->Usage = usage; + obj->Size = size; + if (!data) + return; + + ctx->Driver.MapBuffer(ctx, target, GL_WRITE_ONLY_ARB, obj); + _mesa_memcpy(nbo->cpu_mem->map, data, size); + ctx->Driver.UnmapBuffer(ctx, target, obj); +} + +/*TODO: we don't need to DMA the entire buffer like MapBuffer does.. */ +static void +nouveauBufferSubData(GLcontext *ctx, GLenum target, GLintptrARB offset, + GLsizeiptrARB size, const GLvoid *data, + struct gl_buffer_object *obj) +{ + DEBUG("obj=%p, target=%s, offset=0x%x, size=%d, data=%p\n", + obj, + _mesa_lookup_enum_by_nr(target), + (unsigned int)offset, + (unsigned int)size, + data); + + ctx->Driver.MapBuffer(ctx, target, GL_WRITE_ONLY_ARB, obj); + _mesa_memcpy((GLubyte *)obj->Pointer + offset, data, size); + ctx->Driver.UnmapBuffer(ctx, target, obj); +} + +/*TODO: we don't need to DMA the entire buffer like MapBuffer does.. */ +static void +nouveauGetBufferSubData(GLcontext *ctx, GLenum target, GLintptrARB offset, + GLsizeiptrARB size, GLvoid *data, + struct gl_buffer_object *obj) +{ + DEBUG("obj=%p, target=%s, offset=0x%x, size=%d, data=%p\n", + obj, + _mesa_lookup_enum_by_nr(target), + (unsigned int)offset, + (unsigned int)size, + data); + + ctx->Driver.MapBuffer(ctx, target, GL_READ_ONLY_ARB, obj); + _mesa_memcpy(data, (GLubyte *)obj->Pointer + offset, size); + ctx->Driver.UnmapBuffer(ctx, target, obj); +} + +static void * +nouveauMapBuffer(GLcontext *ctx, GLenum target, GLenum access, + struct gl_buffer_object *obj) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj; + + DEBUG("obj=%p, target=%s, access=%s\n", + obj, + _mesa_lookup_enum_by_nr(target), + _mesa_lookup_enum_by_nr(access)); + + if (obj->Pointer) { + DEBUG("already mapped, return NULL\n"); + return NULL; + } + +#ifdef ALLOW_MULTI_SUBCHANNEL + /* If GPU is accessing the data from VRAM, copy to faster AGP memory + * before CPU access to the buffer. + */ + if (nbo->gpu_mem->type & NOUVEAU_MEM_FB) { + DEBUG("Data in VRAM, copying to AGP for CPU access\n"); + + /* This can happen if BufferData grows the GPU-access buffer */ + if (nbo->cpu_mem && nbo->cpu_mem->size != nbo->gpu_mem->size) { + nouveau_mem_free(ctx, nbo->cpu_mem); + nbo->cpu_mem = NULL; + } + + if (!nbo->cpu_mem) { + nbo->cpu_mem = nouveau_mem_alloc(ctx, + NOUVEAU_MEM_AGP | + NOUVEAU_MEM_MAPPED, + nbo->gpu_mem->size, + 0); + + /* Mark GPU data as modified, so it gets copied to + * the new buffer */ + nbo->gpu_dirty = GL_TRUE; + } + + if (nbo->cpu_mem && nbo->gpu_dirty) { + nouveau_memformat_flat_emit(ctx, nbo->cpu_mem, + nbo->gpu_mem, + 0, 0, + nbo->gpu_mem->size); + + nouveau_notifier_wait_nop(ctx, + nmesa->syncNotifier, + NvSubMemFormat); + nbo->gpu_dirty = GL_FALSE; + } + + /* buffer isn't guaranteed to be up-to-date on the card now */ + nbo->cpu_dirty = GL_TRUE; + } +#endif + + /* If the copy to AGP failed for some reason, just return a pointer + * directly to vram.. + */ + if (!nbo->cpu_mem) { + DEBUG("Returning direct pointer to VRAM\n"); + nbo->cpu_mem = nbo->gpu_mem; + nbo->cpu_dirty = GL_FALSE; + } + + obj->Pointer = nbo->cpu_mem->map; + return obj->Pointer; +} + +static GLboolean +nouveauUnmapBuffer(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj; + + DEBUG("obj=%p, target=%s\n", obj, _mesa_lookup_enum_by_nr(target)); + +#ifdef ALLOW_MULTI_SUBCHANNEL + if (nbo->cpu_dirty && nbo->cpu_mem != nbo->gpu_mem) { + DEBUG("Copying potentially modified data back to GPU\n"); + + /* blit from GPU buffer -> CPU buffer */ + nouveau_memformat_flat_emit(ctx, nbo->gpu_mem, nbo->cpu_mem, + 0, 0, nbo->cpu_mem->size); + + /* buffer is now up-to-date on the hardware (or rather, will + * be by the time any other commands in this channel reference + * the data.) + */ + nbo->cpu_dirty = GL_FALSE; + + /* we can avoid this wait in some cases.. */ + nouveau_notifier_wait_nop(ctx, + nmesa->syncNotifier, + NvSubMemFormat); + + /* If it's likely CPU access to the buffer will occur often, + * keep the cpu_mem around to avoid repeated allocs. + */ + if (obj->Usage != GL_DYNAMIC_DRAW_ARB) { + + nouveau_mem_free(ctx, nbo->cpu_mem); + nbo->cpu_mem = NULL; + } + } +#endif + + obj->Pointer = NULL; + return GL_TRUE; +} + +void +nouveauInitBufferObjects(GLcontext *ctx) +{ + ctx->Driver.BindBuffer = nouveauBindBuffer; + ctx->Driver.NewBufferObject = nouveauNewBufferObject; + ctx->Driver.DeleteBuffer = nouveauDeleteBuffer; + ctx->Driver.BufferData = nouveauBufferData; + ctx->Driver.BufferSubData = nouveauBufferSubData; + ctx->Driver.GetBufferSubData = nouveauGetBufferSubData; + ctx->Driver.MapBuffer = nouveauMapBuffer; + ctx->Driver.UnmapBuffer = nouveauUnmapBuffer; +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h new file mode 100644 index 0000000000..fccc349b83 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h @@ -0,0 +1,27 @@ +#ifndef __NOUVEAU_BUFFEROBJ_H__ +#define __NOUVEAU_BUFFEROBJ_H__ + +#include "mtypes.h" +#include "nouveau_buffers.h" + +typedef struct nouveau_buffer_object_t { + /* Base class, must be first */ + struct gl_buffer_object mesa; + + /* Memory used for GPU access to the buffer*/ + nouveau_mem * gpu_mem; + /* Buffer has been dirtied by the GPU */ + GLboolean gpu_dirty; + + /* Memory used for CPU access to the buffer */ + nouveau_mem * cpu_mem; + /* Buffer has possibly been dirtied by the CPU */ + GLboolean cpu_dirty; +} nouveau_buffer_object; + +extern uint32_t nouveau_bufferobj_gpu_ref(GLcontext *ctx, GLenum access, + struct gl_buffer_object *obj); + +extern void nouveauInitBufferObjects(GLcontext *ctx); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index bb67f72f4a..79da46fc0b 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -65,6 +65,7 @@ static const struct dri_debug_control debug_control[] = { { "shaders" , DEBUG_SHADERS }, { "mem" , DEBUG_MEM }, + { "bufferobj" , DEBUG_BUFFEROBJ }, { NULL , 0 } }; @@ -224,6 +225,7 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, break; } + nouveauInitBufferObjects(ctx); if (!nouveauSyncInitFuncs(ctx)) return GL_FALSE; nmesa->hw_func.InitCard(nmesa); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index b0952070c7..134e2a417e 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -218,6 +218,7 @@ extern int NOUVEAU_DEBUG; #define DEBUG_SHADERS 0x00000001 #define DEBUG_MEM 0x00000002 +#define DEBUG_BUFFEROBJ 0x00000004 #endif /* __NOUVEAU_CONTEXT_H__ */ -- cgit v1.2.3 From 8c180c72d5fed5f26f258759f9649fc647a764ff Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 27 Dec 2006 23:52:40 +1100 Subject: nouveau: Use bufferobj interface for fragment program uploads --- src/mesa/drivers/dri/nouveau/nouveau_shader.h | 4 +-- src/mesa/drivers/dri/nouveau/nv30_fragprog.c | 37 +++++++++++++-------------- 2 files changed, 20 insertions(+), 21 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h index 6e934f2908..08cb7817cf 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -2,7 +2,7 @@ #define __SHADER_COMMON_H__ #include "mtypes.h" -#include "nouveau_buffers.h" +#include "bufferobj.h" typedef struct _nvsFunc nvsFunc; @@ -41,7 +41,7 @@ typedef struct _nouveauShader { unsigned int program_alloc_size; unsigned int program_start_id; unsigned int program_current; - nouveau_mem *program_buffer; + struct gl_buffer_object *program_buffer; unsigned int inputs_read; unsigned int outputs_written; int inst_count; diff --git a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c index b11bc1809e..cd7c955c9e 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c +++ b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c @@ -10,7 +10,7 @@ #include "nouveau_shader.h" #include "nouveau_object.h" #include "nouveau_msg.h" -#include "nouveau_buffers.h" +#include "nouveau_bufferobj.h" #include "nv30_shader.h" unsigned int NVFP_TX_AOP_COUNT = 64; @@ -24,29 +24,28 @@ static void NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + uint32_t offset; - if (!nvs->program_buffer) { - nouveau_mem *fpbuf; + if (!nvs->program_buffer) + nvs->program_buffer = ctx->Driver.NewBufferObject(ctx, 0, + GL_ARRAY_BUFFER_ARB); - fpbuf = nouveau_mem_alloc(ctx, NOUVEAU_MEM_FB|NOUVEAU_MEM_MAPPED, - nvs->program_size * sizeof(uint32_t), 0); - if (!fpbuf) { - fprintf(stderr, "fragprog vram alloc fail!\n"); - return; - } - nvs->program_buffer = fpbuf; - } + /* Should use STATIC_DRAW_ARB if shader doesn't use changable params */ + ctx->Driver.BufferData(ctx, GL_ARRAY_BUFFER_ARB, + nvs->program_size * sizeof(uint32_t), + (const GLvoid *)nvs->program, + GL_DYNAMIC_DRAW_ARB, + nvs->program_buffer); + + offset = nouveau_bufferobj_gpu_ref(ctx, GL_READ_ONLY_ARB, + nvs->program_buffer); - /*XXX: should do a DMA.. and not copy over a possibly in-use program.. */ - /* not using state cache here, updated programs at the same address - * seem to not take effect unless ACTIVE_PROGRAM is called again. hw - * caches the program somewhere? so, maybe not so bad to just clobber the - * old program in vram.. + /* Not using state cache here, updated programs at the same address don't + * seem to take effect unless the ACTIVE_PROGRAM method is called again. + * HW caches the program somewhere? */ - memcpy(nvs->program_buffer->map, nvs->program, - nvs->program_size * sizeof(uint32_t)); BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM, 1); - OUT_RING(nouveau_mem_gpu_offset_get(ctx, nvs->program_buffer) | 1); + OUT_RING (offset | 1); } static void -- cgit v1.2.3 From 3943d7f8b12370dd77dda66e70aa8f1fcd217f9f Mon Sep 17 00:00:00 2001 From: Haihao Xiang Date: Sat, 30 Dec 2006 10:30:42 -0800 Subject: Use the tiled flag in the sarea to determine region tiling. This fixes mis-rendering if back/depth fail to get set up as tiled. While it probably won't ever be the case now that the pitch limits are loosened, this is still the right thing to do. --- src/mesa/drivers/dri/i965/intel_context.c | 6 +++--- src/mesa/drivers/dri/i965/intel_screen.c | 6 +++++- src/mesa/drivers/dri/i965/intel_screen.h | 1 + 3 files changed, 9 insertions(+), 4 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index d13e287fa7..5e97e4d609 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -403,7 +403,7 @@ GLboolean intelInitContext( struct intel_context *intel, intelScreen->cpp, intelScreen->front.pitch / intelScreen->cpp, intelScreen->height, - GL_FALSE); + intelScreen->front.tiled != 0); /* 0: LINEAR */ intel->back_region = @@ -414,7 +414,7 @@ GLboolean intelInitContext( struct intel_context *intel, intelScreen->cpp, intelScreen->back.pitch / intelScreen->cpp, intelScreen->height, - (INTEL_DEBUG & DEBUG_TILE) ? 0 : 1); + intelScreen->back.tiled != 0); /* Still assuming front.cpp == depth.cpp * @@ -430,7 +430,7 @@ GLboolean intelInitContext( struct intel_context *intel, intelScreen->cpp, intelScreen->depth.pitch / intelScreen->cpp, intelScreen->height, - (INTEL_DEBUG & DEBUG_TILE) ? 0 : 1); + intelScreen->depth.tiled != 0); intel_bufferobj_init( intel ); intel->batch = intel_batchbuffer_alloc( intel ); diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c index 56e6a792fa..8269deba66 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.c +++ b/src/mesa/drivers/dri/i965/intel_screen.c @@ -230,16 +230,19 @@ intelUpdateScreenFromSAREA(intelScreenPrivate *intelScreen, intelScreen->front.pitch = sarea->pitch * intelScreen->cpp; intelScreen->front.handle = sarea->front_handle; intelScreen->front.size = sarea->front_size; + intelScreen->front.tiled = sarea->front_tiled; intelScreen->back.offset = sarea->back_offset; intelScreen->back.pitch = sarea->pitch * intelScreen->cpp; intelScreen->back.handle = sarea->back_handle; intelScreen->back.size = sarea->back_size; - + intelScreen->back.tiled = sarea->back_tiled; + intelScreen->depth.offset = sarea->depth_offset; intelScreen->depth.pitch = sarea->pitch * intelScreen->cpp; intelScreen->depth.handle = sarea->depth_handle; intelScreen->depth.size = sarea->depth_size; + intelScreen->depth.tiled = sarea->depth_tiled; intelScreen->tex.offset = sarea->tex_offset; intelScreen->logTextureGranularity = sarea->log_tex_granularity; @@ -249,6 +252,7 @@ intelUpdateScreenFromSAREA(intelScreenPrivate *intelScreen, intelScreen->rotated.offset = sarea->rotated_offset; intelScreen->rotated.pitch = sarea->rotated_pitch * intelScreen->cpp; intelScreen->rotated.size = sarea->rotated_size; + intelScreen->rotated.tiled = sarea->rotated_tiled; intelScreen->current_rotation = sarea->rotation; #if 0 matrix23Rotate(&intelScreen->rotMatrix, diff --git a/src/mesa/drivers/dri/i965/intel_screen.h b/src/mesa/drivers/dri/i965/intel_screen.h index 094158afd8..bf9a716082 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.h +++ b/src/mesa/drivers/dri/i965/intel_screen.h @@ -42,6 +42,7 @@ typedef struct { char *map; /* memory map */ int offset; /* from start of video mem, in bytes */ int pitch; /* row stride, in pixels */ + unsigned int tiled; } intelRegion; typedef struct -- cgit v1.2.3 From b6becfae1087f2577b489677bdd680d64a7ffb4c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sun, 31 Dec 2006 10:01:17 +1100 Subject: fix issue with i915tex advertising visuals it can't support This may not be the proper way to fix this but it does work easily. --- src/mesa/drivers/dri/i915tex/intel_screen.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c index 9bbfabbb8c..efa1b014a6 100644 --- a/src/mesa/drivers/dri/i915tex/intel_screen.c +++ b/src/mesa/drivers/dri/i915tex/intel_screen.c @@ -737,6 +737,9 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits, */ stencil_bits_array[0] = 0; stencil_bits_array[1] = 0; + if (depth_bits == 24) + stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; + stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits; depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1; -- cgit v1.2.3 From 254ce75ac300d8d20ba4e2fce81c4459c692d2b1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 2 Jan 2007 15:09:10 +1100 Subject: nouveau: bump drm patchlevel. --- src/mesa/drivers/dri/nouveau/nouveau_screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index 97bca84d8b..0e3901cfca 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -320,7 +320,7 @@ void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIsc __DRIscreenPrivate *psp; static const __DRIversion ddx_expected = { 1, 2, 0 }; static const __DRIversion dri_expected = { 4, 0, 0 }; - static const __DRIversion drm_expected = { 0, 0, 1 }; + static const __DRIversion drm_expected = { 0, 0, 2 }; dri_interface = interface; -- cgit v1.2.3 From bbfd963f492683dc359b7e3f8fcb7ceb2483f886 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 2 Jan 2007 14:31:16 +0100 Subject: Update spot light params --- src/mesa/drivers/dri/nouveau/nv10_state.c | 27 +++++++++++++++------------ src/mesa/drivers/dri/nouveau/nv20_state.c | 27 +++++++++++++++------------ src/mesa/drivers/dri/nouveau/nv30_state.c | 27 +++++++++++++++------------ 3 files changed, 45 insertions(+), 36 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index be5f5f6e42..c028be2867 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -327,6 +327,7 @@ static void nv10Hint(GLcontext *ctx, GLenum target, GLenum mode) // void (*IndexMask)(GLcontext *ctx, GLuint mask); enum { + SPOTLIGHT_NO_UPDATE, SPOTLIGHT_UPDATE_EXPONENT, SPOTLIGHT_UPDATE_DIRECTION, SPOTLIGHT_UPDATE_ALL @@ -337,7 +338,7 @@ static void nv10Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); GLint p = light - GL_LIGHT0; struct gl_light *l = &ctx->Light.Light[p]; - int spotlightUpdate = -1; + int spotlight_update = SPOTLIGHT_NO_UPDATE; switch(pname) { @@ -366,13 +367,13 @@ static void nv10Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa OUT_RING_CACHEf(params[2]); break; case GL_SPOT_DIRECTION: - spotlightUpdate = SPOTLIGHT_UPDATE_DIRECTION; + spotlight_update = SPOTLIGHT_UPDATE_DIRECTION; break; case GL_SPOT_EXPONENT: - spotlightUpdate = SPOTLIGHT_UPDATE_EXPONENT; + spotlight_update = SPOTLIGHT_UPDATE_EXPONENT; break; case GL_SPOT_CUTOFF: - spotlightUpdate = SPOTLIGHT_UPDATE_ALL; + spotlight_update = SPOTLIGHT_UPDATE_ALL; break; case GL_CONSTANT_ATTENUATION: BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p), 1); @@ -390,13 +391,14 @@ static void nv10Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa break; } - switch(spotlightUpdate) { + switch(spotlight_update) { case SPOTLIGHT_UPDATE_DIRECTION: { GLfloat x,y,z; - x = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[0]; - y = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[1]; - z = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[2]; + GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0); + x = spot_light_coef_a * l->_NormDirection[0]; + y = spot_light_coef_a * l->_NormDirection[1]; + z = spot_light_coef_a * l->_NormDirection[2]; BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p), 3); OUT_RING_CACHEf(x); OUT_RING_CACHEf(y); @@ -418,13 +420,14 @@ static void nv10Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa case SPOTLIGHT_UPDATE_ALL: { GLfloat cc,lc,qc, x,y,z, c; + GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0); cc = 1.0; /* FIXME: These need to be correctly computed */ lc = 0.0; qc = 2.0; - x = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[0]; - y = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[1]; - z = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[2]; - c = -2.0 * (0.5 + l->_CosCutoff); + x = spot_light_coef_a * l->_NormDirection[0]; + y = spot_light_coef_a * l->_NormDirection[1]; + z = spot_light_coef_a * l->_NormDirection[2]; + c = spot_light_coef_a + 1.0; BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 7); OUT_RING_CACHEf(cc); OUT_RING_CACHEf(lc); diff --git a/src/mesa/drivers/dri/nouveau/nv20_state.c b/src/mesa/drivers/dri/nouveau/nv20_state.c index 6bfac8466b..8e38d6eba0 100644 --- a/src/mesa/drivers/dri/nouveau/nv20_state.c +++ b/src/mesa/drivers/dri/nouveau/nv20_state.c @@ -338,6 +338,7 @@ static void nv20Hint(GLcontext *ctx, GLenum target, GLenum mode) // void (*IndexMask)(GLcontext *ctx, GLuint mask); enum { + SPOTLIGHT_NO_UPDATE, SPOTLIGHT_UPDATE_EXPONENT, SPOTLIGHT_UPDATE_DIRECTION, SPOTLIGHT_UPDATE_ALL @@ -348,7 +349,7 @@ static void nv20Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); GLint p = light - GL_LIGHT0; struct gl_light *l = &ctx->Light.Light[p]; - int spotlightUpdate = -1; + int spotlight_update = SPOTLIGHT_NO_UPDATE; /* not sure where the fourth param value goes...*/ switch(pname) @@ -378,13 +379,13 @@ static void nv20Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa OUT_RING_CACHEf(params[2]); break; case GL_SPOT_DIRECTION: - spotlightUpdate = SPOTLIGHT_UPDATE_DIRECTION; + spotlight_update = SPOTLIGHT_UPDATE_DIRECTION; break; case GL_SPOT_EXPONENT: - spotlightUpdate = SPOTLIGHT_UPDATE_EXPONENT; + spotlight_update = SPOTLIGHT_UPDATE_EXPONENT; break; case GL_SPOT_CUTOFF: - spotlightUpdate = SPOTLIGHT_UPDATE_ALL; + spotlight_update = SPOTLIGHT_UPDATE_ALL; break; case GL_CONSTANT_ATTENUATION: BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p), 1); @@ -402,13 +403,14 @@ static void nv20Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa break; } - switch(spotlightUpdate) { + switch(spotlight_update) { case SPOTLIGHT_UPDATE_DIRECTION: { GLfloat x,y,z; - x = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[0]; - y = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[1]; - z = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[2]; + GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0); + x = spot_light_coef_a * l->_NormDirection[0]; + y = spot_light_coef_a * l->_NormDirection[1]; + z = spot_light_coef_a * l->_NormDirection[2]; BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p), 3); OUT_RING_CACHEf(x); OUT_RING_CACHEf(y); @@ -430,13 +432,14 @@ static void nv20Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa case SPOTLIGHT_UPDATE_ALL: { GLfloat cc,lc,qc, x,y,z, c; + GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0); cc = 1.0; /* FIXME: These need to be correctly computed */ lc = 0.0; qc = 2.0; - x = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[0]; - y = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[1]; - z = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[2]; - c = -2.0 * (0.5 + l->_CosCutoff); + x = spot_light_coef_a * l->_NormDirection[0]; + y = spot_light_coef_a * l->_NormDirection[1]; + z = spot_light_coef_a * l->_NormDirection[2]; + c = spot_light_coef_a + 1.0; BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 7); OUT_RING_CACHEf(cc); OUT_RING_CACHEf(lc); diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 45befd0e77..9bf5f2adea 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -369,6 +369,7 @@ static void nv30Hint(GLcontext *ctx, GLenum target, GLenum mode) // void (*IndexMask)(GLcontext *ctx, GLuint mask); enum { + SPOTLIGHT_NO_UPDATE, SPOTLIGHT_UPDATE_EXPONENT, SPOTLIGHT_UPDATE_DIRECTION, SPOTLIGHT_UPDATE_ALL @@ -379,7 +380,7 @@ static void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); GLint p = light - GL_LIGHT0; struct gl_light *l = &ctx->Light.Light[p]; - int spotlightUpdate = -1; + int spotlight_update = SPOTLIGHT_NO_UPDATE; if (NOUVEAU_CARD_USING_SHADERS) return; @@ -412,13 +413,13 @@ static void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa OUT_RING_CACHEf(params[2]); break; case GL_SPOT_DIRECTION: - spotlightUpdate = SPOTLIGHT_UPDATE_DIRECTION; + spotlight_update = SPOTLIGHT_UPDATE_DIRECTION; break; case GL_SPOT_EXPONENT: - spotlightUpdate = SPOTLIGHT_UPDATE_EXPONENT; + spotlight_update = SPOTLIGHT_UPDATE_EXPONENT; break; case GL_SPOT_CUTOFF: - spotlightUpdate = SPOTLIGHT_UPDATE_ALL; + spotlight_update = SPOTLIGHT_UPDATE_ALL; break; case GL_CONSTANT_ATTENUATION: BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_CONSTANT_ATTENUATION(p), 1); @@ -436,13 +437,14 @@ static void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa break; } - switch(spotlightUpdate) { + switch(spotlight_update) { case SPOTLIGHT_UPDATE_DIRECTION: { GLfloat x,y,z; - x = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[0]; - y = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[1]; - z = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[2]; + GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0); + x = spot_light_coef_a * l->_NormDirection[0]; + y = spot_light_coef_a * l->_NormDirection[1]; + z = spot_light_coef_a * l->_NormDirection[2]; BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_DIR_X(p), 3); OUT_RING_CACHEf(x); OUT_RING_CACHEf(y); @@ -464,13 +466,14 @@ static void nv30Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloa case SPOTLIGHT_UPDATE_ALL: { GLfloat cc,lc,qc, x,y,z, c; + GLfloat spot_light_coef_a = 1.0 / (l->_CosCutoff - 1.0); cc = 1.0; /* FIXME: These need to be correctly computed */ lc = 0.0; qc = 2.0; - x = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[0]; - y = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[1]; - z = -2.0 * (1.0 + l->_CosCutoff) * l->_NormDirection[2]; - c = -2.0 * (0.5 + l->_CosCutoff); + x = spot_light_coef_a * l->_NormDirection[0]; + y = spot_light_coef_a * l->_NormDirection[1]; + z = spot_light_coef_a * l->_NormDirection[2]; + c = spot_light_coef_a + 1.0; BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LIGHT_SPOT_CUTOFF_A(p), 7); OUT_RING_CACHEf(cc); OUT_RING_CACHEf(lc); -- cgit v1.2.3 From 1d312ae0137eb39bf74fac91eb97ed25c289a4ca Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Thu, 4 Jan 2007 20:27:49 +0100 Subject: r300: Correct bug introduced by fragprog rework. Thx for Tilman who spoted the bugs. --- src/mesa/drivers/dri/r300/r300_fragprog.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c index f00162a6dc..179bc58e9e 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog.c @@ -257,7 +257,7 @@ static const GLuint undef = REG(REG_TYPE_TEMP, GL_FALSE); /* constant one source */ -static const GLuint pfs_one = REG(REG_TYPE_TEMP, +static const GLuint pfs_one = REG(REG_TYPE_CONST, 0, SWIZZLE_111, SWIZZLE_ONE, @@ -265,7 +265,7 @@ static const GLuint pfs_one = REG(REG_TYPE_TEMP, GL_TRUE); /* constant half source */ -static const GLuint pfs_half = REG(REG_TYPE_TEMP, +static const GLuint pfs_half = REG(REG_TYPE_CONST, 0, SWIZZLE_HHH, SWIZZLE_HALF, @@ -273,7 +273,7 @@ static const GLuint pfs_half = REG(REG_TYPE_TEMP, GL_TRUE); /* constant zero source */ -static const GLuint pfs_zero = REG(REG_TYPE_TEMP, +static const GLuint pfs_zero = REG(REG_TYPE_CONST, 0, SWIZZLE_000, SWIZZLE_ZERO, @@ -463,7 +463,8 @@ static int swz_native(struct r300_fragment_program *rp, GLuint arbneg) { /* Native swizzle, handle negation */ - src |= ((arbneg >> 3) & 1) << REG_NEGS_SHIFT; + src = (src & ~REG_NEGS_SHIFT) | + (((arbneg >> 3) & 1) << REG_NEGS_SHIFT); if ((arbneg & 0x7) == 0x0) { src = src & ~REG_NEGV_MASK; -- cgit v1.2.3 From c2b185cff82a6cdb723cda4e05ffe1a213a9de3e Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 5 Jan 2007 18:19:58 -0800 Subject: Add reporting of damage by DRI drivers when the extension support is available. With this, tools like ximagesrc in gstreamer correctly see updates from GL rendering. Support requires that the Xdamage library be current (but will be disabled if not present) plus a new X Server with support for the new XDamagePost request. libGL now has a new interface version, and also links against libXdamage and libXfixes to support it, but backwards compatibility is retained. Currently, all drivers report damage at SwapBuffers time through common code -- front buffer rendering doesn't result in damage being reported. Also, the damage is against the root window, as our drivers don't yet render to backing store when they should (composited environments). --- configs/freebsd-dri | 3 +- configs/linux-dri | 3 +- include/GL/internal/dri_interface.h | 20 +++++++++++ src/glx/x11/glxcmds.c | 3 +- src/glx/x11/glxext.c | 66 ++++++++++++++++++++++++++++++++++ src/mesa/drivers/dri/common/dri_util.c | 21 ++++++++++- 6 files changed, 112 insertions(+), 4 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/configs/freebsd-dri b/configs/freebsd-dri index 68877c612e..1492e4a4d9 100644 --- a/configs/freebsd-dri +++ b/configs/freebsd-dri @@ -28,7 +28,8 @@ ASM_SOURCES = LIBDRM_CFLAGS = `pkg-config --cflags libdrm` LIBDRM_LIB = `pkg-config --libs libdrm` DRI_LIB_DEPS = -L/usr/local/lib -lm -lpthread -lexpat $(LIBDRM_LIB) -GL_LIB_DEPS = -L/usr/X11R6/lib -lX11 -lXext -lXxf86vm -lm -lpthread $(LIBDRM_LIB) +GL_LIB_DEPS = -L/usr/X11R6/lib -lX11 -lXext -lXxf86vm -lXdamage -lXfixes \ + -lm -lpthread $(LIBDRM_LIB) GLUT_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -L/usr/X11R6/lib -lGLU -lGL -lX11 -lXmu -lXt -lXi -lm GLW_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -L/usr/X11R6/lib -lGL -lXt -lX11 diff --git a/configs/linux-dri b/configs/linux-dri index 7e822e2eb6..5f945a73f1 100644 --- a/configs/linux-dri +++ b/configs/linux-dri @@ -41,7 +41,8 @@ EXTRA_LIB_PATH=-L/usr/X11R6/lib LIBDRM_CFLAGS = `pkg-config --cflags libdrm` LIBDRM_LIB = `pkg-config --libs libdrm` DRI_LIB_DEPS = $(EXTRA_LIB_PATH) -lm -lpthread -lexpat -ldl $(LIBDRM_LIB) -GL_LIB_DEPS = $(EXTRA_LIB_PATH) -lX11 -lXext -lXxf86vm -lm -lpthread -ldl \ +GL_LIB_DEPS = $(EXTRA_LIB_PATH) -lX11 -lXext -lXxf86vm -lXdamage -lXfixes \ + -lm -lpthread -ldl \ $(LIBDRM_LIB) diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index c204ecfe62..a3de2c6aab 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -237,6 +237,26 @@ struct __DRIinterfaceMethodsRec { GLboolean (*getMSCRate)(__DRInativeDisplay * dpy, __DRIid drawable, int32_t * numerator, int32_t * denominator); /*@}*/ + + /** + * Reports areas of the given drawable which have been modified by the + * driver. + * + * \param drawable which the drawing was done to. + * \param rects rectangles affected, with the drawable origin as the + * origin. + * \param x X offset of the drawable within the screen (used in the + * front_buffer case) + * \param y Y offset of the drawable within the screen. + * \param front_buffer boolean flag for whether the drawing to the + * drawable was actually done directly to the front buffer (instead + * of backing storage, for example) + */ + void (*reportDamage)(__DRInativeDisplay * dpy, int screen, + __DRIid drawable, + int x, int y, + drm_clip_rect_t *rects, int num_rects, + int front_buffer); }; diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c index 9d1bb2a0b5..f52b71ffcd 100644 --- a/src/glx/x11/glxcmds.c +++ b/src/glx/x11/glxcmds.c @@ -2883,8 +2883,9 @@ int __glXGetInternalVersion(void) * 20050727 - Gut all the old interfaces. This breaks compatability with * any DRI driver built to any previous version. * 20060314 - Added support for GLX_MESA_copy_sub_buffer. + * 20070105 - Added support for damage reporting. */ - return 20060314; + return 20070105; } diff --git a/src/glx/x11/glxext.c b/src/glx/x11/glxext.c index 8bec2c34c6..29b3a1c01c 100644 --- a/src/glx/x11/glxext.c +++ b/src/glx/x11/glxext.c @@ -48,6 +48,8 @@ #include #include #include +#include +#include #include #include "indirect_init.h" #include "glapi.h" @@ -698,6 +700,68 @@ static __DRIfuncPtr get_proc_address( const char * proc_name ) return NULL; } +#ifdef XDAMAGE_1_1_INTERFACE +static GLboolean has_damage_post(__DRInativeDisplay *dpy) +{ + static GLboolean inited = GL_FALSE; + static GLboolean has_damage; + + if (!inited) { + int major, minor; + + if (XDamageQueryVersion(dpy, &major, &minor) && + major == 1 && minor >= 1) + { + has_damage = GL_TRUE; + } else { + has_damage = GL_FALSE; + } + inited = GL_TRUE; + } + + return has_damage; +} +#endif /* XDAMAGE_1_1_INTERFACE */ + +static void __glXReportDamage(__DRInativeDisplay *dpy, int screen, + __DRIid drawable, + int x, int y, + drm_clip_rect_t *rects, int num_rects, + GLboolean front_buffer) +{ +#ifdef XDAMAGE_1_1_INTERFACE + XRectangle *xrects; + XserverRegion region; + int i; + int x_off, y_off; + + if (!has_damage_post(dpy)) + return; + + if (front_buffer) { + x_off = x; + y_off = y; + drawable = RootWindow(dpy, screen); + } else{ + x_off = 0; + y_off = 0; + } + + xrects = malloc(sizeof(XRectangle) * num_rects); + if (xrects == NULL) + return; + + for (i = 0; i < num_rects; i++) { + xrects[i].x = rects[i].x1 + x_off; + xrects[i].y = rects[i].y1 + y_off; + xrects[i].width = rects[i].x2 - rects[i].x1; + xrects[i].height = rects[i].y2 - rects[i].y1; + } + region = XFixesCreateRegion(dpy, xrects, num_rects); + XDamagePost(dpy, drawable, region); + XFixesDestroyRegion(dpy, region); +#endif +} /** * Table of functions exported by the loader to the driver. @@ -720,6 +784,8 @@ static const __DRIinterfaceMethods interface_methods = { __glXGetUST, __glXGetMscRateOML, + + __glXReportDamage, }; diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index ba251a8143..cc3dcf9d8d 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -482,8 +482,27 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp) static void driSwapBuffers( __DRInativeDisplay *dpy, void *drawablePrivate ) { __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate; + drm_clip_rect_t rect; + dPriv->swapBuffers(dPriv); - (void) dpy; + + /* Check that we actually have the new damage report method */ + if (api_ver < 20070105 || dri_interface->reportDamage == NULL) + return; + + /* Assume it's affecting the whole drawable for now */ + rect.x1 = 0; + rect.y1 = 0; + rect.x2 = rect.x1 + dPriv->w; + rect.y2 = rect.y1 + dPriv->h; + + /* Report the damage. Currently, all our drivers draw directly to the + * front buffer, so we report the damage there rather than to the backing + * store (if any). + */ + (*dri_interface->reportDamage)(dpy, dPriv->screen, dPriv->draw, + dPriv->x, dPriv->y, + &rect, 1, GL_TRUE); } /** -- cgit v1.2.3 From e54ec49155052ab663d8671e7036d985992464a3 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 11 Oct 2006 12:16:09 -0700 Subject: i965: Connect INTEL_DEBUG=sync up to cmd/batch ioctls. Signed-off-by: Keith Packard --- src/mesa/drivers/dri/i965/intel_ioctl.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i965/intel_ioctl.c b/src/mesa/drivers/dri/i965/intel_ioctl.c index f3b76db215..4da31277ea 100644 --- a/src/mesa/drivers/dri/i965/intel_ioctl.c +++ b/src/mesa/drivers/dri/i965/intel_ioctl.c @@ -43,6 +43,26 @@ #include "drm.h" #include "bufmgr.h" +static int intelWaitIdleLocked( struct intel_context *intel ) +{ + static int in_wait_idle = 0; + unsigned int fence; + + if (!in_wait_idle) { + if (INTEL_DEBUG & DEBUG_SYNC) { + fprintf(stderr, "waiting for idle\n"); + } + + in_wait_idle = 1; + fence = bmSetFence(intel); + intelWaitIrq(intel, fence); + in_wait_idle = 0; + + return bmTestFence(intel, fence); + } else { + return 1; + } +} int intelEmitIrqLocked( struct intel_context *intel ) { @@ -140,7 +160,11 @@ void intel_batch_ioctl( struct intel_context *intel, UNLOCK_HARDWARE(intel); exit(1); } - } + + if (INTEL_DEBUG & DEBUG_SYNC) { + intelWaitIdleLocked(intel); + } + } } void intel_cmd_ioctl( struct intel_context *intel, @@ -172,5 +196,9 @@ void intel_cmd_ioctl( struct intel_context *intel, UNLOCK_HARDWARE(intel); exit(1); } - } + + if (INTEL_DEBUG & DEBUG_SYNC) { + intelWaitIdleLocked(intel); + } + } } -- cgit v1.2.3 From 1b9f78195f62959601d440475a6cbba5e8046813 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 18 Oct 2006 00:24:01 -0700 Subject: i965: Avoid branch instructions while in single program flow mode. There is an errata for Broadwater that threads don't have the instruction/loop mask stacks initialized on thread spawn. In single program flow mode, those stacks are not writable, so we can't initialize them. However, they do get read during ELSE and ENDIF instructions. So, instead, replace branch instructions in single program flow mode with predicated jumps (ADD to the ip register), avoiding use of the more complicated branch instructions that may fail. This is also a minor optimization as no ENDIF equivalent is necessary. Signed-off-by: Keith Packard --- src/mesa/drivers/dri/i965/brw_clip.c | 2 + src/mesa/drivers/dri/i965/brw_eu.h | 1 + src/mesa/drivers/dri/i965/brw_eu_emit.c | 155 ++++++++++++++++++++------------ src/mesa/drivers/dri/i965/brw_gs.c | 4 +- src/mesa/drivers/dri/i965/brw_structs.h | 22 ++++- 5 files changed, 125 insertions(+), 59 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i965/brw_clip.c b/src/mesa/drivers/dri/i965/brw_clip.c index 0e8591aaa8..3bec153075 100644 --- a/src/mesa/drivers/dri/i965/brw_clip.c +++ b/src/mesa/drivers/dri/i965/brw_clip.c @@ -62,6 +62,8 @@ static void compile_clip_prog( struct brw_context *brw, */ brw_init_compile(&c.func); + c.func.single_program_flow = 1; + c.key = *key; diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h index 1afa0f816b..d4dbcf38a7 100644 --- a/src/mesa/drivers/dri/i965/brw_eu.h +++ b/src/mesa/drivers/dri/i965/brw_eu.h @@ -104,6 +104,7 @@ struct brw_compile { struct brw_instruction *current; GLuint flag_value; + GLboolean single_program_flow; }; diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c index 6425c91450..9992b47d8a 100644 --- a/src/mesa/drivers/dri/i965/brw_eu_emit.c +++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c @@ -464,7 +464,6 @@ struct brw_instruction *brw_JMPI(struct brw_compile *p, return insn; } - /* EU takes the value from the flag register and pushes it onto some * sort of a stack (presumably merging with any flag value already on * the stack). Within an if block, the flags at the top of the stack @@ -482,7 +481,16 @@ struct brw_instruction *brw_JMPI(struct brw_compile *p, */ struct brw_instruction *brw_IF(struct brw_compile *p, GLuint execute_size) { - struct brw_instruction *insn = next_insn(p, BRW_OPCODE_IF); + struct brw_instruction *insn; + + if (p->single_program_flow) { + assert(execute_size == BRW_EXECUTE_1); + + insn = next_insn(p, BRW_OPCODE_ADD); + insn->header.predicate_inverse = 1; + } else { + insn = next_insn(p, BRW_OPCODE_IF); + } /* Override the defaults for this instruction: */ @@ -504,7 +512,13 @@ struct brw_instruction *brw_IF(struct brw_compile *p, GLuint execute_size) struct brw_instruction *brw_ELSE(struct brw_compile *p, struct brw_instruction *if_insn) { - struct brw_instruction *insn = next_insn(p, BRW_OPCODE_ELSE); + struct brw_instruction *insn; + + if (p->single_program_flow) { + insn = next_insn(p, BRW_OPCODE_ADD); + } else { + insn = next_insn(p, BRW_OPCODE_ELSE); + } brw_set_dest(insn, brw_ip_reg()); brw_set_src0(insn, brw_ip_reg()); @@ -516,11 +530,17 @@ struct brw_instruction *brw_ELSE(struct brw_compile *p, /* Patch the if instruction to point at this instruction. */ - assert(if_insn->header.opcode == BRW_OPCODE_IF); + if (p->single_program_flow) { + assert(if_insn->header.opcode == BRW_OPCODE_ADD); - if_insn->bits3.if_else.jump_count = insn - if_insn; - if_insn->bits3.if_else.pop_count = 1; - if_insn->bits3.if_else.pad0 = 0; + if_insn->bits3.ud = (insn - if_insn + 1) * 16; + } else { + assert(if_insn->header.opcode == BRW_OPCODE_IF); + + if_insn->bits3.if_else.jump_count = insn - if_insn; + if_insn->bits3.if_else.pop_count = 1; + if_insn->bits3.if_else.pad0 = 0; + } return insn; } @@ -528,63 +548,76 @@ struct brw_instruction *brw_ELSE(struct brw_compile *p, void brw_ENDIF(struct brw_compile *p, struct brw_instruction *patch_insn) { - struct brw_instruction *insn = next_insn(p, BRW_OPCODE_ENDIF); + if (p->single_program_flow) { + /* In single program flow mode, there's no need to execute an ENDIF, + * since we don't need to do any stack operations, and if we're executing + * currently, we want to just continue executing. + */ + struct brw_instruction *next = &p->store[p->nr_insn]; - brw_set_dest(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD)); - brw_set_src0(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD)); - brw_set_src1(insn, brw_imm_d(0x0)); + assert(patch_insn->header.opcode == BRW_OPCODE_ADD); - insn->header.compression_control = BRW_COMPRESSION_NONE; - insn->header.execution_size = patch_insn->header.execution_size; - insn->header.mask_control = BRW_MASK_ENABLE; + patch_insn->bits3.ud = (next - patch_insn) * 16; + } else { + struct brw_instruction *insn = next_insn(p, BRW_OPCODE_ENDIF); - assert(patch_insn->bits3.if_else.jump_count == 0); - - /* Patch the if or else instructions to point at this or the next - * instruction respectively. - */ - if (patch_insn->header.opcode == BRW_OPCODE_IF) { - /* Automagically turn it into an IFF: + brw_set_dest(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD)); + brw_set_src0(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD)); + brw_set_src1(insn, brw_imm_d(0x0)); + + insn->header.compression_control = BRW_COMPRESSION_NONE; + insn->header.execution_size = patch_insn->header.execution_size; + insn->header.mask_control = BRW_MASK_ENABLE; + + assert(patch_insn->bits3.if_else.jump_count == 0); + + /* Patch the if or else instructions to point at this or the next + * instruction respectively. */ - patch_insn->header.opcode = BRW_OPCODE_IFF; - patch_insn->bits3.if_else.jump_count = insn - patch_insn + 1; - patch_insn->bits3.if_else.pop_count = 0; - patch_insn->bits3.if_else.pad0 = 0; + if (patch_insn->header.opcode == BRW_OPCODE_IF) { + /* Automagically turn it into an IFF: + */ + patch_insn->header.opcode = BRW_OPCODE_IFF; + patch_insn->bits3.if_else.jump_count = insn - patch_insn + 1; + patch_insn->bits3.if_else.pop_count = 0; + patch_insn->bits3.if_else.pad0 = 0; + } else if (patch_insn->header.opcode == BRW_OPCODE_ELSE) { + patch_insn->bits3.if_else.jump_count = insn - patch_insn + 1; + patch_insn->bits3.if_else.pop_count = 1; + patch_insn->bits3.if_else.pad0 = 0; + } else { + assert(0); + } + /* Also pop item off the stack in the endif instruction: + */ + insn->bits3.if_else.jump_count = 0; + insn->bits3.if_else.pop_count = 1; + insn->bits3.if_else.pad0 = 0; } - else if (patch_insn->header.opcode == BRW_OPCODE_ELSE) { - patch_insn->bits3.if_else.jump_count = insn - patch_insn + 1; - patch_insn->bits3.if_else.pop_count = 1; - patch_insn->bits3.if_else.pad0 = 0; - } - else { - assert(0); - } - - /* Also pop item off the stack in the endif instruction: - */ - insn->bits3.if_else.jump_count = 0; - insn->bits3.if_else.pop_count = 1; - insn->bits3.if_else.pad0 = 0; } /* DO/WHILE loop: */ struct brw_instruction *brw_DO(struct brw_compile *p, GLuint execute_size) { - struct brw_instruction *insn = next_insn(p, BRW_OPCODE_DO); + if (p->single_program_flow) { + return &p->store[p->nr_insn]; + } else { + struct brw_instruction *insn = next_insn(p, BRW_OPCODE_DO); - /* Override the defaults for this instruction: - */ - brw_set_dest(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD)); - brw_set_src0(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD)); - brw_set_src1(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD)); + /* Override the defaults for this instruction: + */ + brw_set_dest(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD)); + brw_set_src0(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD)); + brw_set_src1(insn, retype(brw_vec1_grf(0,0), BRW_REGISTER_TYPE_UD)); - insn->header.compression_control = BRW_COMPRESSION_NONE; - insn->header.execution_size = execute_size; -/* insn->header.mask_control = BRW_MASK_ENABLE; */ + insn->header.compression_control = BRW_COMPRESSION_NONE; + insn->header.execution_size = execute_size; + /* insn->header.mask_control = BRW_MASK_ENABLE; */ - return insn; + return insn; + } } @@ -592,19 +625,31 @@ struct brw_instruction *brw_DO(struct brw_compile *p, GLuint execute_size) void brw_WHILE(struct brw_compile *p, struct brw_instruction *do_insn) { - struct brw_instruction *insn = next_insn(p, BRW_OPCODE_WHILE); + struct brw_instruction *insn; + + if (p->single_program_flow) + insn = next_insn(p, BRW_OPCODE_ADD); + else + insn = next_insn(p, BRW_OPCODE_WHILE); brw_set_dest(insn, brw_ip_reg()); brw_set_src0(insn, brw_ip_reg()); brw_set_src1(insn, brw_imm_d(0x0)); insn->header.compression_control = BRW_COMPRESSION_NONE; - insn->header.execution_size = do_insn->header.execution_size; - assert(do_insn->header.opcode == BRW_OPCODE_DO); - insn->bits3.if_else.jump_count = do_insn - insn; - insn->bits3.if_else.pop_count = 0; - insn->bits3.if_else.pad0 = 0; + if (p->single_program_flow) { + insn->header.execution_size = BRW_EXECUTE_1; + + insn->bits3.d = (do_insn - insn) * 16; + } else { + insn->header.execution_size = do_insn->header.execution_size; + + assert(do_insn->header.opcode == BRW_OPCODE_DO); + insn->bits3.if_else.jump_count = do_insn - insn; + insn->bits3.if_else.pop_count = 0; + insn->bits3.if_else.pad0 = 0; + } /* insn->header.mask_control = BRW_MASK_ENABLE; */ diff --git a/src/mesa/drivers/dri/i965/brw_gs.c b/src/mesa/drivers/dri/i965/brw_gs.c index 7d3f9dd5e3..9066e42252 100644 --- a/src/mesa/drivers/dri/i965/brw_gs.c +++ b/src/mesa/drivers/dri/i965/brw_gs.c @@ -66,7 +66,9 @@ static void compile_gs_prog( struct brw_context *brw, /* Begin the compilation: */ brw_init_compile(&c.func); - + + c.func.single_program_flow = 1; + /* For some reason the thread is spawned with only 4 channels * unmasked. */ diff --git a/src/mesa/drivers/dri/i965/brw_structs.h b/src/mesa/drivers/dri/i965/brw_structs.h index 25acdcfe94..10fee944e8 100644 --- a/src/mesa/drivers/dri/i965/brw_structs.h +++ b/src/mesa/drivers/dri/i965/brw_structs.h @@ -519,7 +519,22 @@ struct thread3 struct brw_clip_unit_state { struct thread0 thread0; - struct thread1 thread1; + struct + { + GLuint pad0:7; + GLuint sw_exception_enable:1; + GLuint pad1:3; + GLuint mask_stack_exception_enable:1; + GLuint pad2:1; + GLuint illegal_op_exception_enable:1; + GLuint pad3:2; + GLuint floating_point_mode:1; + GLuint thread_priority:1; + GLuint binding_table_entry_count:8; + GLuint pad4:5; + GLuint single_program_flow:1; + } thread1; + struct thread2 thread2; struct thread3 thread3; @@ -532,8 +547,8 @@ struct brw_clip_unit_state GLuint pad1:1; GLuint urb_entry_allocation_size:5; GLuint pad2:1; - GLuint max_threads:6; /* may be less */ - GLuint pad3:1; + GLuint max_threads:1; /* may be less */ + GLuint pad3:6; } thread4; struct @@ -1322,6 +1337,7 @@ struct brw_instruction GLuint end_of_thread:1; } generic; + GLint d; GLuint ud; } bits3; }; -- cgit v1.2.3 From 4068e2d1b766a9ccedcb8d7cd07c49d22dff39f0 Mon Sep 17 00:00:00 2001 From: Wang Zhenyu Date: Mon, 11 Dec 2006 00:01:56 -0800 Subject: i965: ARB_occlusion_query support Signed-off-by: Keith Packard --- src/mesa/drivers/dri/i965/brw_wm_state.c | 2 +- src/mesa/drivers/dri/i965/intel_context.c | 34 ++++++++++++++++++++++++++ src/mesa/drivers/dri/i965/intel_context.h | 1 + src/mesa/drivers/dri/i965/server/i830_common.h | 19 ++++++++++++++ 4 files changed, 55 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c index 4707a709e7..e41042d6d2 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_state.c @@ -168,7 +168,7 @@ static void upload_wm_unit(struct brw_context *brw ) wm.wm5.line_stipple = 1; } - if (INTEL_DEBUG & DEBUG_STATS) + if (INTEL_DEBUG & DEBUG_STATS || intel->stats_wm) wm.wm4.stats_enable = 1; brw->wm.state_gs_offset = brw_cache_data( &brw->cache[BRW_WM_UNIT], &wm ); diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 5e97e4d609..9acafe5310 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -70,6 +70,7 @@ int INTEL_DEBUG = (0); #define need_GL_ARB_vertex_buffer_object #define need_GL_ARB_vertex_program #define need_GL_ARB_window_pos +#define need_GL_ARB_occlusion_query #define need_GL_EXT_blend_color #define need_GL_EXT_blend_equation_separate #define need_GL_EXT_blend_func_separate @@ -157,6 +158,7 @@ const struct dri_extension card_extensions[] = { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions }, { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions }, { "GL_ARB_window_pos", GL_ARB_window_pos_functions }, + { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions}, { "GL_EXT_blend_color", GL_EXT_blend_color_functions }, { "GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions }, { "GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions }, @@ -241,6 +243,36 @@ void intelFinish( GLcontext *ctx ) bmFinishFence(intel, bmLockAndFence(intel)); } +static void +intelBeginQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) +{ + struct intel_context *intel = intel_context( ctx ); + GLuint64EXT tmp = 0; + drmI830MMIO io = { + .read_write = MMIO_WRITE, + .reg = MMIO_REGS_PS_DEPTH_COUNT, + .data = &tmp + }; + intel->stats_wm = GL_TRUE; + intelFinish(&intel->ctx); + drmCommandWrite(intel->driFd, DRM_I830_MMIO, &io, sizeof(io)); +} + +static void +intelEndQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) +{ + struct intel_context *intel = intel_context( ctx ); + drmI830MMIO io = { + .read_write = MMIO_READ, + .reg = MMIO_REGS_PS_DEPTH_COUNT, + .data = &q->Result + }; + intelFinish(&intel->ctx); + drmCommandRead(intel->driFd, DRM_I830_MMIO, &io, sizeof(io)); + q->Ready = GL_TRUE; + intel->stats_wm = GL_FALSE; +} + void intelInitDriverFunctions( struct dd_function_table *functions ) { @@ -250,6 +282,8 @@ void intelInitDriverFunctions( struct dd_function_table *functions ) functions->Finish = intelFinish; functions->GetString = intelGetString; functions->UpdateState = intelInvalidateState; + functions->BeginQuery = intelBeginQuery; + functions->EndQuery = intelEndQuery; /* CopyPixels can be accelerated even with the current memory * manager: diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h index 8367a95710..fe7ee382a1 100644 --- a/src/mesa/drivers/dri/i965/intel_context.h +++ b/src/mesa/drivers/dri/i965/intel_context.h @@ -177,6 +177,7 @@ struct intel_context GLuint second_last_swap_fence; GLboolean aub_wrap; + GLboolean stats_wm; struct intel_batchbuffer *batch; diff --git a/src/mesa/drivers/dri/i965/server/i830_common.h b/src/mesa/drivers/dri/i965/server/i830_common.h index e3bbdc7907..f320378c2a 100644 --- a/src/mesa/drivers/dri/i965/server/i830_common.h +++ b/src/mesa/drivers/dri/i965/server/i830_common.h @@ -52,6 +52,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define DRM_I830_INIT_HEAP 0x0a #define DRM_I830_CMDBUFFER 0x0b #define DRM_I830_DESTROY_HEAP 0x0c +#define DRM_I830_MMIO 0x10 typedef struct { enum { @@ -199,5 +200,23 @@ typedef struct { int region; } drmI830MemDestroyHeap; +#define MMIO_READ 0 +#define MMIO_WRITE 1 + +#define MMIO_REGS_IA_PRIMATIVES_COUNT 0 +#define MMIO_REGS_IA_VERTICES_COUNT 1 +#define MMIO_REGS_VS_INVOCATION_COUNT 2 +#define MMIO_REGS_GS_PRIMITIVES_COUNT 3 +#define MMIO_REGS_GS_INVOCATION_COUNT 4 +#define MMIO_REGS_CL_PRIMITIVES_COUNT 5 +#define MMIO_REGS_CL_INVOCATION_COUNT 6 +#define MMIO_REGS_PS_INVOCATION_COUNT 7 +#define MMIO_REGS_PS_DEPTH_COUNT 8 + +typedef struct { + unsigned int read_write:1; + unsigned int reg:31; + void __user *data; +} drmI830MMIO; #endif /* _I830_DRM_H_ */ -- cgit v1.2.3 From 652ae2c3765a471f94ca7b7328a0d572182bb127 Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Tue, 12 Dec 2006 15:00:27 +0800 Subject: i965: Take clip rects into account when computing max prim Signed-off-by: Keith Packard --- src/mesa/drivers/dri/i965/brw_exec_api.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i965/brw_exec_api.c b/src/mesa/drivers/dri/i965/brw_exec_api.c index 470fa6f417..8b243c6084 100644 --- a/src/mesa/drivers/dri/i965/brw_exec_api.c +++ b/src/mesa/drivers/dri/i965/brw_exec_api.c @@ -42,6 +42,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "dispatch.h" #include "brw_exec.h" +#include "intel_context.h" + static void reset_attrfv( struct brw_exec_context *exec ); @@ -522,6 +524,14 @@ static void GLAPIENTRY brw_exec_Begin( GLenum mode ) } +static GLuint brw_max_prim( GLcontext *ctx ) +{ + struct intel_context *intel = intel_context( ctx ); + if (intel->numClipRects <= 1) + return BRW_MAX_PRIM; + return BRW_MAX_PRIM/intel->numClipRects; +} + static void GLAPIENTRY brw_exec_End( void ) { GET_CURRENT_CONTEXT( ctx ); @@ -536,7 +546,7 @@ static void GLAPIENTRY brw_exec_End( void ) ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1; - if (exec->vtx.prim_count == BRW_MAX_PRIM) + if (exec->vtx.prim_count >= brw_max_prim(ctx)) brw_exec_vtx_flush( exec ); } else -- cgit v1.2.3 From ef02f8be10a9f95788fee48bb9e7801dea0c2ba6 Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Wed, 13 Dec 2006 15:27:17 +0800 Subject: i965: xdemos/glxthreads get: Assertion `block->fenced' failed (9201) Signed-off-by: Keith Packard --- src/mesa/drivers/dri/i965/bufmgr.h | 2 ++ src/mesa/drivers/dri/i965/bufmgr_fake.c | 16 ++++++++++++++-- src/mesa/drivers/dri/i965/intel_blit.c | 4 ++-- 3 files changed, 18 insertions(+), 4 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i965/bufmgr.h b/src/mesa/drivers/dri/i965/bufmgr.h index 6932522d3d..e748c0d6d0 100644 --- a/src/mesa/drivers/dri/i965/bufmgr.h +++ b/src/mesa/drivers/dri/i965/bufmgr.h @@ -199,9 +199,11 @@ void *bmFindVirtual( struct intel_context *intel, * For now they can stay, but will likely change/move before final: */ unsigned bmSetFence( struct intel_context * ); +unsigned bmSetFenceLock( struct intel_context * ); unsigned bmLockAndFence( struct intel_context *intel ); int bmTestFence( struct intel_context *, unsigned fence ); void bmFinishFence( struct intel_context *, unsigned fence ); +void bmFinishFenceLock( struct intel_context *, unsigned fence ); void bm_fake_NotifyContendedLockTake( struct intel_context * ); diff --git a/src/mesa/drivers/dri/i965/bufmgr_fake.c b/src/mesa/drivers/dri/i965/bufmgr_fake.c index ed88ab3797..205dc722c0 100644 --- a/src/mesa/drivers/dri/i965/bufmgr_fake.c +++ b/src/mesa/drivers/dri/i965/bufmgr_fake.c @@ -338,7 +338,6 @@ static int evict_mru( struct intel_context *intel, GLuint *pool ) } - static int check_fenced( struct intel_context *intel ) { struct bufmgr *bm = intel->bm; @@ -1328,11 +1327,19 @@ unsigned bmSetFence( struct intel_context *intel ) return intel->bm->last_fence; } +unsigned bmSetFenceLock( struct intel_context *intel ) +{ + LOCK(intel->bm); + bmSetFence(intel); + UNLOCK(intel->bm); +} unsigned bmLockAndFence( struct intel_context *intel ) { if (intel->bm->need_fence) { LOCK_HARDWARE(intel); + LOCK(intel->bm); bmSetFence(intel); + UNLOCK(intel->bm); UNLOCK_HARDWARE(intel); } @@ -1350,7 +1357,12 @@ void bmFinishFence( struct intel_context *intel, unsigned fence ) check_fenced(intel); } - +void bmFinishFenceLock( struct intel_context *intel, unsigned fence ) +{ + LOCK(intel->bm); + bmFinishFence(intel, fence); + UNLOCK(intel->bm); +} /* Specifically ignore texture memory sharing. diff --git a/src/mesa/drivers/dri/i965/intel_blit.c b/src/mesa/drivers/dri/i965/intel_blit.c index c8c5bf93c9..173d1d5b6c 100644 --- a/src/mesa/drivers/dri/i965/intel_blit.c +++ b/src/mesa/drivers/dri/i965/intel_blit.c @@ -66,7 +66,7 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv, intelFlush( &intel->ctx ); - bmFinishFence(intel, intel->last_swap_fence); + bmFinishFenceLock(intel, intel->last_swap_fence); /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets * should work regardless. @@ -155,7 +155,7 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv, intel_batchbuffer_flush( intel->batch ); intel->second_last_swap_fence = intel->last_swap_fence; - intel->last_swap_fence = bmSetFence( intel ); + intel->last_swap_fence = bmSetFenceLock( intel ); UNLOCK_HARDWARE( intel ); if (!rect) -- cgit v1.2.3 From 9311c29558156859c6b26389c1b20a25d361d39d Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 6 Jan 2007 17:13:29 -0800 Subject: Initialize GL_ARB_occlusion_query only if DRM support is present. DRM versions before 1.8 do not include the necessary ioctls to support GL_ARB_occlusion_query, don't enable it on these versions. --- src/mesa/drivers/dri/i965/intel_context.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 9acafe5310..459ed109ed 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -33,6 +33,7 @@ #include "extensions.h" #include "framebuffer.h" #include "imports.h" +#include "points.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" @@ -158,7 +159,6 @@ const struct dri_extension card_extensions[] = { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions }, { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions }, { "GL_ARB_window_pos", GL_ARB_window_pos_functions }, - { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions}, { "GL_EXT_blend_color", GL_EXT_blend_color_functions }, { "GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions }, { "GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions }, @@ -184,7 +184,8 @@ const struct dri_extension card_extensions[] = { NULL, NULL } }; - +static const struct dri_extension arb_oc_extension = + { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions}; static const struct dri_debug_control debug_control[] = { @@ -412,6 +413,9 @@ GLboolean intelInitContext( struct intel_context *intel, driInitExtensions( ctx, card_extensions, GL_TRUE ); + if (intel->intelScreen->drmMinor >= 8) + driInitSingleExtension (ctx, &arb_oc_extension); + INTEL_DEBUG = driParseDebugString( getenv( "INTEL_DEBUG" ), debug_control ); -- cgit v1.2.3 From 62db3cc34982d2fec9165633813ef6e656f7d497 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 6 Jan 2007 17:13:45 -0800 Subject: Various warning fixes for i965 driver. vertex/fragment programs provided as const. bmSetFenceLock should return bmSetFence value. --- src/mesa/drivers/dri/i965/brw_context.h | 4 ++-- src/mesa/drivers/dri/i965/brw_metaops.c | 3 +-- src/mesa/drivers/dri/i965/brw_vs_tnl.c | 4 ++-- src/mesa/drivers/dri/i965/brw_wm_state.c | 2 +- src/mesa/drivers/dri/i965/bufmgr_fake.c | 4 +++- 5 files changed, 9 insertions(+), 8 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index cac4d86d3a..9ee81b8725 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -505,8 +505,8 @@ struct brw_context /* Active vertex program: */ - struct gl_vertex_program *vertex_program; - struct gl_fragment_program *fragment_program; + const struct gl_vertex_program *vertex_program; + const struct gl_fragment_program *fragment_program; /* For populating the gtt: diff --git a/src/mesa/drivers/dri/i965/brw_metaops.c b/src/mesa/drivers/dri/i965/brw_metaops.c index 2deec5eae3..acd1d58191 100644 --- a/src/mesa/drivers/dri/i965/brw_metaops.c +++ b/src/mesa/drivers/dri/i965/brw_metaops.c @@ -492,8 +492,7 @@ static void meta_draw_quad(struct intel_context *intel, } -static void install_meta_state( struct intel_context *intel, - GLenum state ) +static void install_meta_state( struct intel_context *intel ) { GLcontext *ctx = &intel->ctx; struct brw_context *brw = brw_context(ctx); diff --git a/src/mesa/drivers/dri/i965/brw_vs_tnl.c b/src/mesa/drivers/dri/i965/brw_vs_tnl.c index b7893ca3e5..82c1958887 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_tnl.c +++ b/src/mesa/drivers/dri/i965/brw_vs_tnl.c @@ -114,7 +114,7 @@ static GLuint translate_texgen( GLboolean enabled, GLenum mode ) static void make_state_key( GLcontext *ctx, struct state_key *key ) { struct brw_context *brw = brw_context(ctx); - struct gl_fragment_program *fp = brw->fragment_program; + const struct gl_fragment_program *fp = brw->fragment_program; GLuint i; /* This now relies on texenvprogram.c being active: @@ -1628,7 +1628,7 @@ const struct brw_tracked_state brw_tnl_vertprog = { static void update_active_vertprog( struct brw_context *brw ) { - struct gl_vertex_program *prev = brw->vertex_program; + const struct gl_vertex_program *prev = brw->vertex_program; /* NEW_PROGRAM */ if (brw->attribs.VertexProgram->_Enabled) { diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c index e41042d6d2..ff5cb31bdd 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_state.c @@ -122,7 +122,7 @@ static void upload_wm_unit(struct brw_context *brw ) /* BRW_NEW_FRAGMENT_PROGRAM */ { - struct gl_fragment_program *fp = brw->fragment_program; + const struct gl_fragment_program *fp = brw->fragment_program; if (fp->Base.InputsRead & (1<bm); - bmSetFence(intel); + last = bmSetFence(intel); UNLOCK(intel->bm); + return last; } unsigned bmLockAndFence( struct intel_context *intel ) { -- cgit v1.2.3 From 026939b00897665f97669bafb1d486a71f90f935 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 8 Jan 2007 11:53:45 +1100 Subject: nouveau: allow the use of multiple subchannels/objects by default. --- src/mesa/drivers/dri/nouveau/nouveau_object.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.h b/src/mesa/drivers/dri/nouveau/nouveau_object.h index d5fcc6df8d..b1ff5a5d0d 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.h @@ -3,7 +3,7 @@ #include "nouveau_context.h" -//#define ALLOW_MULTI_SUBCHANNEL +#define ALLOW_MULTI_SUBCHANNEL void nouveauObjectInit(nouveauContextPtr nmesa); -- cgit v1.2.3 From 92fb742065f4de941e444916c5a146db87c71701 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Thu, 21 Dec 2006 17:30:00 +0100 Subject: intel_finalize_mipmap_tree: Only flush batchbuffer when necessary. --- src/mesa/drivers/dri/i915tex/intel_tex_validate.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_validate.c b/src/mesa/drivers/dri/i915tex/intel_tex_validate.c index e73c9c2f21..79d587a174 100644 --- a/src/mesa/drivers/dri/i915tex/intel_tex_validate.c +++ b/src/mesa/drivers/dri/i915tex/intel_tex_validate.c @@ -110,6 +110,8 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) GLuint nr_faces = 0; struct intel_texture_image *firstImage; + GLboolean need_flush = GL_FALSE; + /* We know/require this is true by now: */ assert(intelObj->base.Complete); @@ -201,11 +203,13 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) */ if (intelObj->mt != intelImage->mt) { copy_image_data_to_tree(intel, intelObj, intelImage); + need_flush = GL_TRUE; } } } - intel_batchbuffer_flush(intel->batch); + if (need_flush) + intel_batchbuffer_flush(intel->batch); return GL_TRUE; } -- cgit v1.2.3 From dfabf9660751f0d7cfc7cad6539af4d7ccd9147e Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Thu, 21 Dec 2006 18:06:58 +0100 Subject: i915tex: Remove unused tex_program field. --- src/mesa/drivers/dri/i915tex/i915_context.h | 1 - src/mesa/drivers/dri/i915tex/i915_state.c | 1 - src/mesa/drivers/dri/i915tex/i915_tex.c | 35 ----------------------------- 3 files changed, 37 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/i915_context.h b/src/mesa/drivers/dri/i915tex/i915_context.h index 5ae76fcd18..d2713e88f9 100644 --- a/src/mesa/drivers/dri/i915tex/i915_context.h +++ b/src/mesa/drivers/dri/i915tex/i915_context.h @@ -243,7 +243,6 @@ struct i915_context GLuint lodbias_ss2[MAX_TEXTURE_UNITS]; - struct i915_fragment_program tex_program; struct i915_fragment_program *current_program; struct i915_hw_state meta, initial, state, *current; diff --git a/src/mesa/drivers/dri/i915tex/i915_state.c b/src/mesa/drivers/dri/i915tex/i915_state.c index 2f5a30787e..7c742a7bd9 100644 --- a/src/mesa/drivers/dri/i915tex/i915_state.c +++ b/src/mesa/drivers/dri/i915tex/i915_state.c @@ -520,7 +520,6 @@ update_specular(GLcontext * ctx) /* A hack to trigger the rebuild of the fragment program. */ intel_context(ctx)->NewGLState |= _NEW_TEXTURE; - I915_CONTEXT(ctx)->tex_program.translated = 0; } static void diff --git a/src/mesa/drivers/dri/i915tex/i915_tex.c b/src/mesa/drivers/dri/i915tex/i915_tex.c index a53abe9a92..59e148ca04 100644 --- a/src/mesa/drivers/dri/i915tex/i915_tex.c +++ b/src/mesa/drivers/dri/i915tex/i915_tex.c @@ -52,27 +52,6 @@ i915TexEnv(GLcontext * ctx, GLenum target, struct i915_context *i915 = I915_CONTEXT(ctx); switch (pname) { - case GL_TEXTURE_ENV_COLOR: /* Should be a tracked param */ - case GL_TEXTURE_ENV_MODE: - case GL_COMBINE_RGB: - case GL_COMBINE_ALPHA: - case GL_SOURCE0_RGB: - case GL_SOURCE1_RGB: - case GL_SOURCE2_RGB: - case GL_SOURCE0_ALPHA: - case GL_SOURCE1_ALPHA: - case GL_SOURCE2_ALPHA: - case GL_OPERAND0_RGB: - case GL_OPERAND1_RGB: - case GL_OPERAND2_RGB: - case GL_OPERAND0_ALPHA: - case GL_OPERAND1_ALPHA: - case GL_OPERAND2_ALPHA: - case GL_RGB_SCALE: - case GL_ALPHA_SCALE: - i915->tex_program.translated = 0; - break; - case GL_TEXTURE_LOD_BIAS:{ GLuint unit = ctx->Texture.CurrentUnit; GLint b = (int) ((*param) * 16.0); @@ -92,22 +71,8 @@ i915TexEnv(GLcontext * ctx, GLenum target, } -static void -i915BindTexture(GLcontext * ctx, GLenum target, - struct gl_texture_object *texobj) -{ - /* Need this if image format changes between bound textures. - * Could try and shortcircuit by checking for differences in - * state between incoming and outgoing textures: - */ - I915_CONTEXT(ctx)->tex_program.translated = 0; -} - - - void i915InitTextureFuncs(struct dd_function_table *functions) { - functions->BindTexture = i915BindTexture; functions->TexEnv = i915TexEnv; } -- cgit v1.2.3 From b55f1ec9af30ddc5fa44818f85518fffe4580dc6 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Thu, 11 Jan 2007 12:53:06 +0100 Subject: Fix typo from commit 1d312ae0137eb39bf74fac91eb97ed25c289a4ca . --- src/mesa/drivers/dri/r300/r300_fragprog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c index 179bc58e9e..6e85f0b5dd 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog.c @@ -463,7 +463,7 @@ static int swz_native(struct r300_fragment_program *rp, GLuint arbneg) { /* Native swizzle, handle negation */ - src = (src & ~REG_NEGS_SHIFT) | + src = (src & ~REG_NEGS_MASK) | (((arbneg >> 3) & 1) << REG_NEGS_SHIFT); if ((arbneg & 0x7) == 0x0) { -- cgit v1.2.3 From ca75853f9d9e7d131f25daeaa7c646894ab4807e Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 13 Jan 2007 13:22:03 +0100 Subject: nv10 has alpha color mask --- src/mesa/drivers/dri/nouveau/nv10_state.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index c028be2867..162a5e2718 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -106,13 +106,12 @@ static void nv10ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) OUT_RING_CACHEf(equation[3]); } -/* Seems does not support alpha in color mask */ static void nv10ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, GLboolean bmask, GLboolean amask ) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_COLOR_MASK, 1); - OUT_RING_CACHE(/*((amask && 0x01) << 24) |*/ ((rmask && 0x01) << 16) | ((gmask && 0x01)<< 8) | ((bmask && 0x01) << 0)); + OUT_RING_CACHE(((amask && 0x01) << 24) | ((rmask && 0x01) << 16) | ((gmask && 0x01)<< 8) | ((bmask && 0x01) << 0)); } static void nv10ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode) -- cgit v1.2.3 From 308ef2dc3208e9c274763726b541f28e2169324b Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 13 Jan 2007 13:56:18 +0100 Subject: nouveau: Add clear color for nv10 --- src/mesa/drivers/dri/nouveau/nouveau_context.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index 134e2a417e..c7bf387210 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -119,7 +119,10 @@ typedef struct nouveau_context { struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; GLuint vertex_attr_count; - /* Depth/stencil clear state */ + /* Color buffer clear value */ + uint32_t clear_color_value; + + /* Depth/stencil clear value */ uint32_t clear_value; /* Light state */ -- cgit v1.2.3 From fb5f359b93073d85f4cae05cd89ff1012fafeda6 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 13 Jan 2007 14:14:19 +0100 Subject: nouveau: update nv10 state --- src/mesa/drivers/dri/nouveau/nv10_state.c | 116 +++++++++++++++--------------- 1 file changed, 56 insertions(+), 60 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 162a5e2718..d65eb94e42 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -61,40 +61,42 @@ static void nv10BlendColor(GLcontext *ctx, const GLfloat color[4]) static void nv10BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_EQUATION, 1); - OUT_RING_CACHE((modeA<<16) | modeRGB); + /* Not for NV10 */ } static void nv10BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2); - OUT_RING_CACHE((sfactorA<<16) | sfactorRGB); - OUT_RING_CACHE((dfactorA<<16) | dfactorRGB); + /* Not for NV10 */ +} + +static void nv10Clear(GLcontext *ctx, GLbitfield mask) +{ + /* TODO */ } -/* static void nv10ClearColor(GLcontext *ctx, const GLfloat color[4]) { + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte c[4]; + UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,color); + nmesa->clear_color_value = PACK_COLOR_8888(c[3],c[0],c[1],c[2]); } static void nv10ClearDepth(GLcontext *ctx, GLclampd d) { + /* FIXME: check if 16 or 24/32 bits depth buffer */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nmesa->clear_value=((nmesa->clear_value&0x000000FF)|(((uint32_t)(d*0xFFFFFF))<<8)); } -*/ -/* we're don't support indexed buffers - void (*ClearIndex)(GLcontext *ctx, GLuint index) - */ - -/* static void nv10ClearStencil(GLcontext *ctx, GLint s) { + /* FIXME: not valid for 16 bits depth buffer (0 stencil bits) */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nmesa->clear_value=((nmesa->clear_value&0xFFFFFF00)|(s&0x000000FF)); } -*/ static void nv10ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) { @@ -116,7 +118,7 @@ static void nv10ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, static void nv10ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode) { - // TODO I need love + /* TODO I need love */ } static void nv10CullFace(GLcontext *ctx, GLenum mode) @@ -320,7 +322,7 @@ static void nv10Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) static void nv10Hint(GLcontext *ctx, GLenum target, GLenum mode) { - // TODO I need love (fog and line_smooth hints) + /* TODO I need love (fog and line_smooth hints) */ } // void (*IndexMask)(GLcontext *ctx, GLuint mask); @@ -448,6 +450,7 @@ static void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params) static void nv10LineStipple(GLcontext *ctx, GLint factor, GLushort pattern ) { + /* Not for NV10 */ } static void nv10LineWidth(GLcontext *ctx, GLfloat width) @@ -471,7 +474,6 @@ static void nv10PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *pa } -/** Specify the diameter of rasterized points */ static void nv10PointSize(GLcontext *ctx, GLfloat size) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); @@ -479,7 +481,6 @@ static void nv10PointSize(GLcontext *ctx, GLfloat size) OUT_RING_CACHE(((int) (size * 8.0)) & -4); } -/** Select a polygon rasterization mode */ static void nv10PolygonMode(GLcontext *ctx, GLenum face, GLenum mode) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); @@ -495,9 +496,20 @@ static void nv10PolygonMode(GLcontext *ctx, GLenum face, GLenum mode) } /** Set the scale and units used to calculate depth values */ -void (*PolygonOffset)(GLcontext *ctx, GLfloat factor, GLfloat units); +static void nv10PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR, 2); + OUT_RING_CACHEf(factor); + OUT_RING_CACHEf(units); +} + /** Set the polygon stippling pattern */ -void (*PolygonStipple)(GLcontext *ctx, const GLubyte *mask ); +static void nv10PolygonStipple(GLcontext *ctx, const GLubyte *mask ) +{ + /* Not for NV10 */ +} + /* Specifies the current buffer for reading */ void (*ReadBuffer)( GLcontext *ctx, GLenum buffer ); /** Set rasterization mode */ @@ -517,37 +529,21 @@ static void nv10ShadeModel(GLcontext *ctx, GLenum mode) OUT_RING_CACHE(mode); } -/** OpenGL 2.0 two-sided StencilFunc */ static void nv10StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, GLint ref, GLuint mask) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC, 3); - OUT_RING_CACHE(func); - OUT_RING_CACHE(ref); - OUT_RING_CACHE(mask); + /* Not for NV10 */ } -/** OpenGL 2.0 two-sided StencilMask */ static void nv10StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_MASK, 1); - OUT_RING_CACHE(mask); + /* Not for NV10 */ } -/** OpenGL 2.0 two-sided StencilOp */ static void nv10StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, GLenum zfail, GLenum zpass) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL, 1); - OUT_RING_CACHE(fail); - OUT_RING_CACHE(zfail); - OUT_RING_CACHE(zpass); + /* Not for NV10 */ } /** Control the generation of texture coordinates */ @@ -560,7 +556,14 @@ void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname, void (*TexParameter)(GLcontext *ctx, GLenum target, struct gl_texture_object *texObj, GLenum pname, const GLfloat *params); -void (*TextureMatrix)(GLcontext *ctx, GLuint unit, const GLmatrix *mat); + +static void nv10TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16); + /*XXX: This SHOULD work.*/ + OUT_RING_CACHEp(mat->m, 16); +} /** Set the viewport */ static void nv10Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) @@ -597,13 +600,12 @@ void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) func->AlphaFunc = nv10AlphaFunc; func->BlendColor = nv10BlendColor; - func->BlendEquationSeparate = nv10BlendEquationSeparate; - func->BlendFuncSeparate = nv10BlendFuncSeparate; -#if 0 + func->BlendEquationSeparate = nv10BlendEquationSeparate; /* Not for NV10 */ + func->BlendFuncSeparate = nv10BlendFuncSeparate; /* Not for NV10 */ + func->Clear = nv10Clear; func->ClearColor = nv10ClearColor; func->ClearDepth = nv10ClearDepth; func->ClearStencil = nv10ClearStencil; -#endif func->ClipPlane = nv10ClipPlane; func->ColorMask = nv10ColorMask; func->ColorMaterial = nv10ColorMaterial; @@ -617,32 +619,26 @@ void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) func->Hint = nv10Hint; func->Lightfv = nv10Lightfv; /* func->LightModelfv = nv10LightModelfv; */ - func->LineStipple = nv10LineStipple; + func->LineStipple = nv10LineStipple; /* Not for NV10 */ func->LineWidth = nv10LineWidth; func->LogicOpcode = nv10LogicOpcode; func->PointParameterfv = nv10PointParameterfv; func->PointSize = nv10PointSize; func->PolygonMode = nv10PolygonMode; -#if 0 func->PolygonOffset = nv10PolygonOffset; - func->PolygonStipple = nv10PolygonStipple; - func->ReadBuffer = nv10ReadBuffer; - func->RenderMode = nv10RenderMode; -#endif + func->PolygonStipple = nv10PolygonStipple; /* Not for NV10 */ +/* func->ReadBuffer = nv10ReadBuffer;*/ +/* func->RenderMode = nv10RenderMode;*/ func->Scissor = nv10Scissor; func->ShadeModel = nv10ShadeModel; - func->StencilFuncSeparate = nv10StencilFuncSeparate; - func->StencilMaskSeparate = nv10StencilMaskSeparate; - func->StencilOpSeparate = nv10StencilOpSeparate; -#if 0 - func->TexGen = nv10TexGen; - func->TexParameter = nv10TexParameter; + func->StencilFuncSeparate = nv10StencilFuncSeparate; /* Not for NV10 */ + func->StencilMaskSeparate = nv10StencilMaskSeparate; /* Not for NV10 */ + func->StencilOpSeparate = nv10StencilOpSeparate; /* Not for NV10 */ +/* func->TexGen = nv10TexGen;*/ +/* func->TexParameter = nv10TexParameter;*/ func->TextureMatrix = nv10TextureMatrix; -#endif - func->Viewport = nv10Viewport; nmesa->hw_func.InitCard = nv10InitCard; nmesa->hw_func.BindBuffers = nv10BindBuffers; nmesa->hw_func.WindowMoved = nv10WindowMoved; } - -- cgit v1.2.3 From f1ad10b338996275a376809d98c420cda4d6d05a Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 14 Jan 2007 12:45:15 +0100 Subject: nouveau: nv10 blending done, remove nv10Viewport --- src/mesa/drivers/dri/nouveau/nv10_state.c | 38 +++++++++++++++++++------------ 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index d65eb94e42..518ceb31f1 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -45,6 +45,14 @@ static void nv10AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) OUT_RING_CACHE(ubRef); /* NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF */ } +/* + Supported blend extensions on NV10 + EXT_blend_color + EXT_blend_minmax + EXT_blend_subtract + NV_blend_square +*/ + static void nv10BlendColor(GLcontext *ctx, const GLfloat color[4]) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); @@ -61,14 +69,26 @@ static void nv10BlendColor(GLcontext *ctx, const GLfloat color[4]) static void nv10BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA) { - /* Not for NV10 */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + assert( modeRGB == modeA ); + + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_EQUATION, 1); + OUT_RING_CACHE(modeRGB); } static void nv10BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA) { - /* Not for NV10 */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + assert( sfactorRGB == sfactorA ); + assert( dfactorRGB == dfactorA ); + + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2); + OUT_RING_CACHE(sfactorRGB); + OUT_RING_CACHE(dfactorRGB); /* NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_DST */ } static void nv10Clear(GLcontext *ctx, GLbitfield mask) @@ -565,16 +585,6 @@ static void nv10TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) OUT_RING_CACHEp(mat->m, 16); } -/** Set the viewport */ -static void nv10Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) -{ - /* TODO: Where do the VIEWPORT_XFRM_* regs come in? */ - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2); - OUT_RING_CACHE((w << 16) | x); - OUT_RING_CACHE((h << 16) | y); -} - /* Initialise any card-specific non-GL related state */ static GLboolean nv10InitCard(nouveauContextPtr nmesa) { @@ -600,8 +610,8 @@ void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) func->AlphaFunc = nv10AlphaFunc; func->BlendColor = nv10BlendColor; - func->BlendEquationSeparate = nv10BlendEquationSeparate; /* Not for NV10 */ - func->BlendFuncSeparate = nv10BlendFuncSeparate; /* Not for NV10 */ + func->BlendEquationSeparate = nv10BlendEquationSeparate; + func->BlendFuncSeparate = nv10BlendFuncSeparate; func->Clear = nv10Clear; func->ClearColor = nv10ClearColor; func->ClearDepth = nv10ClearDepth; -- cgit v1.2.3 From 29484f24fb2c21772c6a3ddf33a77ec83d415fdc Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 14 Jan 2007 12:51:30 +0100 Subject: nouveau: nv10: currently fails initcard and bindbuffers, till done --- src/mesa/drivers/dri/nouveau/nv10_state.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 518ceb31f1..17336a7b2a 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -588,7 +588,7 @@ static void nv10TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) /* Initialise any card-specific non-GL related state */ static GLboolean nv10InitCard(nouveauContextPtr nmesa) { - return GL_TRUE; + return GL_FALSE; } /* Update buffer offset/pitch/format */ @@ -596,7 +596,7 @@ static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color, nouveau_renderbuffer **color, nouveau_renderbuffer *depth) { - return GL_TRUE; + return GL_FALSE; } /* Update anything that depends on the window position/size */ -- cgit v1.2.3 From faada2485a864298562b5e59b0703748c6f6f9d5 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 14 Jan 2007 14:03:42 +0100 Subject: nouveau: nv10: stencil functions --- src/mesa/drivers/dri/nouveau/nv10_state.c | 45 +++++++++++++++++++------------ 1 file changed, 28 insertions(+), 17 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 17336a7b2a..a9cce932d8 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -41,18 +41,10 @@ static void nv10AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) CLAMPED_FLOAT_TO_UBYTE(ubRef, ref); BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2); - OUT_RING_CACHE(func); /* NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC */ - OUT_RING_CACHE(ubRef); /* NV10_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF */ + OUT_RING_CACHE(func); + OUT_RING_CACHE(ubRef); } -/* - Supported blend extensions on NV10 - EXT_blend_color - EXT_blend_minmax - EXT_blend_subtract - NV_blend_square -*/ - static void nv10BlendColor(GLcontext *ctx, const GLfloat color[4]) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); @@ -88,7 +80,7 @@ static void nv10BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfac BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC, 2); OUT_RING_CACHE(sfactorRGB); - OUT_RING_CACHE(dfactorRGB); /* NV10_TCL_PRIMITIVE_3D_BLEND_FUNC_DST */ + OUT_RING_CACHE(dfactorRGB); } static void nv10Clear(GLcontext *ctx, GLbitfield mask) @@ -549,21 +541,40 @@ static void nv10ShadeModel(GLcontext *ctx, GLenum mode) OUT_RING_CACHE(mode); } +/** OpenGL 2.0 two-sided StencilFunc */ static void nv10StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, GLint ref, GLuint mask) { - /* Not for NV10 */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + /* NV10 do not have separate FRONT and BACK stencils */ + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC, 3); + OUT_RING_CACHE(func); + OUT_RING_CACHE(ref); + OUT_RING_CACHE(mask); } +/** OpenGL 2.0 two-sided StencilMask */ static void nv10StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask) { - /* Not for NV10 */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + /* NV10 do not have separate FRONT and BACK stencils */ + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_MASK, 1); + OUT_RING_CACHE(mask); } +/** OpenGL 2.0 two-sided StencilOp */ static void nv10StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, GLenum zfail, GLenum zpass) { - /* Not for NV10 */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + /* NV10 do not have separate FRONT and BACK stencils */ + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_STENCIL_OP_FAIL, 3); + OUT_RING_CACHE(fail); + OUT_RING_CACHE(zfail); + OUT_RING_CACHE(zpass); } /** Control the generation of texture coordinates */ @@ -641,9 +652,9 @@ void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) /* func->RenderMode = nv10RenderMode;*/ func->Scissor = nv10Scissor; func->ShadeModel = nv10ShadeModel; - func->StencilFuncSeparate = nv10StencilFuncSeparate; /* Not for NV10 */ - func->StencilMaskSeparate = nv10StencilMaskSeparate; /* Not for NV10 */ - func->StencilOpSeparate = nv10StencilOpSeparate; /* Not for NV10 */ + func->StencilFuncSeparate = nv10StencilFuncSeparate; + func->StencilMaskSeparate = nv10StencilMaskSeparate; + func->StencilOpSeparate = nv10StencilOpSeparate; /* func->TexGen = nv10TexGen;*/ /* func->TexParameter = nv10TexParameter;*/ func->TextureMatrix = nv10TextureMatrix; -- cgit v1.2.3 From 86f10c7144d08bc0603a796a9b8aa53f1a37a7e0 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 14 Jan 2007 14:09:04 +0100 Subject: nouveau: import color material r,g,b,a --- src/mesa/drivers/dri/nouveau/nouveau_reg.h | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_reg.h b/src/mesa/drivers/dri/nouveau/nouveau_reg.h index 200e770903..74f55c649a 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_reg.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_reg.h @@ -383,7 +383,10 @@ Object NV11_TCL_PRIMITIVE_3D used on: NV15 # define NV10_TCL_PRIMITIVE_3D_CULL_FACE 0x0000039c # define NV10_TCL_PRIMITIVE_3D_FRONT_FACE 0x000003a0 # define NV10_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE 0x000003a4 -# define NV10_TCL_PRIMITIVE_3D_MATERIAL_DIFFUSE_ALPHA_FRONT 0x000003b4 +# define NV10_TCL_PRIMITIVE_3D_COLOR_MATERIAL_R 0x000003a8 +# define NV10_TCL_PRIMITIVE_3D_COLOR_MATERIAL_G 0x000003ac +# define NV10_TCL_PRIMITIVE_3D_COLOR_MATERIAL_B 0x000003b0 +# define NV10_TCL_PRIMITIVE_3D_COLOR_MATERIAL_A 0x000003b4 # define NV10_TCL_PRIMITIVE_3D_COLOR_CONTROL 0x000003b8 /* Parameters: color_control */ # define NV10_TCL_PRIMITIVE_3D_ENABLED_LIGHTS 0x000003bc /* Parameters: light 7 light 6 light 5 light 4 light 3 light 2 light 1 light 0 */ # define NV10_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE( d) (0x000003c0 + d * 0x0004) @@ -729,8 +732,10 @@ Object NV20_TCL_PRIMITIVE_3D used on: NV20 # define NV20_TCL_PRIMITIVE_3D_CULL_FACE 0x0000039c # define NV20_TCL_PRIMITIVE_3D_FRONT_FACE 0x000003a0 # define NV20_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE 0x000003a4 -# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT 0x000003a8 -# define NV20_TCL_PRIMITIVE_3D_MATERIAL_DIFFUSE_ALPHA_FRONT 0x000003b4 +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_R 0x000003a8 +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_G 0x000003ac +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_B 0x000003b0 +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_A 0x000003b4 # define NV20_TCL_PRIMITIVE_3D_SEPARATE_SPECULAR_ENABLE 0x000003b8 # define NV20_TCL_PRIMITIVE_3D_ENABLED_LIGHTS 0x000003bc /* Parameters: light 7 light 6 light 5 light 4 light 3 light 2 light 1 light 0 */ # define NV20_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(d) (0x000003c0 + d * 0x0004) @@ -930,8 +935,10 @@ Object NV20_TCL_PRIMITIVE_3D used on: NV20 # define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R 0x000017a0 # define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_G 0x000017a4 # define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_B 0x000017a8 -# define NV20_TCL_PRIMITIVE_3D_MATERIAL_DIFFUSE_ALPHA_BACK 0x000017ac -# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK 0x000017b0 +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_A 0x000017ac +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_R 0x000017b0 +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_G 0x000017b4 +# define NV20_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_B 0x000017b8 # define NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE 0x000017bc # define NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP 0x000017c0 # define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_TWO_SIDE_ENABLE 0x000017c4 @@ -1004,7 +1011,10 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE 0x0000037c # define NV30_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR 0x00000394 # define NV30_TCL_PRIMITIVE_3D_DEPTH_RANGE_FAR 0x00000398 -# define NV30_TCL_PRIMITIVE_3D_MATERIAL_DIFFUSE_ALPHA_FRONT 0x000003b4 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_R 0x000003a0 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_G 0x000003a4 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_B 0x000003a8 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_A 0x000003b4 # define NV30_TCL_PRIMITIVE_3D_LINE_WIDTH_SMOOTH 0x000003b8 # define NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(d) (0x00000400 + d * 0x0004) # define NV30_TCL_PRIMITIVE_3D_MODELVIEW_MATRIX( d) (0x00000480 + d * 0x0004) @@ -1196,7 +1206,10 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R 0x000017a0 # define NV30_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_G 0x000017a4 # define NV30_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_B 0x000017a8 -# define NV30_TCL_PRIMITIVE_3D_MATERIAL_DIFFUSE_ALPHA_BACK 0x000017c0 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_R 0x000017b0 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_G 0x000017b4 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_B 0x000017b8 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_A 0x000017c0 # define NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM 0x000008e4 # define NV30_TCL_PRIMITIVE_3D_TX_ADDRESS_UNIT(d) (0x00001a00 + d * 0x0020) # define NV30_TCL_PRIMITIVE_3D_TX_FORMAT_UNIT(d) (0x00001a04 + d * 0x0020) /* Parameters: mipmap type format ncomp cubic */ -- cgit v1.2.3 From e7112be7321c58e6039fde28f47ffe3dce5cc205 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 14 Jan 2007 14:11:10 +0100 Subject: nouveau: remove already defined NV15_TCL and NV17_TCL --- src/mesa/drivers/dri/nouveau/nouveau_card.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_card.c b/src/mesa/drivers/dri/nouveau/nouveau_card.c index a0628389bf..ae4f4c7ae5 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_card.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_card.c @@ -2,9 +2,6 @@ #include "nouveau_card.h" #include "nouveau_reg.h" #include "nouveau_drm.h" -// FIXME hack for now -#define NV15_TCL_PRIMITIVE_3D 0x0096 -#define NV17_TCL_PRIMITIVE_3D 0x0099 #include "nouveau_card_list.h" -- cgit v1.2.3 From 9a4e49aef2abb277544138640c2b71169badaa42 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Sun, 14 Jan 2007 19:31:30 +0100 Subject: r300: Fix vertex program position invariant bug, force position reading. When we have a position invariant program we need to force routing the position otherwise you may handle transform quite random data which might be funny but unlikely what you want :). --- src/mesa/drivers/dri/r300/r300_vertexprog.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/r300/r300_vertexprog.c b/src/mesa/drivers/dri/r300/r300_vertexprog.c index 2492a4a3a0..c08c98767e 100644 --- a/src/mesa/drivers/dri/r300/r300_vertexprog.c +++ b/src/mesa/drivers/dri/r300/r300_vertexprog.c @@ -1072,6 +1072,8 @@ static void insert_wpos(struct r300_vertex_program *vp, vpi = &prog->Instructions[prog->NumInstructions-1]; assert(vpi->Opcode == OPCODE_END); + /* we need position, don't we ? :) */ + prog->InputsRead |= (1 << VERT_ATTRIB_POS); } static void pos_as_texcoord(struct r300_vertex_program *vp, @@ -1101,8 +1103,9 @@ static struct r300_vertex_program *build_program(struct r300_vertex_program_key vp->wpos_idx = wpos_idx; - if(mesa_vp->IsPositionInvariant) + if(mesa_vp->IsPositionInvariant) { position_invariant(&mesa_vp->Base); + } if(wpos_idx > -1) pos_as_texcoord(vp, &mesa_vp->Base); @@ -1158,6 +1161,10 @@ void r300_select_vertex_shader(r300ContextPtr r300) wanted_key.OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i); wanted_key.InputsRead = vpc->mesa_program.Base.InputsRead; + if(vpc->mesa_program.IsPositionInvariant) { + /* we wan't position don't we ? */ + wanted_key.InputsRead |= (1 << VERT_ATTRIB_POS); + } for (vp = vpc->progs; vp; vp = vp->next) if (_mesa_memcmp(&vp->key, &wanted_key, sizeof(wanted_key)) == 0) { @@ -1170,6 +1177,5 @@ void r300_select_vertex_shader(r300ContextPtr r300) vp = build_program(&wanted_key, &vpc->mesa_program, wpos_idx); vp->next = vpc->progs; vpc->progs = vp; - r300->selected_vp = vp; } -- cgit v1.2.3 From 8aabd636f5dd303774a07f8705068d812f7feef8 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 14 Jan 2007 19:55:45 +0100 Subject: nouveau: nv10: added missing functions --- src/mesa/drivers/dri/nouveau/nv10_state.c | 91 +++++++++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 6 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index a9cce932d8..8785879d9d 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -596,10 +596,67 @@ static void nv10TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) OUT_RING_CACHEp(mat->m, 16); } +/* Update anything that depends on the window position/size */ +static void nv10WindowMoved(nouveauContextPtr nmesa) +{ + GLcontext *ctx = nmesa->glCtx; + GLfloat *v = nmesa->viewport.m; + GLuint w = ctx->Viewport.Width; + GLuint h = ctx->Viewport.Height; + GLuint x = ctx->Viewport.X + nmesa->drawX; + GLuint y = ctx->Viewport.Y + nmesa->drawY; + int i; + + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2); + OUT_RING_CACHE((w << 16) | x); + OUT_RING_CACHE((h << 16) | y); + + /* something to do with clears, possibly doesn't belong here */ + BEGIN_RING_CACHE(NvSub3D, + NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 2); + OUT_RING_CACHE(((w+x) << 16) | x | 0x800); + OUT_RING_CACHE(((h+y) << 16) | y | 0x800); + for (i=1; i<7; i++) { + BEGIN_RING_CACHE(NvSub3D, + NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 2); + OUT_RING_CACHE(0); + OUT_RING_CACHE(0); + } + + /* viewport transform */ + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X, 4); + OUT_RING_CACHEf ((GLfloat) x); + OUT_RING_CACHEf ((GLfloat) (y+h)); + OUT_RING_CACHEf (0.0); + OUT_RING_CACHEf (0.0); + + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X, 4); + OUT_RING_CACHEf ((((GLfloat) w) * 0.5) - 2048.0); + OUT_RING_CACHEf ((((GLfloat) h) * 0.5) - 2048.0); + OUT_RING_CACHEf (16777215.0 * 0.5); + OUT_RING_CACHEf (0.0); +} + /* Initialise any card-specific non-GL related state */ static GLboolean nv10InitCard(nouveauContextPtr nmesa) { - return GL_FALSE; + nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); + + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY0, 2); + OUT_RING(NvDmaFB); /* 184 dma_in_memory0 */ + OUT_RING(NvDmaFB); /* 188 dma_in_memory1 */ + BEGIN_RING_SIZE(NvSub3D, NV10_TCL_PRIMITIVE_3D_SET_DMA_IN_MEMORY2, 2); + OUT_RING(NvDmaFB); /* 194 dma_in_memory2 */ + OUT_RING(NvDmaFB); /* 198 dma_in_memory3 */ + + BEGIN_RING_SIZE(NvSub3D, 0x02b4, 1); + OUT_RING(0); + BEGIN_RING_SIZE(NvSub3D, 0x0290, 1); + OUT_RING(0x00100001); + BEGIN_RING_SIZE(NvSub3D, 0x03f4, 1); + OUT_RING(0); + + return GL_FALSE; } /* Update buffer offset/pitch/format */ @@ -607,12 +664,34 @@ static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color, nouveau_renderbuffer **color, nouveau_renderbuffer *depth) { - return GL_FALSE; -} + GLuint x, y, w, h; + GLuint pitch, format; -/* Update anything that depends on the window position/size */ -static void nv10WindowMoved(nouveauContextPtr nmesa) -{ + w = color[0]->mesa.Width; + h = color[0]->mesa.Height; + x = nmesa->drawX; + y = nmesa->drawY; + + if (num_color != 1) + return GL_FALSE; + + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 6); + OUT_RING_CACHE((w << 16) | x); + OUT_RING_CACHE((h << 16) | y); + pitch = color[0]->pitch; + if (depth) { + pitch |= (depth->pitch << 16); + } + format = 0x108; + if (color[0]->mesa._ActualFormat != GL_RGBA8) { + /* FIXME: set 16 bits format */ + } + OUT_RING(format); + OUT_RING(pitch); + OUT_RING(color[0]->offset); + OUT_RING(depth ? depth->offset : color[0]->offset); + + return GL_TRUE; } void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) -- cgit v1.2.3 From 81bd826de8897f3784ad301023bde6e7eb77b5b2 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 14 Jan 2007 20:14:58 +0100 Subject: nouveau: nv10: 16 bits color buffer format --- src/mesa/drivers/dri/nouveau/nv10_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 8785879d9d..dbd8bf306e 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -684,7 +684,7 @@ static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color, } format = 0x108; if (color[0]->mesa._ActualFormat != GL_RGBA8) { - /* FIXME: set 16 bits format */ + format = 0x103; /* R5G6B5 color buffer */ } OUT_RING(format); OUT_RING(pitch); -- cgit v1.2.3 From d57ce408b34b604f9b85114eedc88b5463df4218 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sat, 13 Jan 2007 23:56:55 +0100 Subject: nouveau: Cleanup the nv10 swtcl module. --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 58 ------------------------------- 1 file changed, 58 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 37d9f001d1..12b277de45 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -56,9 +56,6 @@ static void nv10ResetLineStipple( GLcontext *ctx ); -/* the size above which we fire the ring. this is a performance-tunable */ -#define NOUVEAU_FIRE_SIZE (2048/4) - static inline void nv10StartPrimitive(struct nouveau_context* nmesa,uint32_t primitive,uint32_t size) { if (nmesa->screen->card->type==NV_10) @@ -99,52 +96,6 @@ static inline void nv10ExtendPrimitive(struct nouveau_context* nmesa, int size) } } -static inline void nv10_draw_quad(nouveauContextPtr nmesa, - nouveauVertexPtr v0, - nouveauVertexPtr v1, - nouveauVertexPtr v2, - nouveauVertexPtr v3) -{ - GLuint vertsize = nmesa->vertex_size; - nv10ExtendPrimitive(nmesa, 4 * 4 * vertsize); - - OUT_RINGp(v0,vertsize); - OUT_RINGp(v1,vertsize); - OUT_RINGp(v2,vertsize); - OUT_RINGp(v3,vertsize); -} - -static inline void nv10_draw_triangle(nouveauContextPtr nmesa, - nouveauVertexPtr v0, - nouveauVertexPtr v1, - nouveauVertexPtr v2) -{ - GLuint vertsize = nmesa->vertex_size; - nv10ExtendPrimitive(nmesa, 3 * 4 * vertsize); - - OUT_RINGp(v0,vertsize); - OUT_RINGp(v1,vertsize); - OUT_RINGp(v2,vertsize); -} - -static inline void nv10_draw_line(nouveauContextPtr nmesa, - nouveauVertexPtr v0, - nouveauVertexPtr v1) -{ - GLuint vertsize = nmesa->vertex_size; - nv10ExtendPrimitive(nmesa, 2 * 4 * vertsize); - OUT_RINGp(v0,vertsize); - OUT_RINGp(v1,vertsize); -} - -static inline void nv10_draw_point(nouveauContextPtr nmesa, - nouveauVertexPtr v0) -{ - GLuint vertsize = nmesa->vertex_size; - nv10ExtendPrimitive(nmesa, 1 * 4 * vertsize); - OUT_RINGp(v0,vertsize); -} - /**********************************************************************/ /* Render unclipped begin/end objects */ /**********************************************************************/ @@ -343,10 +294,6 @@ static void nv10ChooseRenderState(GLcontext *ctx) TNLcontext *tnl = TNL_CONTEXT(ctx); struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); - nmesa->draw_point = nv10_draw_point; - nmesa->draw_line = nv10_draw_line; - nmesa->draw_tri = nv10_draw_triangle; - tnl->Driver.Render.PrimTabVerts = nv10_render_tab_verts; tnl->Driver.Render.PrimTabElts = nv10_render_tab_elts; tnl->Driver.Render.ClippedLine = NULL; @@ -538,11 +485,6 @@ static void nv10RenderStart(GLcontext *ctx) nmesa->new_render_state |= nmesa->new_state; } - if (nmesa->Fallback) { - tnl->Driver.Render.Start(ctx); - return; - } - if (nmesa->new_render_state) { nv10ChooseVertexState(ctx); nv10ChooseRenderState(ctx); -- cgit v1.2.3 From 8d7e5651fba9fd62e1055c05d1814c7d2de7f43c Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sun, 14 Jan 2007 20:37:57 +0100 Subject: nouveau: add the nv04 swtcl module (it's untested for now). --- src/mesa/drivers/dri/nouveau/Makefile | 1 + src/mesa/drivers/dri/nouveau/nouveau_swtcl.c | 4 +- src/mesa/drivers/dri/nouveau/nv04_swtcl.c | 570 +++++++++++++++++++++++++++ src/mesa/drivers/dri/nouveau/nv04_swtcl.h | 12 + 4 files changed, 585 insertions(+), 2 deletions(-) create mode 100644 src/mesa/drivers/dri/nouveau/nv04_swtcl.c create mode 100644 src/mesa/drivers/dri/nouveau/nv04_swtcl.h (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile index d31b42a568..9eb40fb9c1 100644 --- a/src/mesa/drivers/dri/nouveau/Makefile +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -26,6 +26,7 @@ DRIVER_SOURCES = \ nouveau_tex.c \ nouveau_swtcl.c \ nouveau_sync.c \ + nv04_swtcl.c \ nv10_swtcl.c \ nv10_state.c \ nv20_state.c \ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c b/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c index 746b0fac8c..f5c92a1b4e 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c @@ -82,7 +82,7 @@ void nouveauFallback(struct nouveau_context *nmesa, GLuint bit, GLboolean mode) nmesa->Fallback |= bit; if (oldfallback == 0) { if (nmesa->screen->card->typescreen->card->type +#include + +#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_swtcl.h" +#include "nv04_swtcl.h" +#include "nouveau_context.h" +#include "nouveau_span.h" +#include "nouveau_reg.h" +#include "nouveau_tex.h" +#include "nouveau_fifo.h" +#include "nouveau_msg.h" +#include "nouveau_object.h" + +static void nv04RasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim ); +static void nv04RenderPrimitive( GLcontext *ctx, GLenum prim ); +static void nv04ResetLineStipple( GLcontext *ctx ); + + +static inline void nv04_2triangles(struct nouveau_context *nmesa,nouveauVertex* v0,nouveauVertex* v1,nouveauVertex* v2,nouveauVertex* v3,nouveauVertex* v4,nouveauVertex* v5) +{ + BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0xA),49); + OUT_RINGp(v0,8); + OUT_RINGp(v1,8); + OUT_RINGp(v2,8); + OUT_RINGp(v3,8); + OUT_RINGp(v4,8); + OUT_RINGp(v5,8); + OUT_RING(0xFEDCBA); +} + +static inline void nv04_1triangle(struct nouveau_context *nmesa,nouveauVertex* v0,nouveauVertex* v1,nouveauVertex* v2) +{ + BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0xD),25); + OUT_RINGp(v0,8); + OUT_RINGp(v1,8); + OUT_RINGp(v2,8); + OUT_RING(0xFED); +} + +static inline void nv04_1quad(struct nouveau_context *nmesa,nouveauVertex* v0,nouveauVertex* v1,nouveauVertex* v2,nouveauVertex* v3) +{ + BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0xC),33); + OUT_RINGp(v0,8); + OUT_RINGp(v1,8); + OUT_RINGp(v2,8); + OUT_RINGp(v3,8); + OUT_RING(0xFECEDC); +} + +/**********************************************************************/ +/* Render unclipped begin/end objects */ +/**********************************************************************/ + +static void nv04_render_points_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + // erm +} + +static void nv04_render_lines_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + // umm +} + +static void nv04_render_line_strip_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + // yeah +} + +static void nv04_render_line_loop_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + // right +} + +static void nv04_render_triangles_verts(GLcontext *ctx,GLuint start,GLuint count,GLuint flags) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + int i; + + for(i=start;iverts; + GLuint vertsize = nmesa->vertex_size; + uint32_t striptbl[]={0x321210,0x543432,0x765654,0x987876,0xBA9A98,0xDCBCBA,0xFEDEDC}; + int i,j; + + for(i=start;iverts; + GLuint vertsize = nmesa->vertex_size; + uint32_t fantbl[]={0x320210,0x540430,0x760650,0x980870,0xBA0A90,0xDC0CB0,0xFE0ED0}; + int i,j; + + BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0),8); + OUT_RINGp((nouveauVertex*)(vertptr+start*vertsize),8); + + for(i=start+1;iverts; + GLuint vertsize = nmesa->vertex_size; + int i; + + for(i=start;iverts; + GLuint vertsize = nmesa->vertex_size; + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; + int i; + + for(i=start;iverts; + GLuint vertsize = nmesa->vertex_size; + uint32_t striptbl[]={0x321210,0x543432,0x765654,0x987876,0xBA9A98,0xDCBCBA,0xFEDEDC}; + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; + int i,j; + + for(i=start;iverts; + GLuint vertsize = nmesa->vertex_size; + uint32_t fantbl[]={0x320210,0x540430,0x760650,0x980870,0xBA0A90,0xDC0CB0,0xFE0ED0}; + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; + int i,j; + + BEGIN_RING_SIZE(NvSub3D,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0),8); + OUT_RINGp((nouveauVertex*)(vertptr+elt[start]*vertsize),8); + + for(i=start+1;iverts; + GLuint vertsize = nmesa->vertex_size; + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; + int i; + + for(i=start;ivertex_attrs[nmesa->vertex_attr_count].attrib = (ATTR); \ + nmesa->vertex_attrs[nmesa->vertex_attr_count].format = (STYLE); \ + nmesa->vertex_attr_count++; \ +} while (0) + +#define EMIT_PAD( N ) \ +do { \ + nmesa->vertex_attrs[nmesa->vertex_attr_count].attrib = 0; \ + nmesa->vertex_attrs[nmesa->vertex_attr_count].format = EMIT_PAD; \ + nmesa->vertex_attrs[nmesa->vertex_attr_count].offset = (N); \ + nmesa->vertex_attr_count++; \ +} while (0) + + +static void nv04ChooseRenderState(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + tnl->Driver.Render.PrimTabVerts = nv04_render_tab_verts; + tnl->Driver.Render.PrimTabElts = nv04_render_tab_elts; + tnl->Driver.Render.ClippedLine = NULL; + tnl->Driver.Render.ClippedPolygon = NULL; +} + + + +static inline void nv04OutputVertexFormat(struct nouveau_context* nmesa) +{ + GLcontext* ctx=nmesa->glCtx; + DECLARE_RENDERINPUTS(index); + + /* + * Tell t_vertex about the vertex format + */ + RENDERINPUTS_COPY(index, nmesa->render_inputs_bitset); + + // SX SY SZ INVW + // FIXME : we use W instead of INVW, but since W=1 it doesn't matter + if (RENDERINPUTS_TEST(index, _TNL_ATTRIB_POS)) + EMIT_ATTR(_TNL_ATTRIB_POS,EMIT_4F_VIEWPORT); + else + EMIT_PAD(4*sizeof(float)); + + // COLOR + if (RENDERINPUTS_TEST(index, _TNL_ATTRIB_COLOR0)) + EMIT_ATTR(_TNL_ATTRIB_COLOR0,EMIT_4UB_4F_ABGR); + else + EMIT_PAD(4); + + // SPECULAR + if (RENDERINPUTS_TEST(index, _TNL_ATTRIB_COLOR1)) + EMIT_ATTR(_TNL_ATTRIB_COLOR1,EMIT_4UB_4F_ABGR); + else + EMIT_PAD(4); + + // TEXTURE + if (RENDERINPUTS_TEST(index, _TNL_ATTRIB_TEX0)) + EMIT_ATTR(_TNL_ATTRIB_TEX0,EMIT_2F); + else + EMIT_PAD(2*sizeof(float)); + + nmesa->vertex_size=_tnl_install_attrs( ctx, + nmesa->vertex_attrs, + nmesa->vertex_attr_count, + ctx->Viewport._WindowMap.m, 0 ); +} + + +static void nv04ChooseVertexState( GLcontext *ctx ) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + DECLARE_RENDERINPUTS(index); + + RENDERINPUTS_COPY(index, tnl->render_inputs_bitset); + if (!RENDERINPUTS_EQUAL(index, nmesa->render_inputs_bitset)) + { + RENDERINPUTS_COPY(nmesa->render_inputs_bitset, index); + nv04OutputVertexFormat(nmesa); + } +} + + +/**********************************************************************/ +/* High level hooks for t_vb_render.c */ +/**********************************************************************/ + + +static void nv04RenderStart(GLcontext *ctx) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + + if (nmesa->new_state) { + nmesa->new_render_state |= nmesa->new_state; + } + + if (nmesa->new_render_state) { + nv04ChooseVertexState(ctx); + nv04ChooseRenderState(ctx); + nmesa->new_render_state = 0; + } +} + +static void nv04RenderFinish(GLcontext *ctx) +{ +} + + +/* System to flush dma and emit state changes based on the rasterized + * primitive. + */ +void nv04RasterPrimitive(GLcontext *ctx, + GLenum glprim, + GLuint hwprim) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + + assert (!nmesa->new_state); + + if (hwprim != nmesa->current_primitive) + { + nmesa->current_primitive=hwprim; + + } +} + +static const GLuint hw_prim[GL_POLYGON+1] = { + GL_POINTS+1, + GL_LINES+1, + GL_LINE_STRIP+1, + GL_LINE_LOOP+1, + GL_TRIANGLES+1, + GL_TRIANGLE_STRIP+1, + GL_TRIANGLE_FAN+1, + GL_QUADS+1, + GL_QUAD_STRIP+1, + GL_POLYGON+1 +}; + +/* Callback for mesa: + */ +static void nv04RenderPrimitive( GLcontext *ctx, GLuint prim ) +{ + nv04RasterPrimitive( ctx, prim, hw_prim[prim] ); +} + +static void nv04ResetLineStipple( GLcontext *ctx ) +{ + /* FIXME do something here */ + WARN_ONCE("Unimplemented nv04ResetLineStipple\n"); +} + + +/**********************************************************************/ +/* Initialization. */ +/**********************************************************************/ + +void nv04TriInitFunctions(GLcontext *ctx) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + + tnl->Driver.RunPipeline = nouveauRunPipeline; + tnl->Driver.Render.Start = nv04RenderStart; + tnl->Driver.Render.Finish = nv04RenderFinish; + tnl->Driver.Render.PrimitiveNotify = nv04RenderPrimitive; + tnl->Driver.Render.ResetLineStipple = nv04ResetLineStipple; + 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, 32 ); + + nmesa->verts = (GLubyte *)tnl->clipspace.vertex_buf; +} + + diff --git a/src/mesa/drivers/dri/nouveau/nv04_swtcl.h b/src/mesa/drivers/dri/nouveau/nv04_swtcl.h new file mode 100644 index 0000000000..42dde5383e --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_swtcl.h @@ -0,0 +1,12 @@ +#ifndef __NV04_SWTCL_H__ +#define __NV04_SWTCL_H__ + +#include "mtypes.h" + +extern void nv04Fallback( GLcontext *ctx, GLuint bit, GLboolean mode ); +extern void nv04FinishPrimitive(struct nouveau_context *nmesa); +extern void nv04TriInitFunctions(GLcontext *ctx); +#define FALLBACK( nmesa, bit, mode ) nouveauFallback( nmesa->glCtx, bit, mode ) + +#endif /* __NV04_SWTCL_H__ */ + -- cgit v1.2.3 From 65e3d5e45e3d14f4ff98a15af0662e6c6e589cd2 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sun, 14 Jan 2007 21:17:08 +0100 Subject: nouveau: Make the state cache hierarchical. --- src/mesa/drivers/dri/nouveau/nouveau_fifo.h | 3 +++ src/mesa/drivers/dri/nouveau/nouveau_state_cache.c | 5 +++++ src/mesa/drivers/dri/nouveau/nouveau_state_cache.h | 8 +++++++- 3 files changed, 15 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h index 05d00d4769..9056bfb255 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h @@ -31,6 +31,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_context.h" #include "nouveau_ctrlreg.h" +#include "nouveau_state_cache.h" //#define NOUVEAU_RING_DEBUG //#define NOUVEAU_STATE_CACHE_DISABLE @@ -114,6 +115,7 @@ extern void nouveau_state_cache_init(nouveauContextPtr nmesa); #define OUT_RING_CACHE(n) do { \ if (nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value!=(n)) { \ nmesa->state_cache.atoms[nmesa->state_cache.current_pos].dirty=1; \ + nmesa->state_cache.hdirty[nmesa->state_cache.current_pos/NOUVEAU_STATE_CACHE_HIER_SIZE]=1; \ nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value=(n); \ } \ nmesa->state_cache.current_pos++; \ @@ -122,6 +124,7 @@ extern void nouveau_state_cache_init(nouveauContextPtr nmesa); #define OUT_RING_CACHEf(n) do { \ if ((*(float*)(&nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value))!=(n)){ \ nmesa->state_cache.atoms[nmesa->state_cache.current_pos].dirty=1; \ + nmesa->state_cache.hdirty[nmesa->state_cache.current_pos/NOUVEAU_STATE_CACHE_HIER_SIZE]=1; \ (*(float*)(&nmesa->state_cache.atoms[nmesa->state_cache.current_pos].value))=(n);\ } \ nmesa->state_cache.current_pos++; \ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state_cache.c b/src/mesa/drivers/dri/nouveau/nouveau_state_cache.c index 36f0c1024b..cb4b9d3027 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state_cache.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state_cache.c @@ -25,6 +25,8 @@ void nouveau_state_cache_flush(nouveauContextPtr nmesa) do { // jump to a dirty state + while((nmesa->state_cache.hdirty[i/NOUVEAU_STATE_CACHE_HIER_SIZE]==0)&&(istate_cache.atoms[i].dirty==0)&&(istate_cache.atoms[i+j].value); nmesa->state_cache.atoms[i+j].dirty=0; + if ((i+j)%NOUVEAU_STATE_CACHE_HIER_SIZE==0) + nmesa->state_cache.hdirty[(i+j)/NOUVEAU_STATE_CACHE_HIER_SIZE-1]=0; } i+=run; } } while(istate_cache.hdirty[NOUVEAU_STATE_CACHE_HIER_SIZE/NOUVEAU_STATE_CACHE_HIER_SIZE-1]=0; } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state_cache.h b/src/mesa/drivers/dri/nouveau/nouveau_state_cache.h index 2488274846..5f9d426450 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state_cache.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_state_cache.h @@ -5,6 +5,10 @@ #include "mtypes.h" #define NOUVEAU_STATE_CACHE_ENTRIES 2048 +// size of a dirty requests block +// you can play with that and tune the value to increase/decrease performance +// but keep it a power of 2 ! +#define NOUVEAU_STATE_CACHE_HIER_SIZE 32 typedef struct nouveau_state_atom_t{ uint32_t value; @@ -14,8 +18,10 @@ typedef struct nouveau_state_atom_t{ typedef struct nouveau_state_cache_t{ nouveau_state_atom atoms[NOUVEAU_STATE_CACHE_ENTRIES]; uint32_t current_pos; + // hierarchical dirty flags + uint8_t hdirty[NOUVEAU_STATE_CACHE_ENTRIES/NOUVEAU_STATE_CACHE_HIER_SIZE]; // master dirty flag - uint32_t dirty; + uint8_t dirty; }nouveau_state_cache; -- cgit v1.2.3 From e2295511f5ee5fc4f5b39cba9e9c1c7a2f4e1eb5 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sun, 14 Jan 2007 22:39:37 +0100 Subject: nouveau: Update nouveau_reg.h from renouveau to the latest version. --- src/mesa/drivers/dri/nouveau/nouveau_reg.h | 230 ++++++++++++++++++++++++++--- 1 file changed, 212 insertions(+), 18 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_reg.h b/src/mesa/drivers/dri/nouveau/nouveau_reg.h index 74f55c649a..f52d381f74 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_reg.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_reg.h @@ -43,7 +43,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ************************************************************************** - Created from objects.c rev. 1.350 + Created from objects.c rev. 1.398 */ #ifndef _NOUVEAU_REG_H @@ -60,6 +60,7 @@ Object NV01_CONTEXT_CLIP_RECTANGLE used on: NV03 NV04 NV10 NV15 NV20 NV40 G70 Object NV_MEMORY_TO_MEMORY_FORMAT used on: NV04 NV10 NV15 NV20 NV30 NV40 G70 */ #define NV_MEMORY_TO_MEMORY_FORMAT 0x00000039 +# define NV_MEMORY_TO_MEMORY_FORMAT_NOP 0x00000100 # define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x00000104 # define NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY 0x00000180 # define NV_MEMORY_TO_MEMORY_FORMAT_OBJECT_IN 0x00000184 @@ -70,6 +71,8 @@ Object NV_MEMORY_TO_MEMORY_FORMAT used on: NV04 NV10 NV15 NV20 NV30 NV40 G70 # define NV_MEMORY_TO_MEMORY_FORMAT_PITCH_OUT 0x00000318 # define NV_MEMORY_TO_MEMORY_FORMAT_LINE_LENGTH_IN 0x0000031c # define NV_MEMORY_TO_MEMORY_FORMAT_LINE_COUNT 0x00000320 +# define NV_MEMORY_TO_MEMORY_FORMAT_FORMAT 0x00000324 /* Parameters: src_inc dst_inc */ +# define NV_MEMORY_TO_MEMORY_FORMAT_BUF_NOTIFY 0x00000328 /****************************************** Object NV03_PRIMITIVE_RASTER_OP used on: NV03 NV04 NV10 NV15 NV20 NV30 NV40 G70 @@ -322,18 +325,19 @@ Object NV11_TCL_PRIMITIVE_3D used on: NV15 # define NV10_TCL_PRIMITIVE_3D_TX_NPOT_PITCH(d) (0x00000230 + d * 0x0004) /* Parameters: pitch */ # define NV10_TCL_PRIMITIVE_3D_TX_NPOT_SIZE(d) (0x00000240 + d * 0x0004) /* Parameters: width height */ # define NV10_TCL_PRIMITIVE_3D_TX_FILTER(d) (0x00000248 + d * 0x0004) /* Parameters: mag_filter min_filter */ +# define NV10_TCL_PRIMITIVE_3D_TX_PALETTE_OFFSET(d) (0x00000250 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_TX_MATRIX_ENABLE(d) (0x000003e0 + d * 0x0004) +# define NV10_TCL_PRIMITIVE_3D_TX_MATRIX(x,y) (0x00000540 + y * 0x0010 + x * 0x0004) # define NV10_TCL_PRIMITIVE_3D_RC_IN_ALPHA(d) (0x00000260 + d * 0x0004) /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ # define NV10_TCL_PRIMITIVE_3D_RC_IN_RGB(d) (0x00000268 + d * 0x0004) /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ # define NV10_TCL_PRIMITIVE_3D_RC_OUT_ALPHA(d) (0x00000278 + d * 0x0004) /* Parameters: scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ # define NV10_TCL_PRIMITIVE_3D_RC_OUT_RGB(d) (0x00000280 + d * 0x0004) /* Parameters: rc1_tx_units_enabled rc1_rc_enabled scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ -# define NV10_TCL_PRIMITIVE_3D_TX_MATRIX_ENABLE(d) (0x000003e0 + d * 0x0004) -# define NV10_TCL_PRIMITIVE_3D_TX_MATRIX(x,y) (0x00000540 + y * 0x0010 + x * 0x0004) # define NV10_TCL_PRIMITIVE_3D_RC_COLOR0 0x00000270 /* Parameters: a r g b */ # define NV10_TCL_PRIMITIVE_3D_RC_COLOR1 0x00000274 /* Parameters: a r g b */ # define NV10_TCL_PRIMITIVE_3D_RC_FINAL0 0x00000288 /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ # define NV10_TCL_PRIMITIVE_3D_RC_FINAL1 0x0000028c /* Parameters: vare_mapping vare_component_usage vare_input varf_mapping varf_component_usage varf_input varg_mapping varg_component_usage varg_input color_sum_clamp */ # define NV10_TCL_PRIMITIVE_3D_LIGHT_MODEL 0x00000294 /* Parameters: local_viewer color_control */ -# define NV10_TCL_PRIMITIVE_3D_COLOR_MATERIAL 0x00000298 /* Parameters: specular diffuse ambient emission */ +# define NV10_TCL_PRIMITIVE_3D_COLOR_MATERIAL_ENABLE 0x00000298 /* Parameters: specular diffuse ambient emission */ # define NV10_TCL_PRIMITIVE_3D_FOG_MODE 0x0000029c # define NV10_TCL_PRIMITIVE_3D_FOG_COORD_DIST 0x000002a0 # define NV10_TCL_PRIMITIVE_3D_FOG_ENABLE 0x000002a4 @@ -363,7 +367,7 @@ Object NV11_TCL_PRIMITIVE_3D used on: NV15 # define NV10_TCL_PRIMITIVE_3D_BLEND_COLOR 0x0000034c /* Parameters: a r g b */ # define NV10_TCL_PRIMITIVE_3D_BLEND_EQUATION 0x00000350 # define NV10_TCL_PRIMITIVE_3D_DEPTH_FUNC 0x00000354 -# define NV10_TCL_PRIMITIVE_3D_COLOR_MASK 0x00000358 /* Parameters: r g b */ +# define NV10_TCL_PRIMITIVE_3D_COLOR_MASK 0x00000358 /* Parameters: a r g b */ # define NV10_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE 0x0000035c # define NV10_TCL_PRIMITIVE_3D_STENCIL_MASK 0x00000360 # define NV10_TCL_PRIMITIVE_3D_STENCIL_FUNC_FUNC 0x00000364 @@ -498,7 +502,7 @@ Object NV11_TCL_PRIMITIVE_3D used on: NV15 # define NV10_TCL_PRIMITIVE_3D_VERTEX_FOG_1F 0x00000ce0 # define NV10_TCL_PRIMITIVE_3D_VERTEX_WGH_1F 0x00000ce4 # define NV10_TCL_PRIMITIVE_3D_EDGEFLAG_ENABLE 0x00000cec -# define NV10_TCL_PRIMITIVE_3D_VERTEX_ATTR( d) (0x00000d04 + d * 0x0008) +# define NV10_TCL_PRIMITIVE_3D_VERTEX_ATTR( d) (0x00000d04 + d * 0x0008) /* Parameters: stride fields type */ # define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_VALIDATE 0x00000cf0 # define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_OFFSET_POS 0x00000d00 # define NV10_TCL_PRIMITIVE_3D_VERTEX_ARRAY_FORMAT_POS 0x00000d04 /* Parameters: stride fields type */ @@ -595,6 +599,7 @@ Object NV10_UNK0072 used on: NV10 NV15 NV20 NV40 G70 */ #define NV10_UNK0072 0x00000072 # define NV10_UNK0072_COUNTER 0x00000050 +# define NV40_UNK0072_SET_OBJECT 0x00000060 # define NV10_UNK0072_SET_DMA_NOTIFY 0x00000180 /****************************************** @@ -667,6 +672,8 @@ Object NV20_SWIZZLED_SURFACE used on: NV20 NV30 NV40 G70 Object NV20_TCL_PRIMITIVE_3D used on: NV20 */ #define NV20_TCL_PRIMITIVE_3D 0x00000097 +# define NV20_TCL_PRIMITIVE_3D_NOP 0x00000100 +# define NV20_TCL_PRIMITIVE_3D_NOTIFY 0x00000104 # define NV20_TCL_PRIMITIVE_3D_SET_OBJECT0 0x00000180 # define NV20_TCL_PRIMITIVE_3D_SET_OBJECT1 0x00000184 # define NV20_TCL_PRIMITIVE_3D_SET_OBJECT2 0x00000188 @@ -691,6 +698,8 @@ Object NV20_TCL_PRIMITIVE_3D used on: NV20 # define NV20_TCL_PRIMITIVE_3D_FOG_MODE 0x0000029c # define NV20_TCL_PRIMITIVE_3D_FOG_COORD_DIST 0x000002a0 # define NV20_TCL_PRIMITIVE_3D_FOG_ENABLE 0x000002a4 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(d) (0x000002c0 + d * 0x0004) /* Parameters: x2 x1 */ +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(d) (0x000002e0 + d * 0x0004) /* Parameters: y2 y1 */ # define NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE 0x00000300 # define NV20_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE 0x00000304 # define NV20_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE 0x00000308 @@ -759,6 +768,10 @@ Object NV20_TCL_PRIMITIVE_3D used on: NV20 # define NV20_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_E 0x000009f0 # define NV20_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_F 0x000009f4 # define NV20_TCL_PRIMITIVE_3D_POINT_SPRITE 0x00000a1c /* Parameters: coord_replace r_mode enable */ +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_OX 0x00000a20 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_OY 0x00000a24 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_DEPTH_AVG_S 0x00000a28 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_UNKNOWN_A 0x00000a2c # define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_A 0x00000a30 # define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_B 0x00000a34 # define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_C 0x00000a38 @@ -767,6 +780,10 @@ Object NV20_TCL_PRIMITIVE_3D used on: NV20 # define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_F 0x00000a44 # define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_G 0x00000a48 # define NV20_TCL_PRIMITIVE_3D_POINT_PARAMETER_H 0x00000a4c +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_PX_DIV2 0x00000af0 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_PY_DIV2 0x00000af4 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_DEPTH_HALF_S 0x00000af8 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_UNKNOWN_B 0x00000afc # define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_INST0 0x00000b00 # define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_INST1 0x00000b04 # define NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_INST2 0x00000b08 @@ -781,10 +798,13 @@ Object NV20_TCL_PRIMITIVE_3D used on: NV20 # define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_FRONT_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_B 0x00000a18 # define NV20_TCL_PRIMITIVE_3D_TX_OFFSET(d) (0x00001b00 + d * 0x0040) # define NV20_TCL_PRIMITIVE_3D_TX_FORMAT(d) (0x00001b04 + d * 0x0040) /* Parameters: log2(height) log2(width) lod format cube_map */ +# define NV20_TCL_PRIMITIVE_3D_TX_WRAP(d) (0x00001b08 + d * 0x0040) /* Parameters: wrap_s wrap_t wrap_r */ # define NV20_TCL_PRIMITIVE_3D_TX_ENABLE(d) (0x00001b0c + d * 0x0040) /* Parameters: enable anisotropy */ # define NV20_TCL_PRIMITIVE_3D_TX_NPOT_PITCH(d) (0x00001b10 + d * 0x0040) /* Parameters: pitch */ # define NV20_TCL_PRIMITIVE_3D_TX_FILTER(d) (0x00001b14 + d * 0x0040) /* Parameters: mag_filter min_filter */ # define NV20_TCL_PRIMITIVE_3D_TX_NPOT_SIZE(d) (0x00001b1c + d * 0x0040) /* Parameters: width height */ +# define NV20_TCL_PRIMITIVE_3D_TX_PALETTE_OFFSET(d) (0x00001b20 + d * 0x0040) +# define NV20_TCL_PRIMITIVE_3D_RC_ENABLE 0x00001e60 /* Parameters: number of rc enabled */ # define NV20_TCL_PRIMITIVE_3D_TX_SHADER_OP 0x00001e70 /* Parameters: op0 op1 op2 op3 */ # define NV20_TCL_PRIMITIVE_3D_TX_SHADER_CULL_MODE 0x000017f8 /* Parameters: cull0 cull1 cull2 cull3 */ # define NV20_TCL_PRIMITIVE_3D_TX_SHADER_PREVIOUS 0x00001e78 /* Parameters: prev2 prev3 */ @@ -794,6 +814,8 @@ Object NV20_TCL_PRIMITIVE_3D used on: NV20 # define NV20_TCL_PRIMITIVE_3D_RC_FINAL1 0x0000028c /* Parameters: vare_mapping vare_component_usage vare_input varf_mapping varf_component_usage varf_input varg_mapping varg_component_usage varg_input color_sum_clamp */ # define NV20_TCL_PRIMITIVE_3D_RC_IN_ALPHA(d) (0x00000260 + d * 0x0004) /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ # define NV20_TCL_PRIMITIVE_3D_RC_IN_RGB(d) (0x00000ac0 + d * 0x0004) /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ +# define NV20_TCL_PRIMITIVE_3D_RC_CONSTANT_COLOR0(d) (0x00000a60 + d * 0x0004) /* Parameters: a r g b */ +# define NV20_TCL_PRIMITIVE_3D_RC_CONSTANT_COLOR1(d) (0x00000a80 + d * 0x0004) /* Parameters: a r g b */ # define NV20_TCL_PRIMITIVE_3D_RC_OUT_ALPHA(d) (0x00000aa0 + d * 0x0004) /* Parameters: scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ # define NV20_TCL_PRIMITIVE_3D_RC_OUT_RGB(d) (0x00001e40 + d * 0x0004) /* Parameters: scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ # define NV20_TCL_PRIMITIVE_3D_LIGHT_POSITION_X(d) (0x0000105c + d * 0x0080) @@ -943,12 +965,18 @@ Object NV20_TCL_PRIMITIVE_3D used on: NV20 # define NV20_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP 0x000017c0 # define NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_TWO_SIDE_ENABLE 0x000017c4 # define NV20_TCL_PRIMITIVE_3D_BEGIN_END 0x000017fc +# define NV20_TCL_PRIMITIVE_3D_SCISSOR_X2_X1 0x00001c30 /* Parameters: x2 x1 */ +# define NV20_TCL_PRIMITIVE_3D_SCISSOR_Y2_Y1 0x00001c50 /* Parameters: y2 y1 */ # define NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_DEPTH 0x00001d8c # define NV20_TCL_PRIMITIVE_3D_CLEAR_VALUE_ARGB 0x00001d90 # define NV20_TCL_PRIMITIVE_3D_CLEAR_WHICH_BUFFERS 0x00001d94 /* Parameters: clear color a clear color b clear color g clear color r clear depth clear stencil */ # define NV20_TCL_PRIMITIVE_3D_INDEX_DATA 0x00001800 /* Parameters: index1 index0 */ # define NV20_TCL_PRIMITIVE_3D_VB_VERTEX_BATCH 0x00001810 /* Parameters: count_vertices offset_vertices */ # define NV20_TCL_PRIMITIVE_3D_VERTEX_DATA 0x00001818 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X 0x00001f00 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_Y 0x00001f04 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_Z 0x00001f08 +# define NV20_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_W 0x00001f0c /****************************************** Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 @@ -965,8 +993,8 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_SET_OBJECT8 0x000001ac # define NV30_TCL_PRIMITIVE_3D_SET_OBJECT9 0x000001b4 # define NV30_TCL_PRIMITIVE_3D_SET_OBJECT10 0x000001b8 -# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT11 0x0000019c -# define NV30_TCL_PRIMITIVE_3D_SET_OBJECT12 0x000001a0 +# define NV30_TCL_PRIMITIVE_3D_SET_VB_SRC0_OBJECT 0x0000019c +# define NV30_TCL_PRIMITIVE_3D_SET_VB_SRC1_OBJECT 0x000001a0 # define NV30_TCL_PRIMITIVE_3D_BUFFER0_PITCH 0x0000020c /* Parameters: depth/stencil buffer pitch color0 buffer pitch */ # define NV30_TCL_PRIMITIVE_3D_COLOR0_OFFSET 0x00000210 # define NV30_TCL_PRIMITIVE_3D_DEPTH_OFFSET 0x00000214 @@ -1016,6 +1044,7 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_B 0x000003a8 # define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_FRONT_A 0x000003b4 # define NV30_TCL_PRIMITIVE_3D_LINE_WIDTH_SMOOTH 0x000003b8 +# define NV30_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE 0x000003bc # define NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(d) (0x00000400 + d * 0x0004) # define NV30_TCL_PRIMITIVE_3D_MODELVIEW_MATRIX( d) (0x00000480 + d * 0x0004) # define NV30_TCL_PRIMITIVE_3D_INVERSE_MODELVIEW_MATRIX( d) (0x00000580 + d * 0x0004) @@ -1027,12 +1056,17 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT 0x000008d0 # define NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_LINEAR 0x000008d4 # define NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_QUADRATIC 0x000008d8 +# define NV30_TCL_PRIMITIVE_3D_RC_COLOR0 0x000008ec /* Parameters: a r g b */ +# define NV30_TCL_PRIMITIVE_3D_RC_COLOR1 0x000008f0 /* Parameters: a r g b */ # define NV30_TCL_PRIMITIVE_3D_RC_FINAL0 0x000008f4 /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ # define NV30_TCL_PRIMITIVE_3D_RC_FINAL1 0x000008f8 /* Parameters: vare_mapping vare_component_usage vare_input varf_mapping varf_component_usage varf_input varg_mapping varg_component_usage varg_input color_sum_clamp */ -# define NV30_TCL_PRIMITIVE_3D_RC_IN_ALPHA 0x00000900 /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ -# define NV30_TCL_PRIMITIVE_3D_RC_IN_RGB 0x00000904 /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ -# define NV30_TCL_PRIMITIVE_3D_RC_OUT_ALPHA 0x00000910 /* Parameters: scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ -# define NV30_TCL_PRIMITIVE_3D_RC_OUT_RGB 0x00000914 /* Parameters: scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ +# define NV30_TCL_PRIMITIVE_3D_RC_ENABLE 0x000008fc /* Parameters: number of rc enabled */ +# define NV30_TCL_PRIMITIVE_3D_RC_IN_ALPHA(d) (0x00000900 + d * 0x0020) /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ +# define NV30_TCL_PRIMITIVE_3D_RC_IN_RGB(d) (0x00000904 + d * 0x0020) /* Parameters: vara_mapping vara_component_usage vara_input varb_mapping varb_component_usage varb_input varc_mapping varc_component_usage varc_input vard_mapping vard_component_usage vard_input */ +# define NV30_TCL_PRIMITIVE_3D_RC_CONSTANT_COLOR0(d) (0x00000908 + d * 0x0020) /* Parameters: a r g b */ +# define NV30_TCL_PRIMITIVE_3D_RC_CONSTANT_COLOR1(d) (0x0000090c + d * 0x0020) /* Parameters: a r g b */ +# define NV30_TCL_PRIMITIVE_3D_RC_OUT_ALPHA(d) (0x00000910 + d * 0x0020) /* Parameters: scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ +# define NV30_TCL_PRIMITIVE_3D_RC_OUT_RGB(d) (0x00000914 + d * 0x0020) /* Parameters: scale bias mux_sum ab_dot_product cd_dot_product sum_output ab_output cd_output */ # define NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_DIM0 0x00000200 /* Parameters: width x_offset */ # define NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_DIM1 0x00000204 /* Parameters: height y_offset */ # define NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_OFS0 0x000002c0 /* Parameters: width x_offset */ @@ -1054,6 +1088,7 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_F 0x00001ed4 # define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_G 0x00001ed8 # define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETER_H 0x00001edc +# define NV30_TCL_PRIMITIVE_3D_POINT_PARAMETERS_ENABLE 0x00001ee4 # define NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_OX 0x00000a20 # define NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_OY 0x00000a24 # define NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_NPF_DIV2 0x00000a28 @@ -1074,6 +1109,10 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_INST1 0x00000b84 # define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_INST2 0x00000b88 # define NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_INST3 0x00000b8c +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_R 0x000017b0 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_G 0x000017b4 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_B 0x000017b8 +# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_A 0x000017c0 # define NV30_TCL_PRIMITIVE_3D_OCC_QUERY_OR_COLOR_BUFF_ENABLE 0x000017c8 # define NV30_TCL_PRIMITIVE_3D_STORE_RESULT 0x00001800 # define NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_A(d) (0x00000e00 + d * 0x0010) @@ -1115,7 +1154,9 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_E 0x00001410 # define NV30_TCL_PRIMITIVE_3D_FRONT_MATERIAL_SHININESS_F 0x00001414 # define NV30_TCL_PRIMITIVE_3D_ENABLED_LIGHTS 0x00001420 /* Parameters: light 7 light 6 light 5 light 4 light 3 light 2 light 1 light 0 */ -# define NV30_TCL_PRIMITIVE_3D_LINE_STIPPLE 0x00001db4 +# define NV30_TCL_PRIMITIVE_3D_UNK1D6C_OFFSET 0x00001d6c +# define NV30_TCL_PRIMITIVE_3D_UNK1D70_VALUE 0x00001d70 +# define NV30_TCL_PRIMITIVE_3D_LINE_STIPPLE_ENABLE 0x00001db4 # define NV30_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN 0x00001db8 /* Parameters: factor pattern */ # define NV30_TCL_PRIMITIVE_3D_BEGIN_END 0x00001808 # define NV30_TCL_PRIMITIVE_3D_CULL_FACE 0x00001830 @@ -1159,7 +1200,7 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_VTX_ATTR_4Y(d) (0x00001c04 + d * 0x0010) # define NV30_TCL_PRIMITIVE_3D_VTX_ATTR_4Z(d) (0x00001c08 + d * 0x0010) # define NV30_TCL_PRIMITIVE_3D_VTX_ATTR_4W(d) (0x00001c0c + d * 0x0010) -# define NV30_TCL_PRIMITIVE_3D_VB_POINTER_ATTR(d) (0x00001680 + d * 0x0004) /* Parameters: enabled? offset */ +# define NV30_TCL_PRIMITIVE_3D_VB_POINTER_ATTR(d) (0x00001680 + d * 0x0004) /* Parameters: source: offset */ # define NV30_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_XY 0x00000a90 /* Parameters: y x */ # define NV30_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_Z 0x00000a94 /* Parameters: z */ # define NV30_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_S 0x000018c0 @@ -1206,10 +1247,6 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_R 0x000017a0 # define NV30_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_G 0x000017a4 # define NV30_TCL_PRIMITIVE_3D_LIGHT_MODEL_BACK_SIDE_PRODUCT_AMBIENT_PLUS_EMISSION_B 0x000017a8 -# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_R 0x000017b0 -# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_G 0x000017b4 -# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_B 0x000017b8 -# define NV30_TCL_PRIMITIVE_3D_COLOR_MATERIAL_BACK_A 0x000017c0 # define NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM 0x000008e4 # define NV30_TCL_PRIMITIVE_3D_TX_ADDRESS_UNIT(d) (0x00001a00 + d * 0x0020) # define NV30_TCL_PRIMITIVE_3D_TX_FORMAT_UNIT(d) (0x00001a04 + d * 0x0020) /* Parameters: mipmap type format ncomp cubic */ @@ -1221,6 +1258,8 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_TX_UNK07_UNIT(d) (0x00001a1c + d * 0x0020) # define NV30_TCL_PRIMITIVE_3D_TX_DEPTH_UNIT(d) (0x00001840 + d * 0x0004) /* Parameters: depth NPOT pitch */ # define NV30_TCL_PRIMITIVE_3D_VB_VERTEX_BATCH 0x00001814 /* Parameters: count_vertices offset_vertices */ +# define NV30_TCL_PRIMITIVE_3D_VB_ELEMENT_U16 0x0000180c /* Parameters: 1: 0: */ +# define NV30_TCL_PRIMITIVE_3D_VB_ELEMENT_U32 0x00001810 # define NV30_TCL_PRIMITIVE_3D_VERTEX_DATA 0x00001818 # define NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE 0x00000374 # define NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_OP 0x00000378 @@ -1244,6 +1283,161 @@ Object NV30_CLEAR_BUFFER used on: NV30 NV40 G70 # define NV30_CLEAR_BUFFER_SET_CONTEXT_SURFACE_2D 0x00000198 # define NV30_CLEAR_BUFFER_UNK002fc 0x000002fc +/****************************************** +Object NV50_TCL_PRIMITIVE_3D used on: +*/ +#define NV50_TCL_PRIMITIVE_3D 0x00000097 +# define NV50_TCL_PRIMITIVE_3D_SET_OBJECT_0( d) (0x00000180 + d * 0x0004) +# define NV50_TCL_PRIMITIVE_3D_SET_OBJECT_1( d) (0x000001c0 + d * 0x0004) +# define NV50_TCL_PRIMITIVE_3D_VERTEX_FOG_1F 0x00000314 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_2F_X 0x00000380 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_2F_Y 0x00000384 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_S 0x000003c0 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX0_2F_T 0x000003c4 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_S 0x000003c8 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX1_2F_T 0x000003cc +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX2_2F_S 0x000003d0 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX2_2F_T 0x000003d4 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX3_2F_S 0x000003d8 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX3_2F_T 0x000003dc +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_3F_X 0x00000400 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_3F_Y 0x00000404 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_3F_Z 0x00000408 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_X 0x00000420 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_Y 0x00000424 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_NOR_3F_Z 0x00000428 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL_3F_R 0x00000430 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL_3F_G 0x00000434 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL_3F_B 0x00000438 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_R 0x00000440 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_G 0x00000444 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL2_3F_B 0x00000448 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_4F_X 0x00000500 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_4F_Y 0x00000504 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_4F_Z 0x00000508 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_4F_W 0x0000050c +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL_4F_R 0x00000530 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL_4F_G 0x00000534 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL_4F_B 0x00000538 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL_4F_A 0x0000053c +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_S 0x00000580 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_T 0x00000584 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_R 0x00000588 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX0_4F_Q 0x0000058c +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_S 0x00000590 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_T 0x00000594 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_R 0x00000598 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX1_4F_Q 0x0000059c +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX2_4F_S 0x000005a0 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX2_4F_T 0x000005a4 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX2_4F_R 0x000005a8 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX2_4F_Q 0x000005ac +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX3_4F_S 0x000005b0 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX3_4F_T 0x000005b4 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX3_4F_R 0x000005b8 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX3_4F_Q 0x000005bc +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX0_2I 0x000006a0 /* Parameters: t s */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX1_2I 0x000006a4 /* Parameters: t s */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX2_2I 0x000006a8 /* Parameters: t s */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX3_2I 0x000006ac /* Parameters: t s */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_4I_XY 0x00000700 /* Parameters: y x */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_POS_4I_ZW 0x00000704 /* Parameters: w z */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_ST 0x00000740 /* Parameters: t s */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX0_4I_RQ 0x00000744 /* Parameters: q r */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_ST 0x00000748 /* Parameters: t s */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX1_4I_RQ 0x0000074c /* Parameters: q r */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX2_4I_ST 0x00000750 /* Parameters: t s */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX2_4I_RQ 0x00000754 /* Parameters: q r */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX3_4I_ST 0x00000758 /* Parameters: t s */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_TX3_4I_RQ 0x0000075c /* Parameters: q r */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_XY 0x00000790 /* Parameters: y x */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_NOR_3I_Z 0x00000794 /* Parameters: z */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL_4I 0x0000088c /* Parameters: a b g r */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_COL2_3I 0x00000890 /* Parameters: a b g r */ +# define NV50_TCL_PRIMITIVE_3D_VIEWPORT_UNK0_X 0x00000a00 +# define NV50_TCL_PRIMITIVE_3D_VIEWPORT_UNK0_Y 0x00000a04 +# define NV50_TCL_PRIMITIVE_3D_VIEWPORT_UNK0_Z 0x00000a08 +# define NV50_TCL_PRIMITIVE_3D_VIEWPORT_UNK1_X 0x00000a0c +# define NV50_TCL_PRIMITIVE_3D_VIEWPORT_UNK1_Y 0x00000a10 +# define NV50_TCL_PRIMITIVE_3D_VIEWPORT_UNK1_Z 0x00000a14 +# define NV50_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR 0x00000c08 +# define NV50_TCL_PRIMITIVE_3D_DEPTH_RANGE_FAR 0x00000c0c +# define NV50_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(d) (0x00000d00 + d * 0x0008) /* Parameters: x2 x1 */ +# define NV50_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(d) (0x00000d04 + d * 0x0008) /* Parameters: y2 y1 */ +# define NV50_TCL_PRIMITIVE_3D_VERTEX_BUFFER_FIRST 0x00000d74 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_BUFFER_COUNT 0x00000d78 +# define NV50_TCL_PRIMITIVE_3D_CLEAR_COLOR_R 0x00000d80 +# define NV50_TCL_PRIMITIVE_3D_CLEAR_COLOR_G 0x00000d84 +# define NV50_TCL_PRIMITIVE_3D_CLEAR_COLOR_B 0x00000d88 +# define NV50_TCL_PRIMITIVE_3D_CLEAR_COLOR_A 0x00000d8c +# define NV50_TCL_PRIMITIVE_3D_CLEAR_DEPTH 0x00000d90 +# define NV50_TCL_PRIMITIVE_3D_CLEAR_STENCIL 0x00000da0 +# define NV50_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT 0x00000dac +# define NV50_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK 0x00000db0 +# define NV50_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE 0x00000db4 +# define NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE 0x00000dc0 +# define NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE 0x00000dc4 +# define NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE 0x00000dc8 +# define NV50_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS 0x00000e04 /* Parameters: w x */ +# define NV50_TCL_PRIMITIVE_3D_SCISSOR_HEIGHT_YPOS 0x00000e08 /* Parameters: h y */ +# define NV50_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_ID 0x00000f00 +# define NV50_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_X 0x00000f04 +# define NV50_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_Y 0x00000f08 +# define NV50_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_Z 0x00000f0c +# define NV50_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_W 0x00000f10 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_REF 0x00000f54 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_MASK 0x00000f58 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_MASK 0x00000f5c +# define NV50_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE 0x000012cc +# define NV50_TCL_PRIMITIVE_3D_SHADE_MODEL 0x000012d4 +# define NV50_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE 0x000012e8 +# define NV50_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE 0x000012ec +# define NV50_TCL_PRIMITIVE_3D_DEPTH_FUNC 0x0000130c +# define NV50_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF 0x00001310 +# define NV50_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC 0x00001314 +# define NV50_TCL_PRIMITIVE_3D_BLEND_COLOR_R 0x0000131c +# define NV50_TCL_PRIMITIVE_3D_BLEND_COLOR_G 0x00001320 +# define NV50_TCL_PRIMITIVE_3D_BLEND_COLOR_B 0x00001324 +# define NV50_TCL_PRIMITIVE_3D_BLEND_COLOR_A 0x00001328 +# define NV50_TCL_PRIMITIVE_3D_BLEND_EQUATION_RGB 0x00001340 +# define NV50_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC_RGB 0x00001344 +# define NV50_TCL_PRIMITIVE_3D_BLEND_FUNC_DST_RGB 0x00001348 +# define NV50_TCL_PRIMITIVE_3D_BLEND_EQUATION_ALPHA 0x0000134c +# define NV50_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC_ALPHA 0x00001350 +# define NV50_TCL_PRIMITIVE_3D_BLEND_FUNC_DST_ALPHA 0x00001358 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_ENABLE 0x00001380 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_FAIL 0x00001384 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_ZFAIL 0x00001388 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_ZPASS 0x0000138c +# define NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_FUNC 0x00001390 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_REF 0x00001394 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_MASK 0x00001398 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_MASK 0x0000139c +# define NV50_TCL_PRIMITIVE_3D_LINE_WIDTH 0x000013b0 +# define NV50_TCL_PRIMITIVE_3D_POINT_SIZE 0x00001518 +# define NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR 0x0000156c +# define NV50_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE 0x00001570 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_ENABLE 0x00001594 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_FAIL 0x00001598 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_ZFAIL 0x0000159c +# define NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_ZPASS 0x000015a0 +# define NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_FUNC 0x000015a4 +# define NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_UNITS 0x000015bc +# define NV50_TCL_PRIMITIVE_3D_VERTEX_BEGIN 0x000015dc +# define NV50_TCL_PRIMITIVE_3D_VERTEX_END 0x000015e0 +# define NV50_TCL_PRIMITIVE_3D_VERTEX_DATA 0x00001640 +# define NV50_TCL_PRIMITIVE_3D_LINE_STIPPLE_ENABLE 0x0000166c +# define NV50_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN 0x00001680 /* Parameters: pattern factor */ +# define NV50_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE 0x0000168c +# define NV50_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN( d) (0x00001700 + d * 0x0004) +# define NV50_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE 0x00001918 +# define NV50_TCL_PRIMITIVE_3D_FRONT_FACE 0x0000191c +# define NV50_TCL_PRIMITIVE_3D_CULL_FACE 0x00001920 +# define NV50_TCL_PRIMITIVE_3D_LOGIC_OP_ENABLE 0x000019c4 +# define NV50_TCL_PRIMITIVE_3D_LOGIC_OP_OP 0x000019c8 +# define NV50_TCL_PRIMITIVE_3D_CLEAR_BUFFERS 0x000019d0 /* Parameters: color stencil depth */ +# define NV50_TCL_PRIMITIVE_3D_COLOR_MASK( d) (0x00001a00 + d * 0x0004) /* Parameters: a b g r */ + /****************************************** Object NV_DMA_FROM_MEMORY used on: NV03 NV04 NV10 NV15 NV20 NV30 NV40 G70 */ -- cgit v1.2.3 From 89f91d1804c0c4919c25d6b9931973733db1e664 Mon Sep 17 00:00:00 2001 From: Carlos Martín Nieto Date: Mon, 15 Jan 2007 00:00:30 +0100 Subject: nouveau: Implement much of the fog handling. --- src/mesa/drivers/dri/nouveau/nouveau_reg.h | 1 + src/mesa/drivers/dri/nouveau/nv30_state.c | 66 +++++++++++++++++++++++++++--- 2 files changed, 61 insertions(+), 6 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_reg.h b/src/mesa/drivers/dri/nouveau/nouveau_reg.h index f52d381f74..8758b538c8 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_reg.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_reg.h @@ -1035,6 +1035,7 @@ Object NV30_TCL_PRIMITIVE_3D used on: NV30 NV40 G70 # define NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_ZPASS 0x00000364 # define NV30_TCL_PRIMITIVE_3D_SHADE_MODEL 0x00000368 # define NV30_TCL_PRIMITIVE_3D_FOG_ENABLE 0x0000036c +# define NV30_TCL_PRIMITIVE_3D_FOG_COLOR 0x00000370 # define NV40_TCL_PRIMITIVE_3D_COLOR_MASK_BUFFER123 0x00000370 /* Parameters: buffer3 b buffer3 g buffer3 r buffer3 a buffer2 b buffer2 g buffer2 r buffer2 a buffer1 b buffer1 g buffer1 r buffer1 a */ # define NV30_TCL_PRIMITIVE_3D_NORMALIZE_ENABLE 0x0000037c # define NV30_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR 0x00000394 diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 9bf5f2adea..4d79bb6127 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -348,17 +348,71 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) static void nv30Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (NOUVEAU_CARD_USING_SHADERS) + return; + switch(pname) { - case GL_FOG_MODE: - //BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_MODE, 1); - //OUT_RING_CACHE (params); + case GL_FOG_MODE: + { + int mode = 0; + /* The modes are different in GL and the card. */ + switch(ctx->Fog.Mode) + { + case GL_LINEAR: + mode = 0x804; break; - /* TODO: unsure about the rest.*/ - default: + case GL_EXP: + mode = 0x802; break; + case GL_EXP2: + mode = 0x803; + break; + } + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_MODE, 1); + OUT_RING_CACHE (mode); + break; + } + case GL_FOG_COLOR: + { + GLubyte c[4]; + UNCLAMPED_FLOAT_TO_RGBA_CHAN(c,params); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_COLOR, 1); + /* nvidia ignores the alpha channel */ + OUT_RING_CACHE(PACK_COLOR_8888_REV(c[0],c[1],c[2],c[3])); + break; + } + case GL_FOG_DENSITY: + case GL_FOG_START: + case GL_FOG_END: + { + GLfloat f=0., c=0.; + switch(ctx->Fog.Mode) + { + case GL_LINEAR: + f = -1.0/(ctx->Fog.End - ctx->Fog.Start); + c = ctx->Fog.Start/(ctx->Fog.End - ctx->Fog.Start) + 2.001953; + break; + case GL_EXP: + f = -0.090168*ctx->Fog.Density; + c = 1.5; + case GL_EXP2: + f = -0.212330*ctx->Fog.Density; + c = 1.5; + } + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_LINEAR, 1); + OUT_RING_CACHE(f); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_CONSTANT, 1); + OUT_RING_CACHE(c); + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_EQUATION_QUADRATIC, 1); + OUT_RING_CACHE(0); /* Is this always the same? */ + break; + } +// case GL_FOG_COORD_SRC: + default: + break; } - } static void nv30Hint(GLcontext *ctx, GLenum target, GLenum mode) -- cgit v1.2.3 From 634b4b3487dcb22e1660959b6a7ce9a42fa50fe2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 15 Jan 2007 17:23:04 +1100 Subject: nouveau: fail CreateScreen on unknown cards instead of guessing. --- src/mesa/drivers/dri/nouveau/nouveau_card.c | 4 ++-- src/mesa/drivers/dri/nouveau/nouveau_screen.c | 9 ++++++++- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_card.c b/src/mesa/drivers/dri/nouveau/nouveau_card.c index ae4f4c7ae5..91f12f0d70 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_card.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_card.c @@ -10,8 +10,8 @@ nouveau_card* nouveau_card_lookup(uint32_t device_id) int i; for(i=0;icard=nouveau_card_lookup(dri_priv->device_id); + if (!screen->card) { + __driUtilMessage("%s: Unknown card type 0x%04x:0x%04x\n", + __func__, dri_priv->device_id >> 16, dri_priv->device_id & 0xFFFF); + FREE(screen); + return NULL; + } + /* parse information in __driConfigOptions */ driParseOptionInfo (&screen->optionCache,__driConfigOptions, __driNConfigOptions); @@ -82,7 +90,6 @@ static nouveauScreenPtr nouveauCreateScreen(__DRIscreenPrivate *sPriv) screen->depthOffset = dri_priv->depth_offset; screen->depthPitch = dri_priv->depth_pitch; - screen->card=nouveau_card_lookup(dri_priv->device_id); screen->driScreen = sPriv; return screen; } -- cgit v1.2.3 From 16f35a3a22fa782f6bb8a51ef32d6668a5c60e85 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 15 Jan 2007 17:28:56 +1100 Subject: nouveau: Add 0x0244 pciid manually for now.. pciids.sf.net is slow to add it so our generator picks it up, and it's *really* annoying me :) --- src/mesa/drivers/dri/nouveau/nouveau_card_list.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_card_list.h b/src/mesa/drivers/dri/nouveau/nouveau_card_list.h index f8ea3c355e..14e7b69802 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_card_list.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_card_list.h @@ -132,6 +132,7 @@ static nouveau_card nouveau_card_list[]={ {0x0221, "GeForce 6200", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, {0x0240, "GeForce 6150", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, {0x0242, "GeForce 6100", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, +{0x0244, "GeForce 6150 Go", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, {0x0250, "GeForce4 Ti 4600", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, {0x0251, "GeForce4 Ti 4400", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, {0x0252, "GeForce4 Ti", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -- cgit v1.2.3 From 4c7d36b688866129a17c3f59aa9374b2f9a874de Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Mon, 15 Jan 2007 12:38:24 +0100 Subject: nouveau: Fix a bug in the nv04 swtcl. --- src/mesa/drivers/dri/nouveau/nv04_swtcl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv04_swtcl.c b/src/mesa/drivers/dri/nouveau/nv04_swtcl.c index e4ace92134..f31c0d692d 100644 --- a/src/mesa/drivers/dri/nouveau/nv04_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv04_swtcl.c @@ -178,7 +178,7 @@ static void nv04_render_tri_fan_verts(GLcontext *ctx,GLuint start,GLuint count,G for(i=start+1;i Date: Mon, 15 Jan 2007 18:58:24 +0100 Subject: nouveau:nv10: fix setting clip region --- src/mesa/drivers/dri/nouveau/nv10_state.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index dbd8bf306e..0e912e73ff 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -618,8 +618,10 @@ static void nv10WindowMoved(nouveauContextPtr nmesa) OUT_RING_CACHE(((h+y) << 16) | y | 0x800); for (i=1; i<7; i++) { BEGIN_RING_CACHE(NvSub3D, - NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 2); + NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 1); OUT_RING_CACHE(0); + BEGIN_RING_CACHE(NvSub3D, + NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(i), 1); OUT_RING_CACHE(0); } -- cgit v1.2.3 From 7c8f311e406a4502982fd03e09d61f6269e0e82c Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Tue, 16 Jan 2007 21:43:54 +0100 Subject: nouveau: Use the most recent card list. --- src/mesa/drivers/dri/nouveau/nouveau_card_list.h | 170 ++++++++++++----------- 1 file changed, 86 insertions(+), 84 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_card_list.h b/src/mesa/drivers/dri/nouveau/nouveau_card_list.h index 14e7b69802..8ec5c4a188 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_card_list.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_card_list.h @@ -2,15 +2,15 @@ static nouveau_card nouveau_card_list[]={ {0x0008, "EDGE 3D", 0, NV_03, 0}, {0x0009, "EDGE 3D", 0, NV_03, 0}, {0x0010, "Mutara V08", 0, NV_03, 0}, -{0x0020, "RIVA TNT", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, -{0x0028, "RIVA TNT2/TNT2 Pro", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, -{0x0029, "RIVA TNT2 Ultra", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, -{0x002A, "Riva TnT2", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, -{0x002B, "Riva TnT2", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, -{0x002C, "Vanta/Vanta LT", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, -{0x002D, "RIVA TNT2 Model 64/Model 64 Pro", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, -{0x002E, "Vanta", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, -{0x002F, "Vanta", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, +{0x0020, "RIVA TNT", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x0028, "RIVA TNT2/TNT2 Pro", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x0029, "RIVA TNT2 Ultra", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x002A, "Riva TnT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x002B, "Riva TnT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x002C, "Vanta/Vanta LT", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x002D, "RIVA TNT2 Model 64/Model 64 Pro", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x002E, "Vanta", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x002F, "Vanta", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, {0x0040, "GeForce 6800 Ultra", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x0041, "GeForce 6800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x0042, "GeForce 6800 LE", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, @@ -30,7 +30,7 @@ static nouveau_card nouveau_card_list[]={ {0x0098, "GeForce Go 7800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x0099, "GE Force Go 7800 GTX", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x009D, "Quadro FX4500", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, -{0x00A0, "Aladdin TNT2", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, +{0x00A0, "Aladdin TNT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, {0x00C0, "GeForce 6800 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x00C1, "GeForce 6800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x00C2, "GeForce 6800 LE", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, @@ -49,11 +49,11 @@ static nouveau_card nouveau_card_list[]={ {0x00F6, "GeForce 6600 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x00F8, "Quadro FX 3400/4400", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x00F9, "GeForce 6800 Ultra/GeForce 6800 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, -{0x00FA, "GeForce PCX 5750", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, +{0x00FA, "GeForce PCX 5750", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, {0x00FB, "GeForce PCX 5900", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, {0x00FC, "Quadro FX 330/GeForce PCX 5300", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0}, {0x00FD, "Quadro FX 330/Quadro NVS280", NV30_TCL_PRIMITIVE_3D|0x0600, NV_30, 0}, -{0x00FE, "Quadro FX 1300", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, +{0x00FE, "Quadro FX 1300", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, {0x00FF, "GeForce PCX 4300", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, {0x0100, "GeForce 256 SDR", NV10_TCL_PRIMITIVE_3D, NV_10, 0}, {0x0101, "GeForce 256 DDR", NV10_TCL_PRIMITIVE_3D, NV_10, 0}, @@ -71,7 +71,8 @@ static nouveau_card nouveau_card_list[]={ {0x0148, "GeForce Go 6600", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x0149, "GeForce Go 6600 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x014A, "Quadro NVS 440", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, -{0x014D, "Quadro FX 550", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, +{0x014C, "Quadro FX 550", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, +{0x014D, "Quadro FX 550", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x014E, "Quadro FX 540", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x014F, "GeForce 6200", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x0150, "GeForce2 GTS/Pro", NV11_TCL_PRIMITIVE_3D, NV_15, 0}, @@ -121,10 +122,10 @@ static nouveau_card nouveau_card_list[]={ {0x01DA, "Quadro NVS 110M", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, {0x01DF, "GeForce 7300 GS", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, {0x01F0, "GeForce4 MX - nForce GPU", NV17_TCL_PRIMITIVE_3D, NV_17, 0}, -{0x0200, "GeForce3", NV20_TCL_PRIMITIVE_3D|0x2000, NV_20, 0}, -{0x0201, "GeForce3 Ti 200", NV20_TCL_PRIMITIVE_3D|0x2000, NV_20, 0}, -{0x0202, "GeForce3 Ti 500", NV20_TCL_PRIMITIVE_3D|0x2000, NV_20, 0}, -{0x0203, "Quadro DCC", NV20_TCL_PRIMITIVE_3D|0x2000, NV_20, 0}, +{0x0200, "GeForce3", NV20_TCL_PRIMITIVE_3D, NV_20, 0}, +{0x0201, "GeForce3 Ti 200", NV20_TCL_PRIMITIVE_3D, NV_20, 0}, +{0x0202, "GeForce3 Ti 500", NV20_TCL_PRIMITIVE_3D, NV_20, 0}, +{0x0203, "Quadro DCC", NV20_TCL_PRIMITIVE_3D, NV_20, 0}, {0x0211, "GeForce 6800", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x0212, "GeForce 6800 LE", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x0215, "GeForce 6800 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, @@ -132,21 +133,21 @@ static nouveau_card nouveau_card_list[]={ {0x0221, "GeForce 6200", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, {0x0240, "GeForce 6150", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, {0x0242, "GeForce 6100", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, -{0x0244, "GeForce 6150 Go", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, -{0x0250, "GeForce4 Ti 4600", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -{0x0251, "GeForce4 Ti 4400", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -{0x0252, "GeForce4 Ti", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -{0x0253, "GeForce4 Ti 4200", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -{0x0258, "Quadro4 900 XGL", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -{0x0259, "Quadro4 750 XGL", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -{0x025B, "Quadro4 700 XGL", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -{0x0280, "GeForce4 Ti 4800", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -{0x0281, "GeForce4 Ti 4200 AGP 8x", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -{0x0282, "GeForce4 Ti 4800 SE", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -{0x0286, "GeForce4 Ti 4200 Go AGP 8x", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -{0x0288, "Quadro4 980 XGL", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -{0x0289, "Quadro4 780 XGL", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, -{0x028C, "Quadro4 700 GoGL", NV20_TCL_PRIMITIVE_3D|0x2500, NV_25, 0}, +{0x0244, "Geforce 6150 Go", NV30_TCL_PRIMITIVE_3D|0x4400, NV_44, 0}, +{0x0250, "GeForce4 Ti 4600", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0251, "GeForce4 Ti 4400", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0252, "GeForce4 Ti", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0253, "GeForce4 Ti 4200", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0258, "Quadro4 900 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0259, "Quadro4 750 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x025B, "Quadro4 700 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0280, "GeForce4 Ti 4800", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0281, "GeForce4 Ti 4200 AGP 8x", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0282, "GeForce4 Ti 4800 SE", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0286, "GeForce4 Ti 4200 Go AGP 8x", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0288, "Quadro4 980 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x0289, "Quadro4 780 XGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, +{0x028C, "Quadro4 700 GoGL", NV20_TCL_PRIMITIVE_3D|0x0500, NV_25, 0}, {0x0290, "GeForce 7900 GTX", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x0291, "GeForce 7900 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x0292, "GeForce 7900 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, @@ -158,58 +159,59 @@ static nouveau_card nouveau_card_list[]={ {0x029D, "Quadro FX 3500", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x029E, "Quadro FX 1500", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x029F, "Quadro FX 4500 X2", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, -{0x02A0, "XGPU", NV20_TCL_PRIMITIVE_3D|0x2000, NV_20, 0}, +{0x02A0, "XGPU", NV20_TCL_PRIMITIVE_3D, NV_20, 0}, {0x02E1, "GeForce 7600 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, -{0x0300, "GeForce FX", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0301, "GeForce FX 5800 Ultra", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0302, "GeForce FX 5800", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0308, "Quadro FX 2000", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0309, "Quadro FX 1000", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0311, "GeForce FX 5600 Ultra", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0312, "GeForce FX 5600", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0313, "NV31", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0314, "GeForce FX 5600XT", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0316, "NV31M", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0317, "NV31M Pro", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x031A, "GeForce FX Go5600", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x031B, "GeForce FX Go5650", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x031D, "NV31GLM", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x031E, "NV31GLM Pro", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x031F, "NV31GLM Pro", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0320, "GeForce FX 5200", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x0321, "GeForce FX 5200 Ultra", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x0322, "GeForce FX 5200", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x0323, "GeForce FX 5200LE", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x0324, "GeForce FX Go5200", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x0325, "GeForce FX Go5250", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x0326, "GeForce FX 5500", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x0327, "GeForce FX 5100", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x0328, "GeForce FX Go5200 32M/64M", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x0329, "GeForce FX Go5200", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x032A, "Quadro NVS 280 PCI", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x032B, "Quadro FX 500/600 PCI", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x032C, "GeForce FX Go 5300", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x032D, "GeForce FX Go5100", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, -{0x032F, "NV34GL", NV30_TCL_PRIMITIVE_3D|0x3400, NV_34, 0}, +{0x0300, "GeForce FX", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0301, "GeForce FX 5800 Ultra", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0302, "GeForce FX 5800", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0308, "Quadro FX 2000", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0309, "Quadro FX 1000", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0311, "GeForce FX 5600 Ultra", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0312, "GeForce FX 5600", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0313, "NV31", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0314, "GeForce FX 5600XT", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0316, "NV31M", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0317, "NV31M Pro", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x031A, "GeForce FX Go5600", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x031B, "GeForce FX Go5650", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x031C, "NVIDIA Quadro FX Go700", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x031D, "NV31GLM", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x031E, "NV31GLM Pro", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x031F, "NV31GLM Pro", NV30_TCL_PRIMITIVE_3D|0x0300, NV_30, 0}, +{0x0320, "GeForce FX 5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0321, "GeForce FX 5200 Ultra", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0322, "GeForce FX 5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0323, "GeForce FX 5200LE", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0324, "GeForce FX Go5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0325, "GeForce FX Go5250", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0326, "GeForce FX 5500", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0327, "GeForce FX 5100", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0328, "GeForce FX Go5200 32M/64M", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x0329, "GeForce FX Go5200", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x032A, "Quadro NVS 280 PCI", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x032B, "Quadro FX 500/600 PCI", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x032C, "GeForce FX Go 5300", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x032D, "GeForce FX Go5100", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, +{0x032F, "NV34GL", NV30_TCL_PRIMITIVE_3D|0x0600, NV_34, 0}, {0x0330, "GeForce FX 5900 Ultra", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, {0x0331, "GeForce FX 5900", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, {0x0332, "GeForce FX 5900XT", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, -{0x0333, "GeForce FX 5950 Ultra", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, +{0x0333, "GeForce FX 5950 Ultra", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, {0x0334, "GeForce FX 5900ZT", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, -{0x0338, "Quadro FX 3000", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x033F, "Quadro FX 700", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0341, "GeForce FX 5700 Ultra", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0342, "GeForce FX 5700", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0343, "GeForce FX 5700LE", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0344, "GeForce FX 5700VE", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0345, "NV36.5", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0347, "GeForce FX Go5700", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0348, "GeForce FX Go5700", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x0349, "NV36M Pro", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x034B, "NV36MAP", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x034C, "Quadro FX Go1000", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x034E, "Quadro FX 1100", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, -{0x034F, "NV36GL", NV30_TCL_PRIMITIVE_3D|0x3000, NV_30, 0}, +{0x0338, "Quadro FX 3000", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x033F, "Quadro FX 700", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0341, "GeForce FX 5700 Ultra", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0342, "GeForce FX 5700", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0343, "GeForce FX 5700LE", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0344, "GeForce FX 5700VE", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0345, "NV36.5", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0347, "GeForce FX Go5700", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0348, "GeForce FX Go5700", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x0349, "NV36M Pro", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x034B, "NV36MAP", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x034C, "Quadro FX Go1000", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x034E, "Quadro FX 1100", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, +{0x034F, "NV36GL", NV30_TCL_PRIMITIVE_3D|0x0400, NV_30, 0}, {0x0391, "GeForce 7600 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x0392, "GeForce 7600 GS", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, {0x0393, "GeForce 7300 GT", NV30_TCL_PRIMITIVE_3D|0x4000, NV_40, 0}, @@ -222,9 +224,9 @@ static nouveau_card nouveau_card_list[]={ {0x0009, "DAC64", 0, NV_03, 0}, {0x0018, "Riva128", 0, NV_03, 0}, {0x0019, "Riva128ZX", 0, NV_03, 0}, -{0x0020, "TNT", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, -{0x0028, "TNT2", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, -{0x0029, "UTNT2", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, -{0x002C, "VTNT2", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, -{0x00A0, "ITNT2", NV04_DX6_MULTITEX_TRIANGLE, NV_04, 0}, +{0x0020, "TNT", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x0028, "TNT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x0029, "UTNT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x002C, "VTNT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, +{0x00A0, "ITNT2", NV04_DX5_TEXTURED_TRIANGLE, NV_04, 0}, }; -- cgit v1.2.3 From 747c9129c0b592941b14c290ff3d8ab22ad66acb Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Wed, 17 Jan 2007 10:39:50 +0800 Subject: I965: fix bug#9625-get the correct PV for quardstrip The order of vertices in payload for quardstrip is (0, 1, 3, 2), so the PV for quardstrip is c->reg.vertex[2]. --- src/mesa/drivers/dri/i965/brw_gs.c | 5 ++++- src/mesa/drivers/dri/i965/brw_gs.h | 1 + src/mesa/drivers/dri/i965/brw_gs_emit.c | 10 ++++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i965/brw_gs.c b/src/mesa/drivers/dri/i965/brw_gs.c index 9066e42252..73263a5fff 100644 --- a/src/mesa/drivers/dri/i965/brw_gs.c +++ b/src/mesa/drivers/dri/i965/brw_gs.c @@ -82,6 +82,9 @@ static void compile_gs_prog( struct brw_context *brw, case GL_QUADS: brw_gs_quads( &c ); break; + case GL_QUAD_STRIP: + brw_gs_quad_strip( &c ); + break; case GL_LINE_LOOP: brw_gs_lines( &c ); break; @@ -145,7 +148,7 @@ static const GLenum gs_prim[GL_POLYGON+1] = { GL_TRIANGLES, GL_TRIANGLES, GL_QUADS, - GL_QUADS, + GL_QUAD_STRIP, GL_TRIANGLES }; diff --git a/src/mesa/drivers/dri/i965/brw_gs.h b/src/mesa/drivers/dri/i965/brw_gs.h index f9aa71d919..29a4e80ce1 100644 --- a/src/mesa/drivers/dri/i965/brw_gs.h +++ b/src/mesa/drivers/dri/i965/brw_gs.h @@ -67,6 +67,7 @@ struct brw_gs_compile { #define ATTR_SIZE (4*4) void brw_gs_quads( struct brw_gs_compile *c ); +void brw_gs_quad_strip( struct brw_gs_compile *c ); void brw_gs_tris( struct brw_gs_compile *c ); void brw_gs_lines( struct brw_gs_compile *c ); void brw_gs_points( struct brw_gs_compile *c ); diff --git a/src/mesa/drivers/dri/i965/brw_gs_emit.c b/src/mesa/drivers/dri/i965/brw_gs_emit.c index e4eed36a46..9abb94d82e 100644 --- a/src/mesa/drivers/dri/i965/brw_gs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_gs_emit.c @@ -116,6 +116,16 @@ void brw_gs_quads( struct brw_gs_compile *c ) brw_gs_emit_vue(c, c->reg.vertex[2], 1, ((_3DPRIM_POLYGON << 2) | R02_PRIM_END)); } +void brw_gs_quad_strip( struct brw_gs_compile *c ) +{ + brw_gs_alloc_regs(c, 4); + + brw_gs_emit_vue(c, c->reg.vertex[2], 0, ((_3DPRIM_POLYGON << 2) | R02_PRIM_START)); + brw_gs_emit_vue(c, c->reg.vertex[3], 0, (_3DPRIM_POLYGON << 2)); + brw_gs_emit_vue(c, c->reg.vertex[0], 0, (_3DPRIM_POLYGON << 2)); + brw_gs_emit_vue(c, c->reg.vertex[1], 1, ((_3DPRIM_POLYGON << 2) | R02_PRIM_END)); +} + void brw_gs_tris( struct brw_gs_compile *c ) { brw_gs_alloc_regs(c, 3); -- cgit v1.2.3 From 62efc4ba3eb53ca75abbe9b52feabe49a5fd56b5 Mon Sep 17 00:00:00 2001 From: Aapo Tahkola Date: Thu, 18 Jan 2007 05:56:13 +0200 Subject: support as much of GL_EXT_stencil_two_side as we can. untested. --- src/mesa/drivers/dri/r300/r300_context.c | 8 ++++++++ src/mesa/drivers/dri/r300/r300_render.c | 4 ++++ src/mesa/drivers/dri/r300/r300_state.c | 27 +++++++++++++++++++-------- src/mesa/drivers/dri/radeon/radeon_screen.c | 8 +++++++- 4 files changed, 38 insertions(+), 9 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index 54eb081d05..71402761ae 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -73,6 +73,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. int future_hw_tcl_on=1; int hw_tcl_on=1; +#define need_GL_EXT_stencil_two_side #define need_GL_ARB_multisample #define need_GL_ARB_texture_compression #define need_GL_ARB_vertex_buffer_object @@ -126,6 +127,10 @@ const struct dri_extension card_extensions[] = { {NULL, NULL} }; +const struct dri_extension stencil_two_side[] = { + {"GL_EXT_stencil_two_side", GL_EXT_stencil_two_side_functions}, +}; + extern struct tnl_pipeline_stage _r300_render_stage; extern const struct tnl_pipeline_stage _r300_tcl_stage; extern const struct tnl_pipeline_stage _r300_texrect_stage; @@ -331,6 +336,9 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, driInitExtensions(ctx, card_extensions, GL_TRUE); + if (driQueryOptionb(&r300->radeon.optionCache, "disable_stencil_two_side") == 0) + driInitSingleExtension(ctx, stencil_two_side); + if (r300->radeon.glCtx->Mesa_DXTn && !driQueryOptionb (&r300->radeon.optionCache, "disable_s3tc")) { _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); _mesa_enable_extension( ctx, "GL_S3_s3tc" ); diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index 03f168365d..91305cb5a2 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -406,6 +406,10 @@ int r300Fallback(GLcontext *ctx) */ FALLBACK_IF(ctx->Fog.Enabled); #endif + FALLBACK_IF(ctx->Stencil._TestTwoSide && + (ctx->Stencil.Ref[0] != ctx->Stencil.Ref[1] || + ctx->Stencil.ValueMask[0] != ctx->Stencil.ValueMask[1] || + ctx->Stencil.WriteMask[0] != ctx->Stencil.WriteMask[1])); if(!r300->disable_lowimpact_fallback){ /* GL_POLYGON_OFFSET_POINT */ diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 72255066d5..6a22ccad2f 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -509,7 +509,6 @@ static void r300Enable(GLcontext* ctx, GLenum cap, GLboolean state) if (r300->state.stencil.hw_stencil) { R300_STATECHANGE(r300, zs); if (state) { - WARN_ONCE("TODO - double side stencil !\n"); r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_RB3D_STENCIL_ENABLE; } else { @@ -863,9 +862,12 @@ static void r300StencilFuncSeparate(GLcontext * ctx, GLenum face, (R300_RB3D_ZS2_STENCIL_MASK << R300_RB3D_ZS2_STENCIL_MASK_SHIFT)); flag = translate_func(ctx->Stencil.Function[0]); - - rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= (flag << R300_RB3D_ZS1_FRONT_FUNC_SHIFT) - | (flag << R300_RB3D_ZS1_BACK_FUNC_SHIFT); + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= (flag << R300_RB3D_ZS1_FRONT_FUNC_SHIFT); + + if (ctx->Stencil._TestTwoSide) + flag = translate_func(ctx->Stencil.Function[1]); + + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= (flag << R300_RB3D_ZS1_BACK_FUNC_SHIFT); rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |= refmask; } @@ -894,10 +896,19 @@ static void r300StencilOpSeparate(GLcontext * ctx, GLenum face, GLenum fail, rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= (translate_stencil_op(ctx->Stencil.FailFunc[0]) << R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT) |(translate_stencil_op(ctx->Stencil.ZFailFunc[0]) << R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT) - |(translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT) - |(translate_stencil_op(ctx->Stencil.FailFunc[0]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT) - |(translate_stencil_op(ctx->Stencil.ZFailFunc[0]) << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT) - |(translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT); + |(translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT); + + if (ctx->Stencil._TestTwoSide) { + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= + (translate_stencil_op(ctx->Stencil.FailFunc[1]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT) + |(translate_stencil_op(ctx->Stencil.ZFailFunc[1]) << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT) + |(translate_stencil_op(ctx->Stencil.ZPassFunc[1]) << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT); + } else { + rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= + (translate_stencil_op(ctx->Stencil.FailFunc[0]) << R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT) + |(translate_stencil_op(ctx->Stencil.ZFailFunc[0]) << R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT) + |(translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT); + } } static void r300ClearStencil(GLcontext * ctx, GLint s) diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 279357ab59..cee1f7e2f9 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -163,6 +163,11 @@ DRI_CONF_OPT_BEGIN(disable_lowimpact_fallback,bool,def) \ DRI_CONF_DESC(en,"Disable Low-impact fallback") \ DRI_CONF_OPT_END +#define DRI_CONF_DISABLE_DOUBLE_SIDE_STENCIL(def) \ +DRI_CONF_OPT_BEGIN(disable_stencil_two_side,bool,def) \ + DRI_CONF_DESC(en,"Disable GL_EXT_stencil_two_side") \ +DRI_CONF_OPT_END + const char __driConfigOptions[] = DRI_CONF_BEGIN @@ -174,6 +179,7 @@ DRI_CONF_BEGIN DRI_CONF_MAX_TEXTURE_COORD_UNITS(8, 2, 8) DRI_CONF_COMMAND_BUFFER_SIZE(8, 8, 32) DRI_CONF_DISABLE_FALLBACK(false) + DRI_CONF_DISABLE_DOUBLE_SIDE_STENCIL(false) DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB) @@ -189,7 +195,7 @@ DRI_CONF_BEGIN DRI_CONF_NO_RAST(false) DRI_CONF_SECTION_END DRI_CONF_END; -static const GLuint __driNConfigOptions = 16; +static const GLuint __driNConfigOptions = 17; #ifndef RADEON_DEBUG int RADEON_DEBUG = 0; -- cgit v1.2.3 From 3c59483ed7c5700a58f47ca9b4a61214d02c9307 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Thu, 18 Jan 2007 22:07:17 +0100 Subject: nouveau: preliminary nv50 state --- src/mesa/drivers/dri/nouveau/Makefile | 1 + src/mesa/drivers/dri/nouveau/nv50_state.c | 567 ++++++++++++++++++++++++++++++ 2 files changed, 568 insertions(+) create mode 100644 src/mesa/drivers/dri/nouveau/nv50_state.c (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile index 9eb40fb9c1..7ffba27bac 100644 --- a/src/mesa/drivers/dri/nouveau/Makefile +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -31,6 +31,7 @@ DRIVER_SOURCES = \ nv10_state.c \ nv20_state.c \ nv30_state.c \ + nv50_state.c \ nouveau_state_cache.c \ nv20_vertprog.c \ nv30_fragprog.c \ diff --git a/src/mesa/drivers/dri/nouveau/nv50_state.c b/src/mesa/drivers/dri/nouveau/nv50_state.c new file mode 100644 index 0000000000..d03c6bf6f2 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv50_state.c @@ -0,0 +1,567 @@ +/************************************************************************** + +Copyright 2006 Nouveau +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_object.h" +#include "nouveau_fifo.h" +#include "nouveau_reg.h" +#include "nouveau_state.h" + +#include "tnl/t_pipeline.h" + +#include "mtypes.h" +#include "colormac.h" + +static void nv50AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte ubRef; + CLAMPED_FLOAT_TO_UBYTE(ubRef, ref); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF, 2); + OUT_RING_CACHE(ubRef); + OUT_RING_CACHE(func); +} + +static void nv50BlendColor(GLcontext *ctx, const GLfloat color[4]) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_BLEND_COLOR_R, 4); + OUT_RING_CACHEf(color[0]); + OUT_RING_CACHEf(color[1]); + OUT_RING_CACHEf(color[2]); + OUT_RING_CACHEf(color[3]); +} + +static void nv50BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_BLEND_EQUATION_RGB, 1); + OUT_RING_CACHE(modeRGB); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_BLEND_EQUATION_ALPHA, 1); + OUT_RING_CACHE(modeA); +} + + +static void nv50BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC_RGB, 2); + OUT_RING_CACHE(sfactorRGB); /* FIXME, sometimes has |0x4000 */ + OUT_RING_CACHE(dfactorRGB); /* FIXME, sometimes has |0x4000 */ + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_BLEND_FUNC_SRC_ALPHA, 2); + OUT_RING_CACHE(sfactorA); /* FIXME, sometimes has |0x4000 */ + OUT_RING_CACHE(dfactorA); /* FIXME, sometimes has |0x4000 */ +} + +static void nv50Clear(GLcontext *ctx, GLbitfield mask) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLuint hw_bufs = 0; + + if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT)) + hw_bufs |= 0x3c; + if (mask & (BUFFER_BIT_STENCIL)) + hw_bufs |= 0x02; + if (mask & (BUFFER_BIT_DEPTH)) + hw_bufs |= 0x01; + + if (hw_bufs) { + BEGIN_RING_SIZE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CLEAR_BUFFERS, 1); + OUT_RING(hw_bufs); + } +} + +static void nv50ClearColor(GLcontext *ctx, const GLfloat color[4]) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CLEAR_COLOR_R, 4); + OUT_RING_CACHEf(color[0]); + OUT_RING_CACHEf(color[1]); + OUT_RING_CACHEf(color[2]); + OUT_RING_CACHEf(color[3]); +} + +static void nv50ClearDepth(GLcontext *ctx, GLclampd d) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CLEAR_DEPTH, 1); + OUT_RING_CACHEf(d); +} + +/* we're don't support indexed buffers + void (*ClearIndex)(GLcontext *ctx, GLuint index) + */ + +static void nv50ClearStencil(GLcontext *ctx, GLint s) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CLEAR_STENCIL, 1); + OUT_RING_CACHE(s); +} + +static void nv50ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) +{ + /* Only using shaders */ +} + +static void nv50ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, + GLboolean bmask, GLboolean amask ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + int i; + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_COLOR_MASK(0), 8); + for (i=0; i<8; i++) { + OUT_RING_CACHE(((amask && 0x01) << 12) | ((bmask && 0x01) << 8) | ((gmask && 0x01)<< 4) | ((rmask && 0x01) << 0)); + } +} + +static void nv50ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode) +{ + // TODO I need love +} + +static void nv50CullFace(GLcontext *ctx, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CULL_FACE, 1); + OUT_RING_CACHE(mode); +} + +static void nv50FrontFace(GLcontext *ctx, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_FRONT_FACE, 1); + OUT_RING_CACHE(mode); +} + +static void nv50DepthFunc(GLcontext *ctx, GLenum func) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_DEPTH_FUNC, 1); + OUT_RING_CACHE(func); +} + +static void nv50DepthMask(GLcontext *ctx, GLboolean flag) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 1); + OUT_RING_CACHE(flag); +} + +static void nv50DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2); + OUT_RING_CACHEf(nearval); + OUT_RING_CACHEf(farval); +} + +/** Specify the current buffer for writing */ +//void (*DrawBuffer)( GLcontext *ctx, GLenum buffer ); +/** Specify the buffers for writing for fragment programs*/ +//void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers ); + +static void nv50Enable(GLcontext *ctx, GLenum cap, GLboolean state) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + switch(cap) + { + case GL_ALPHA_TEST: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_AUTO_NORMAL: +// case GL_BLEND: +// case GL_CLIP_PLANE0: +// case GL_CLIP_PLANE1: +// case GL_CLIP_PLANE2: +// case GL_CLIP_PLANE3: +// case GL_CLIP_PLANE4: +// case GL_CLIP_PLANE5: + case GL_COLOR_LOGIC_OP: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LOGIC_OP_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_COLOR_MATERIAL: +// case GL_COLOR_SUM_EXT: +// case GL_COLOR_TABLE: +// case GL_CONVOLUTION_1D: +// case GL_CONVOLUTION_2D: + case GL_CULL_FACE: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_DEPTH_TEST: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_DEPTH_TEST_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_DITHER: +// case GL_FOG: +// case GL_HISTOGRAM: +// case GL_INDEX_LOGIC_OP: +// case GL_LIGHT0: +// case GL_LIGHT1: +// case GL_LIGHT2: +// case GL_LIGHT3: +// case GL_LIGHT4: +// case GL_LIGHT5: +// case GL_LIGHT6: +// case GL_LIGHT7: +// case GL_LIGHTING: + case GL_LINE_SMOOTH: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LINE_SMOOTH_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_LINE_STIPPLE: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LINE_STIPPLE_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_MAP1_COLOR_4: +// case GL_MAP1_INDEX: +// case GL_MAP1_NORMAL: +// case GL_MAP1_TEXTURE_COORD_1: +// case GL_MAP1_TEXTURE_COORD_2: +// case GL_MAP1_TEXTURE_COORD_3: +// case GL_MAP1_TEXTURE_COORD_4: +// case GL_MAP1_VERTEX_3: +// case GL_MAP1_VERTEX_4: +// case GL_MAP2_COLOR_4: +// case GL_MAP2_INDEX: +// case GL_MAP2_NORMAL: +// case GL_MAP2_TEXTURE_COORD_1: +// case GL_MAP2_TEXTURE_COORD_2: +// case GL_MAP2_TEXTURE_COORD_3: +// case GL_MAP2_TEXTURE_COORD_4: +// case GL_MAP2_VERTEX_3: +// case GL_MAP2_VERTEX_4: +// case GL_MINMAX: +// case GL_NORMALIZE: +// case GL_POINT_SMOOTH: + case GL_POLYGON_OFFSET_POINT: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_POINT_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_POLYGON_OFFSET_LINE: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_LINE_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_POLYGON_OFFSET_FILL: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FILL_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_POLYGON_SMOOTH: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_SMOOTH_ENABLE, 1); + OUT_RING_CACHE(state); + break; + case GL_POLYGON_STIPPLE: + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_POST_COLOR_MATRIX_COLOR_TABLE: +// case GL_POST_CONVOLUTION_COLOR_TABLE: +// case GL_RESCALE_NORMAL: +// case GL_SCISSOR_TEST: +// case GL_SEPARABLE_2D: + case GL_STENCIL_TEST: + // TODO BACK and FRONT ? + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_ENABLE, 1); + OUT_RING_CACHE(state); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_ENABLE, 1); + OUT_RING_CACHE(state); + break; +// case GL_TEXTURE_GEN_Q: +// case GL_TEXTURE_GEN_R: +// case GL_TEXTURE_GEN_S: +// case GL_TEXTURE_GEN_T: +// case GL_TEXTURE_1D: +// case GL_TEXTURE_2D: +// case GL_TEXTURE_3D: + } +} + +static void nv50Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + /* Only using shaders */ +} + +static void nv50Hint(GLcontext *ctx, GLenum target, GLenum mode) +{ + // TODO I need love (fog and line_smooth hints) +} + +// void (*IndexMask)(GLcontext *ctx, GLuint mask); + +static void nv50Lightfv(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params ) +{ + /* Only with shaders */ +} + +/** Set the lighting model parameters */ +void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params); + + +static void nv50LineStipple(GLcontext *ctx, GLint factor, GLushort pattern ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LINE_STIPPLE_PATTERN, 1); + OUT_RING_CACHE((pattern << 8) | factor); +} + +static void nv50LineWidth(GLcontext *ctx, GLfloat width) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LINE_WIDTH, 1); + OUT_RING_CACHEf(width); +} + +static void nv50LogicOpcode(GLcontext *ctx, GLenum opcode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_LOGIC_OP_OP, 1); + OUT_RING_CACHE(opcode); +} + +static void nv50PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + /*TODO: not sure what goes here. */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + +} + +/** Specify the diameter of rasterized points */ +static void nv50PointSize(GLcontext *ctx, GLfloat size) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POINT_SIZE, 1); + OUT_RING_CACHEf(size); +} + +/** Select a polygon rasterization mode */ +static void nv50PolygonMode(GLcontext *ctx, GLenum face, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 1); + OUT_RING_CACHE(mode); + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_MODE_BACK, 1); + OUT_RING_CACHE(mode); + } +} + +/** Set the scale and units used to calculate depth values */ +static void nv50PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR, 1); + OUT_RING_CACHEf(factor); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_OFFSET_UNITS, 1); + OUT_RING_CACHEf(units); +} + +/** Set the polygon stippling pattern */ +static void nv50PolygonStipple(GLcontext *ctx, const GLubyte *mask ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(0), 32); + OUT_RING_CACHEp(mask, 32); +} + +/* Specifies the current buffer for reading */ +void (*ReadBuffer)( GLcontext *ctx, GLenum buffer ); +/** Set rasterization mode */ +void (*RenderMode)(GLcontext *ctx, GLenum mode ); + +/** Define the scissor box */ +static void nv50Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); +} + +/** Select flat or smooth shading */ +static void nv50ShadeModel(GLcontext *ctx, GLenum mode) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_SHADE_MODEL, 1); + OUT_RING_CACHE(mode); +} + +/** OpenGL 2.0 two-sided StencilFunc */ +static void nv50StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, + GLint ref, GLuint mask) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_FUNC, 1); + OUT_RING_CACHE(func); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_REF, 1); + OUT_RING_CACHE(ref); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_FUNC_MASK, 1); + OUT_RING_CACHE(mask); + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_FUNC, 2); + OUT_RING_CACHE(func); + OUT_RING_CACHE(ref); + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_FUNC_MASK, 1); + OUT_RING_CACHE(mask); + } +} + +/** OpenGL 2.0 two-sided StencilMask */ +static void nv50StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_MASK, 1); + OUT_RING_CACHE(mask); + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_MASK, 1); + OUT_RING_CACHE(mask); + } +} + +/** OpenGL 2.0 two-sided StencilOp */ +static void nv50StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, + GLenum zfail, GLenum zpass) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_FRONT_OP_FAIL, 3); + OUT_RING_CACHE(fail); + OUT_RING_CACHE(zfail); + OUT_RING_CACHE(zpass); + } + if (face == GL_BACK || face == GL_FRONT_AND_BACK) { + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_STENCIL_BACK_OP_FAIL, 3); + OUT_RING_CACHE(fail); + OUT_RING_CACHE(zfail); + OUT_RING_CACHE(zpass); + } +} + +/** Control the generation of texture coordinates */ +void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname, + const GLfloat *params); +/** Set texture environment parameters */ +void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname, + const GLfloat *param); +/** Set texture parameters */ +void (*TexParameter)(GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj, + GLenum pname, const GLfloat *params); + +static void nv50TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) +{ + /* Only with shaders */ +} + +static void nv50WindowMoved(nouveauContextPtr nmesa) +{ +} + +static GLboolean nv50InitCard(nouveauContextPtr nmesa) +{ + return GL_FALSE; +} + +static GLboolean nv50BindBuffers(nouveauContextPtr nmesa, int num_color, + nouveau_renderbuffer **color, + nouveau_renderbuffer *depth) +{ + return GL_FALSE; +} + +void nv50InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + func->AlphaFunc = nv50AlphaFunc; + func->BlendColor = nv50BlendColor; + func->BlendEquationSeparate = nv50BlendEquationSeparate; + func->BlendFuncSeparate = nv50BlendFuncSeparate; + func->Clear = nv50Clear; + func->ClearColor = nv50ClearColor; + func->ClearDepth = nv50ClearDepth; + func->ClearStencil = nv50ClearStencil; + func->ClipPlane = nv50ClipPlane; + func->ColorMask = nv50ColorMask; + func->ColorMaterial = nv50ColorMaterial; + func->CullFace = nv50CullFace; + func->FrontFace = nv50FrontFace; + func->DepthFunc = nv50DepthFunc; + func->DepthMask = nv50DepthMask; + func->DepthRange = nv50DepthRange; + func->Enable = nv50Enable; + func->Fogfv = nv50Fogfv; + func->Hint = nv50Hint; + func->Lightfv = nv50Lightfv; +/* func->LightModelfv = nv50LightModelfv; */ + func->LineStipple = nv50LineStipple; + func->LineWidth = nv50LineWidth; + func->LogicOpcode = nv50LogicOpcode; + func->PointParameterfv = nv50PointParameterfv; + func->PointSize = nv50PointSize; + func->PolygonMode = nv50PolygonMode; + func->PolygonOffset = nv50PolygonOffset; + func->PolygonStipple = nv50PolygonStipple; +/* func->ReadBuffer = nv50ReadBuffer; */ +/* func->RenderMode = nv50RenderMode; */ + func->Scissor = nv50Scissor; + func->ShadeModel = nv50ShadeModel; + func->StencilFuncSeparate = nv50StencilFuncSeparate; + func->StencilMaskSeparate = nv50StencilMaskSeparate; + func->StencilOpSeparate = nv50StencilOpSeparate; +/* func->TexGen = nv50TexGen; */ +/* func->TexParameter = nv50TexParameter; */ + func->TextureMatrix = nv50TextureMatrix; + + nmesa->hw_func.InitCard = nv50InitCard; + nmesa->hw_func.BindBuffers = nv50BindBuffers; + nmesa->hw_func.WindowMoved = nv50WindowMoved; +} -- cgit v1.2.3 From 669fefd3da55e3946b4b65a5d1104540c04717cb Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 19 Jan 2007 15:39:36 +1100 Subject: nouveau: bump drm patchlevel --- src/mesa/drivers/dri/nouveau/nouveau_screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index ab7742df14..781ba0113f 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -327,7 +327,7 @@ void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIsc __DRIscreenPrivate *psp; static const __DRIversion ddx_expected = { 1, 2, 0 }; static const __DRIversion dri_expected = { 4, 0, 0 }; - static const __DRIversion drm_expected = { 0, 0, 2 }; + static const __DRIversion drm_expected = { 0, 0, 3 }; dri_interface = interface; -- cgit v1.2.3 From ee3d0617f923cd4bcc8bfdc1ce878648480c2679 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 21 Jan 2007 09:13:27 +1100 Subject: nouveau: shader backend branching support for all cards that support it. --- src/mesa/drivers/dri/nouveau/nouveau_shader.h | 5 +++ src/mesa/drivers/dri/nouveau/nv30_vertprog.c | 7 +++++ src/mesa/drivers/dri/nouveau/nv40_fragprog.c | 45 +++++++++++++++++++++++++++ src/mesa/drivers/dri/nouveau/nv40_vertprog.c | 10 ++++++ 4 files changed, 67 insertions(+) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h index 08cb7817cf..dfa53cad95 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -275,6 +275,11 @@ struct _nvsFunc { void (*SetSaturate) (nvsFunc *); void (*SetLastInst) (nvsFunc *); + void (*SetBranchTarget) (nvsFunc *, int addr); + void (*SetBranchElse) (nvsFunc *, int addr); + void (*SetBranchEnd) (nvsFunc *, int addr); + void (*SetLoopParams) (nvsFunc *, int cnt, int init, int inc); + int (*HasMergedInst) (nvsFunc *); int (*IsLastInst) (nvsFunc *); int (*GetOffsetNext) (nvsFunc *); diff --git a/src/mesa/drivers/dri/nouveau/nv30_vertprog.c b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c index 6ba8e35d55..0b7678f55d 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_vertprog.c +++ b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c @@ -48,6 +48,12 @@ NV30VPUpdateConst(GLcontext *ctx, nouveauShader *nvs, int id) /***************************************************************************** * Assembly routines */ +static void +NV30VPSetBranchTarget(nvsFunc *shader, int addr) +{ + shader->inst[2] &= ~NV30_VP_INST_IADDR_MASK; + shader->inst[2] |= (addr << NV30_VP_INST_IADDR_SHIFT); +} /***************************************************************************** * Disassembly routines @@ -349,5 +355,6 @@ NV30VPInitShaderFuncs(nvsFunc * shader) shader->GetCondRegID = NV30VPGetCondRegID; shader->GetBranch = NV30VPGetBranch; + shader->SetBranchTarget = NV30VPSetBranchTarget; } diff --git a/src/mesa/drivers/dri/nouveau/nv40_fragprog.c b/src/mesa/drivers/dri/nouveau/nv40_fragprog.c index 3d58d6b666..8bca6ae938 100644 --- a/src/mesa/drivers/dri/nouveau/nv40_fragprog.c +++ b/src/mesa/drivers/dri/nouveau/nv40_fragprog.c @@ -5,6 +5,47 @@ unsigned int NVFP_TX_BOP_COUNT = 5; struct _op_xlat NVFP_TX_BOP[64]; + +/***************************************************************************** + * Assembly routines + * - These extend the NV30 routines, which are almost identical. NV40 + * just has branching hacked into the instruction set. + */ +static void +NV40FPSetBranchTarget(nvsFunc *shader, int addr) +{ + shader->inst[2] &= ~NV40_FP_OP_IADDR_MASK; + shader->inst[2] |= (addr << NV40_FP_OP_IADDR_SHIFT); +} + +static void +NV40FPSetBranchElse(nvsFunc *shader, int addr) +{ + shader->inst[2] &= ~NV40_FP_OP_ELSE_ID_MASK; + shader->inst[2] |= (addr << NV40_FP_OP_ELSE_ID_SHIFT); +} + +static void +NV40FPSetBranchEnd(nvsFunc *shader, int addr) +{ + shader->inst[3] &= ~NV40_FP_OP_END_ID_MASK; + shader->inst[3] |= (addr << NV40_FP_OP_END_ID_SHIFT); +} + +static void +NV40FPSetLoopParams(nvsFunc *shader, int count, int initial, int increment) +{ + shader->inst[2] &= ~(NV40_FP_OP_LOOP_COUNT_MASK | + NV40_FP_OP_LOOP_INDEX_MASK | + NV40_FP_OP_LOOP_INCR_MASK); + shader->inst[2] |= ((count << NV40_FP_OP_LOOP_COUNT_SHIFT) | + (initial << NV40_FP_OP_LOOP_INDEX_SHIFT) | + (increment << NV40_FP_OP_LOOP_INCR_SHIFT)); +} + +/***************************************************************************** + * Disassembly routines + */ static struct _op_xlat * NV40FPGetOPTXRec(nvsFunc * shader, int merged) { @@ -149,4 +190,8 @@ NV40FPInitShaderFuncs(nvsFunc * shader) shader->GetLoopCount = NV40FPGetLoopCount; shader->GetLoopInitial = NV40FPGetLoopInitial; shader->GetLoopIncrement = NV40FPGetLoopIncrement; + shader->SetBranchTarget = NV40FPSetBranchTarget; + shader->SetBranchElse = NV40FPSetBranchElse; + shader->SetBranchEnd = NV40FPSetBranchEnd; + shader->SetLoopParams = NV40FPSetLoopParams; } diff --git a/src/mesa/drivers/dri/nouveau/nv40_vertprog.c b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c index 0493e18403..1ba1cfd155 100644 --- a/src/mesa/drivers/dri/nouveau/nv40_vertprog.c +++ b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c @@ -227,6 +227,15 @@ NV40VPSetSource(nvsFunc *shader, nvsRegister * src, int pos) } } +static void +NV40VPSetBranchTarget(nvsFunc *shader, int addr) +{ + shader->inst[2] &= ~NV40_VP_INST_IADDRH_MASK; + shader->inst[2] |= ((addr & 0xf8) >> 3) << NV40_VP_INST_IADDRH_SHIFT; + shader->inst[3] &= ~NV40_VP_INST_IADDRL_MASK; + shader->inst[3] |= ((addr & 0x07) << NV40_VP_INST_IADDRL_SHIFT); +} + static void NV40VPInitInstruction(nvsFunc *shader) { @@ -657,6 +666,7 @@ NV40VPInitShaderFuncs(nvsFunc * shader) shader->SetResult = NV40VPSetResult; shader->SetSource = NV40VPSetSource; shader->SetLastInst = NV40VPSetLastInst; + shader->SetBranchTarget = NV40VPSetBranchTarget; shader->HasMergedInst = NV40VPHasMergedInst; shader->GetOpcodeHW = NV40VPGetOpcodeHW; -- cgit v1.2.3 From 029b81742ad474245e18e0b629d669afe588111c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 21 Jan 2007 09:31:00 +1100 Subject: nouveau: kill off shader pass1. It sucks, and we have someone who can do a much better job than I can starting work on it soon. alloc_temp/free_temp is left in pass2 to workaround fragprog temps/outputs overlapping, but this all belongs in the optimiser. --- src/mesa/drivers/dri/nouveau/nouveau_shader.h | 4 - src/mesa/drivers/dri/nouveau/nouveau_shader_1.c | 304 ------------------------ src/mesa/drivers/dri/nouveau/nouveau_shader_2.c | 16 +- 3 files changed, 1 insertion(+), 323 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h index dfa53cad95..4b94625286 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -56,10 +56,6 @@ typedef struct _nouveauShader { int hw_index_cnt; } params[NVS_MAX_CONSTS]; - struct { - int last_use; - } temps[NVS_MAX_TEMPS]; - /* Pass-private data */ void *pass_rec; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_1.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_1.c index 5de9017f58..90c57d3807 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_1.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_1.c @@ -1,316 +1,12 @@ -/* - * Copyright (C) 2006 Ben Skeggs. - * - * 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, 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: - * Ben Skeggs - */ - #include "glheader.h" #include "macros.h" #include "enums.h" #include "nouveau_shader.h" -#define PASS1_OK 0 -#define PASS1_KILL 1 -#define PASS1_FAIL 2 - -struct pass1_rec { - unsigned int temp[NVS_MAX_TEMPS]; - unsigned int result[NVS_MAX_ATTRIBS]; - unsigned int address[NVS_MAX_ADDRESS]; - unsigned int cc[2]; -}; - -static void -pass1_remove_fragment(nvsPtr nvs, nvsFragmentList *item) -{ - if (item->prev) item->prev->next = item->next; - if (item->next) item->next->prev = item->prev; - if (nvs->list_head == item) nvs->list_head = item->next; - if (nvs->list_tail == item) nvs->list_tail = item->prev; - - nvs->inst_count--; -} - -static int -pass1_result_needed(struct pass1_rec *rec, nvsInstruction *inst) -{ - if (inst->cond_update && rec->cc[inst->cond_reg]) - return 1; - /* Only write components that are read later */ - if (inst->dest.file == NVS_FILE_TEMP) - return (inst->mask & rec->temp[inst->dest.index]); - if (inst->dest.file == NVS_FILE_ADDRESS) - return (inst->mask & rec->address[inst->dest.index]); - /* No point writing result components that are written later */ - if (inst->dest.file == NVS_FILE_RESULT) - return (inst->mask & ~rec->result[inst->dest.index]); - assert(0); -} - -static void -pass1_track_result(struct pass1_rec *rec, nvsInstruction *inst) -{ - if (inst->cond_test) - rec->cc[inst->cond_reg] = 1; - if (inst->dest.file == NVS_FILE_TEMP) { - inst->mask &= rec->temp[inst->dest.index]; - } else if (inst->dest.file == NVS_FILE_RESULT) { - inst->mask &= ~rec->result[inst->dest.index]; - rec->result[inst->dest.index] |= inst->mask; - } else if (inst->dest.file == NVS_FILE_ADDRESS) { - inst->mask &= rec->address[inst->dest.index]; - } -} - -static void -pass1_track_source(nouveauShader *nvs, nvsInstruction *inst, int pos, - unsigned int read) -{ - struct pass1_rec *rec = nvs->pass_rec; - nvsRegister *src = &inst->src[pos]; - unsigned int really_read = 0; - int i,sc; - - /* Account for swizzling */ - for (i=0; i<4; i++) - if (read & (1<swizzle[i]); - - /* Track register reads */ - if (src->file == NVS_FILE_TEMP) { - if (nvs->temps[src->index].last_use == -1) - nvs->temps[src->index].last_use = inst->header.position; - rec->temp [src->index] |= really_read; - } else if (src->indexed) { - rec->address[src->addr_reg] |= (1<addr_comp); - } - - /* Modify swizzle to only access read components */ - /* Find a component that is used.. */ - for (sc=0;sc<4;sc++) - if (really_read & (1<swizzle[i] = sc; -} - -static int -pass1_check_instruction(nouveauShader *nvs, nvsInstruction *inst) -{ - struct pass1_rec *rec = nvs->pass_rec; - unsigned int read0, read1, read2; - - if (inst->op != NVS_OP_KIL) { - if (!pass1_result_needed(rec, inst)) - return PASS1_KILL; - } - pass1_track_result(rec, inst); - - read0 = read1 = read2 = 0; - - switch (inst->op) { - case NVS_OP_FLR: - case NVS_OP_FRC: - case NVS_OP_MOV: - case NVS_OP_SSG: - case NVS_OP_ARL: - read0 = inst->mask; - break; - case NVS_OP_ADD: - case NVS_OP_MAX: - case NVS_OP_MIN: - case NVS_OP_MUL: - case NVS_OP_SEQ: - case NVS_OP_SFL: - case NVS_OP_SGE: - case NVS_OP_SGT: - case NVS_OP_SLE: - case NVS_OP_SLT: - case NVS_OP_SNE: - case NVS_OP_STR: - case NVS_OP_SUB: - read0 = inst->mask; - read1 = inst->mask; - break; - case NVS_OP_CMP: - case NVS_OP_LRP: - case NVS_OP_MAD: - read0 = inst->mask; - read1 = inst->mask; - read2 = inst->mask; - break; - case NVS_OP_XPD: - if (inst->mask & SMASK_X) read0 |= SMASK_Y|SMASK_Z; - if (inst->mask & SMASK_Y) read0 |= SMASK_X|SMASK_Z; - if (inst->mask & SMASK_Z) read0 |= SMASK_X|SMASK_Y; - read1 = read0; - break; - case NVS_OP_COS: - case NVS_OP_EX2: - case NVS_OP_EXP: - case NVS_OP_LG2: - case NVS_OP_LOG: - case NVS_OP_RCC: - case NVS_OP_RCP: - case NVS_OP_RSQ: - case NVS_OP_SCS: - case NVS_OP_SIN: - read0 = SMASK_X; - break; - case NVS_OP_POW: - read0 = SMASK_X; - read1 = SMASK_X; - break; - case NVS_OP_DIV: - read0 = inst->mask; - read1 = SMASK_X; - break; - case NVS_OP_DP2: - read0 = SMASK_X|SMASK_Y; - read1 = SMASK_X|SMASK_Y; - break; - case NVS_OP_DP3: - case NVS_OP_RFL: - read0 = SMASK_X|SMASK_Y|SMASK_Z; - read1 = SMASK_X|SMASK_Y|SMASK_Z; - break; - case NVS_OP_DP4: - read0 = SMASK_ALL; - read1 = SMASK_ALL; - break; - case NVS_OP_DPH: - read0 = SMASK_X|SMASK_Y|SMASK_Z; - read1 = SMASK_ALL; - break; - case NVS_OP_DST: - if (inst->mask & SMASK_Y) read0 = read1 = SMASK_Y; - if (inst->mask & SMASK_Z) read0 |= SMASK_Z; - if (inst->mask & SMASK_W) read1 |= SMASK_W; - break; - case NVS_OP_NRM: - read0 = SMASK_X|SMASK_Y|SMASK_Z; - break; - case NVS_OP_PK2H: - case NVS_OP_PK2US: - read0 = SMASK_X|SMASK_Y; - break; - case NVS_OP_DDX: - case NVS_OP_DDY: - case NVS_OP_UP2H: - case NVS_OP_UP2US: - case NVS_OP_PK4B: - case NVS_OP_PK4UB: - case NVS_OP_UP4B: - case NVS_OP_UP4UB: - read0 = SMASK_ALL; - break; - case NVS_OP_X2D: - read1 = SMASK_X|SMASK_Y; - if (inst->mask & (SMASK_X|SMASK_Z)) { - read0 |= SMASK_X; - read2 |= SMASK_X|SMASK_Y; - } - if (inst->mask & (SMASK_Y|SMASK_W)) { - read0 |= SMASK_Y; - read2 |= SMASK_Z|SMASK_W; - } - break; - case NVS_OP_LIT: - read0 |= SMASK_X|SMASK_Y|SMASK_W; - break; - case NVS_OP_TEX: - case NVS_OP_TXP: - case NVS_OP_TXL: - case NVS_OP_TXB: - read0 = SMASK_ALL; - break; - case NVS_OP_TXD: - read0 = SMASK_ALL; - read1 = SMASK_ALL; - read2 = SMASK_ALL; - break; - case NVS_OP_KIL: - break; - default: - fprintf(stderr, "Unknown sop=%d", inst->op); - return PASS1_FAIL; - } - - /* Any values that are written by this inst can't have been read further up */ - if (inst->dest.file == NVS_FILE_TEMP) - rec->temp[inst->dest.index] &= ~inst->mask; - - if (read0) pass1_track_source(nvs, inst, 0, read0); - if (read1) pass1_track_source(nvs, inst, 1, read1); - if (read2) pass1_track_source(nvs, inst, 2, read2); - - return PASS1_OK; -} - -/* Some basic dead code elimination - * - Remove unused instructions - * - Don't write unused register components - * - Modify swizzles to not reference unneeded components. - */ GLboolean nouveau_shader_pass1(nvsPtr nvs) { - nvsFragmentList *list = nvs->list_tail; - int i; - - for (i=0; itemps[i].last_use = -1; - - nvs->pass_rec = calloc(1, sizeof(struct pass1_rec)); - - while (list) { - assert(list->fragment->type == NVS_INSTRUCTION); - - switch(pass1_check_instruction(nvs, (nvsInstruction *)list->fragment)) { - case PASS1_OK: - break; - case PASS1_KILL: - pass1_remove_fragment(nvs, list); - break; - case PASS1_FAIL: - default: - free(nvs->pass_rec); - nvs->pass_rec = NULL; - return GL_FALSE; - } - - list = list->prev; - } - - free(nvs->pass_rec); - nvs->pass_rec = NULL; return GL_TRUE; } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c index 2177413b66..0476b05f58 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c @@ -68,29 +68,15 @@ pass2_alloc_hw_temp(nvsPtr nvs) return -1; } -static void -pass2_free_hw_temp(nvsPtr nvs, int reg) -{ - struct pass2_rec *rec = nvs->pass_rec; - rec->hw_temps[reg] = 0; -} - static nvsRegister pass2_mangle_reg(nvsPtr nvs, nvsInstruction *inst, nvsRegister reg) { struct pass2_rec *rec = nvs->pass_rec; if (reg.file == NVS_FILE_TEMP) { - int hwidx; - if (rec->temps[reg.index] == -1) rec->temps[reg.index] = pass2_alloc_hw_temp(nvs); - hwidx = rec->temps[reg.index]; - - if (nvs->temps[reg.index].last_use <= inst->header.position) - pass2_free_hw_temp(nvs, hwidx); - - reg.index = hwidx; + reg.index = rec->temps[reg.index]; } return reg; -- cgit v1.2.3 From 4f800c5bacb9734d3030fe11144c8003ec4f169a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 21 Jan 2007 09:48:33 +1100 Subject: nouveau: rename pass0_arb to pass0. I was expecting to have 2 frontends for the shader code (asm, glsl). With Brian's work on GLSL this is unnecessary :) --- src/mesa/drivers/dri/nouveau/Makefile | 2 +- src/mesa/drivers/dri/nouveau/nouveau_shader.c | 4 +- src/mesa/drivers/dri/nouveau/nouveau_shader.h | 3 +- src/mesa/drivers/dri/nouveau/nouveau_shader_0.c | 710 +++++++++++++++++++++ .../drivers/dri/nouveau/nouveau_shader_0_arb.c | 710 --------------------- 5 files changed, 714 insertions(+), 715 deletions(-) create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_shader_0.c delete mode 100644 src/mesa/drivers/dri/nouveau/nouveau_shader_0_arb.c (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile index 7ffba27bac..9718f3bf46 100644 --- a/src/mesa/drivers/dri/nouveau/Makefile +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -20,7 +20,7 @@ DRIVER_SOURCES = \ nouveau_span.c \ nouveau_state.c \ nouveau_shader.c \ - nouveau_shader_0_arb.c \ + nouveau_shader_0.c \ nouveau_shader_1.c \ nouveau_shader_2.c \ nouveau_tex.c \ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.c b/src/mesa/drivers/dri/nouveau/nouveau_shader.c index dc366b36c0..e4db115362 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.c @@ -111,7 +111,7 @@ nvsUpdateShader(GLcontext *ctx, nouveauShader *nvs) /* Translate to HW format now if necessary */ if (!nvs->translated) { /* Mesa ASM shader -> nouveauShader */ - if (!nouveau_shader_pass0_arb(ctx, nvs)) + if (!nouveau_shader_pass0(ctx, nvs)) return GL_FALSE; /* Basic dead code elimination + register usage info */ if (!nouveau_shader_pass1(nvs)) @@ -187,7 +187,7 @@ nvsBuildTextShader(GLcontext *ctx, GLenum target, const char *text) &nvs->mesa.fp); } - nouveau_shader_pass0_arb(ctx, nvs); + nouveau_shader_pass0(ctx, nvs); nouveau_shader_pass1(nvs); nouveau_shader_pass2(nvs); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h index 4b94625286..1a971e56bf 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -366,8 +366,7 @@ extern void NV40FPInitShaderFuncs(nvsFunc *); extern void nouveauShaderInitFuncs(GLcontext *ctx); -extern GLboolean nouveau_shader_pass0_arb(GLcontext *ctx, nouveauShader *nvs); -extern GLboolean nouveau_shader_pass0_slang(GLcontext *ctx, nouveauShader *nvs); +extern GLboolean nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs); extern GLboolean nouveau_shader_pass1(nvsPtr nvs); extern GLboolean nouveau_shader_pass2(nvsPtr nvs); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c new file mode 100644 index 0000000000..34475cad03 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -0,0 +1,710 @@ +/* + * Copyright (C) 2006 Ben Skeggs. + * + * 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, 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: + * Ben Skeggs + */ + +#include "glheader.h" +#include "macros.h" +#include "enums.h" + +#include "program.h" +#include "programopt.h" +#include "program_instruction.h" + +#include "nouveau_context.h" +#include "nouveau_shader.h" + +static nvsFixedReg _tx_mesa_vp_dst_reg[VERT_RESULT_MAX] = { + NVS_FR_POSITION, NVS_FR_COL0, NVS_FR_COL1, NVS_FR_FOGCOORD, + NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, + NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7, + NVS_FR_POINTSZ, NVS_FR_BFC0, NVS_FR_BFC1, NVS_FR_UNKNOWN /* EDGE */ +}; + +static nvsFixedReg _tx_mesa_fp_dst_reg[FRAG_RESULT_MAX] = { + NVS_FR_FRAGDATA0 /* COLR */, NVS_FR_FRAGDATA0 /* COLH */, + NVS_FR_UNKNOWN /* DEPR */ +}; + +static nvsFixedReg _tx_mesa_vp_src_reg[VERT_ATTRIB_MAX] = { + NVS_FR_POSITION, NVS_FR_WEIGHT, NVS_FR_NORMAL, NVS_FR_COL0, NVS_FR_COL1, + NVS_FR_FOGCOORD, NVS_FR_UNKNOWN /* COLOR_INDEX */, NVS_FR_UNKNOWN, + NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, + NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7, +/* Generic attribs 0-15, aliased to the above */ + NVS_FR_POSITION, NVS_FR_WEIGHT, NVS_FR_NORMAL, NVS_FR_COL0, NVS_FR_COL1, + NVS_FR_FOGCOORD, NVS_FR_UNKNOWN /* COLOR_INDEX */, NVS_FR_UNKNOWN, + NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, + NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7 +}; + +static nvsFixedReg _tx_mesa_fp_src_reg[FRAG_ATTRIB_MAX] = { + NVS_FR_POSITION, NVS_FR_COL0, NVS_FR_COL1, NVS_FR_FOGCOORD, + NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, + NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7 +}; + +static nvsSwzComp _tx_mesa_swizzle[4] = { + NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W +}; + +static nvsOpcode _tx_mesa_opcode[] = { + [OPCODE_ABS] = NVS_OP_ABS, [OPCODE_ADD] = NVS_OP_ADD, + [OPCODE_ARA] = NVS_OP_ARA, [OPCODE_ARL] = NVS_OP_ARL, + [OPCODE_ARL_NV] = NVS_OP_ARL, [OPCODE_ARR] = NVS_OP_ARR, + [OPCODE_CMP] = NVS_OP_CMP, [OPCODE_COS] = NVS_OP_COS, + [OPCODE_DDX] = NVS_OP_DDX, [OPCODE_DDY] = NVS_OP_DDY, + [OPCODE_DP3] = NVS_OP_DP3, [OPCODE_DP4] = NVS_OP_DP4, + [OPCODE_DPH] = NVS_OP_DPH, [OPCODE_DST] = NVS_OP_DST, + [OPCODE_EX2] = NVS_OP_EX2, [OPCODE_EXP] = NVS_OP_EXP, + [OPCODE_FLR] = NVS_OP_FLR, [OPCODE_FRC] = NVS_OP_FRC, + [OPCODE_KIL] = NVS_OP_EMUL, [OPCODE_KIL_NV] = NVS_OP_KIL, + [OPCODE_LG2] = NVS_OP_LG2, [OPCODE_LIT] = NVS_OP_LIT, + [OPCODE_LOG] = NVS_OP_LOG, + [OPCODE_LRP] = NVS_OP_LRP, + [OPCODE_MAD] = NVS_OP_MAD, [OPCODE_MAX] = NVS_OP_MAX, + [OPCODE_MIN] = NVS_OP_MIN, [OPCODE_MOV] = NVS_OP_MOV, + [OPCODE_MUL] = NVS_OP_MUL, + [OPCODE_PK2H] = NVS_OP_PK2H, [OPCODE_PK2US] = NVS_OP_PK2US, + [OPCODE_PK4B] = NVS_OP_PK4B, [OPCODE_PK4UB] = NVS_OP_PK4UB, + [OPCODE_POW] = NVS_OP_POW, [OPCODE_POPA] = NVS_OP_POPA, + [OPCODE_PUSHA] = NVS_OP_PUSHA, + [OPCODE_RCC] = NVS_OP_RCC, [OPCODE_RCP] = NVS_OP_RCP, + [OPCODE_RFL] = NVS_OP_RFL, [OPCODE_RSQ] = NVS_OP_RSQ, + [OPCODE_SCS] = NVS_OP_SCS, [OPCODE_SEQ] = NVS_OP_SEQ, + [OPCODE_SFL] = NVS_OP_SFL, [OPCODE_SGE] = NVS_OP_SGE, + [OPCODE_SGT] = NVS_OP_SGT, [OPCODE_SIN] = NVS_OP_SIN, + [OPCODE_SLE] = NVS_OP_SLE, [OPCODE_SLT] = NVS_OP_SLT, + [OPCODE_SNE] = NVS_OP_SNE, [OPCODE_SSG] = NVS_OP_SSG, + [OPCODE_STR] = NVS_OP_STR, [OPCODE_SUB] = NVS_OP_SUB, + [OPCODE_SWZ] = NVS_OP_MOV, + [OPCODE_TEX] = NVS_OP_TEX, [OPCODE_TXB] = NVS_OP_TXB, + [OPCODE_TXD] = NVS_OP_TXD, + [OPCODE_TXL] = NVS_OP_TXL, [OPCODE_TXP] = NVS_OP_TXP, + [OPCODE_TXP_NV] = NVS_OP_TXP, + [OPCODE_UP2H] = NVS_OP_UP2H, [OPCODE_UP2US] = NVS_OP_UP2US, + [OPCODE_UP4B] = NVS_OP_UP4B, [OPCODE_UP4UB] = NVS_OP_UP4UB, + [OPCODE_X2D] = NVS_OP_X2D, + [OPCODE_XPD] = NVS_OP_XPD +}; + +static nvsCond _tx_mesa_condmask[] = { + NVS_COND_UNKNOWN, NVS_COND_GT, NVS_COND_LT, NVS_COND_UN, NVS_COND_GE, + NVS_COND_LE, NVS_COND_NE, NVS_COND_NE, NVS_COND_TR, NVS_COND_FL +}; + +struct pass0_rec { + int nvs_ipos; + int next_temp; + int swzconst_done; + int swzconst_id; + nvsRegister const_half; +}; + +#define X NVS_SWZ_X +#define Y NVS_SWZ_Y +#define Z NVS_SWZ_Z +#define W NVS_SWZ_W + +static void +pass0_append_fragment(nouveauShader *nvs, nvsFragmentHeader *fragment) +{ + nvsFragmentList *list = calloc(1, sizeof(nvsFragmentList)); + if (!list) + return; + + list->fragment = fragment; + list->prev = nvs->list_tail; + if ( nvs->list_tail) + nvs->list_tail->next = list; + if (!nvs->list_head) + nvs->list_head = list; + nvs->list_tail = list; + + nvs->inst_count++; +} + +static void +pass0_make_reg(nouveauShader *nvs, nvsRegister *reg, + nvsRegFile file, unsigned int index) +{ + struct pass0_rec *rec = nvs->pass_rec; + + /* defaults */ + *reg = nvr_unused; + /* -1 == quick-and-dirty temp alloc */ + if (file == NVS_FILE_TEMP && index == -1) { + index = rec->next_temp++; + assert(index < NVS_MAX_TEMPS); + } + reg->file = file; + reg->index = index; +} + +static void +pass0_make_swizzle(nvsSwzComp *swz, unsigned int mesa) +{ + int i; + + for (i=0;i<4;i++) + swz[i] = _tx_mesa_swizzle[GET_SWZ(mesa, i)]; +} + +static nvsOpcode +pass0_make_opcode(enum prog_opcode op) +{ + if (op > MAX_OPCODE) + return NVS_OP_UNKNOWN; + return _tx_mesa_opcode[op]; +} + +static nvsCond +pass0_make_condmask(GLuint mesa) +{ + if (mesa > COND_FL) + return NVS_COND_UNKNOWN; + return _tx_mesa_condmask[mesa]; +} + +static unsigned int +pass0_make_mask(GLuint mesa_mask) +{ + unsigned int mask = 0; + + if (mesa_mask & WRITEMASK_X) mask |= SMASK_X; + if (mesa_mask & WRITEMASK_Y) mask |= SMASK_Y; + if (mesa_mask & WRITEMASK_Z) mask |= SMASK_Z; + if (mesa_mask & WRITEMASK_W) mask |= SMASK_W; + + return mask; +} + +static nvsTexTarget +pass0_make_tex_target(GLuint mesa) +{ + switch (mesa) { + case TEXTURE_1D_INDEX: return NVS_TEX_TARGET_1D; + case TEXTURE_2D_INDEX: return NVS_TEX_TARGET_2D; + case TEXTURE_3D_INDEX: return NVS_TEX_TARGET_3D; + case TEXTURE_CUBE_INDEX: return NVS_TEX_TARGET_CUBE; + case TEXTURE_RECT_INDEX: return NVS_TEX_TARGET_RECT; + default: + return NVS_TEX_TARGET_UNKNOWN; + } +} + +static void +pass0_make_dst_reg(nvsPtr nvs, nvsRegister *reg, + struct prog_dst_register *dst) +{ + struct gl_program *mesa = (struct gl_program*)&nvs->mesa.vp; + nvsFixedReg sfr; + + switch (dst->File) { + case PROGRAM_OUTPUT: + if (mesa->Target == GL_VERTEX_PROGRAM_ARB) { + sfr = (dst->Index < VERT_RESULT_MAX) ? + _tx_mesa_vp_dst_reg[dst->Index] : NVS_FR_UNKNOWN; + } else { + sfr = (dst->Index < FRAG_RESULT_MAX) ? + _tx_mesa_fp_dst_reg[dst->Index] : NVS_FR_UNKNOWN; + } + pass0_make_reg(nvs, reg, NVS_FILE_RESULT, sfr); + break; + case PROGRAM_TEMPORARY: + pass0_make_reg(nvs, reg, NVS_FILE_TEMP, dst->Index); + break; + case PROGRAM_ADDRESS: + pass0_make_reg(nvs, reg, NVS_FILE_ADDRESS, dst->Index); + break; + default: + fprintf(stderr, "Unknown dest file %d\n", dst->File); + assert(0); + } +} + +static void +pass0_make_src_reg(nvsPtr nvs, nvsRegister *reg, struct prog_src_register *src) +{ + struct gl_program *mesa = (struct gl_program *)&nvs->mesa.vp.Base; + struct gl_program_parameter_list *p = mesa->Parameters; + + *reg = nvr_unused; + + switch (src->File) { + case PROGRAM_INPUT: + reg->file = NVS_FILE_ATTRIB; + if (mesa->Target == GL_VERTEX_PROGRAM_ARB) { + reg->index = (src->Index < VERT_ATTRIB_MAX) ? + _tx_mesa_vp_src_reg[src->Index] : NVS_FR_UNKNOWN; + } else { + reg->index = (src->Index < FRAG_ATTRIB_MAX) ? + _tx_mesa_fp_src_reg[src->Index] : NVS_FR_UNKNOWN; + } + break; + /* All const types seem to get shoved into here, not really sure why */ + case PROGRAM_STATE_VAR: + switch (p->Parameters[src->Index].Type) { + case PROGRAM_NAMED_PARAM: + case PROGRAM_CONSTANT: + nvs->params[src->Index].source_val = NULL; + COPY_4V(nvs->params[src->Index].val, p->ParameterValues[src->Index]); + break; + case PROGRAM_STATE_VAR: + nvs->params[src->Index].source_val = p->ParameterValues[src->Index]; + break; + default: + fprintf(stderr, "Unknown parameter type %d\n", + p->Parameters[src->Index].Type); + assert(0); + break; + } + + if (src->RelAddr) { + reg->indexed = 1; + reg->addr_reg = 0; + reg->addr_comp = NVS_SWZ_X; + } else + reg->indexed = 0; + reg->file = NVS_FILE_CONST; + reg->index = src->Index; + break; + case PROGRAM_TEMPORARY: + reg->file = NVS_FILE_TEMP; + reg->index = src->Index; + break; + default: + fprintf(stderr, "Unknown source type %d\n", src->File); + assert(0); + } + + /* per-component negate handled elsewhere */ + reg->negate = src->NegateBase != 0; + reg->abs = src->Abs; + pass0_make_swizzle(reg->swizzle, src->Swizzle); +} + +static nvsInstruction * +pass0_emit(nouveauShader *nvs, nvsOpcode op, nvsRegister dst, + unsigned int mask, int saturate, + nvsRegister src0, nvsRegister src1, nvsRegister src2) +{ + struct pass0_rec *rec = nvs->pass_rec; + nvsInstruction *sif = NULL; + + /* Seems mesa doesn't explicitly 0 this.. */ + if (nvs->mesa.vp.Base.Target == GL_VERTEX_PROGRAM_ARB) + saturate = 0; + + sif = calloc(1, sizeof(nvsInstruction)); + if (sif) { + sif->header.type = NVS_INSTRUCTION; + sif->header.position = rec->nvs_ipos++; + sif->op = op; + sif->saturate = saturate; + sif->dest = dst; + sif->mask = mask; + sif->src[0] = src0; + sif->src[1] = src1; + sif->src[2] = src2; + sif->cond = COND_TR; + sif->cond_reg = 0; + sif->cond_test = 0; + sif->cond_update = 0; + pass0_make_swizzle(sif->cond_swizzle, SWIZZLE_NOOP); + pass0_append_fragment(nvs, (nvsFragmentHeader *)sif); + } + + return sif; +} + +static void +pass0_fixup_swizzle(nvsPtr nvs, + struct prog_src_register *src, + unsigned int sm1, + unsigned int sm2) +{ + static const float sc[4] = { 1.0, 0.0, -1.0, 0.0 }; + struct pass0_rec *rec = nvs->pass_rec; + int fixup_1, fixup_2; + nvsRegister sr, dr = nvr_unused; + nvsRegister sm1const, sm2const; + + if (!rec->swzconst_done) { + struct gl_program *prog = &nvs->mesa.vp.Base; + rec->swzconst_id = _mesa_add_unnamed_constant(prog->Parameters, sc, 4); + rec->swzconst_done = 1; + COPY_4V(nvs->params[rec->swzconst_id].val, sc); + } + + fixup_1 = (sm1 != MAKE_SWIZZLE4(0,0,0,0) && sm2 != MAKE_SWIZZLE4(2,2,2,2)); + fixup_2 = (sm2 != MAKE_SWIZZLE4(2,2,2,2)); + + if (src->File != PROGRAM_TEMPORARY && src->File != PROGRAM_INPUT) { + /* We can't use more than one const in an instruction, so move the const + * into a temp, and swizzle from there. + *TODO: should just emit the swizzled const, instead of swizzling it + * in the shader.. would need to reswizzle any state params when they + * change however.. + */ + pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); + pass0_make_src_reg(nvs, &sr, src); + pass0_emit(nvs, NVS_OP_MOV, dr, SMASK_ALL, 0, sr, nvr_unused, nvr_unused); + pass0_make_reg(nvs, &sr, NVS_FILE_TEMP, dr.index); + } else { + if (fixup_1) + src->NegateBase = 0; + pass0_make_src_reg(nvs, &sr, src); + pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); + } + + pass0_make_reg(nvs, &sm1const, NVS_FILE_CONST, rec->swzconst_id); + pass0_make_swizzle(sm1const.swizzle, sm1); + if (fixup_1 && fixup_2) { + /* Any combination with SWIZZLE_ONE */ + pass0_make_reg(nvs, &sm2const, NVS_FILE_CONST, rec->swzconst_id); + pass0_make_swizzle(sm2const.swizzle, sm2); + pass0_emit(nvs, NVS_OP_MAD, dr, SMASK_ALL, 0, sr, sm1const, sm2const); + } else { + /* SWIZZLE_ZERO || arbitrary negate */ + pass0_emit(nvs, NVS_OP_MUL, dr, SMASK_ALL, 0, sr, sm1const, nvr_unused); + } + + src->File = PROGRAM_TEMPORARY; + src->Index = dr.index; + src->Swizzle = SWIZZLE_NOOP; +} + +#define SET_SWZ(fs, cp, c) fs = (fs & ~(0x7<<(cp*3))) | (c<<(cp*3)) +static void +pass0_check_sources(nvsPtr nvs, struct prog_instruction *inst) +{ + unsigned int insrc = -1, constsrc = -1; + int i; + + for (i=0;i<_mesa_num_inst_src_regs(inst->Opcode);i++) { + struct prog_src_register *src = &inst->SrcReg[i]; + unsigned int sm_1 = 0, sm_2 = 0; + nvsRegister sr, dr; + int do_mov = 0, c; + + /* Build up swizzle masks as if we were going to use + * "MAD new, src, const1, const2" to support arbitrary negation + * and SWIZZLE_ZERO/SWIZZLE_ONE. + */ + for (c=0;c<4;c++) { + if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ZERO) { + SET_SWZ(sm_1, c, SWIZZLE_Y); /* 0.0 */ + SET_SWZ(sm_2, c, SWIZZLE_Y); + SET_SWZ(src->Swizzle, c, SWIZZLE_X); + } else if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ONE) { + SET_SWZ(sm_1, c, SWIZZLE_Y); + if (src->NegateBase & (1<Swizzle, c, SWIZZLE_X); + } else { + if (src->NegateBase & (1<File) { + case PROGRAM_INPUT: + if (insrc != -1 && insrc != src->Index) + do_mov = 1; + else insrc = src->Index; + break; + case PROGRAM_STATE_VAR: + if (constsrc != -1 && constsrc != src->Index) + do_mov = 1; + else constsrc = src->Index; + break; + default: + break; + } + + /* Emit any extra ATTRIB/CONST to a temp, and modify the Mesa instruction + * to point at the temp. + */ + if (do_mov) { + pass0_make_src_reg(nvs, &sr, src); + pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); + pass0_emit(nvs, NVS_OP_MOV, dr, SMASK_ALL, 0, + sr, nvr_unused, nvr_unused); + + src->File = PROGRAM_TEMPORARY; + src->Index = dr.index; + src->Swizzle= SWIZZLE_NOOP; + } + } +} + +static GLboolean +pass0_emulate_instruction(nouveauShader *nvs, struct prog_instruction *inst) +{ + nvsFunc *shader = nvs->func; + nvsRegister src[3], dest, temp; + nvsInstruction *nvsinst; + struct pass0_rec *rec = nvs->pass_rec; + unsigned int mask = pass0_make_mask(inst->DstReg.WriteMask); + int i, sat; + + sat = (inst->SaturateMode == SATURATE_ZERO_ONE); + + /* Build all the "real" regs for the instruction */ + for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++) + pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]); + if (inst->Opcode != OPCODE_KIL) + pass0_make_dst_reg(nvs, &dest, &inst->DstReg); + + switch (inst->Opcode) { + case OPCODE_ABS: + if (shader->caps & SCAP_SRC_ABS) + pass0_emit(nvs, NVS_OP_MOV, dest, mask, sat, + nvsAbs(src[0]), nvr_unused, nvr_unused); + else + pass0_emit(nvs, NVS_OP_MAX, dest, mask, sat, + src[0], nvsNegate(src[0]), nvr_unused); + break; + case OPCODE_KIL: + /* This is only in ARB shaders, so we don't have to worry + * about clobbering a CC reg as they aren't supported anyway. + */ + /* MOVC0 temp, src */ + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + nvsinst = pass0_emit(nvs, NVS_OP_MOV, temp, SMASK_ALL, 0, + src[0], nvr_unused, nvr_unused); + nvsinst->cond_update = 1; + nvsinst->cond_reg = 0; + /* KIL_NV (LT0.xyzw) temp */ + nvsinst = pass0_emit(nvs, NVS_OP_KIL, nvr_unused, 0, 0, + nvr_unused, nvr_unused, nvr_unused); + nvsinst->cond = COND_LT; + nvsinst->cond_reg = 0; + nvsinst->cond_test = 1; + pass0_make_swizzle(nvsinst->cond_swizzle, MAKE_SWIZZLE4(0,1,2,3)); + break; + case OPCODE_LIT: + break; + case OPCODE_LRP: + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + pass0_emit(nvs, NVS_OP_MAD, temp, mask, 0, + nvsNegate(src[0]), src[2], src[2]); + pass0_emit(nvs, NVS_OP_MAD, dest, mask, sat, + src[0], src[1], temp); + break; + case OPCODE_POW: + if (shader->SupportsOpcode(shader, NVS_OP_LG2) && + shader->SupportsOpcode(shader, NVS_OP_EX2)) { + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + /* LG2 temp.x, src0.c */ + pass0_emit(nvs, NVS_OP_LG2, temp, SMASK_X, 0, + nvsSwizzle(src[0], X, X, X, X), + nvr_unused, + nvr_unused); + /* MUL temp.x, temp.x, src1.c */ + pass0_emit(nvs, NVS_OP_MUL, temp, SMASK_X, 0, + nvsSwizzle(temp, X, X, X, X), + nvsSwizzle(src[1], X, X, X, X), + nvr_unused); + /* EX2 dest, temp.x */ + pass0_emit(nvs, NVS_OP_EX2, dest, mask, sat, + nvsSwizzle(temp, X, X, X, X), + nvr_unused, + nvr_unused); + } else { + /* can we use EXP/LOG instead of EX2/LG2?? */ + fprintf(stderr, "Implement POW for NV20 vtxprog!\n"); + return GL_FALSE; + } + break; + case OPCODE_RSQ: + if (rec->const_half.file != NVS_FILE_CONST) { + GLfloat const_half[4] = { 0.5, 0.0, 0.0, 0.0 }; + pass0_make_reg(nvs, &rec->const_half, NVS_FILE_CONST, + _mesa_add_unnamed_constant(nvs->mesa.vp.Base.Parameters, + const_half, 4)); + COPY_4V(nvs->params[rec->const_half.index].val, const_half); + } + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + pass0_emit(nvs, NVS_OP_LG2, temp, SMASK_X, 0, + nvsAbs(nvsSwizzle(src[0], X, X, X, X)), + nvr_unused, + nvr_unused); + pass0_emit(nvs, NVS_OP_MUL, temp, SMASK_X, 0, + nvsSwizzle(temp, X, X, X, X), + nvsNegate(rec->const_half), + nvr_unused); + pass0_emit(nvs, NVS_OP_EX2, dest, mask, sat, + nvsSwizzle(temp, X, X, X, X), + nvr_unused, + nvr_unused); + break; + case OPCODE_SCS: + if (mask & SMASK_X) + pass0_emit(nvs, NVS_OP_COS, dest, SMASK_X, sat, + nvsSwizzle(src[0], X, X, X, X), + nvr_unused, + nvr_unused); + if (mask & SMASK_Y) + pass0_emit(nvs, NVS_OP_SIN, dest, SMASK_Y, sat, + nvsSwizzle(src[0], X, X, X, X), + nvr_unused, + nvr_unused); + break; + case OPCODE_SUB: + pass0_emit(nvs, NVS_OP_ADD, dest, mask, sat, + src[0], nvsNegate(src[1]), nvr_unused); + break; + case OPCODE_XPD: + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + pass0_emit(nvs, NVS_OP_MUL, temp, SMASK_ALL, 0, + nvsSwizzle(src[0], Z, X, Y, Y), + nvsSwizzle(src[1], Y, Z, X, X), + nvr_unused); + pass0_emit(nvs, NVS_OP_MAD, dest, (mask & ~SMASK_W), sat, + nvsSwizzle(src[0], Y, Z, X, X), + nvsSwizzle(src[1], Z, X, Y, Y), + nvsNegate(temp)); + break; + default: + fprintf(stderr, "hw doesn't support opcode \"%s\", and no emulation found\n", + _mesa_opcode_string(inst->Opcode)); + return GL_FALSE; + } + + return GL_TRUE; +} + +static GLboolean +pass0_translate_instructions(nouveauShader *nvs) +{ + struct gl_program *prog = (struct gl_program *)&nvs->mesa.vp; + nvsFunc *shader = nvs->func; + int ipos; + + for (ipos=0; iposNumInstructions; ipos++) { + struct prog_instruction *inst = &prog->Instructions[ipos]; + + if (inst->Opcode == OPCODE_END) + break; + + /* Deal with multiple ATTRIB/PARAM in a single instruction */ + pass0_check_sources(nvs, inst); + + /* Now it's safe to do the prog_instruction->nvsInstruction conversion */ + if (shader->SupportsOpcode(shader, pass0_make_opcode(inst->Opcode))) { + nvsInstruction *nvsinst; + nvsRegister src[3], dest; + int i; + + for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++) + pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]); + pass0_make_dst_reg(nvs, &dest, &inst->DstReg); + + nvsinst = pass0_emit(nvs, + pass0_make_opcode(inst->Opcode), + dest, + pass0_make_mask(inst->DstReg.WriteMask), + (inst->SaturateMode != SATURATE_OFF), + src[0], src[1], src[2]); + nvsinst->tex_unit = inst->TexSrcUnit; + nvsinst->tex_target = pass0_make_tex_target(inst->TexSrcTarget); + /* TODO when NV_fp/vp is implemented */ + nvsinst->cond = COND_TR; + } else { + if (!pass0_emulate_instruction(nvs, inst)) + return GL_FALSE; + } + } + + return GL_TRUE; +} + +GLboolean +nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + struct gl_program *prog = (struct gl_program*)nvs; + struct gl_vertex_program *vp = (struct gl_vertex_program *)prog; + struct gl_fragment_program *fp = (struct gl_fragment_program *)prog; + struct pass0_rec *rec; + int ret; + + switch (prog->Target) { + case GL_VERTEX_PROGRAM_ARB: + nvs->func = &nmesa->VPfunc; + if (vp->IsPositionInvariant) + _mesa_insert_mvp_code(ctx, vp); +#if 0 + if (IS_FIXEDFUNCTION_PROG && CLIP_PLANES_USED) + pass0_insert_ff_clip_planes(); +#endif + break; + case GL_FRAGMENT_PROGRAM_ARB: + nvs->func = &nmesa->FPfunc; + if (fp->FogOption != GL_NONE) + _mesa_append_fog_code(ctx, fp); + break; + default: + fprintf(stderr, "Unknown program type %d", prog->Target); + return GL_FALSE; + } + + rec = calloc(1, sizeof(struct pass0_rec)); + rec->next_temp = prog->NumTemporaries; + nvs->pass_rec = rec; + + ret = pass0_translate_instructions(nvs); + if (!ret) { + /* DESTROY list */ + } + + free(nvs->pass_rec); + return ret; +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0_arb.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0_arb.c deleted file mode 100644 index afb889d421..0000000000 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0_arb.c +++ /dev/null @@ -1,710 +0,0 @@ -/* - * Copyright (C) 2006 Ben Skeggs. - * - * 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, 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: - * Ben Skeggs - */ - -#include "glheader.h" -#include "macros.h" -#include "enums.h" - -#include "program.h" -#include "programopt.h" -#include "program_instruction.h" - -#include "nouveau_context.h" -#include "nouveau_shader.h" - -static nvsFixedReg _tx_mesa_vp_dst_reg[VERT_RESULT_MAX] = { - NVS_FR_POSITION, NVS_FR_COL0, NVS_FR_COL1, NVS_FR_FOGCOORD, - NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, - NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7, - NVS_FR_POINTSZ, NVS_FR_BFC0, NVS_FR_BFC1, NVS_FR_UNKNOWN /* EDGE */ -}; - -static nvsFixedReg _tx_mesa_fp_dst_reg[FRAG_RESULT_MAX] = { - NVS_FR_FRAGDATA0 /* COLR */, NVS_FR_FRAGDATA0 /* COLH */, - NVS_FR_UNKNOWN /* DEPR */ -}; - -static nvsFixedReg _tx_mesa_vp_src_reg[VERT_ATTRIB_MAX] = { - NVS_FR_POSITION, NVS_FR_WEIGHT, NVS_FR_NORMAL, NVS_FR_COL0, NVS_FR_COL1, - NVS_FR_FOGCOORD, NVS_FR_UNKNOWN /* COLOR_INDEX */, NVS_FR_UNKNOWN, - NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, - NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7, -/* Generic attribs 0-15, aliased to the above */ - NVS_FR_POSITION, NVS_FR_WEIGHT, NVS_FR_NORMAL, NVS_FR_COL0, NVS_FR_COL1, - NVS_FR_FOGCOORD, NVS_FR_UNKNOWN /* COLOR_INDEX */, NVS_FR_UNKNOWN, - NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, - NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7 -}; - -static nvsFixedReg _tx_mesa_fp_src_reg[FRAG_ATTRIB_MAX] = { - NVS_FR_POSITION, NVS_FR_COL0, NVS_FR_COL1, NVS_FR_FOGCOORD, - NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, - NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7 -}; - -static nvsSwzComp _tx_mesa_swizzle[4] = { - NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W -}; - -static nvsOpcode _tx_mesa_opcode[] = { - [OPCODE_ABS] = NVS_OP_ABS, [OPCODE_ADD] = NVS_OP_ADD, - [OPCODE_ARA] = NVS_OP_ARA, [OPCODE_ARL] = NVS_OP_ARL, - [OPCODE_ARL_NV] = NVS_OP_ARL, [OPCODE_ARR] = NVS_OP_ARR, - [OPCODE_CMP] = NVS_OP_CMP, [OPCODE_COS] = NVS_OP_COS, - [OPCODE_DDX] = NVS_OP_DDX, [OPCODE_DDY] = NVS_OP_DDY, - [OPCODE_DP3] = NVS_OP_DP3, [OPCODE_DP4] = NVS_OP_DP4, - [OPCODE_DPH] = NVS_OP_DPH, [OPCODE_DST] = NVS_OP_DST, - [OPCODE_EX2] = NVS_OP_EX2, [OPCODE_EXP] = NVS_OP_EXP, - [OPCODE_FLR] = NVS_OP_FLR, [OPCODE_FRC] = NVS_OP_FRC, - [OPCODE_KIL] = NVS_OP_EMUL, [OPCODE_KIL_NV] = NVS_OP_KIL, - [OPCODE_LG2] = NVS_OP_LG2, [OPCODE_LIT] = NVS_OP_LIT, - [OPCODE_LOG] = NVS_OP_LOG, - [OPCODE_LRP] = NVS_OP_LRP, - [OPCODE_MAD] = NVS_OP_MAD, [OPCODE_MAX] = NVS_OP_MAX, - [OPCODE_MIN] = NVS_OP_MIN, [OPCODE_MOV] = NVS_OP_MOV, - [OPCODE_MUL] = NVS_OP_MUL, - [OPCODE_PK2H] = NVS_OP_PK2H, [OPCODE_PK2US] = NVS_OP_PK2US, - [OPCODE_PK4B] = NVS_OP_PK4B, [OPCODE_PK4UB] = NVS_OP_PK4UB, - [OPCODE_POW] = NVS_OP_POW, [OPCODE_POPA] = NVS_OP_POPA, - [OPCODE_PUSHA] = NVS_OP_PUSHA, - [OPCODE_RCC] = NVS_OP_RCC, [OPCODE_RCP] = NVS_OP_RCP, - [OPCODE_RFL] = NVS_OP_RFL, [OPCODE_RSQ] = NVS_OP_RSQ, - [OPCODE_SCS] = NVS_OP_SCS, [OPCODE_SEQ] = NVS_OP_SEQ, - [OPCODE_SFL] = NVS_OP_SFL, [OPCODE_SGE] = NVS_OP_SGE, - [OPCODE_SGT] = NVS_OP_SGT, [OPCODE_SIN] = NVS_OP_SIN, - [OPCODE_SLE] = NVS_OP_SLE, [OPCODE_SLT] = NVS_OP_SLT, - [OPCODE_SNE] = NVS_OP_SNE, [OPCODE_SSG] = NVS_OP_SSG, - [OPCODE_STR] = NVS_OP_STR, [OPCODE_SUB] = NVS_OP_SUB, - [OPCODE_SWZ] = NVS_OP_MOV, - [OPCODE_TEX] = NVS_OP_TEX, [OPCODE_TXB] = NVS_OP_TXB, - [OPCODE_TXD] = NVS_OP_TXD, - [OPCODE_TXL] = NVS_OP_TXL, [OPCODE_TXP] = NVS_OP_TXP, - [OPCODE_TXP_NV] = NVS_OP_TXP, - [OPCODE_UP2H] = NVS_OP_UP2H, [OPCODE_UP2US] = NVS_OP_UP2US, - [OPCODE_UP4B] = NVS_OP_UP4B, [OPCODE_UP4UB] = NVS_OP_UP4UB, - [OPCODE_X2D] = NVS_OP_X2D, - [OPCODE_XPD] = NVS_OP_XPD -}; - -static nvsCond _tx_mesa_condmask[] = { - NVS_COND_UNKNOWN, NVS_COND_GT, NVS_COND_LT, NVS_COND_UN, NVS_COND_GE, - NVS_COND_LE, NVS_COND_NE, NVS_COND_NE, NVS_COND_TR, NVS_COND_FL -}; - -struct pass0_rec { - int nvs_ipos; - int next_temp; - int swzconst_done; - int swzconst_id; - nvsRegister const_half; -}; - -#define X NVS_SWZ_X -#define Y NVS_SWZ_Y -#define Z NVS_SWZ_Z -#define W NVS_SWZ_W - -static void -pass0_append_fragment(nouveauShader *nvs, nvsFragmentHeader *fragment) -{ - nvsFragmentList *list = calloc(1, sizeof(nvsFragmentList)); - if (!list) - return; - - list->fragment = fragment; - list->prev = nvs->list_tail; - if ( nvs->list_tail) - nvs->list_tail->next = list; - if (!nvs->list_head) - nvs->list_head = list; - nvs->list_tail = list; - - nvs->inst_count++; -} - -static void -pass0_make_reg(nouveauShader *nvs, nvsRegister *reg, - nvsRegFile file, unsigned int index) -{ - struct pass0_rec *rec = nvs->pass_rec; - - /* defaults */ - *reg = nvr_unused; - /* -1 == quick-and-dirty temp alloc */ - if (file == NVS_FILE_TEMP && index == -1) { - index = rec->next_temp++; - assert(index < NVS_MAX_TEMPS); - } - reg->file = file; - reg->index = index; -} - -static void -pass0_make_swizzle(nvsSwzComp *swz, unsigned int mesa) -{ - int i; - - for (i=0;i<4;i++) - swz[i] = _tx_mesa_swizzle[GET_SWZ(mesa, i)]; -} - -static nvsOpcode -pass0_make_opcode(enum prog_opcode op) -{ - if (op > MAX_OPCODE) - return NVS_OP_UNKNOWN; - return _tx_mesa_opcode[op]; -} - -static nvsCond -pass0_make_condmask(GLuint mesa) -{ - if (mesa > COND_FL) - return NVS_COND_UNKNOWN; - return _tx_mesa_condmask[mesa]; -} - -static unsigned int -pass0_make_mask(GLuint mesa_mask) -{ - unsigned int mask = 0; - - if (mesa_mask & WRITEMASK_X) mask |= SMASK_X; - if (mesa_mask & WRITEMASK_Y) mask |= SMASK_Y; - if (mesa_mask & WRITEMASK_Z) mask |= SMASK_Z; - if (mesa_mask & WRITEMASK_W) mask |= SMASK_W; - - return mask; -} - -static nvsTexTarget -pass0_make_tex_target(GLuint mesa) -{ - switch (mesa) { - case TEXTURE_1D_INDEX: return NVS_TEX_TARGET_1D; - case TEXTURE_2D_INDEX: return NVS_TEX_TARGET_2D; - case TEXTURE_3D_INDEX: return NVS_TEX_TARGET_3D; - case TEXTURE_CUBE_INDEX: return NVS_TEX_TARGET_CUBE; - case TEXTURE_RECT_INDEX: return NVS_TEX_TARGET_RECT; - default: - return NVS_TEX_TARGET_UNKNOWN; - } -} - -static void -pass0_make_dst_reg(nvsPtr nvs, nvsRegister *reg, - struct prog_dst_register *dst) -{ - struct gl_program *mesa = (struct gl_program*)&nvs->mesa.vp; - nvsFixedReg sfr; - - switch (dst->File) { - case PROGRAM_OUTPUT: - if (mesa->Target == GL_VERTEX_PROGRAM_ARB) { - sfr = (dst->Index < VERT_RESULT_MAX) ? - _tx_mesa_vp_dst_reg[dst->Index] : NVS_FR_UNKNOWN; - } else { - sfr = (dst->Index < FRAG_RESULT_MAX) ? - _tx_mesa_fp_dst_reg[dst->Index] : NVS_FR_UNKNOWN; - } - pass0_make_reg(nvs, reg, NVS_FILE_RESULT, sfr); - break; - case PROGRAM_TEMPORARY: - pass0_make_reg(nvs, reg, NVS_FILE_TEMP, dst->Index); - break; - case PROGRAM_ADDRESS: - pass0_make_reg(nvs, reg, NVS_FILE_ADDRESS, dst->Index); - break; - default: - fprintf(stderr, "Unknown dest file %d\n", dst->File); - assert(0); - } -} - -static void -pass0_make_src_reg(nvsPtr nvs, nvsRegister *reg, struct prog_src_register *src) -{ - struct gl_program *mesa = (struct gl_program *)&nvs->mesa.vp.Base; - struct gl_program_parameter_list *p = mesa->Parameters; - - *reg = nvr_unused; - - switch (src->File) { - case PROGRAM_INPUT: - reg->file = NVS_FILE_ATTRIB; - if (mesa->Target == GL_VERTEX_PROGRAM_ARB) { - reg->index = (src->Index < VERT_ATTRIB_MAX) ? - _tx_mesa_vp_src_reg[src->Index] : NVS_FR_UNKNOWN; - } else { - reg->index = (src->Index < FRAG_ATTRIB_MAX) ? - _tx_mesa_fp_src_reg[src->Index] : NVS_FR_UNKNOWN; - } - break; - /* All const types seem to get shoved into here, not really sure why */ - case PROGRAM_STATE_VAR: - switch (p->Parameters[src->Index].Type) { - case PROGRAM_NAMED_PARAM: - case PROGRAM_CONSTANT: - nvs->params[src->Index].source_val = NULL; - COPY_4V(nvs->params[src->Index].val, p->ParameterValues[src->Index]); - break; - case PROGRAM_STATE_VAR: - nvs->params[src->Index].source_val = p->ParameterValues[src->Index]; - break; - default: - fprintf(stderr, "Unknown parameter type %d\n", - p->Parameters[src->Index].Type); - assert(0); - break; - } - - if (src->RelAddr) { - reg->indexed = 1; - reg->addr_reg = 0; - reg->addr_comp = NVS_SWZ_X; - } else - reg->indexed = 0; - reg->file = NVS_FILE_CONST; - reg->index = src->Index; - break; - case PROGRAM_TEMPORARY: - reg->file = NVS_FILE_TEMP; - reg->index = src->Index; - break; - default: - fprintf(stderr, "Unknown source type %d\n", src->File); - assert(0); - } - - /* per-component negate handled elsewhere */ - reg->negate = src->NegateBase != 0; - reg->abs = src->Abs; - pass0_make_swizzle(reg->swizzle, src->Swizzle); -} - -static nvsInstruction * -pass0_emit(nouveauShader *nvs, nvsOpcode op, nvsRegister dst, - unsigned int mask, int saturate, - nvsRegister src0, nvsRegister src1, nvsRegister src2) -{ - struct pass0_rec *rec = nvs->pass_rec; - nvsInstruction *sif = NULL; - - /* Seems mesa doesn't explicitly 0 this.. */ - if (nvs->mesa.vp.Base.Target == GL_VERTEX_PROGRAM_ARB) - saturate = 0; - - sif = calloc(1, sizeof(nvsInstruction)); - if (sif) { - sif->header.type = NVS_INSTRUCTION; - sif->header.position = rec->nvs_ipos++; - sif->op = op; - sif->saturate = saturate; - sif->dest = dst; - sif->mask = mask; - sif->src[0] = src0; - sif->src[1] = src1; - sif->src[2] = src2; - sif->cond = COND_TR; - sif->cond_reg = 0; - sif->cond_test = 0; - sif->cond_update = 0; - pass0_make_swizzle(sif->cond_swizzle, SWIZZLE_NOOP); - pass0_append_fragment(nvs, (nvsFragmentHeader *)sif); - } - - return sif; -} - -static void -pass0_fixup_swizzle(nvsPtr nvs, - struct prog_src_register *src, - unsigned int sm1, - unsigned int sm2) -{ - static const float sc[4] = { 1.0, 0.0, -1.0, 0.0 }; - struct pass0_rec *rec = nvs->pass_rec; - int fixup_1, fixup_2; - nvsRegister sr, dr = nvr_unused; - nvsRegister sm1const, sm2const; - - if (!rec->swzconst_done) { - struct gl_program *prog = &nvs->mesa.vp.Base; - rec->swzconst_id = _mesa_add_unnamed_constant(prog->Parameters, sc, 4); - rec->swzconst_done = 1; - COPY_4V(nvs->params[rec->swzconst_id].val, sc); - } - - fixup_1 = (sm1 != MAKE_SWIZZLE4(0,0,0,0) && sm2 != MAKE_SWIZZLE4(2,2,2,2)); - fixup_2 = (sm2 != MAKE_SWIZZLE4(2,2,2,2)); - - if (src->File != PROGRAM_TEMPORARY && src->File != PROGRAM_INPUT) { - /* We can't use more than one const in an instruction, so move the const - * into a temp, and swizzle from there. - *TODO: should just emit the swizzled const, instead of swizzling it - * in the shader.. would need to reswizzle any state params when they - * change however.. - */ - pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); - pass0_make_src_reg(nvs, &sr, src); - pass0_emit(nvs, NVS_OP_MOV, dr, SMASK_ALL, 0, sr, nvr_unused, nvr_unused); - pass0_make_reg(nvs, &sr, NVS_FILE_TEMP, dr.index); - } else { - if (fixup_1) - src->NegateBase = 0; - pass0_make_src_reg(nvs, &sr, src); - pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); - } - - pass0_make_reg(nvs, &sm1const, NVS_FILE_CONST, rec->swzconst_id); - pass0_make_swizzle(sm1const.swizzle, sm1); - if (fixup_1 && fixup_2) { - /* Any combination with SWIZZLE_ONE */ - pass0_make_reg(nvs, &sm2const, NVS_FILE_CONST, rec->swzconst_id); - pass0_make_swizzle(sm2const.swizzle, sm2); - pass0_emit(nvs, NVS_OP_MAD, dr, SMASK_ALL, 0, sr, sm1const, sm2const); - } else { - /* SWIZZLE_ZERO || arbitrary negate */ - pass0_emit(nvs, NVS_OP_MUL, dr, SMASK_ALL, 0, sr, sm1const, nvr_unused); - } - - src->File = PROGRAM_TEMPORARY; - src->Index = dr.index; - src->Swizzle = SWIZZLE_NOOP; -} - -#define SET_SWZ(fs, cp, c) fs = (fs & ~(0x7<<(cp*3))) | (c<<(cp*3)) -static void -pass0_check_sources(nvsPtr nvs, struct prog_instruction *inst) -{ - unsigned int insrc = -1, constsrc = -1; - int i; - - for (i=0;i<_mesa_num_inst_src_regs(inst->Opcode);i++) { - struct prog_src_register *src = &inst->SrcReg[i]; - unsigned int sm_1 = 0, sm_2 = 0; - nvsRegister sr, dr; - int do_mov = 0, c; - - /* Build up swizzle masks as if we were going to use - * "MAD new, src, const1, const2" to support arbitrary negation - * and SWIZZLE_ZERO/SWIZZLE_ONE. - */ - for (c=0;c<4;c++) { - if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ZERO) { - SET_SWZ(sm_1, c, SWIZZLE_Y); /* 0.0 */ - SET_SWZ(sm_2, c, SWIZZLE_Y); - SET_SWZ(src->Swizzle, c, SWIZZLE_X); - } else if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ONE) { - SET_SWZ(sm_1, c, SWIZZLE_Y); - if (src->NegateBase & (1<Swizzle, c, SWIZZLE_X); - } else { - if (src->NegateBase & (1<File) { - case PROGRAM_INPUT: - if (insrc != -1 && insrc != src->Index) - do_mov = 1; - else insrc = src->Index; - break; - case PROGRAM_STATE_VAR: - if (constsrc != -1 && constsrc != src->Index) - do_mov = 1; - else constsrc = src->Index; - break; - default: - break; - } - - /* Emit any extra ATTRIB/CONST to a temp, and modify the Mesa instruction - * to point at the temp. - */ - if (do_mov) { - pass0_make_src_reg(nvs, &sr, src); - pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); - pass0_emit(nvs, NVS_OP_MOV, dr, SMASK_ALL, 0, - sr, nvr_unused, nvr_unused); - - src->File = PROGRAM_TEMPORARY; - src->Index = dr.index; - src->Swizzle= SWIZZLE_NOOP; - } - } -} - -static GLboolean -pass0_emulate_instruction(nouveauShader *nvs, struct prog_instruction *inst) -{ - nvsFunc *shader = nvs->func; - nvsRegister src[3], dest, temp; - nvsInstruction *nvsinst; - struct pass0_rec *rec = nvs->pass_rec; - unsigned int mask = pass0_make_mask(inst->DstReg.WriteMask); - int i, sat; - - sat = (inst->SaturateMode == SATURATE_ZERO_ONE); - - /* Build all the "real" regs for the instruction */ - for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++) - pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]); - if (inst->Opcode != OPCODE_KIL) - pass0_make_dst_reg(nvs, &dest, &inst->DstReg); - - switch (inst->Opcode) { - case OPCODE_ABS: - if (shader->caps & SCAP_SRC_ABS) - pass0_emit(nvs, NVS_OP_MOV, dest, mask, sat, - nvsAbs(src[0]), nvr_unused, nvr_unused); - else - pass0_emit(nvs, NVS_OP_MAX, dest, mask, sat, - src[0], nvsNegate(src[0]), nvr_unused); - break; - case OPCODE_KIL: - /* This is only in ARB shaders, so we don't have to worry - * about clobbering a CC reg as they aren't supported anyway. - */ - /* MOVC0 temp, src */ - pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - nvsinst = pass0_emit(nvs, NVS_OP_MOV, temp, SMASK_ALL, 0, - src[0], nvr_unused, nvr_unused); - nvsinst->cond_update = 1; - nvsinst->cond_reg = 0; - /* KIL_NV (LT0.xyzw) temp */ - nvsinst = pass0_emit(nvs, NVS_OP_KIL, nvr_unused, 0, 0, - nvr_unused, nvr_unused, nvr_unused); - nvsinst->cond = COND_LT; - nvsinst->cond_reg = 0; - nvsinst->cond_test = 1; - pass0_make_swizzle(nvsinst->cond_swizzle, MAKE_SWIZZLE4(0,1,2,3)); - break; - case OPCODE_LIT: - break; - case OPCODE_LRP: - pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - pass0_emit(nvs, NVS_OP_MAD, temp, mask, 0, - nvsNegate(src[0]), src[2], src[2]); - pass0_emit(nvs, NVS_OP_MAD, dest, mask, sat, - src[0], src[1], temp); - break; - case OPCODE_POW: - if (shader->SupportsOpcode(shader, NVS_OP_LG2) && - shader->SupportsOpcode(shader, NVS_OP_EX2)) { - pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - /* LG2 temp.x, src0.c */ - pass0_emit(nvs, NVS_OP_LG2, temp, SMASK_X, 0, - nvsSwizzle(src[0], X, X, X, X), - nvr_unused, - nvr_unused); - /* MUL temp.x, temp.x, src1.c */ - pass0_emit(nvs, NVS_OP_MUL, temp, SMASK_X, 0, - nvsSwizzle(temp, X, X, X, X), - nvsSwizzle(src[1], X, X, X, X), - nvr_unused); - /* EX2 dest, temp.x */ - pass0_emit(nvs, NVS_OP_EX2, dest, mask, sat, - nvsSwizzle(temp, X, X, X, X), - nvr_unused, - nvr_unused); - } else { - /* can we use EXP/LOG instead of EX2/LG2?? */ - fprintf(stderr, "Implement POW for NV20 vtxprog!\n"); - return GL_FALSE; - } - break; - case OPCODE_RSQ: - if (rec->const_half.file != NVS_FILE_CONST) { - GLfloat const_half[4] = { 0.5, 0.0, 0.0, 0.0 }; - pass0_make_reg(nvs, &rec->const_half, NVS_FILE_CONST, - _mesa_add_unnamed_constant(nvs->mesa.vp.Base.Parameters, - const_half, 4)); - COPY_4V(nvs->params[rec->const_half.index].val, const_half); - } - pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - pass0_emit(nvs, NVS_OP_LG2, temp, SMASK_X, 0, - nvsAbs(nvsSwizzle(src[0], X, X, X, X)), - nvr_unused, - nvr_unused); - pass0_emit(nvs, NVS_OP_MUL, temp, SMASK_X, 0, - nvsSwizzle(temp, X, X, X, X), - nvsNegate(rec->const_half), - nvr_unused); - pass0_emit(nvs, NVS_OP_EX2, dest, mask, sat, - nvsSwizzle(temp, X, X, X, X), - nvr_unused, - nvr_unused); - break; - case OPCODE_SCS: - if (mask & SMASK_X) - pass0_emit(nvs, NVS_OP_COS, dest, SMASK_X, sat, - nvsSwizzle(src[0], X, X, X, X), - nvr_unused, - nvr_unused); - if (mask & SMASK_Y) - pass0_emit(nvs, NVS_OP_SIN, dest, SMASK_Y, sat, - nvsSwizzle(src[0], X, X, X, X), - nvr_unused, - nvr_unused); - break; - case OPCODE_SUB: - pass0_emit(nvs, NVS_OP_ADD, dest, mask, sat, - src[0], nvsNegate(src[1]), nvr_unused); - break; - case OPCODE_XPD: - pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - pass0_emit(nvs, NVS_OP_MUL, temp, SMASK_ALL, 0, - nvsSwizzle(src[0], Z, X, Y, Y), - nvsSwizzle(src[1], Y, Z, X, X), - nvr_unused); - pass0_emit(nvs, NVS_OP_MAD, dest, (mask & ~SMASK_W), sat, - nvsSwizzle(src[0], Y, Z, X, X), - nvsSwizzle(src[1], Z, X, Y, Y), - nvsNegate(temp)); - break; - default: - fprintf(stderr, "hw doesn't support opcode \"%s\", and no emulation found\n", - _mesa_opcode_string(inst->Opcode)); - return GL_FALSE; - } - - return GL_TRUE; -} - -static GLboolean -pass0_translate_instructions(nouveauShader *nvs) -{ - struct gl_program *prog = (struct gl_program *)&nvs->mesa.vp; - nvsFunc *shader = nvs->func; - int ipos; - - for (ipos=0; iposNumInstructions; ipos++) { - struct prog_instruction *inst = &prog->Instructions[ipos]; - - if (inst->Opcode == OPCODE_END) - break; - - /* Deal with multiple ATTRIB/PARAM in a single instruction */ - pass0_check_sources(nvs, inst); - - /* Now it's safe to do the prog_instruction->nvsInstruction conversion */ - if (shader->SupportsOpcode(shader, pass0_make_opcode(inst->Opcode))) { - nvsInstruction *nvsinst; - nvsRegister src[3], dest; - int i; - - for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++) - pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]); - pass0_make_dst_reg(nvs, &dest, &inst->DstReg); - - nvsinst = pass0_emit(nvs, - pass0_make_opcode(inst->Opcode), - dest, - pass0_make_mask(inst->DstReg.WriteMask), - (inst->SaturateMode != SATURATE_OFF), - src[0], src[1], src[2]); - nvsinst->tex_unit = inst->TexSrcUnit; - nvsinst->tex_target = pass0_make_tex_target(inst->TexSrcTarget); - /* TODO when NV_fp/vp is implemented */ - nvsinst->cond = COND_TR; - } else { - if (!pass0_emulate_instruction(nvs, inst)) - return GL_FALSE; - } - } - - return GL_TRUE; -} - -GLboolean -nouveau_shader_pass0_arb(GLcontext *ctx, nouveauShader *nvs) -{ - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - struct gl_program *prog = (struct gl_program*)nvs; - struct gl_vertex_program *vp = (struct gl_vertex_program *)prog; - struct gl_fragment_program *fp = (struct gl_fragment_program *)prog; - struct pass0_rec *rec; - int ret; - - switch (prog->Target) { - case GL_VERTEX_PROGRAM_ARB: - nvs->func = &nmesa->VPfunc; - if (vp->IsPositionInvariant) - _mesa_insert_mvp_code(ctx, vp); -#if 0 - if (IS_FIXEDFUNCTION_PROG && CLIP_PLANES_USED) - pass0_insert_ff_clip_planes(); -#endif - break; - case GL_FRAGMENT_PROGRAM_ARB: - nvs->func = &nmesa->FPfunc; - if (fp->FogOption != GL_NONE) - _mesa_append_fog_code(ctx, fp); - break; - default: - fprintf(stderr, "Unknown program type %d", prog->Target); - return GL_FALSE; - } - - rec = calloc(1, sizeof(struct pass0_rec)); - rec->next_temp = prog->NumTemporaries; - nvs->pass_rec = rec; - - ret = pass0_translate_instructions(nvs); - if (!ret) { - /* DESTROY list */ - } - - free(nvs->pass_rec); - return ret; -} - -- cgit v1.2.3 From 3c0961d29993a2203323b4c308ae6d7e418ac5aa Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sun, 21 Jan 2007 04:06:57 +0100 Subject: nouveau: add nv04 state support, and small nv04 fixes. --- src/mesa/drivers/dri/nouveau/Makefile | 11 +- src/mesa/drivers/dri/nouveau/nouveau_context.c | 3 +- src/mesa/drivers/dri/nouveau/nouveau_context.h | 18 +- src/mesa/drivers/dri/nouveau/nouveau_object.c | 11 +- src/mesa/drivers/dri/nouveau/nouveau_state.c | 4 +- src/mesa/drivers/dri/nouveau/nouveau_state.h | 1 + src/mesa/drivers/dri/nouveau/nv04_state.c | 497 +++++++++++++++++++++++++ 7 files changed, 527 insertions(+), 18 deletions(-) create mode 100644 src/mesa/drivers/dri/nouveau/nv04_state.c (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile index 9718f3bf46..492e743360 100644 --- a/src/mesa/drivers/dri/nouveau/Makefile +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -19,6 +19,7 @@ DRIVER_SOURCES = \ nouveau_screen.c \ nouveau_span.c \ nouveau_state.c \ + nouveau_state_cache.c \ nouveau_shader.c \ nouveau_shader_0.c \ nouveau_shader_1.c \ @@ -26,18 +27,18 @@ DRIVER_SOURCES = \ nouveau_tex.c \ nouveau_swtcl.c \ nouveau_sync.c \ + nv04_state.c \ nv04_swtcl.c \ - nv10_swtcl.c \ nv10_state.c \ + nv10_swtcl.c \ nv20_state.c \ - nv30_state.c \ - nv50_state.c \ - nouveau_state_cache.c \ nv20_vertprog.c \ + nv30_state.c \ nv30_fragprog.c \ nv30_vertprog.c \ nv40_fragprog.c \ - nv40_vertprog.c + nv40_vertprog.c \ + nv50_state.c C_SOURCES = \ $(COMMON_SOURCES) \ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 79da46fc0b..5db93eb012 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -50,6 +50,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_msg.h" #include "nouveau_reg.h" #include "nouveau_lock.h" +#include "nv04_swtcl.h" #include "nv10_swtcl.h" #include "vblank.h" @@ -212,7 +213,7 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, break; case NV_04: case NV_05: - //nv04TriInitFunctions( ctx ); + nv04TriInitFunctions( ctx ); break; case NV_10: case NV_20: diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index c7bf387210..bcfbb9fb8d 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -170,15 +170,15 @@ typedef struct nouveau_context { /* Configuration cache */ driOptionCache optionCache; - /* vblank stuff */ - uint32_t vblank_flags; - uint32_t vblank_seq; - - GLuint new_state; - GLuint new_render_state; - GLuint render_index; - GLmatrix viewport; - GLfloat depth_scale; + /* vblank stuff */ + uint32_t vblank_flags; + uint32_t vblank_seq; + + GLuint new_state; + GLuint new_render_state; + GLuint render_index; + GLmatrix viewport; + GLfloat depth_scale; }nouveauContextRec, *nouveauContextPtr; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.c b/src/mesa/drivers/dri/nouveau/nouveau_object.c index 1558f2963d..26086e16e4 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.c @@ -62,10 +62,17 @@ void nouveauObjectInit(nouveauContextPtr nmesa) nouveauCreateContextObject(nmesa, Nv3D, nmesa->screen->card->class_3d, 0, 0, 0, 0); - nouveauCreateContextObject(nmesa, NvCtxSurf2D, NV10_CONTEXT_SURFACES_2D, + if (nmesa->screen->card->type>=NV_10) { + nouveauCreateContextObject(nmesa, NvCtxSurf2D, NV10_CONTEXT_SURFACES_2D, 0, 0, 0, 0); - nouveauCreateContextObject(nmesa, NvImageBlit, NV10_IMAGE_BLIT, + nouveauCreateContextObject(nmesa, NvImageBlit, NV10_IMAGE_BLIT, NV_DMA_CONTEXT_FLAGS_PATCH_SRCCOPY, 0, 0, 0); + } else { + nouveauCreateContextObject(nmesa, NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D, + 0, 0, 0, 0); + nouveauCreateContextObject(nmesa, NvImageBlit, NV_IMAGE_BLIT, + NV_DMA_CONTEXT_FLAGS_PATCH_SRCCOPY, 0, 0, 0); + } nouveauCreateContextObject(nmesa, NvMemFormat, NV_MEMORY_TO_MEMORY_FORMAT, 0, 0, 0, 0); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c index 1ff881f054..18f6ffb2ad 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -156,9 +156,11 @@ void nouveauDDInitState(nouveauContextPtr nmesa) switch(type) { case NV_03: + /* Unimplemented */ + break; case NV_04: case NV_05: - /* No TCL engines for these ones */ + nv04InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver); break; case NV_10: nv10InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.h b/src/mesa/drivers/dri/nouveau/nouveau_state.h index 16d63a6ac2..5b85287445 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.h @@ -32,6 +32,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. extern void nouveauDDInitState(nouveauContextPtr nmesa); extern void nouveauDDInitStateFuncs(GLcontext *ctx); +extern void nv04InitStateFuncs(GLcontext *ctx, struct dd_function_table *func); extern void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func); extern void nv20InitStateFuncs(GLcontext *ctx, struct dd_function_table *func); extern void nv30InitStateFuncs(GLcontext *ctx, struct dd_function_table *func); diff --git a/src/mesa/drivers/dri/nouveau/nv04_state.c b/src/mesa/drivers/dri/nouveau/nv04_state.c new file mode 100644 index 0000000000..83ad8ae432 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_state.c @@ -0,0 +1,497 @@ +/************************************************************************** + +Copyright 2007 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_object.h" +#include "nouveau_fifo.h" +#include "nouveau_reg.h" +#include "nouveau_msg.h" + +#include "tnl/t_pipeline.h" + +#include "mtypes.h" +#include "colormac.h" + +static uint32_t nv04_compare_func(GLcontext *ctx,GLuint f) +{ + switch ( ctx->Color.AlphaFunc ) { + case GL_NEVER: return 1; + case GL_LESS: return 2; + case GL_EQUAL: return 3; + case GL_LEQUAL: return 4; + case GL_GREATER: return 5; + case GL_NOTEQUAL: return 6; + case GL_GEQUAL: return 7; + case GL_ALWAYS: return 8; + } + WARN_ONCE("Unable to find the function\n"); + return 0; +} + +static uint32_t nv04_blend_func(GLcontext *ctx,GLuint f) +{ + switch ( ctx->Color.AlphaFunc ) { + case GL_ZERO: return 0x1; + case GL_ONE: return 0x2; + case GL_SRC_COLOR: return 0x3; + case GL_ONE_MINUS_SRC_COLOR: return 0x4; + case GL_SRC_ALPHA: return 0x5; + case GL_ONE_MINUS_SRC_ALPHA: return 0x6; + case GL_DST_ALPHA: return 0x7; + case GL_ONE_MINUS_DST_ALPHA: return 0x8; + case GL_DST_COLOR: return 0x9; + case GL_ONE_MINUS_DST_COLOR: return 0xA; + case GL_SRC_ALPHA_SATURATE: return 0xB; + } + WARN_ONCE("Unable to find the function\n"); + return 0; +} + +static void nv04_emit_control(GLcontext *ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + uint32_t control,cull; + GLubyte alpha_ref; + + CLAMPED_FLOAT_TO_UBYTE(alpha_ref, ctx->Color.AlphaRef); + control=alpha_ref; + control|=(nv04_compare_func(ctx,ctx->Color.AlphaFunc)<<8); + control|=(ctx->Color.AlphaEnabled<<12); + control|=(1<<13); + control|=(ctx->Depth.Test<<14); + control|=(nv04_compare_func(ctx,ctx->Depth.Func)<<16); + if ((ctx->Polygon.CullFlag)&&(ctx->Polygon.CullFaceMode!=GL_FRONT_AND_BACK)) + { + if ((ctx->Polygon.FrontFace==GL_CW)&&(ctx->Polygon.CullFaceMode==GL_FRONT)) + cull=2; + if ((ctx->Polygon.FrontFace==GL_CW)&&(ctx->Polygon.CullFaceMode==GL_BACK)) + cull=3; + if ((ctx->Polygon.FrontFace==GL_CCW)&&(ctx->Polygon.CullFaceMode==GL_FRONT)) + cull=3; + if ((ctx->Polygon.FrontFace==GL_CCW)&&(ctx->Polygon.CullFaceMode==GL_BACK)) + cull=2; + } + else + if (ctx->Polygon.CullFaceMode==GL_FRONT_AND_BACK) + cull=0; + else + cull=1; + control|=(cull<<20); + control|=(ctx->Color.DitherFlag<<22); + if ((ctx->Depth.Test)&&(ctx->Depth.Mask)) + control|=(1<<24); + + control|=(1<<30); // integer zbuffer format + + BEGIN_RING_CACHE(NvSub3D, NV04_DX5_TEXTURED_TRIANGLE_CONTROL, 1); + OUT_RING_CACHE(control); +} + +static void nv04_emit_blend(GLcontext *ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + uint32_t blend; + + blend=0x4; // texture MODULATE_ALPHA + blend|=0x20; // alpha is MSB + switch(ctx->Light.ShadeModel) { + case GL_SMOOTH:blend|=(1<<6);break; + case GL_FLAT: blend|=(2<<6);break; + default:break; + } + if (ctx->Hint.PerspectiveCorrection!=GL_FASTEST) + blend|=(1<<8); + blend|=(ctx->Fog.Enabled<<16); + blend|=(ctx->Color.BlendEnabled<<20); + blend|=(nv04_blend_func(ctx,ctx->Color.BlendSrcRGB)<<24); + blend|=(nv04_blend_func(ctx,ctx->Color.BlendDstRGB)<<28); + + BEGIN_RING_CACHE(NvSub3D, NV04_DX5_TEXTURED_TRIANGLE_BLEND, 1); + OUT_RING_CACHE(blend); +} + +static void nv04_emit_fog_color(GLcontext *ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte c[4]; + c[0] = FLOAT_TO_UBYTE( ctx->Fog.Color[0] ); + c[1] = FLOAT_TO_UBYTE( ctx->Fog.Color[1] ); + c[2] = FLOAT_TO_UBYTE( ctx->Fog.Color[2] ); + c[3] = FLOAT_TO_UBYTE( ctx->Fog.Color[3] ); + BEGIN_RING_CACHE(NvSub3D, NV04_DX5_TEXTURED_TRIANGLE_FOG_COLOR, 1); + OUT_RING_CACHE(PACK_COLOR_8888_REV(c[0],c[1],c[2],c[3])); +} + +static void nv04AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) +{ + nv04_emit_control(ctx); +} + +static void nv04BlendColor(GLcontext *ctx, const GLfloat color[4]) +{ + nv04_emit_blend(ctx); +} + +static void nv04BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA) +{ + nv04_emit_blend(ctx); +} + + +static void nv04BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA) +{ + nv04_emit_blend(ctx); +} + +static void nv04Clear(GLcontext *ctx, GLbitfield mask) +{ + /* TODO */ +} + +static void nv04ClearColor(GLcontext *ctx, const GLfloat color[4]) +{ + /* TODO */ +} + +static void nv04ClearDepth(GLcontext *ctx, GLclampd d) +{ + /* TODO */ +} + +static void nv04ClearStencil(GLcontext *ctx, GLint s) +{ + /* TODO */ +} + +static void nv04ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) +{ + /* TODO */ +} + +static void nv04ColorMask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, + GLboolean bmask, GLboolean amask ) +{ + /* TODO */ +} + +static void nv04ColorMaterial(GLcontext *ctx, GLenum face, GLenum mode) +{ + /* TODO I need love */ +} + +static void nv04CullFace(GLcontext *ctx, GLenum mode) +{ + nv04_emit_control(ctx); +} + +static void nv04FrontFace(GLcontext *ctx, GLenum mode) +{ + /* TODO */ +} + +static void nv04DepthFunc(GLcontext *ctx, GLenum func) +{ + nv04_emit_control(ctx); +} + +static void nv04DepthMask(GLcontext *ctx, GLboolean flag) +{ + /* TODO */ +} + +static void nv04DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval) +{ + /* TODO */ +} + +/** Specify the current buffer for writing */ +//void (*DrawBuffer)( GLcontext *ctx, GLenum buffer ); +/** Specify the buffers for writing for fragment programs*/ +//void (*DrawBuffers)( GLcontext *ctx, GLsizei n, const GLenum *buffers ); + +static void nv04Enable(GLcontext *ctx, GLenum cap, GLboolean state) +{ + switch(cap) + { + case GL_ALPHA_TEST: + nv04_emit_control(ctx); + break; +// case GL_AUTO_NORMAL: + case GL_BLEND: + nv04_emit_blend(ctx); + break; +// case GL_CLIP_PLANE0: +// case GL_CLIP_PLANE1: +// case GL_CLIP_PLANE2: +// case GL_CLIP_PLANE3: +// case GL_CLIP_PLANE4: +// case GL_CLIP_PLANE5: +// case GL_COLOR_LOGIC_OP: +// case GL_COLOR_MATERIAL: +// case GL_COLOR_SUM_EXT: +// case GL_COLOR_TABLE: +// case GL_CONVOLUTION_1D: +// case GL_CONVOLUTION_2D: + case GL_CULL_FACE: + nv04_emit_control(ctx); + break; + case GL_DEPTH_TEST: + nv04_emit_control(ctx); + break; + case GL_DITHER: + nv04_emit_control(ctx); + break; + case GL_FOG: + nv04_emit_blend(ctx); + break; +// case GL_HISTOGRAM: +// case GL_INDEX_LOGIC_OP: +// case GL_LIGHT0: +// case GL_LIGHT1: +// case GL_LIGHT2: +// case GL_LIGHT3: +// case GL_LIGHT4: +// case GL_LIGHT5: +// case GL_LIGHT6: +// case GL_LIGHT7: +// case GL_LIGHTING: +// case GL_LINE_SMOOTH: +// case GL_LINE_STIPPLE: +// case GL_MAP1_COLOR_4: +// case GL_MAP1_INDEX: +// case GL_MAP1_NORMAL: +// case GL_MAP1_TEXTURE_COORD_1: +// case GL_MAP1_TEXTURE_COORD_2: +// case GL_MAP1_TEXTURE_COORD_3: +// case GL_MAP1_TEXTURE_COORD_4: +// case GL_MAP1_VERTEX_3: +// case GL_MAP1_VERTEX_4: +// case GL_MAP2_COLOR_4: +// case GL_MAP2_INDEX: +// case GL_MAP2_NORMAL: +// case GL_MAP2_TEXTURE_COORD_1: +// case GL_MAP2_TEXTURE_COORD_2: +// case GL_MAP2_TEXTURE_COORD_3: +// case GL_MAP2_TEXTURE_COORD_4: +// case GL_MAP2_VERTEX_3: +// case GL_MAP2_VERTEX_4: +// case GL_MINMAX: +// case GL_NORMALIZE: +// case GL_POINT_SMOOTH: +// case GL_POLYGON_OFFSET_POINT: +// case GL_POLYGON_OFFSET_LINE: +// case GL_POLYGON_OFFSET_FILL: +// case GL_POLYGON_SMOOTH: +// case GL_POLYGON_STIPPLE: +// case GL_POST_COLOR_MATRIX_COLOR_TABLE: +// case GL_POST_CONVOLUTION_COLOR_TABLE: +// case GL_RESCALE_NORMAL: +// case GL_SCISSOR_TEST: +// case GL_SEPARABLE_2D: +// case GL_STENCIL_TEST: +// case GL_TEXTURE_GEN_Q: +// case GL_TEXTURE_GEN_R: +// case GL_TEXTURE_GEN_S: +// case GL_TEXTURE_GEN_T: +// case GL_TEXTURE_1D: +// case GL_TEXTURE_2D: +// case GL_TEXTURE_3D: + } +} + +static void nv04Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + nv04_emit_blend(ctx); + nv04_emit_fog_color(ctx); +} + +static void nv04Hint(GLcontext *ctx, GLenum target, GLenum mode) +{ + switch(target) + { + case GL_PERSPECTIVE_CORRECTION_HINT:nv04_emit_blend(ctx);break; + default:break; + } +} + +static void nv04LineStipple(GLcontext *ctx, GLint factor, GLushort pattern ) +{ + /* TODO not even in your dreams */ +} + +static void nv04LineWidth(GLcontext *ctx, GLfloat width) +{ + /* TODO */ +} + +static void nv04LogicOpcode(GLcontext *ctx, GLenum opcode) +{ + /* TODO */ +} + +static void nv04PointParameterfv(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + /* TODO */ +} + +static void nv04PointSize(GLcontext *ctx, GLfloat size) +{ + /* TODO */ +} + +static void nv04PolygonMode(GLcontext *ctx, GLenum face, GLenum mode) +{ + /* TODO */ +} + +/** Set the scale and units used to calculate depth values */ +static void nv04PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units) +{ + /* TODO */ +} + +/** Set the polygon stippling pattern */ +static void nv04PolygonStipple(GLcontext *ctx, const GLubyte *mask ) +{ + /* TODO */ +} + +/* Specifies the current buffer for reading */ +void (*ReadBuffer)( GLcontext *ctx, GLenum buffer ); +/** Set rasterization mode */ +void (*RenderMode)(GLcontext *ctx, GLenum mode ); + +/** Define the scissor box */ +static void nv04Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + /* TODO */ +} + +/** Select flat or smooth shading */ +static void nv04ShadeModel(GLcontext *ctx, GLenum mode) +{ + nv04_emit_blend(ctx); +} + +/** OpenGL 2.0 two-sided StencilFunc */ +static void nv04StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, + GLint ref, GLuint mask) +{ + /* TODO */ +} + +/** OpenGL 2.0 two-sided StencilMask */ +static void nv04StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask) +{ + /* TODO */ +} + +/** OpenGL 2.0 two-sided StencilOp */ +static void nv04StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, + GLenum zfail, GLenum zpass) +{ + /* TODO */ +} + +/** Control the generation of texture coordinates */ +void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname, + const GLfloat *params); +/** Set texture environment parameters */ +void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname, + const GLfloat *param); +/** Set texture parameters */ +void (*TexParameter)(GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj, + GLenum pname, const GLfloat *params); + +/* Update anything that depends on the window position/size */ +static void nv04WindowMoved(nouveauContextPtr nmesa) +{ +} + +/* Initialise any card-specific non-GL related state */ +static GLboolean nv04InitCard(nouveauContextPtr nmesa) +{ + return GL_TRUE; +} + +/* Update buffer offset/pitch/format */ +static GLboolean nv04BindBuffers(nouveauContextPtr nmesa, int num_color, + nouveau_renderbuffer **color, + nouveau_renderbuffer *depth) +{ + return GL_TRUE; +} + +void nv04InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + func->AlphaFunc = nv04AlphaFunc; + func->BlendColor = nv04BlendColor; + func->BlendEquationSeparate = nv04BlendEquationSeparate; + func->BlendFuncSeparate = nv04BlendFuncSeparate; + func->Clear = nv04Clear; + func->ClearColor = nv04ClearColor; + func->ClearDepth = nv04ClearDepth; + func->ClearStencil = nv04ClearStencil; + func->ClipPlane = nv04ClipPlane; + func->ColorMask = nv04ColorMask; + func->ColorMaterial = nv04ColorMaterial; + func->CullFace = nv04CullFace; + func->FrontFace = nv04FrontFace; + func->DepthFunc = nv04DepthFunc; + func->DepthMask = nv04DepthMask; + func->DepthRange = nv04DepthRange; + func->Enable = nv04Enable; + func->Fogfv = nv04Fogfv; + func->Hint = nv04Hint; +/* func->Lightfv = nv04Lightfv;*/ +/* func->LightModelfv = nv04LightModelfv; */ + func->LineStipple = nv04LineStipple; /* Not for NV04 */ + func->LineWidth = nv04LineWidth; + func->LogicOpcode = nv04LogicOpcode; + func->PointParameterfv = nv04PointParameterfv; + func->PointSize = nv04PointSize; + func->PolygonMode = nv04PolygonMode; + func->PolygonOffset = nv04PolygonOffset; + func->PolygonStipple = nv04PolygonStipple; /* Not for NV04 */ +/* func->ReadBuffer = nv04ReadBuffer;*/ +/* func->RenderMode = nv04RenderMode;*/ + func->Scissor = nv04Scissor; + func->ShadeModel = nv04ShadeModel; + func->StencilFuncSeparate = nv04StencilFuncSeparate; + func->StencilMaskSeparate = nv04StencilMaskSeparate; + func->StencilOpSeparate = nv04StencilOpSeparate; +/* func->TexGen = nv04TexGen;*/ +/* func->TexParameter = nv04TexParameter;*/ +/* func->TextureMatrix = nv04TextureMatrix;*/ + + nmesa->hw_func.InitCard = nv04InitCard; + nmesa->hw_func.BindBuffers = nv04BindBuffers; + nmesa->hw_func.WindowMoved = nv04WindowMoved; +} -- cgit v1.2.3 From d1f0a55af42c8a34c2d59ca003e7d7a8263665fb Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Mon, 22 Jan 2007 00:12:05 +0100 Subject: nouveau: fix some bugs in the nv10 swtcl. --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 12b277de45..f916912c7e 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -23,7 +23,7 @@ * DEALINGS IN THE SOFTWARE. */ -/* Software TCL for NV10, NV20, NV30, NV40, G70 */ +/* Software TCL for NV10, NV20, NV30, NV40, NV50 */ #include #include @@ -288,6 +288,20 @@ do { \ nmesa->vertex_attr_count++; \ } while (0) +static void nv10_render_clipped_line(GLcontext *ctx,GLuint ii,GLuint jj) +{ + +} + +static void nv10_render_clipped_poly(GLcontext *ctx,const GLuint *elts,GLuint n) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint *tmp = VB->Elts; + VB->Elts = (GLuint *)elts; + nv10_render_generic_primitive_elts( ctx, 0, n, PRIM_BEGIN|PRIM_END,GL_POLYGON ); + VB->Elts = tmp; +} static void nv10ChooseRenderState(GLcontext *ctx) { @@ -296,8 +310,8 @@ static void nv10ChooseRenderState(GLcontext *ctx) tnl->Driver.Render.PrimTabVerts = nv10_render_tab_verts; tnl->Driver.Render.PrimTabElts = nv10_render_tab_elts; - tnl->Driver.Render.ClippedLine = NULL; - tnl->Driver.Render.ClippedPolygon = NULL; + tnl->Driver.Render.ClippedLine = nv10_render_clipped_line; + tnl->Driver.Render.ClippedPolygon = nv10_render_clipped_poly; } @@ -323,6 +337,7 @@ static inline void nv10OutputVertexFormat(struct nouveau_context* nmesa) 0.0, 0.0, 0.0, 1.0 }; + nmesa->vertex_attr_count = 0; RENDERINPUTS_COPY(index, nmesa->render_inputs_bitset); /* -- cgit v1.2.3 From ea441355d304ceff0d7eac4e112ed713ea08a43f Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Sun, 21 Jan 2007 20:30:31 -0500 Subject: nouveau: Fixes for nv30. --- src/mesa/drivers/dri/nouveau/nv30_state.c | 128 ++++++++++++++++++++++-------- 1 file changed, 96 insertions(+), 32 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 4d79bb6127..e788a9235a 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -764,8 +764,66 @@ static void nv30WindowMoved(nouveauContextPtr nmesa) static GLboolean nv30InitCard(nouveauContextPtr nmesa) { - /* Need some love.. */ - return GL_FALSE; + int i; + nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); + + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT1, 3); + OUT_RING(NvDmaFB); + OUT_RING(NvDmaAGP); + OUT_RING(NvDmaFB); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT8, 1); + OUT_RING(NvDmaFB); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT4, 2); + OUT_RING(NvDmaFB); + OUT_RING(NvDmaFB); + BEGIN_RING_SIZE(NvSub3D, 0x1b0, 1); /* SET_OBJECT8B*/ + OUT_RING(NvDmaFB); + + for(i = 0x2c8; i <= 0x2fc; i += 4) + { + BEGIN_RING_SIZE(NvSub3D, i, 1); + OUT_RING(0x0); + } + + BEGIN_RING_SIZE(NvSub3D, 0x0220, 1); + OUT_RING(1); + + BEGIN_RING_SIZE(NvSub3D, 0x03b0, 1); + OUT_RING(0x00100000); + BEGIN_RING_SIZE(NvSub3D, 0x1454, 1); + OUT_RING(0); + BEGIN_RING_SIZE(NvSub3D, 0x1d80, 1); + OUT_RING(3); + BEGIN_RING_SIZE(NvSub3D, 0x1450, 1); + OUT_RING(0x00030004); + + /* NEW */ + BEGIN_RING_SIZE(NvSub3D, 0x1e98, 1); + OUT_RING(0); + BEGIN_RING_SIZE(NvSub3D, 0x17e0, 3); + OUT_RING(0); + OUT_RING(0); + OUT_RING(0x3f800000); + BEGIN_RING_SIZE(NvSub3D, 0x1f80, 16); + OUT_RING(0); OUT_RING(0); OUT_RING(0); OUT_RING(0); + OUT_RING(0); OUT_RING(0); OUT_RING(0); OUT_RING(0); + OUT_RING(0x0000ffff); + OUT_RING(0); OUT_RING(0); OUT_RING(0); OUT_RING(0); + OUT_RING(0); OUT_RING(0); OUT_RING(0); +/* + BEGIN_RING_SIZE(NvSub3D, 0x100, 2); + OUT_RING(0); + OUT_RING(0); +*/ + BEGIN_RING_SIZE(NvSub3D, 0x120, 3); + OUT_RING(0); + OUT_RING(1); + OUT_RING(2); + + BEGIN_RING_SIZE(NvSub3D, 0x1d88, 1); + OUT_RING(0x00001200); + + return GL_TRUE; } static GLboolean nv40InitCard(nouveauContextPtr nmesa) @@ -811,36 +869,41 @@ static GLboolean nv40InitCard(nouveauContextPtr nmesa) } static GLboolean nv30BindBuffers(nouveauContextPtr nmesa, int num_color, - nouveau_renderbuffer **color, - nouveau_renderbuffer *depth) -{ - GLuint x, y, w, h; - - w = color[0]->mesa.Width; - h = color[0]->mesa.Height; - x = nmesa->drawX; - y = nmesa->drawY; - - if (num_color != 1) - return GL_FALSE; - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_DIM0, 5); - OUT_RING (((w+x)<<16)|x); - OUT_RING (((h+y)<<16)|y); - if (color[0]->mesa._ActualFormat == GL_RGBA8) - OUT_RING (0x148); - else - OUT_RING (0x143); - OUT_RING (color[0]->pitch); - OUT_RING (color[0]->offset); - - if (depth) { - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_OFFSET, 1); - OUT_RING (depth->offset); - BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH, 1); - OUT_RING (depth->pitch); - } - - return GL_TRUE; + nouveau_renderbuffer **color, + nouveau_renderbuffer *depth) +{ + GLuint x, y, w, h; + + w = color[0]->mesa.Width; + h = color[0]->mesa.Height; + x = nmesa->drawX; + y = nmesa->drawY; + + if (num_color != 1) + return GL_FALSE; + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_DIM0, 5); + OUT_RING (((w+x)<<16)|x); + OUT_RING (((h+y)<<16)|y); + if (color[0]->mesa._ActualFormat == GL_RGBA8) + OUT_RING (0x148); + else + OUT_RING (0x143); + if (nmesa->screen->card->type >= NV_40) + OUT_RING (color[0]->pitch); + else + OUT_RING (color[0]->pitch | (depth ? (depth->pitch << 16): 0)); + OUT_RING (color[0]->offset); + + if (depth) { + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_OFFSET, 1); + OUT_RING (depth->offset); + if (nmesa->screen->card->type >= NV_40) { + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH, 1); + OUT_RING (depth->pitch >> 2); + } + } + + return GL_TRUE; } void nv30InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) @@ -862,6 +925,7 @@ void nv30InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) func->FrontFace = nv30FrontFace; func->DepthFunc = nv30DepthFunc; func->DepthMask = nv30DepthMask; + func->DepthRange = nv30DepthRange; func->Enable = nv30Enable; func->Fogfv = nv30Fogfv; func->Hint = nv30Hint; -- cgit v1.2.3 From c3ac2709967299481928dee175a124bf8a72fecd Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 21 Jan 2007 16:45:40 +1100 Subject: nouveau: start converting shaders into a tree format again.. No branching stuff implemented yet. Works enough for gears, probably other stuff broken. --- src/mesa/drivers/dri/nouveau/nouveau_shader.c | 6 +- src/mesa/drivers/dri/nouveau/nouveau_shader.h | 60 +++- src/mesa/drivers/dri/nouveau/nouveau_shader_0.c | 375 +++++++++++++++--------- src/mesa/drivers/dri/nouveau/nouveau_shader_2.c | 45 ++- 4 files changed, 315 insertions(+), 171 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.c b/src/mesa/drivers/dri/nouveau/nouveau_shader.c index e4db115362..f911347d62 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.c @@ -563,12 +563,12 @@ nvsDumpInstruction(nvsInstruction * inst, int slot, int lvl) } void -nvsDumpFragmentList(nvsFragmentList *f, int lvl) +nvsDumpFragmentList(nvsFragmentHeader *f, int lvl) { while (f) { - switch (f->fragment->type) { + switch (f->type) { case NVS_INSTRUCTION: - nvsDumpInstruction((nvsInstruction*)f->fragment, 0, lvl); + nvsDumpInstruction((nvsInstruction*)f, 0, lvl); break; default: fprintf(stderr, "%s: Only NVS_INSTRUCTION fragments can be in" diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h index 1a971e56bf..a3ab027142 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -12,19 +12,18 @@ typedef struct _nvsFunc nvsFunc; #define NVS_MAX_ADDRESS 2 #define NVS_MAX_INSNS 4096 -typedef struct { +typedef struct _nvs_fragment_header { + struct _nvs_fragment_header *parent; + struct _nvs_fragment_header *prev; + struct _nvs_fragment_header *next; enum { NVS_INSTRUCTION, + NVS_BRANCH, + NVS_LOOP, + NVS_SUBROUTINE } type; - int position; } nvsFragmentHeader; -typedef struct _nvs_fragment_list { - struct _nvs_fragment_list *prev; - struct _nvs_fragment_list *next; - nvsFragmentHeader *fragment; -} nvsFragmentList; - typedef struct _nouveauShader { union { struct gl_vertex_program vp; @@ -59,8 +58,7 @@ typedef struct _nouveauShader { /* Pass-private data */ void *pass_rec; - nvsFragmentList *list_head; - nvsFragmentList *list_tail; + nvsFragmentHeader *program_tree; } nouveauShader, *nvsPtr; typedef enum { @@ -186,7 +184,8 @@ typedef enum { NVS_TEX_TARGET_UNKNOWN = 0 } nvsTexTarget; -typedef struct { +/* Arith/TEX instructions */ +typedef struct nvs_instruction { nvsFragmentHeader header; nvsOpcode op; @@ -207,6 +206,43 @@ typedef struct { int cond_update; } nvsInstruction; +/* BRA, CAL, IF */ +typedef struct nvs_branch { + nvsFragmentHeader header; + + nvsOpcode op; + + nvsCond cond; + nvsSwzComp cond_swizzle[4]; + int cond_test; + + nvsFragmentHeader *target_head; + nvsFragmentHeader *target_tail; + nvsFragmentHeader *else_head; + nvsFragmentHeader *else_tail; +} nvsBranch; + +/* LOOP+ENDLOOP */ +typedef struct { + nvsFragmentHeader header; + + int count; + int initial; + int increment; + + nvsFragmentHeader *insn_head; + nvsFragmentHeader *insn_tail; +} nvsLoop; + +/* label+following instructions */ +typedef struct nvs_subroutine { + nvsFragmentHeader header; + + char * label; + nvsFragmentHeader *insn_head; + nvsFragmentHeader *insn_tail; +} nvsSubroutine; + #define SMASK_X (1<<0) #define SMASK_Y (1<<1) #define SMASK_Z (1<<2) @@ -353,7 +389,7 @@ nvsSwizzle(nvsRegister reg, nvsSwzComp x, nvsSwzComp y, extern GLboolean nvsUpdateShader(GLcontext *ctx, nouveauShader *nvs); extern void nvsDisasmHWShader(nvsPtr); -extern void nvsDumpFragmentList(nvsFragmentList *f, int lvl); +extern void nvsDumpFragmentList(nvsFragmentHeader *f, int lvl); extern nouveauShader *nvsBuildTextShader(GLcontext *ctx, GLenum target, const char *text); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c index 34475cad03..503eae36b7 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -40,6 +40,7 @@ #include "nouveau_context.h" #include "nouveau_shader.h" +#include "nouveau_msg.h" static nvsFixedReg _tx_mesa_vp_dst_reg[VERT_RESULT_MAX] = { NVS_FR_POSITION, NVS_FR_COL0, NVS_FR_COL1, NVS_FR_FOGCOORD, @@ -134,21 +135,63 @@ struct pass0_rec { #define W NVS_SWZ_W static void -pass0_append_fragment(nouveauShader *nvs, nvsFragmentHeader *fragment) +pass0_append_fragment(nvsFragmentHeader *parent, + nvsFragmentHeader *fragment, + int pos) { - nvsFragmentList *list = calloc(1, sizeof(nvsFragmentList)); - if (!list) - return; - - list->fragment = fragment; - list->prev = nvs->list_tail; - if ( nvs->list_tail) - nvs->list_tail->next = list; - if (!nvs->list_head) - nvs->list_head = list; - nvs->list_tail = list; - - nvs->inst_count++; + nvsFragmentHeader **head, **tail; + assert(parent && fragment); + + switch (parent->type) { + case NVS_BRANCH: + if (pos == 0) { + head = &((nvsBranch *)parent)->target_head; + tail = &((nvsBranch *)parent)->target_tail; + } else { + head = &((nvsBranch *)parent)->else_head; + tail = &((nvsBranch *)parent)->else_tail; + } + break; + case NVS_LOOP: + head = &((nvsLoop *)parent)->insn_head; + tail = &((nvsLoop *)parent)->insn_tail; + break; + case NVS_SUBROUTINE: + head = &((nvsSubroutine *)parent)->insn_head; + tail = &((nvsSubroutine *)parent)->insn_tail; + break; + default: + assert(0); + break; + } + + fragment->parent = parent; + fragment->prev = *tail; + fragment->next = NULL; + if (!(*head)) + *head = fragment; + else + (*tail)->next = fragment; + *tail = fragment; + +} + +static nvsSubroutine * +pass0_create_subroutine(nouveauShader *nvs, const char *label) +{ + nvsSubroutine *sub; + + sub = CALLOC_STRUCT(nvs_subroutine); + if (sub) { + sub->header.type = NVS_SUBROUTINE; + sub->label = strdup(label); + if (!nvs->program_tree) + nvs->program_tree = &sub->header; + else + pass0_append_fragment(nvs->program_tree, &sub->header, 0); + } + + return sub; } static void @@ -312,41 +355,40 @@ pass0_make_src_reg(nvsPtr nvs, nvsRegister *reg, struct prog_src_register *src) } static nvsInstruction * -pass0_emit(nouveauShader *nvs, nvsOpcode op, nvsRegister dst, - unsigned int mask, int saturate, +pass0_emit(nouveauShader *nvs, nvsFragmentHeader *parent, int fpos, + nvsOpcode op, nvsRegister dst, + unsigned int mask, int saturate, nvsRegister src0, nvsRegister src1, nvsRegister src2) { - struct pass0_rec *rec = nvs->pass_rec; - nvsInstruction *sif = NULL; - - /* Seems mesa doesn't explicitly 0 this.. */ - if (nvs->mesa.vp.Base.Target == GL_VERTEX_PROGRAM_ARB) - saturate = 0; - - sif = calloc(1, sizeof(nvsInstruction)); - if (sif) { - sif->header.type = NVS_INSTRUCTION; - sif->header.position = rec->nvs_ipos++; - sif->op = op; - sif->saturate = saturate; - sif->dest = dst; - sif->mask = mask; - sif->src[0] = src0; - sif->src[1] = src1; - sif->src[2] = src2; - sif->cond = COND_TR; - sif->cond_reg = 0; - sif->cond_test = 0; - sif->cond_update = 0; - pass0_make_swizzle(sif->cond_swizzle, SWIZZLE_NOOP); - pass0_append_fragment(nvs, (nvsFragmentHeader *)sif); - } - - return sif; + nvsInstruction *sif; + + sif = CALLOC_STRUCT(nvs_instruction); + if (!sif) + return NULL; + + /* Seems mesa doesn't explicitly 0 this.. */ + if (nvs->mesa.vp.Base.Target == GL_VERTEX_PROGRAM_ARB) + saturate = 0; + + sif->op = op; + sif->saturate = saturate; + sif->dest = dst; + sif->mask = mask; + sif->src[0] = src0; + sif->src[1] = src1; + sif->src[2] = src2; + sif->cond = COND_TR; + sif->cond_reg = 0; + sif->cond_test = 0; + sif->cond_update= 0; + pass0_make_swizzle(sif->cond_swizzle, SWIZZLE_NOOP); + pass0_append_fragment(parent, &sif->header, fpos); + + return sif; } static void -pass0_fixup_swizzle(nvsPtr nvs, +pass0_fixup_swizzle(nvsPtr nvs, nvsFragmentHeader *parent, int fpos, struct prog_src_register *src, unsigned int sm1, unsigned int sm2) @@ -376,7 +418,7 @@ pass0_fixup_swizzle(nvsPtr nvs, */ pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); pass0_make_src_reg(nvs, &sr, src); - pass0_emit(nvs, NVS_OP_MOV, dr, SMASK_ALL, 0, sr, nvr_unused, nvr_unused); + pass0_emit(nvs, parent, fpos, NVS_OP_MOV, dr, SMASK_ALL, 0, sr, nvr_unused, nvr_unused); pass0_make_reg(nvs, &sr, NVS_FILE_TEMP, dr.index); } else { if (fixup_1) @@ -391,10 +433,10 @@ pass0_fixup_swizzle(nvsPtr nvs, /* Any combination with SWIZZLE_ONE */ pass0_make_reg(nvs, &sm2const, NVS_FILE_CONST, rec->swzconst_id); pass0_make_swizzle(sm2const.swizzle, sm2); - pass0_emit(nvs, NVS_OP_MAD, dr, SMASK_ALL, 0, sr, sm1const, sm2const); + pass0_emit(nvs, parent, fpos, NVS_OP_MAD, dr, SMASK_ALL, 0, sr, sm1const, sm2const); } else { /* SWIZZLE_ZERO || arbitrary negate */ - pass0_emit(nvs, NVS_OP_MUL, dr, SMASK_ALL, 0, sr, sm1const, nvr_unused); + pass0_emit(nvs, parent, fpos, NVS_OP_MUL, dr, SMASK_ALL, 0, sr, sm1const, nvr_unused); } src->File = PROGRAM_TEMPORARY; @@ -404,7 +446,8 @@ pass0_fixup_swizzle(nvsPtr nvs, #define SET_SWZ(fs, cp, c) fs = (fs & ~(0x7<<(cp*3))) | (c<<(cp*3)) static void -pass0_check_sources(nvsPtr nvs, struct prog_instruction *inst) +pass0_check_sources(nvsPtr nvs, nvsFragmentHeader *parent, int fpos, + struct prog_instruction *inst) { unsigned int insrc = -1, constsrc = -1; int i; @@ -444,7 +487,7 @@ pass0_check_sources(nvsPtr nvs, struct prog_instruction *inst) */ if ((sm_1 != MAKE_SWIZZLE4(0,0,0,0) && sm_1 != MAKE_SWIZZLE4(2,2,2,2)) || sm_2 != MAKE_SWIZZLE4(1,1,1,1)) { - pass0_fixup_swizzle(nvs, src, sm_1, sm_2); + pass0_fixup_swizzle(nvs, parent, fpos, src, sm_1, sm_2); /* The source is definitely in a temp now, so don't bother checking * for multiple ATTRIB/CONST regs. */ @@ -473,7 +516,7 @@ pass0_check_sources(nvsPtr nvs, struct prog_instruction *inst) if (do_mov) { pass0_make_src_reg(nvs, &sr, src); pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); - pass0_emit(nvs, NVS_OP_MOV, dr, SMASK_ALL, 0, + pass0_emit(nvs, parent, fpos, NVS_OP_MOV, dr, SMASK_ALL, 0, sr, nvr_unused, nvr_unused); src->File = PROGRAM_TEMPORARY; @@ -484,7 +527,9 @@ pass0_check_sources(nvsPtr nvs, struct prog_instruction *inst) } static GLboolean -pass0_emulate_instruction(nouveauShader *nvs, struct prog_instruction *inst) +pass0_emulate_instruction(nouveauShader *nvs, + nvsFragmentHeader *parent, int fpos, + struct prog_instruction *inst) { nvsFunc *shader = nvs->func; nvsRegister src[3], dest, temp; @@ -504,10 +549,10 @@ pass0_emulate_instruction(nouveauShader *nvs, struct prog_instruction *inst) switch (inst->Opcode) { case OPCODE_ABS: if (shader->caps & SCAP_SRC_ABS) - pass0_emit(nvs, NVS_OP_MOV, dest, mask, sat, + pass0_emit(nvs, parent, fpos, NVS_OP_MOV, dest, mask, sat, nvsAbs(src[0]), nvr_unused, nvr_unused); else - pass0_emit(nvs, NVS_OP_MAX, dest, mask, sat, + pass0_emit(nvs, parent, fpos, NVS_OP_MAX, dest, mask, sat, src[0], nvsNegate(src[0]), nvr_unused); break; case OPCODE_KIL: @@ -516,12 +561,12 @@ pass0_emulate_instruction(nouveauShader *nvs, struct prog_instruction *inst) */ /* MOVC0 temp, src */ pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - nvsinst = pass0_emit(nvs, NVS_OP_MOV, temp, SMASK_ALL, 0, + nvsinst = pass0_emit(nvs, parent, fpos, NVS_OP_MOV, temp, SMASK_ALL, 0, src[0], nvr_unused, nvr_unused); nvsinst->cond_update = 1; nvsinst->cond_reg = 0; /* KIL_NV (LT0.xyzw) temp */ - nvsinst = pass0_emit(nvs, NVS_OP_KIL, nvr_unused, 0, 0, + nvsinst = pass0_emit(nvs, parent, fpos, NVS_OP_KIL, nvr_unused, 0, 0, nvr_unused, nvr_unused, nvr_unused); nvsinst->cond = COND_LT; nvsinst->cond_reg = 0; @@ -532,9 +577,9 @@ pass0_emulate_instruction(nouveauShader *nvs, struct prog_instruction *inst) break; case OPCODE_LRP: pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - pass0_emit(nvs, NVS_OP_MAD, temp, mask, 0, + pass0_emit(nvs, parent, fpos, NVS_OP_MAD, temp, mask, 0, nvsNegate(src[0]), src[2], src[2]); - pass0_emit(nvs, NVS_OP_MAD, dest, mask, sat, + pass0_emit(nvs, parent, fpos, NVS_OP_MAD, dest, mask, sat, src[0], src[1], temp); break; case OPCODE_POW: @@ -542,17 +587,17 @@ pass0_emulate_instruction(nouveauShader *nvs, struct prog_instruction *inst) shader->SupportsOpcode(shader, NVS_OP_EX2)) { pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); /* LG2 temp.x, src0.c */ - pass0_emit(nvs, NVS_OP_LG2, temp, SMASK_X, 0, + pass0_emit(nvs, parent, fpos, NVS_OP_LG2, temp, SMASK_X, 0, nvsSwizzle(src[0], X, X, X, X), nvr_unused, nvr_unused); /* MUL temp.x, temp.x, src1.c */ - pass0_emit(nvs, NVS_OP_MUL, temp, SMASK_X, 0, + pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_X, 0, nvsSwizzle(temp, X, X, X, X), nvsSwizzle(src[1], X, X, X, X), nvr_unused); /* EX2 dest, temp.x */ - pass0_emit(nvs, NVS_OP_EX2, dest, mask, sat, + pass0_emit(nvs, parent, fpos, NVS_OP_EX2, dest, mask, sat, nvsSwizzle(temp, X, X, X, X), nvr_unused, nvr_unused); @@ -571,42 +616,42 @@ pass0_emulate_instruction(nouveauShader *nvs, struct prog_instruction *inst) COPY_4V(nvs->params[rec->const_half.index].val, const_half); } pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - pass0_emit(nvs, NVS_OP_LG2, temp, SMASK_X, 0, + pass0_emit(nvs, parent, fpos, NVS_OP_LG2, temp, SMASK_X, 0, nvsAbs(nvsSwizzle(src[0], X, X, X, X)), nvr_unused, nvr_unused); - pass0_emit(nvs, NVS_OP_MUL, temp, SMASK_X, 0, + pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_X, 0, nvsSwizzle(temp, X, X, X, X), nvsNegate(rec->const_half), nvr_unused); - pass0_emit(nvs, NVS_OP_EX2, dest, mask, sat, + pass0_emit(nvs, parent, fpos, NVS_OP_EX2, dest, mask, sat, nvsSwizzle(temp, X, X, X, X), nvr_unused, nvr_unused); break; case OPCODE_SCS: if (mask & SMASK_X) - pass0_emit(nvs, NVS_OP_COS, dest, SMASK_X, sat, + pass0_emit(nvs, parent, fpos, NVS_OP_COS, dest, SMASK_X, sat, nvsSwizzle(src[0], X, X, X, X), nvr_unused, nvr_unused); if (mask & SMASK_Y) - pass0_emit(nvs, NVS_OP_SIN, dest, SMASK_Y, sat, + pass0_emit(nvs, parent, fpos, NVS_OP_SIN, dest, SMASK_Y, sat, nvsSwizzle(src[0], X, X, X, X), nvr_unused, nvr_unused); break; case OPCODE_SUB: - pass0_emit(nvs, NVS_OP_ADD, dest, mask, sat, + pass0_emit(nvs, parent, fpos, NVS_OP_ADD, dest, mask, sat, src[0], nvsNegate(src[1]), nvr_unused); break; case OPCODE_XPD: pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - pass0_emit(nvs, NVS_OP_MUL, temp, SMASK_ALL, 0, + pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_ALL, 0, nvsSwizzle(src[0], Z, X, Y, Y), nvsSwizzle(src[1], Y, Z, X, X), nvr_unused); - pass0_emit(nvs, NVS_OP_MAD, dest, (mask & ~SMASK_W), sat, + pass0_emit(nvs, parent, fpos, NVS_OP_MAD, dest, (mask & ~SMASK_W), sat, nvsSwizzle(src[0], Y, Z, X, X), nvsSwizzle(src[1], Z, X, Y, Y), nvsNegate(temp)); @@ -621,90 +666,132 @@ pass0_emulate_instruction(nouveauShader *nvs, struct prog_instruction *inst) } static GLboolean -pass0_translate_instructions(nouveauShader *nvs) +pass0_translate_arith(nouveauShader *nvs, struct gl_program *prog, + int ipos, int fpos, + nvsFragmentHeader *parent) { - struct gl_program *prog = (struct gl_program *)&nvs->mesa.vp; - nvsFunc *shader = nvs->func; - int ipos; - - for (ipos=0; iposNumInstructions; ipos++) { - struct prog_instruction *inst = &prog->Instructions[ipos]; - - if (inst->Opcode == OPCODE_END) - break; - - /* Deal with multiple ATTRIB/PARAM in a single instruction */ - pass0_check_sources(nvs, inst); - - /* Now it's safe to do the prog_instruction->nvsInstruction conversion */ - if (shader->SupportsOpcode(shader, pass0_make_opcode(inst->Opcode))) { - nvsInstruction *nvsinst; - nvsRegister src[3], dest; - int i; - - for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++) - pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]); - pass0_make_dst_reg(nvs, &dest, &inst->DstReg); - - nvsinst = pass0_emit(nvs, - pass0_make_opcode(inst->Opcode), - dest, - pass0_make_mask(inst->DstReg.WriteMask), - (inst->SaturateMode != SATURATE_OFF), - src[0], src[1], src[2]); - nvsinst->tex_unit = inst->TexSrcUnit; - nvsinst->tex_target = pass0_make_tex_target(inst->TexSrcTarget); - /* TODO when NV_fp/vp is implemented */ - nvsinst->cond = COND_TR; - } else { - if (!pass0_emulate_instruction(nvs, inst)) - return GL_FALSE; - } - } + struct prog_instruction *inst = &prog->Instructions[ipos]; + nvsFunc *shader = nvs->func; + nvsInstruction *nvsinst; + GLboolean ret; + + /* Deal with multiple ATTRIB/PARAM in a single instruction */ + pass0_check_sources(nvs, parent, fpos, inst); + + /* Now it's safe to do the prog_instruction->nvsInstruction + * conversion + */ + if (shader->SupportsOpcode(shader, + pass0_make_opcode(inst->Opcode))) { + nvsRegister src[3], dest; + int i; + + for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++) + pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]); + pass0_make_dst_reg(nvs, &dest, &inst->DstReg); + + nvsinst = pass0_emit(nvs, parent, fpos, + pass0_make_opcode(inst->Opcode), + dest, + pass0_make_mask(inst->DstReg.WriteMask), + (inst->SaturateMode != SATURATE_OFF), + src[0], src[1], src[2]); + nvsinst->tex_unit = inst->TexSrcUnit; + nvsinst->tex_target = pass0_make_tex_target(inst->TexSrcTarget); + /* TODO when NV_fp/vp is implemented */ + nvsinst->cond = COND_TR; + + ret = GL_TRUE; + } else + ret = pass0_emulate_instruction(nvs, parent, fpos, inst); + + return ret; +} - return GL_TRUE; +static GLboolean +pass0_translate_instructions(nouveauShader *nvs, int ipos, int fpos, + nvsFragmentHeader *parent) +{ + struct gl_program *prog = (struct gl_program *)&nvs->mesa.vp; + + while (1) { + struct prog_instruction *inst = &prog->Instructions[ipos]; + + switch (inst->Opcode) { + case OPCODE_END: + return GL_TRUE; + case OPCODE_BRA: + case OPCODE_CAL: + //case OPCDOE_RET: + //case OPCODE_LOOP: + //case OPCODE_ENDLOOP: + //case OPCODE_IF: + //case OPCODE_ELSE: + //case OPCODE_ENDIF: + WARN_ONCE("branch ops unimplemented\n"); + return GL_FALSE; + break; + default: + if (!pass0_translate_arith(nvs, prog, + ipos, fpos, parent)) + return GL_FALSE; + break; + } + + ipos++; + } + + return GL_TRUE; } GLboolean nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - struct gl_program *prog = (struct gl_program*)nvs; - struct gl_vertex_program *vp = (struct gl_vertex_program *)prog; - struct gl_fragment_program *fp = (struct gl_fragment_program *)prog; - struct pass0_rec *rec; - int ret; - - switch (prog->Target) { - case GL_VERTEX_PROGRAM_ARB: - nvs->func = &nmesa->VPfunc; - if (vp->IsPositionInvariant) - _mesa_insert_mvp_code(ctx, vp); + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + struct gl_program *prog = (struct gl_program*)nvs; + struct gl_vertex_program *vp = (struct gl_vertex_program *)prog; + struct gl_fragment_program *fp = (struct gl_fragment_program *)prog; + struct pass0_rec *rec; + int ret = GL_FALSE; + + switch (prog->Target) { + case GL_VERTEX_PROGRAM_ARB: + nvs->func = &nmesa->VPfunc; + + if (vp->IsPositionInvariant) + _mesa_insert_mvp_code(ctx, vp); #if 0 - if (IS_FIXEDFUNCTION_PROG && CLIP_PLANES_USED) - pass0_insert_ff_clip_planes(); + if (IS_FIXEDFUNCTION_PROG && CLIP_PLANES_USED) + pass0_insert_ff_clip_planes(); #endif - break; - case GL_FRAGMENT_PROGRAM_ARB: - nvs->func = &nmesa->FPfunc; - if (fp->FogOption != GL_NONE) - _mesa_append_fog_code(ctx, fp); - break; - default: - fprintf(stderr, "Unknown program type %d", prog->Target); - return GL_FALSE; - } - - rec = calloc(1, sizeof(struct pass0_rec)); - rec->next_temp = prog->NumTemporaries; - nvs->pass_rec = rec; - - ret = pass0_translate_instructions(nvs); - if (!ret) { - /* DESTROY list */ - } - - free(nvs->pass_rec); - return ret; + break; + case GL_FRAGMENT_PROGRAM_ARB: + nvs->func = &nmesa->FPfunc; + + if (fp->FogOption != GL_NONE) + _mesa_append_fog_code(ctx, fp); + break; + default: + fprintf(stderr, "Unknown program type %d", prog->Target); + return GL_FALSE; + } + + rec = CALLOC_STRUCT(pass0_rec); + if (rec) { + rec->next_temp = prog->NumTemporaries; + nvs->pass_rec = rec; + + nvs->program_tree = (nvsFragmentHeader*) + pass0_create_subroutine(nvs, "program body"); + if (nvs->program_tree) { + ret = pass0_translate_instructions(nvs, + 0, 0, + nvs->program_tree); + /*XXX: if (!ret) DESTROY TREE!!! */ + } + FREE(rec); + } + + return ret; } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c index 0476b05f58..b9b87ccf91 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c @@ -38,6 +38,7 @@ #include "nouveau_context.h" #include "nouveau_shader.h" +#include "nouveau_msg.h" struct pass2_rec { /* Map nvsRegister temp ID onto hw temp ID */ @@ -166,11 +167,37 @@ pass2_assemble_instruction(nvsPtr nvs, nvsInstruction *inst, int last) return 1; } +static GLboolean +pass2_translate(nvsPtr nvs, nvsFragmentHeader *f) +{ + nvsFunc *shader = nvs->func; + GLboolean last; + + while (f) { + last = (f == ((nvsSubroutine*)nvs->program_tree)->insn_tail); + + switch (f->type) { + case NVS_INSTRUCTION: + if (!pass2_assemble_instruction(nvs, + (nvsInstruction *)f, + last)) + return GL_FALSE; + break; + default: + WARN_ONCE("Unimplemented fragment type\n"); + return GL_FALSE; + } + + f = f->next; + } + + return GL_TRUE; +} + /* Translate program into hardware format */ GLboolean nouveau_shader_pass2(nvsPtr nvs) { - nvsFragmentList *list = nvs->list_head; struct pass2_rec *rec; int i; @@ -182,21 +209,15 @@ nouveau_shader_pass2(nvsPtr nvs) /* Start off with allocating 4 uint32_t's for each inst, will be grown * if necessary.. */ - nvs->program_alloc_size = nvs->inst_count * 4; + nvs->program_alloc_size = nvs->mesa.vp.Base.NumInstructions * 4; nvs->program = calloc(nvs->program_alloc_size, sizeof(uint32_t)); nvs->program_size = 0; nvs->program_current = 0; - while (list) { - assert(list->fragment->type == NVS_INSTRUCTION); - - if (!pass2_assemble_instruction(nvs, (nvsInstruction *)list->fragment, list->next ? 0 : 1)) { - free(nvs->program); - nvs->program = NULL; - return GL_FALSE; - } - - list = list->next; + if (!pass2_translate(nvs, ((nvsSubroutine*)nvs->program_tree)->insn_head)) { + free(nvs->program); + nvs->program = NULL; + return GL_FALSE; } /* Shrink allocated memory to only what we need */ -- cgit v1.2.3 From 50227f6fd23f3a4737dada1a98d26f6d0141af47 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 21 Jan 2007 17:16:39 +1100 Subject: nouveau: reindent shader pass0/pass2 if this gets rejected by the commit list, just ignore it.. nothing interesting to see here :) --- src/mesa/drivers/dri/nouveau/nouveau_shader_0.c | 779 ++++++++++++------------ src/mesa/drivers/dri/nouveau/nouveau_shader_2.c | 311 +++++----- 2 files changed, 566 insertions(+), 524 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c index 503eae36b7..d6ea42573a 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -188,7 +188,8 @@ pass0_create_subroutine(nouveauShader *nvs, const char *label) if (!nvs->program_tree) nvs->program_tree = &sub->header; else - pass0_append_fragment(nvs->program_tree, &sub->header, 0); + pass0_append_fragment(nvs->program_tree, + &sub->header, 0); } return sub; @@ -196,162 +197,168 @@ pass0_create_subroutine(nouveauShader *nvs, const char *label) static void pass0_make_reg(nouveauShader *nvs, nvsRegister *reg, - nvsRegFile file, unsigned int index) + nvsRegFile file, unsigned int index) { - struct pass0_rec *rec = nvs->pass_rec; - - /* defaults */ - *reg = nvr_unused; - /* -1 == quick-and-dirty temp alloc */ - if (file == NVS_FILE_TEMP && index == -1) { - index = rec->next_temp++; - assert(index < NVS_MAX_TEMPS); - } - reg->file = file; - reg->index = index; + struct pass0_rec *rec = nvs->pass_rec; + + /* defaults */ + *reg = nvr_unused; + /* -1 == quick-and-dirty temp alloc */ + if (file == NVS_FILE_TEMP && index == -1) { + index = rec->next_temp++; + assert(index < NVS_MAX_TEMPS); + } + reg->file = file; + reg->index = index; } static void pass0_make_swizzle(nvsSwzComp *swz, unsigned int mesa) { - int i; + int i; - for (i=0;i<4;i++) - swz[i] = _tx_mesa_swizzle[GET_SWZ(mesa, i)]; + for (i=0;i<4;i++) + swz[i] = _tx_mesa_swizzle[GET_SWZ(mesa, i)]; } static nvsOpcode pass0_make_opcode(enum prog_opcode op) { - if (op > MAX_OPCODE) - return NVS_OP_UNKNOWN; - return _tx_mesa_opcode[op]; + if (op > MAX_OPCODE) + return NVS_OP_UNKNOWN; + return _tx_mesa_opcode[op]; } static nvsCond pass0_make_condmask(GLuint mesa) { - if (mesa > COND_FL) - return NVS_COND_UNKNOWN; - return _tx_mesa_condmask[mesa]; + if (mesa > COND_FL) + return NVS_COND_UNKNOWN; + return _tx_mesa_condmask[mesa]; } static unsigned int pass0_make_mask(GLuint mesa_mask) { - unsigned int mask = 0; + unsigned int mask = 0; - if (mesa_mask & WRITEMASK_X) mask |= SMASK_X; - if (mesa_mask & WRITEMASK_Y) mask |= SMASK_Y; - if (mesa_mask & WRITEMASK_Z) mask |= SMASK_Z; - if (mesa_mask & WRITEMASK_W) mask |= SMASK_W; + if (mesa_mask & WRITEMASK_X) mask |= SMASK_X; + if (mesa_mask & WRITEMASK_Y) mask |= SMASK_Y; + if (mesa_mask & WRITEMASK_Z) mask |= SMASK_Z; + if (mesa_mask & WRITEMASK_W) mask |= SMASK_W; - return mask; + return mask; } static nvsTexTarget pass0_make_tex_target(GLuint mesa) { - switch (mesa) { - case TEXTURE_1D_INDEX: return NVS_TEX_TARGET_1D; - case TEXTURE_2D_INDEX: return NVS_TEX_TARGET_2D; - case TEXTURE_3D_INDEX: return NVS_TEX_TARGET_3D; - case TEXTURE_CUBE_INDEX: return NVS_TEX_TARGET_CUBE; - case TEXTURE_RECT_INDEX: return NVS_TEX_TARGET_RECT; - default: - return NVS_TEX_TARGET_UNKNOWN; - } + switch (mesa) { + case TEXTURE_1D_INDEX: return NVS_TEX_TARGET_1D; + case TEXTURE_2D_INDEX: return NVS_TEX_TARGET_2D; + case TEXTURE_3D_INDEX: return NVS_TEX_TARGET_3D; + case TEXTURE_CUBE_INDEX: return NVS_TEX_TARGET_CUBE; + case TEXTURE_RECT_INDEX: return NVS_TEX_TARGET_RECT; + default: + return NVS_TEX_TARGET_UNKNOWN; + } } static void pass0_make_dst_reg(nvsPtr nvs, nvsRegister *reg, struct prog_dst_register *dst) { - struct gl_program *mesa = (struct gl_program*)&nvs->mesa.vp; - nvsFixedReg sfr; - - switch (dst->File) { - case PROGRAM_OUTPUT: - if (mesa->Target == GL_VERTEX_PROGRAM_ARB) { - sfr = (dst->Index < VERT_RESULT_MAX) ? - _tx_mesa_vp_dst_reg[dst->Index] : NVS_FR_UNKNOWN; - } else { - sfr = (dst->Index < FRAG_RESULT_MAX) ? - _tx_mesa_fp_dst_reg[dst->Index] : NVS_FR_UNKNOWN; - } - pass0_make_reg(nvs, reg, NVS_FILE_RESULT, sfr); - break; - case PROGRAM_TEMPORARY: - pass0_make_reg(nvs, reg, NVS_FILE_TEMP, dst->Index); - break; - case PROGRAM_ADDRESS: - pass0_make_reg(nvs, reg, NVS_FILE_ADDRESS, dst->Index); - break; - default: - fprintf(stderr, "Unknown dest file %d\n", dst->File); - assert(0); - } + struct gl_program *mesa = (struct gl_program*)&nvs->mesa.vp; + nvsFixedReg sfr; + + switch (dst->File) { + case PROGRAM_OUTPUT: + if (mesa->Target == GL_VERTEX_PROGRAM_ARB) { + sfr = (dst->Index < VERT_RESULT_MAX) ? + _tx_mesa_vp_dst_reg[dst->Index] : + NVS_FR_UNKNOWN; + } else { + sfr = (dst->Index < FRAG_RESULT_MAX) ? + _tx_mesa_fp_dst_reg[dst->Index] : + NVS_FR_UNKNOWN; + } + pass0_make_reg(nvs, reg, NVS_FILE_RESULT, sfr); + break; + case PROGRAM_TEMPORARY: + pass0_make_reg(nvs, reg, NVS_FILE_TEMP, dst->Index); + break; + case PROGRAM_ADDRESS: + pass0_make_reg(nvs, reg, NVS_FILE_ADDRESS, dst->Index); + break; + default: + fprintf(stderr, "Unknown dest file %d\n", dst->File); + assert(0); + } } static void pass0_make_src_reg(nvsPtr nvs, nvsRegister *reg, struct prog_src_register *src) { - struct gl_program *mesa = (struct gl_program *)&nvs->mesa.vp.Base; - struct gl_program_parameter_list *p = mesa->Parameters; - - *reg = nvr_unused; - - switch (src->File) { - case PROGRAM_INPUT: - reg->file = NVS_FILE_ATTRIB; - if (mesa->Target == GL_VERTEX_PROGRAM_ARB) { - reg->index = (src->Index < VERT_ATTRIB_MAX) ? - _tx_mesa_vp_src_reg[src->Index] : NVS_FR_UNKNOWN; - } else { - reg->index = (src->Index < FRAG_ATTRIB_MAX) ? - _tx_mesa_fp_src_reg[src->Index] : NVS_FR_UNKNOWN; - } - break; - /* All const types seem to get shoved into here, not really sure why */ - case PROGRAM_STATE_VAR: - switch (p->Parameters[src->Index].Type) { - case PROGRAM_NAMED_PARAM: - case PROGRAM_CONSTANT: - nvs->params[src->Index].source_val = NULL; - COPY_4V(nvs->params[src->Index].val, p->ParameterValues[src->Index]); - break; - case PROGRAM_STATE_VAR: - nvs->params[src->Index].source_val = p->ParameterValues[src->Index]; - break; - default: - fprintf(stderr, "Unknown parameter type %d\n", - p->Parameters[src->Index].Type); - assert(0); - break; - } - - if (src->RelAddr) { - reg->indexed = 1; - reg->addr_reg = 0; - reg->addr_comp = NVS_SWZ_X; - } else - reg->indexed = 0; - reg->file = NVS_FILE_CONST; - reg->index = src->Index; - break; - case PROGRAM_TEMPORARY: - reg->file = NVS_FILE_TEMP; - reg->index = src->Index; - break; - default: - fprintf(stderr, "Unknown source type %d\n", src->File); - assert(0); - } - - /* per-component negate handled elsewhere */ - reg->negate = src->NegateBase != 0; - reg->abs = src->Abs; - pass0_make_swizzle(reg->swizzle, src->Swizzle); + struct gl_program *mesa = (struct gl_program *)&nvs->mesa.vp.Base; + struct gl_program_parameter_list *p = mesa->Parameters; + + *reg = nvr_unused; + + switch (src->File) { + case PROGRAM_INPUT: + reg->file = NVS_FILE_ATTRIB; + if (mesa->Target == GL_VERTEX_PROGRAM_ARB) { + reg->index = (src->Index < VERT_ATTRIB_MAX) ? + _tx_mesa_vp_src_reg[src->Index] : + NVS_FR_UNKNOWN; + } else { + reg->index = (src->Index < FRAG_ATTRIB_MAX) ? + _tx_mesa_fp_src_reg[src->Index] : + NVS_FR_UNKNOWN; + } + break; + /* All const types seem to get shoved into here, not really sure why */ + case PROGRAM_STATE_VAR: + switch (p->Parameters[src->Index].Type) { + case PROGRAM_NAMED_PARAM: + case PROGRAM_CONSTANT: + nvs->params[src->Index].source_val = NULL; + COPY_4V(nvs->params[src->Index].val, + p->ParameterValues[src->Index]); + break; + case PROGRAM_STATE_VAR: + nvs->params[src->Index].source_val = + p->ParameterValues[src->Index]; + break; + default: + fprintf(stderr, "Unknown parameter type %d\n", + p->Parameters[src->Index].Type); + assert(0); + break; + } + + if (src->RelAddr) { + reg->indexed = 1; + reg->addr_reg = 0; + reg->addr_comp = NVS_SWZ_X; + } else + reg->indexed = 0; + reg->file = NVS_FILE_CONST; + reg->index = src->Index; + break; + case PROGRAM_TEMPORARY: + reg->file = NVS_FILE_TEMP; + reg->index = src->Index; + break; + default: + fprintf(stderr, "Unknown source type %d\n", src->File); + assert(0); + } + + /* per-component negate handled elsewhere */ + reg->negate = src->NegateBase != 0; + reg->abs = src->Abs; + pass0_make_swizzle(reg->swizzle, src->Swizzle); } static nvsInstruction * @@ -389,59 +396,66 @@ pass0_emit(nouveauShader *nvs, nvsFragmentHeader *parent, int fpos, static void pass0_fixup_swizzle(nvsPtr nvs, nvsFragmentHeader *parent, int fpos, - struct prog_src_register *src, + struct prog_src_register *src, unsigned int sm1, unsigned int sm2) { - static const float sc[4] = { 1.0, 0.0, -1.0, 0.0 }; - struct pass0_rec *rec = nvs->pass_rec; - int fixup_1, fixup_2; - nvsRegister sr, dr = nvr_unused; - nvsRegister sm1const, sm2const; - - if (!rec->swzconst_done) { - struct gl_program *prog = &nvs->mesa.vp.Base; - rec->swzconst_id = _mesa_add_unnamed_constant(prog->Parameters, sc, 4); - rec->swzconst_done = 1; - COPY_4V(nvs->params[rec->swzconst_id].val, sc); - } - - fixup_1 = (sm1 != MAKE_SWIZZLE4(0,0,0,0) && sm2 != MAKE_SWIZZLE4(2,2,2,2)); - fixup_2 = (sm2 != MAKE_SWIZZLE4(2,2,2,2)); - - if (src->File != PROGRAM_TEMPORARY && src->File != PROGRAM_INPUT) { - /* We can't use more than one const in an instruction, so move the const - * into a temp, and swizzle from there. - *TODO: should just emit the swizzled const, instead of swizzling it - * in the shader.. would need to reswizzle any state params when they - * change however.. - */ - pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); - pass0_make_src_reg(nvs, &sr, src); - pass0_emit(nvs, parent, fpos, NVS_OP_MOV, dr, SMASK_ALL, 0, sr, nvr_unused, nvr_unused); - pass0_make_reg(nvs, &sr, NVS_FILE_TEMP, dr.index); - } else { - if (fixup_1) - src->NegateBase = 0; - pass0_make_src_reg(nvs, &sr, src); - pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); - } - - pass0_make_reg(nvs, &sm1const, NVS_FILE_CONST, rec->swzconst_id); - pass0_make_swizzle(sm1const.swizzle, sm1); - if (fixup_1 && fixup_2) { - /* Any combination with SWIZZLE_ONE */ - pass0_make_reg(nvs, &sm2const, NVS_FILE_CONST, rec->swzconst_id); - pass0_make_swizzle(sm2const.swizzle, sm2); - pass0_emit(nvs, parent, fpos, NVS_OP_MAD, dr, SMASK_ALL, 0, sr, sm1const, sm2const); - } else { - /* SWIZZLE_ZERO || arbitrary negate */ - pass0_emit(nvs, parent, fpos, NVS_OP_MUL, dr, SMASK_ALL, 0, sr, sm1const, nvr_unused); - } - - src->File = PROGRAM_TEMPORARY; - src->Index = dr.index; - src->Swizzle = SWIZZLE_NOOP; + static const float sc[4] = { 1.0, 0.0, -1.0, 0.0 }; + struct pass0_rec *rec = nvs->pass_rec; + int fixup_1, fixup_2; + nvsRegister sr, dr = nvr_unused; + nvsRegister sm1const, sm2const; + + if (!rec->swzconst_done) { + struct gl_program *prog = &nvs->mesa.vp.Base; + rec->swzconst_id = _mesa_add_unnamed_constant(prog->Parameters, + sc, 4); + rec->swzconst_done = 1; + COPY_4V(nvs->params[rec->swzconst_id].val, sc); + } + + fixup_1 = (sm1 != MAKE_SWIZZLE4(0,0,0,0) && + sm2 != MAKE_SWIZZLE4(2,2,2,2)); + fixup_2 = (sm2 != MAKE_SWIZZLE4(2,2,2,2)); + + if (src->File != PROGRAM_TEMPORARY && src->File != PROGRAM_INPUT) { + /* We can't use more than one const in an instruction, + * so move the const into a temp, and swizzle from there. + * + * TODO: should just emit the swizzled const, instead of + * swizzling it in the shader.. would need to reswizzle + * any state params when they change however.. + */ + pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); + pass0_make_src_reg(nvs, &sr, src); + pass0_emit(nvs, parent, fpos, NVS_OP_MOV, + dr, SMASK_ALL, 0, sr, nvr_unused, nvr_unused); + pass0_make_reg(nvs, &sr, NVS_FILE_TEMP, dr.index); + } else { + if (fixup_1) + src->NegateBase = 0; + pass0_make_src_reg(nvs, &sr, src); + pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); + } + + pass0_make_reg(nvs, &sm1const, NVS_FILE_CONST, rec->swzconst_id); + pass0_make_swizzle(sm1const.swizzle, sm1); + if (fixup_1 && fixup_2) { + /* Any combination with SWIZZLE_ONE */ + pass0_make_reg(nvs, &sm2const, + NVS_FILE_CONST, rec->swzconst_id); + pass0_make_swizzle(sm2const.swizzle, sm2); + pass0_emit(nvs, parent, fpos, NVS_OP_MAD, + dr, SMASK_ALL, 0, sr, sm1const, sm2const); + } else { + /* SWIZZLE_ZERO || arbitrary negate */ + pass0_emit(nvs, parent, fpos, NVS_OP_MUL, + dr, SMASK_ALL, 0, sr, sm1const, nvr_unused); + } + + src->File = PROGRAM_TEMPORARY; + src->Index = dr.index; + src->Swizzle = SWIZZLE_NOOP; } #define SET_SWZ(fs, cp, c) fs = (fs & ~(0x7<<(cp*3))) | (c<<(cp*3)) @@ -449,81 +463,86 @@ static void pass0_check_sources(nvsPtr nvs, nvsFragmentHeader *parent, int fpos, struct prog_instruction *inst) { - unsigned int insrc = -1, constsrc = -1; - int i; - - for (i=0;i<_mesa_num_inst_src_regs(inst->Opcode);i++) { - struct prog_src_register *src = &inst->SrcReg[i]; - unsigned int sm_1 = 0, sm_2 = 0; - nvsRegister sr, dr; - int do_mov = 0, c; - - /* Build up swizzle masks as if we were going to use - * "MAD new, src, const1, const2" to support arbitrary negation - * and SWIZZLE_ZERO/SWIZZLE_ONE. - */ - for (c=0;c<4;c++) { - if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ZERO) { - SET_SWZ(sm_1, c, SWIZZLE_Y); /* 0.0 */ - SET_SWZ(sm_2, c, SWIZZLE_Y); - SET_SWZ(src->Swizzle, c, SWIZZLE_X); - } else if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ONE) { - SET_SWZ(sm_1, c, SWIZZLE_Y); - if (src->NegateBase & (1<Swizzle, c, SWIZZLE_X); - } else { - if (src->NegateBase & (1<File) { - case PROGRAM_INPUT: - if (insrc != -1 && insrc != src->Index) - do_mov = 1; - else insrc = src->Index; - break; - case PROGRAM_STATE_VAR: - if (constsrc != -1 && constsrc != src->Index) - do_mov = 1; - else constsrc = src->Index; - break; - default: - break; - } - - /* Emit any extra ATTRIB/CONST to a temp, and modify the Mesa instruction - * to point at the temp. - */ - if (do_mov) { - pass0_make_src_reg(nvs, &sr, src); - pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); - pass0_emit(nvs, parent, fpos, NVS_OP_MOV, dr, SMASK_ALL, 0, - sr, nvr_unused, nvr_unused); - - src->File = PROGRAM_TEMPORARY; - src->Index = dr.index; - src->Swizzle= SWIZZLE_NOOP; - } - } + unsigned int insrc = -1, constsrc = -1; + int i; + + for (i=0;i<_mesa_num_inst_src_regs(inst->Opcode);i++) { + struct prog_src_register *src = &inst->SrcReg[i]; + unsigned int sm_1 = 0, sm_2 = 0; + nvsRegister sr, dr; + int do_mov = 0, c; + + /* Build up swizzle masks as if we were going to use + * "MAD new, src, const1, const2" to support arbitrary negation + * and SWIZZLE_ZERO/SWIZZLE_ONE. + */ + for (c=0;c<4;c++) { + if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ZERO) { + SET_SWZ(sm_1, c, SWIZZLE_Y); /* 0.0 */ + SET_SWZ(sm_2, c, SWIZZLE_Y); + SET_SWZ(src->Swizzle, c, SWIZZLE_X); + } else if (GET_SWZ(src->Swizzle, c) == SWIZZLE_ONE) { + SET_SWZ(sm_1, c, SWIZZLE_Y); + if (src->NegateBase & (1<Swizzle, c, SWIZZLE_X); + } else { + if (src->NegateBase & (1<File) { + case PROGRAM_INPUT: + if (insrc != -1 && insrc != src->Index) + do_mov = 1; + else insrc = src->Index; + break; + case PROGRAM_STATE_VAR: + if (constsrc != -1 && constsrc != src->Index) + do_mov = 1; + else constsrc = src->Index; + break; + default: + break; + } + + /* Emit any extra ATTRIB/CONST to a temp, and modify the Mesa + * instruction to point at the temp. + */ + if (do_mov) { + pass0_make_src_reg(nvs, &sr, src); + pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); + pass0_emit(nvs, parent, fpos, NVS_OP_MOV, + dr, SMASK_ALL, 0, + sr, nvr_unused, nvr_unused); + + src->File = PROGRAM_TEMPORARY; + src->Index = dr.index; + src->Swizzle= SWIZZLE_NOOP; + } + } } static GLboolean @@ -531,138 +550,150 @@ pass0_emulate_instruction(nouveauShader *nvs, nvsFragmentHeader *parent, int fpos, struct prog_instruction *inst) { - nvsFunc *shader = nvs->func; - nvsRegister src[3], dest, temp; - nvsInstruction *nvsinst; - struct pass0_rec *rec = nvs->pass_rec; - unsigned int mask = pass0_make_mask(inst->DstReg.WriteMask); - int i, sat; - - sat = (inst->SaturateMode == SATURATE_ZERO_ONE); - - /* Build all the "real" regs for the instruction */ - for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++) - pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]); - if (inst->Opcode != OPCODE_KIL) - pass0_make_dst_reg(nvs, &dest, &inst->DstReg); - - switch (inst->Opcode) { - case OPCODE_ABS: - if (shader->caps & SCAP_SRC_ABS) - pass0_emit(nvs, parent, fpos, NVS_OP_MOV, dest, mask, sat, - nvsAbs(src[0]), nvr_unused, nvr_unused); - else - pass0_emit(nvs, parent, fpos, NVS_OP_MAX, dest, mask, sat, - src[0], nvsNegate(src[0]), nvr_unused); - break; - case OPCODE_KIL: - /* This is only in ARB shaders, so we don't have to worry - * about clobbering a CC reg as they aren't supported anyway. - */ - /* MOVC0 temp, src */ - pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - nvsinst = pass0_emit(nvs, parent, fpos, NVS_OP_MOV, temp, SMASK_ALL, 0, - src[0], nvr_unused, nvr_unused); - nvsinst->cond_update = 1; - nvsinst->cond_reg = 0; - /* KIL_NV (LT0.xyzw) temp */ - nvsinst = pass0_emit(nvs, parent, fpos, NVS_OP_KIL, nvr_unused, 0, 0, - nvr_unused, nvr_unused, nvr_unused); - nvsinst->cond = COND_LT; - nvsinst->cond_reg = 0; - nvsinst->cond_test = 1; - pass0_make_swizzle(nvsinst->cond_swizzle, MAKE_SWIZZLE4(0,1,2,3)); - break; - case OPCODE_LIT: - break; - case OPCODE_LRP: - pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - pass0_emit(nvs, parent, fpos, NVS_OP_MAD, temp, mask, 0, - nvsNegate(src[0]), src[2], src[2]); - pass0_emit(nvs, parent, fpos, NVS_OP_MAD, dest, mask, sat, - src[0], src[1], temp); - break; - case OPCODE_POW: - if (shader->SupportsOpcode(shader, NVS_OP_LG2) && - shader->SupportsOpcode(shader, NVS_OP_EX2)) { - pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - /* LG2 temp.x, src0.c */ - pass0_emit(nvs, parent, fpos, NVS_OP_LG2, temp, SMASK_X, 0, - nvsSwizzle(src[0], X, X, X, X), - nvr_unused, - nvr_unused); - /* MUL temp.x, temp.x, src1.c */ - pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_X, 0, - nvsSwizzle(temp, X, X, X, X), - nvsSwizzle(src[1], X, X, X, X), - nvr_unused); - /* EX2 dest, temp.x */ - pass0_emit(nvs, parent, fpos, NVS_OP_EX2, dest, mask, sat, - nvsSwizzle(temp, X, X, X, X), - nvr_unused, - nvr_unused); - } else { - /* can we use EXP/LOG instead of EX2/LG2?? */ - fprintf(stderr, "Implement POW for NV20 vtxprog!\n"); - return GL_FALSE; - } - break; - case OPCODE_RSQ: - if (rec->const_half.file != NVS_FILE_CONST) { - GLfloat const_half[4] = { 0.5, 0.0, 0.0, 0.0 }; - pass0_make_reg(nvs, &rec->const_half, NVS_FILE_CONST, - _mesa_add_unnamed_constant(nvs->mesa.vp.Base.Parameters, - const_half, 4)); - COPY_4V(nvs->params[rec->const_half.index].val, const_half); - } - pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - pass0_emit(nvs, parent, fpos, NVS_OP_LG2, temp, SMASK_X, 0, - nvsAbs(nvsSwizzle(src[0], X, X, X, X)), - nvr_unused, - nvr_unused); - pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_X, 0, - nvsSwizzle(temp, X, X, X, X), - nvsNegate(rec->const_half), - nvr_unused); - pass0_emit(nvs, parent, fpos, NVS_OP_EX2, dest, mask, sat, - nvsSwizzle(temp, X, X, X, X), - nvr_unused, - nvr_unused); - break; - case OPCODE_SCS: - if (mask & SMASK_X) - pass0_emit(nvs, parent, fpos, NVS_OP_COS, dest, SMASK_X, sat, - nvsSwizzle(src[0], X, X, X, X), - nvr_unused, - nvr_unused); - if (mask & SMASK_Y) - pass0_emit(nvs, parent, fpos, NVS_OP_SIN, dest, SMASK_Y, sat, - nvsSwizzle(src[0], X, X, X, X), - nvr_unused, - nvr_unused); - break; - case OPCODE_SUB: - pass0_emit(nvs, parent, fpos, NVS_OP_ADD, dest, mask, sat, - src[0], nvsNegate(src[1]), nvr_unused); - break; - case OPCODE_XPD: - pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_ALL, 0, - nvsSwizzle(src[0], Z, X, Y, Y), - nvsSwizzle(src[1], Y, Z, X, X), - nvr_unused); - pass0_emit(nvs, parent, fpos, NVS_OP_MAD, dest, (mask & ~SMASK_W), sat, - nvsSwizzle(src[0], Y, Z, X, X), - nvsSwizzle(src[1], Z, X, Y, Y), - nvsNegate(temp)); - break; - default: - fprintf(stderr, "hw doesn't support opcode \"%s\", and no emulation found\n", - _mesa_opcode_string(inst->Opcode)); - return GL_FALSE; - } - - return GL_TRUE; + nvsFunc *shader = nvs->func; + nvsRegister src[3], dest, temp; + nvsInstruction *nvsinst; + struct pass0_rec *rec = nvs->pass_rec; + unsigned int mask = pass0_make_mask(inst->DstReg.WriteMask); + int i, sat; + + sat = (inst->SaturateMode == SATURATE_ZERO_ONE); + + /* Build all the "real" regs for the instruction */ + for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++) + pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]); + if (inst->Opcode != OPCODE_KIL) + pass0_make_dst_reg(nvs, &dest, &inst->DstReg); + + switch (inst->Opcode) { + case OPCODE_ABS: + if (shader->caps & SCAP_SRC_ABS) + pass0_emit(nvs, parent, fpos, NVS_OP_MOV, + dest, mask, sat, + nvsAbs(src[0]), nvr_unused, nvr_unused); + else + pass0_emit(nvs, parent, fpos, NVS_OP_MAX, + dest, mask, sat, + src[0], nvsNegate(src[0]), nvr_unused); + break; + case OPCODE_KIL: + /* This is only in ARB shaders, so we don't have to worry + * about clobbering a CC reg as they aren't supported anyway. + */ + /* MOVC0 temp, src */ + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + nvsinst = pass0_emit(nvs, parent, fpos, NVS_OP_MOV, + temp, SMASK_ALL, 0, + src[0], nvr_unused, nvr_unused); + nvsinst->cond_update = 1; + nvsinst->cond_reg = 0; + /* KIL_NV (LT0.xyzw) temp */ + nvsinst = pass0_emit(nvs, parent, fpos, NVS_OP_KIL, + nvr_unused, 0, 0, + nvr_unused, nvr_unused, nvr_unused); + nvsinst->cond = COND_LT; + nvsinst->cond_reg = 0; + nvsinst->cond_test = 1; + pass0_make_swizzle(nvsinst->cond_swizzle, + MAKE_SWIZZLE4(0,1,2,3)); + break; + case OPCODE_LRP: + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + pass0_emit(nvs, parent, fpos, NVS_OP_MAD, temp, mask, 0, + nvsNegate(src[0]), src[2], src[2]); + pass0_emit(nvs, parent, fpos, NVS_OP_MAD, dest, mask, sat, + src[0], src[1], temp); + break; + case OPCODE_POW: + if (shader->SupportsOpcode(shader, NVS_OP_LG2) && + shader->SupportsOpcode(shader, NVS_OP_EX2)) { + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + /* LG2 temp.x, src0.c */ + pass0_emit(nvs, parent, fpos, NVS_OP_LG2, + temp, SMASK_X, 0, + nvsSwizzle(src[0], X, X, X, X), + nvr_unused, + nvr_unused); + /* MUL temp.x, temp.x, src1.c */ + pass0_emit(nvs, parent, fpos, NVS_OP_MUL, + temp, SMASK_X, 0, + nvsSwizzle(temp, X, X, X, X), + nvsSwizzle(src[1], X, X, X, X), + nvr_unused); + /* EX2 dest, temp.x */ + pass0_emit(nvs, parent, fpos, NVS_OP_EX2, + dest, mask, sat, + nvsSwizzle(temp, X, X, X, X), + nvr_unused, + nvr_unused); + } else { + /* can we use EXP/LOG instead of EX2/LG2?? */ + fprintf(stderr, "Implement POW for NV20 vtxprog!\n"); + return GL_FALSE; + } + break; + case OPCODE_RSQ: + if (rec->const_half.file != NVS_FILE_CONST) { + GLfloat const_half[4] = { 0.5, 0.0, 0.0, 0.0 }; + pass0_make_reg(nvs, &rec->const_half, NVS_FILE_CONST, + _mesa_add_unnamed_constant( + nvs->mesa.vp.Base.Parameters, + const_half, 4)); + COPY_4V(nvs->params[rec->const_half.index].val, + const_half); + } + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + pass0_emit(nvs, parent, fpos, NVS_OP_LG2, temp, SMASK_X, 0, + nvsAbs(nvsSwizzle(src[0], X, X, X, X)), + nvr_unused, + nvr_unused); + pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_X, 0, + nvsSwizzle(temp, X, X, X, X), + nvsNegate(rec->const_half), + nvr_unused); + pass0_emit(nvs, parent, fpos, NVS_OP_EX2, dest, mask, sat, + nvsSwizzle(temp, X, X, X, X), + nvr_unused, + nvr_unused); + break; + case OPCODE_SCS: + if (mask & SMASK_X) + pass0_emit(nvs, parent, fpos, NVS_OP_COS, + dest, SMASK_X, sat, + nvsSwizzle(src[0], X, X, X, X), + nvr_unused, + nvr_unused); + if (mask & SMASK_Y) + pass0_emit(nvs, parent, fpos, NVS_OP_SIN, + dest, SMASK_Y, sat, + nvsSwizzle(src[0], X, X, X, X), + nvr_unused, + nvr_unused); + break; + case OPCODE_SUB: + pass0_emit(nvs, parent, fpos, NVS_OP_ADD, dest, mask, sat, + src[0], nvsNegate(src[1]), nvr_unused); + break; + case OPCODE_XPD: + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_ALL, 0, + nvsSwizzle(src[0], Z, X, Y, Y), + nvsSwizzle(src[1], Y, Z, X, X), + nvr_unused); + pass0_emit(nvs, parent, fpos, NVS_OP_MAD, + dest, (mask & ~SMASK_W), sat, + nvsSwizzle(src[0], Y, Z, X, X), + nvsSwizzle(src[1], Z, X, Y, Y), + nvsNegate(temp)); + break; + default: + WARN_ONCE("hw doesn't support opcode \"%s\"," + "and no emulation found\n", + _mesa_opcode_string(inst->Opcode)); + return GL_FALSE; + } + + return GL_TRUE; } static GLboolean diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c index b9b87ccf91..6fb36c1daf 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c @@ -41,130 +41,138 @@ #include "nouveau_msg.h" struct pass2_rec { - /* Map nvsRegister temp ID onto hw temp ID */ - unsigned int temps[NVS_MAX_TEMPS]; - /* Track free hw registers */ - unsigned int hw_temps[NVS_MAX_TEMPS]; + /* Map nvsRegister temp ID onto hw temp ID */ + unsigned int temps[NVS_MAX_TEMPS]; + /* Track free hw registers */ + unsigned int hw_temps[NVS_MAX_TEMPS]; }; static int pass2_alloc_hw_temp(nvsPtr nvs) { - struct pass2_rec *rec = nvs->pass_rec; - int i; - - for (i=0; ifunc->MaxTemp; i++) { - /* This is a *horrible* hack.. R0 is both temp0 and result.color - * in NV30/40 fragprogs, we can use R0 as a temp before result is - * written however.. - */ - if (nvs->mesa.vp.Base.Target == GL_FRAGMENT_PROGRAM_ARB && i==0) - continue; - - if (rec->hw_temps[i] == 0) { - rec->hw_temps[i] = 1; - return i; - } - } - return -1; + struct pass2_rec *rec = nvs->pass_rec; + int i; + + for (i=0; ifunc->MaxTemp; i++) { + /* This is a *horrible* hack.. R0 is both temp0 and result.color + * in NV30/40 fragprogs, we can use R0 as a temp before result + * is written however.. + */ + if (nvs->mesa.vp.Base.Target == GL_FRAGMENT_PROGRAM_ARB && i==0) + continue; + if (rec->hw_temps[i] == 0) { + rec->hw_temps[i] = 1; + return i; + } + } + + return -1; } static nvsRegister pass2_mangle_reg(nvsPtr nvs, nvsInstruction *inst, nvsRegister reg) { - struct pass2_rec *rec = nvs->pass_rec; + struct pass2_rec *rec = nvs->pass_rec; - if (reg.file == NVS_FILE_TEMP) { - if (rec->temps[reg.index] == -1) - rec->temps[reg.index] = pass2_alloc_hw_temp(nvs); - reg.index = rec->temps[reg.index]; - } + if (reg.file == NVS_FILE_TEMP) { + if (rec->temps[reg.index] == -1) + rec->temps[reg.index] = pass2_alloc_hw_temp(nvs); + reg.index = rec->temps[reg.index]; + } - return reg; + return reg; } static void pass2_add_instruction(nvsPtr nvs, nvsInstruction *inst, - struct _op_xlat *op, int slot) + struct _op_xlat *op, int slot) { - nvsSwzComp default_swz[4] = { NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W }; - nvsFunc *shader = nvs->func; - nvsRegister reg; - int i; - - shader->SetOpcode(shader, op->NV, slot); - if (inst->saturate ) shader->SetSaturate(shader); - if (inst->cond_update) shader->SetCCUpdate(shader); - if (inst->cond_test ) shader->SetCondition(shader, 1, inst->cond, - inst->cond_reg, - inst->cond_swizzle); - else shader->SetCondition(shader, 0, NVS_COND_TR, - 0, - default_swz); - switch (inst->op) { - case NVS_OP_TEX: - case NVS_OP_TXB: - case NVS_OP_TXL: - case NVS_OP_TXP: - case NVS_OP_TXD: - shader->SetTexImageUnit(shader, inst->tex_unit); - break; - default: - break; - } - - for (i = 0; i < 3; i++) { - if (op->srcpos[i] != -1) { - reg = pass2_mangle_reg(nvs, inst, inst->src[i]); - if (reg.file == NVS_FILE_ATTRIB) - nvs->inputs_read |= (1 << reg.index); - shader->SetSource(shader, ®, op->srcpos[i]); - if (reg.file == NVS_FILE_CONST && shader->GetSourceConstVal) { - int idx_slot = nvs->params[reg.index].hw_index_cnt++; - nvs->params[reg.index].hw_index = realloc( - nvs->params[reg.index].hw_index, sizeof(int) * idx_slot+1); - nvs->params[reg.index].hw_index[idx_slot] = nvs->program_current + 4; - } - } - } - - reg = pass2_mangle_reg(nvs, inst, inst->dest); - if (reg.file == NVS_FILE_RESULT) - nvs->outputs_written |= (1 << reg.index); - shader->SetResult(shader, ®, inst->mask, slot); + nvsSwzComp default_swz[4] = { NVS_SWZ_X, NVS_SWZ_Y, + NVS_SWZ_Z, NVS_SWZ_W }; + nvsFunc *shader = nvs->func; + nvsRegister reg; + int i; + + shader->SetOpcode(shader, op->NV, slot); + if (inst->saturate ) shader->SetSaturate(shader); + if (inst->cond_update ) shader->SetCCUpdate(shader); + if (inst->cond_test ) shader->SetCondition(shader, 1, inst->cond, + inst->cond_reg, + inst->cond_swizzle); + else shader->SetCondition(shader, 0, NVS_COND_TR, + 0, + default_swz); + switch (inst->op) { + case NVS_OP_TEX: + case NVS_OP_TXB: + case NVS_OP_TXL: + case NVS_OP_TXP: + case NVS_OP_TXD: + shader->SetTexImageUnit(shader, inst->tex_unit); + break; + default: + break; + } + + for (i = 0; i < 3; i++) { + if (op->srcpos[i] != -1) { + reg = pass2_mangle_reg(nvs, inst, inst->src[i]); + + if (reg.file == NVS_FILE_ATTRIB) + nvs->inputs_read |= (1 << reg.index); + shader->SetSource(shader, ®, op->srcpos[i]); + + if (reg.file == NVS_FILE_CONST && + shader->GetSourceConstVal) { + int idx_slot = + nvs->params[reg.index].hw_index_cnt++; + nvs->params[reg.index].hw_index = realloc( + nvs->params[reg.index].hw_index, + sizeof(int) * idx_slot+1); + nvs->params[reg.index].hw_index[idx_slot] = + nvs->program_current + 4; + } + } + } + + reg = pass2_mangle_reg(nvs, inst, inst->dest); + if (reg.file == NVS_FILE_RESULT) + nvs->outputs_written |= (1 << reg.index); + shader->SetResult(shader, ®, inst->mask, slot); } static int pass2_assemble_instruction(nvsPtr nvs, nvsInstruction *inst, int last) { - nvsFunc *shader = nvs->func; - struct _op_xlat *op; - unsigned int hw_inst[8]; - int slot; - int instsz; - int i; - - shader->inst = hw_inst; - - /* Assemble this instruction */ - if (!(op = shader->GetOPTXFromSOP(inst->op, &slot))) - return 0; - shader->InitInstruction(shader); - pass2_add_instruction(nvs, inst, op, slot); - if (last) - shader->SetLastInst(shader); - - instsz = shader->GetOffsetNext(nvs->func); - if (nvs->program_size + instsz >= nvs->program_alloc_size) { - nvs->program_alloc_size *= 2; - nvs->program = realloc(nvs->program, - nvs->program_alloc_size * sizeof(uint32_t)); - } - - for (i=0; iprogram[nvs->program_current++] = hw_inst[i]; - nvs->program_size = nvs->program_current; - return 1; + nvsFunc *shader = nvs->func; + struct _op_xlat *op; + unsigned int hw_inst[8]; + int slot; + int instsz; + int i; + + shader->inst = hw_inst; + + /* Assemble this instruction */ + if (!(op = shader->GetOPTXFromSOP(inst->op, &slot))) + return 0; + shader->InitInstruction(shader); + pass2_add_instruction(nvs, inst, op, slot); + if (last) + shader->SetLastInst(shader); + + instsz = shader->GetOffsetNext(nvs->func); + if (nvs->program_size + instsz >= nvs->program_alloc_size) { + nvs->program_alloc_size *= 2; + nvs->program = realloc(nvs->program, + nvs->program_alloc_size * + sizeof(uint32_t)); + } + + for (i=0; iprogram[nvs->program_current++] = hw_inst[i]; + nvs->program_size = nvs->program_current; + return 1; } static GLboolean @@ -198,53 +206,56 @@ pass2_translate(nvsPtr nvs, nvsFragmentHeader *f) GLboolean nouveau_shader_pass2(nvsPtr nvs) { - struct pass2_rec *rec; - int i; - - rec = calloc(1, sizeof(struct pass2_rec)); - for (i=0; itemps[i] = -1; - nvs->pass_rec = rec; - - /* Start off with allocating 4 uint32_t's for each inst, will be grown - * if necessary.. - */ - nvs->program_alloc_size = nvs->mesa.vp.Base.NumInstructions * 4; - nvs->program = calloc(nvs->program_alloc_size, sizeof(uint32_t)); - nvs->program_size = 0; - nvs->program_current = 0; - - if (!pass2_translate(nvs, ((nvsSubroutine*)nvs->program_tree)->insn_head)) { - free(nvs->program); - nvs->program = NULL; - return GL_FALSE; - } - - /* Shrink allocated memory to only what we need */ - nvs->program = realloc(nvs->program, nvs->program_size * sizeof(uint32_t)); - nvs->program_alloc_size = nvs->program_size; - - nvs->translated = 1; - nvs->on_hardware = 0; - - if (NOUVEAU_DEBUG & DEBUG_SHADERS) { - fflush(stdout); fflush(stderr); - fprintf(stderr, "----------------MESA PROGRAM target=%s, id=0x%x\n", - _mesa_lookup_enum_by_nr(nvs->mesa.vp.Base.Target), - nvs->mesa.vp.Base.Id); - fflush(stdout); fflush(stderr); - _mesa_print_program(&nvs->mesa.vp.Base); - fflush(stdout); fflush(stderr); - fprintf(stderr, "^^^^^^^^^^^^^^^^MESA PROGRAM\n"); - fflush(stdout); fflush(stderr); - fprintf(stderr, "----------------NV PROGRAM\n"); - fflush(stdout); fflush(stderr); - nvsDisasmHWShader(nvs); - fflush(stdout); fflush(stderr); - fprintf(stderr, "^^^^^^^^^^^^^^^^NV PROGRAM\n"); - fflush(stdout); fflush(stderr); - } - - return GL_TRUE; + struct pass2_rec *rec; + int i; + + rec = calloc(1, sizeof(struct pass2_rec)); + for (i=0; itemps[i] = -1; + nvs->pass_rec = rec; + + /* Start off with allocating 4 uint32_t's for each inst, will be grown + * if necessary.. + */ + nvs->program_alloc_size = nvs->mesa.vp.Base.NumInstructions * 4; + nvs->program = calloc(nvs->program_alloc_size, sizeof(uint32_t)); + nvs->program_size = 0; + nvs->program_current = 0; + + if (!pass2_translate(nvs, + ((nvsSubroutine*)nvs->program_tree)->insn_head)) { + free(nvs->program); + nvs->program = NULL; + return GL_FALSE; + } + + /* Shrink allocated memory to only what we need */ + nvs->program = realloc(nvs->program, + nvs->program_size * sizeof(uint32_t)); + nvs->program_alloc_size = nvs->program_size; + + nvs->translated = 1; + nvs->on_hardware = 0; + + if (NOUVEAU_DEBUG & DEBUG_SHADERS) { + fflush(stdout); fflush(stderr); + fprintf(stderr, "-----------MESA PROGRAM target=%s, id=0x%x\n", + _mesa_lookup_enum_by_nr( + nvs->mesa.vp.Base.Target), + nvs->mesa.vp.Base.Id); + fflush(stdout); fflush(stderr); + _mesa_print_program(&nvs->mesa.vp.Base); + fflush(stdout); fflush(stderr); + fprintf(stderr, "^^^^^^^^^^^^^^^^MESA PROGRAM\n"); + fflush(stdout); fflush(stderr); + fprintf(stderr, "----------------NV PROGRAM\n"); + fflush(stdout); fflush(stderr); + nvsDisasmHWShader(nvs); + fflush(stdout); fflush(stderr); + fprintf(stderr, "^^^^^^^^^^^^^^^^NV PROGRAM\n"); + fflush(stdout); fflush(stderr); + } + + return GL_TRUE; } -- cgit v1.2.3 From ed69205684a0c3c69d27a9e2d13213997aaa5b93 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 23 Jan 2007 11:06:16 +1100 Subject: nouveau: unbreak nv40 --- src/mesa/drivers/dri/nouveau/nv30_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index e788a9235a..9bb4f14909 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -899,7 +899,7 @@ static GLboolean nv30BindBuffers(nouveauContextPtr nmesa, int num_color, OUT_RING (depth->offset); if (nmesa->screen->card->type >= NV_40) { BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH, 1); - OUT_RING (depth->pitch >> 2); + OUT_RING (depth->pitch); } } -- cgit v1.2.3 From a8b9d13f745405e370353cfb4aca680314a42d46 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 23 Jan 2007 13:36:45 +1100 Subject: nouveau: fill in condition info for instructions --- src/mesa/drivers/dri/nouveau/nouveau_shader_0.c | 153 ++++++++++++------------ 1 file changed, 76 insertions(+), 77 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c index d6ea42573a..5845d4f63a 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -117,7 +117,8 @@ static nvsOpcode _tx_mesa_opcode[] = { }; static nvsCond _tx_mesa_condmask[] = { - NVS_COND_UNKNOWN, NVS_COND_GT, NVS_COND_LT, NVS_COND_UN, NVS_COND_GE, + NVS_COND_TR, /* workaround mesa not filling a valid value */ + NVS_COND_GT, NVS_COND_LT, NVS_COND_UN, NVS_COND_GE, NVS_COND_LE, NVS_COND_NE, NVS_COND_NE, NVS_COND_TR, NVS_COND_FL }; @@ -134,6 +135,26 @@ struct pass0_rec { #define Z NVS_SWZ_Z #define W NVS_SWZ_W +#define FILL_CONDITION_FLAGS(fragment) do { \ + (fragment)->cond = \ + pass0_make_condmask(inst->DstReg.CondMask); \ + if ((fragment)->cond != NVS_COND_TR) \ + (fragment)->cond_test = 1; \ + (fragment)->cond_reg = inst->CondDst; \ + pass0_make_swizzle((fragment)->cond_swizzle, inst->DstReg.CondSwizzle);\ +} while(0) + +#define ARITH(op,dest,mask,sat,s0,s1,s2) do { \ + nvsinst = pass0_emit(nvs, parent, fpos, (op), \ + (dest), (mask), (sat), (s0), (s1), (s2));\ + FILL_CONDITION_FLAGS(nvsinst); \ +} while(0) + +#define ARITHu(op,dest,mask,sat,s0,s1,s2) do { \ + nvsinst = pass0_emit(nvs, parent, fpos, (op), \ + (dest), (mask), (sat), (s0), (s1), (s2));\ +} while(0) + static void pass0_append_fragment(nvsFragmentHeader *parent, nvsFragmentHeader *fragment, @@ -403,6 +424,7 @@ pass0_fixup_swizzle(nvsPtr nvs, nvsFragmentHeader *parent, int fpos, static const float sc[4] = { 1.0, 0.0, -1.0, 0.0 }; struct pass0_rec *rec = nvs->pass_rec; int fixup_1, fixup_2; + nvsInstruction *nvsinst; nvsRegister sr, dr = nvr_unused; nvsRegister sm1const, sm2const; @@ -428,8 +450,8 @@ pass0_fixup_swizzle(nvsPtr nvs, nvsFragmentHeader *parent, int fpos, */ pass0_make_reg(nvs, &dr, NVS_FILE_TEMP, -1); pass0_make_src_reg(nvs, &sr, src); - pass0_emit(nvs, parent, fpos, NVS_OP_MOV, - dr, SMASK_ALL, 0, sr, nvr_unused, nvr_unused); + ARITHu(NVS_OP_MOV, dr, SMASK_ALL, 0, + sr, nvr_unused, nvr_unused); pass0_make_reg(nvs, &sr, NVS_FILE_TEMP, dr.index); } else { if (fixup_1) @@ -445,12 +467,10 @@ pass0_fixup_swizzle(nvsPtr nvs, nvsFragmentHeader *parent, int fpos, pass0_make_reg(nvs, &sm2const, NVS_FILE_CONST, rec->swzconst_id); pass0_make_swizzle(sm2const.swizzle, sm2); - pass0_emit(nvs, parent, fpos, NVS_OP_MAD, - dr, SMASK_ALL, 0, sr, sm1const, sm2const); + ARITHu(NVS_OP_MAD, dr, SMASK_ALL, 0, sr, sm1const, sm2const); } else { /* SWIZZLE_ZERO || arbitrary negate */ - pass0_emit(nvs, parent, fpos, NVS_OP_MUL, - dr, SMASK_ALL, 0, sr, sm1const, nvr_unused); + ARITHu(NVS_OP_MUL, dr, SMASK_ALL, 0, sr, sm1const, nvr_unused); } src->File = PROGRAM_TEMPORARY; @@ -568,64 +588,54 @@ pass0_emulate_instruction(nouveauShader *nvs, switch (inst->Opcode) { case OPCODE_ABS: if (shader->caps & SCAP_SRC_ABS) - pass0_emit(nvs, parent, fpos, NVS_OP_MOV, - dest, mask, sat, + ARITH(NVS_OP_MOV, dest, mask, sat, nvsAbs(src[0]), nvr_unused, nvr_unused); else - pass0_emit(nvs, parent, fpos, NVS_OP_MAX, - dest, mask, sat, + ARITH(NVS_OP_MAX, dest, mask, sat, src[0], nvsNegate(src[0]), nvr_unused); break; case OPCODE_KIL: /* This is only in ARB shaders, so we don't have to worry * about clobbering a CC reg as they aren't supported anyway. + *XXX: might have to worry with GLSL however... */ /* MOVC0 temp, src */ pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - nvsinst = pass0_emit(nvs, parent, fpos, NVS_OP_MOV, - temp, SMASK_ALL, 0, - src[0], nvr_unused, nvr_unused); + ARITHu(NVS_OP_MOV, temp, SMASK_ALL, 0, + src[0], nvr_unused, nvr_unused); nvsinst->cond_update = 1; nvsinst->cond_reg = 0; /* KIL_NV (LT0.xyzw) temp */ - nvsinst = pass0_emit(nvs, parent, fpos, NVS_OP_KIL, - nvr_unused, 0, 0, - nvr_unused, nvr_unused, nvr_unused); + ARITHu(NVS_OP_KIL, nvr_unused, 0, 0, + nvr_unused, nvr_unused, nvr_unused); nvsinst->cond = COND_LT; nvsinst->cond_reg = 0; nvsinst->cond_test = 1; - pass0_make_swizzle(nvsinst->cond_swizzle, - MAKE_SWIZZLE4(0,1,2,3)); + pass0_make_swizzle(nvsinst->cond_swizzle, SWIZZLE_NOOP); break; case OPCODE_LRP: pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - pass0_emit(nvs, parent, fpos, NVS_OP_MAD, temp, mask, 0, - nvsNegate(src[0]), src[2], src[2]); - pass0_emit(nvs, parent, fpos, NVS_OP_MAD, dest, mask, sat, - src[0], src[1], temp); + ARITHu(NVS_OP_MAD, temp, mask, 0, + nvsNegate(src[0]), src[2], src[2]); + ARITH (NVS_OP_MAD, dest, mask, sat, src[0], src[1], temp); break; case OPCODE_POW: if (shader->SupportsOpcode(shader, NVS_OP_LG2) && shader->SupportsOpcode(shader, NVS_OP_EX2)) { pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); /* LG2 temp.x, src0.c */ - pass0_emit(nvs, parent, fpos, NVS_OP_LG2, - temp, SMASK_X, 0, - nvsSwizzle(src[0], X, X, X, X), - nvr_unused, - nvr_unused); + ARITHu(NVS_OP_LG2, temp, SMASK_X, 0, + nvsSwizzle(src[0], X, X, X, X), + nvr_unused, nvr_unused); /* MUL temp.x, temp.x, src1.c */ - pass0_emit(nvs, parent, fpos, NVS_OP_MUL, - temp, SMASK_X, 0, - nvsSwizzle(temp, X, X, X, X), - nvsSwizzle(src[1], X, X, X, X), - nvr_unused); + ARITHu(NVS_OP_MUL, temp, SMASK_X, 0, + nvsSwizzle(temp, X, X, X, X), + nvsSwizzle(src[1], X, X, X, X), + nvr_unused); /* EX2 dest, temp.x */ - pass0_emit(nvs, parent, fpos, NVS_OP_EX2, - dest, mask, sat, - nvsSwizzle(temp, X, X, X, X), - nvr_unused, - nvr_unused); + ARITH (NVS_OP_EX2, dest, mask, sat, + nvsSwizzle(temp, X, X, X, X), + nvr_unused, nvr_unused); } else { /* can we use EXP/LOG instead of EX2/LG2?? */ fprintf(stderr, "Implement POW for NV20 vtxprog!\n"); @@ -643,48 +653,41 @@ pass0_emulate_instruction(nouveauShader *nvs, const_half); } pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - pass0_emit(nvs, parent, fpos, NVS_OP_LG2, temp, SMASK_X, 0, - nvsAbs(nvsSwizzle(src[0], X, X, X, X)), - nvr_unused, - nvr_unused); - pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_X, 0, - nvsSwizzle(temp, X, X, X, X), - nvsNegate(rec->const_half), - nvr_unused); - pass0_emit(nvs, parent, fpos, NVS_OP_EX2, dest, mask, sat, - nvsSwizzle(temp, X, X, X, X), - nvr_unused, - nvr_unused); + ARITHu(NVS_OP_LG2, temp, SMASK_X, 0, + nvsAbs(nvsSwizzle(src[0], X, X, X, X)), + nvr_unused, nvr_unused); + ARITHu(NVS_OP_MUL, temp, SMASK_X, 0, + nvsSwizzle(temp, X, X, X, X), + nvsNegate(rec->const_half), + nvr_unused); + ARITH (NVS_OP_EX2, dest, mask, sat, + nvsSwizzle(temp, X, X, X, X), + nvr_unused, nvr_unused); break; case OPCODE_SCS: if (mask & SMASK_X) - pass0_emit(nvs, parent, fpos, NVS_OP_COS, - dest, SMASK_X, sat, + ARITH(NVS_OP_COS, dest, SMASK_X, sat, nvsSwizzle(src[0], X, X, X, X), - nvr_unused, - nvr_unused); + nvr_unused, nvr_unused); if (mask & SMASK_Y) - pass0_emit(nvs, parent, fpos, NVS_OP_SIN, - dest, SMASK_Y, sat, + ARITH(NVS_OP_SIN, dest, SMASK_Y, sat, nvsSwizzle(src[0], X, X, X, X), - nvr_unused, - nvr_unused); + nvr_unused, nvr_unused); break; case OPCODE_SUB: - pass0_emit(nvs, parent, fpos, NVS_OP_ADD, dest, mask, sat, + ARITH(NVS_OP_ADD, dest, mask, sat, src[0], nvsNegate(src[1]), nvr_unused); break; case OPCODE_XPD: pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); - pass0_emit(nvs, parent, fpos, NVS_OP_MUL, temp, SMASK_ALL, 0, - nvsSwizzle(src[0], Z, X, Y, Y), - nvsSwizzle(src[1], Y, Z, X, X), - nvr_unused); - pass0_emit(nvs, parent, fpos, NVS_OP_MAD, - dest, (mask & ~SMASK_W), sat, - nvsSwizzle(src[0], Y, Z, X, X), - nvsSwizzle(src[1], Z, X, Y, Y), - nvsNegate(temp)); + ARITHu(NVS_OP_MUL, temp, SMASK_ALL, 0, + nvsSwizzle(src[0], Z, X, Y, Y), + nvsSwizzle(src[1], Y, Z, X, X), + nvr_unused); + ARITH (NVS_OP_MAD, dest, (mask & ~SMASK_W), sat, + nvsSwizzle(src[0], Y, Z, X, X), + nvsSwizzle(src[1], Z, X, Y, Y), + nvsNegate(temp)); break; default: WARN_ONCE("hw doesn't support opcode \"%s\"," @@ -721,16 +724,12 @@ pass0_translate_arith(nouveauShader *nvs, struct gl_program *prog, pass0_make_src_reg(nvs, &src[i], &inst->SrcReg[i]); pass0_make_dst_reg(nvs, &dest, &inst->DstReg); - nvsinst = pass0_emit(nvs, parent, fpos, - pass0_make_opcode(inst->Opcode), - dest, - pass0_make_mask(inst->DstReg.WriteMask), - (inst->SaturateMode != SATURATE_OFF), - src[0], src[1], src[2]); + ARITH(pass0_make_opcode(inst->Opcode), dest, + pass0_make_mask(inst->DstReg.WriteMask), + (inst->SaturateMode != SATURATE_OFF), + src[0], src[1], src[2]); nvsinst->tex_unit = inst->TexSrcUnit; nvsinst->tex_target = pass0_make_tex_target(inst->TexSrcTarget); - /* TODO when NV_fp/vp is implemented */ - nvsinst->cond = COND_TR; ret = GL_TRUE; } else @@ -753,7 +752,7 @@ pass0_translate_instructions(nouveauShader *nvs, int ipos, int fpos, return GL_TRUE; case OPCODE_BRA: case OPCODE_CAL: - //case OPCDOE_RET: + case OPCODE_RET: //case OPCODE_LOOP: //case OPCODE_ENDLOOP: //case OPCODE_IF: -- cgit v1.2.3 From cf33bcf0b246f75094673beaa989034fa27c4b9f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 23 Jan 2007 16:07:12 +1100 Subject: nouveau: allow for card-specific shader infos to be kept NV30/40 fragprog: build FP_CONTROL per-shader, still some hardcoded bits for this reg.. It looks like it has to do with the number of temps used, but needs more looking at. NV40 vtxprog : build VP_IN_REG/VP_OUT_REG during shader compile --- src/mesa/drivers/dri/nouveau/nouveau_shader.h | 74 ++++++++------- src/mesa/drivers/dri/nouveau/nouveau_shader_0.c | 1 + src/mesa/drivers/dri/nouveau/nouveau_shader_2.c | 4 - src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 3 - src/mesa/drivers/dri/nouveau/nv30_fragprog.c | 4 + src/mesa/drivers/dri/nouveau/nv30_state.c | 3 - src/mesa/drivers/dri/nouveau/nv30_vertprog.c | 4 + src/mesa/drivers/dri/nouveau/nv40_vertprog.c | 118 +++++++++++++++++++----- 8 files changed, 149 insertions(+), 62 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h index a3ab027142..8b4be9dfe7 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -24,6 +24,16 @@ typedef struct _nvs_fragment_header { } type; } nvsFragmentHeader; +typedef union { + struct { + uint32_t fp_control; + } NV30FP; + struct { + uint32_t vp_in_reg; + uint32_t vp_out_reg; + } NV30VP; +} nvsCardPriv; + typedef struct _nouveauShader { union { struct gl_vertex_program vp; @@ -41,10 +51,10 @@ typedef struct _nouveauShader { unsigned int program_start_id; unsigned int program_current; struct gl_buffer_object *program_buffer; - unsigned int inputs_read; - unsigned int outputs_written; int inst_count; + nvsCardPriv card_priv; + struct { GLfloat *source_val; /* NULL if invariant */ float val[4]; @@ -113,35 +123,35 @@ typedef enum { } nvsSwzComp; typedef enum { - NVS_FR_POSITION, - NVS_FR_WEIGHT, - NVS_FR_NORMAL, - NVS_FR_COL0, - NVS_FR_COL1, - NVS_FR_BFC0, - NVS_FR_BFC1, - NVS_FR_FOGCOORD, - NVS_FR_POINTSZ, - NVS_FR_TEXCOORD0, - NVS_FR_TEXCOORD1, - NVS_FR_TEXCOORD2, - NVS_FR_TEXCOORD3, - NVS_FR_TEXCOORD4, - NVS_FR_TEXCOORD5, - NVS_FR_TEXCOORD6, - NVS_FR_TEXCOORD7, - NVS_FR_FRAGDATA0, - NVS_FR_FRAGDATA1, - NVS_FR_FRAGDATA2, - NVS_FR_FRAGDATA3, - NVS_FR_CLIP0, - NVS_FR_CLIP1, - NVS_FR_CLIP2, - NVS_FR_CLIP3, - NVS_FR_CLIP4, - NVS_FR_CLIP5, - NVS_FR_CLIP6, - NVS_FR_FACING, + NVS_FR_POSITION = 0, + NVS_FR_WEIGHT = 1, + NVS_FR_NORMAL = 2, + NVS_FR_COL0 = 3, + NVS_FR_COL1 = 4, + NVS_FR_FOGCOORD = 5, + NVS_FR_TEXCOORD0 = 8, + NVS_FR_TEXCOORD1 = 9, + NVS_FR_TEXCOORD2 = 10, + NVS_FR_TEXCOORD3 = 11, + NVS_FR_TEXCOORD4 = 12, + NVS_FR_TEXCOORD5 = 13, + NVS_FR_TEXCOORD6 = 14, + NVS_FR_TEXCOORD7 = 15, + NVS_FR_BFC0 = 16, + NVS_FR_BFC1 = 17, + NVS_FR_POINTSZ = 18, + NVS_FR_FRAGDATA0 = 19, + NVS_FR_FRAGDATA1 = 20, + NVS_FR_FRAGDATA2 = 21, + NVS_FR_FRAGDATA3 = 22, + NVS_FR_CLIP0 = 23, + NVS_FR_CLIP1 = 24, + NVS_FR_CLIP2 = 25, + NVS_FR_CLIP3 = 26, + NVS_FR_CLIP4 = 27, + NVS_FR_CLIP5 = 28, + NVS_FR_CLIP6 = 29, + NVS_FR_FACING = 30, NVS_FR_UNKNOWN } nvsFixedReg; @@ -279,6 +289,8 @@ extern nvsSwzComp NV20VP_TX_SWIZZLE[4]; #define SCAP_SRC_ABS (1<<0) struct _nvsFunc { + nvsCardPriv *card_priv; + unsigned int MaxInst; unsigned int MaxAttrib; unsigned int MaxTemp; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c index 5845d4f63a..3e542ea9c0 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -805,6 +805,7 @@ nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) fprintf(stderr, "Unknown program type %d", prog->Target); return GL_FALSE; } + nvs->func->card_priv = &nvs->card_priv; rec = CALLOC_STRUCT(pass0_rec); if (rec) { diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c index 6fb36c1daf..c106fd2d94 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c @@ -118,8 +118,6 @@ pass2_add_instruction(nvsPtr nvs, nvsInstruction *inst, if (op->srcpos[i] != -1) { reg = pass2_mangle_reg(nvs, inst, inst->src[i]); - if (reg.file == NVS_FILE_ATTRIB) - nvs->inputs_read |= (1 << reg.index); shader->SetSource(shader, ®, op->srcpos[i]); if (reg.file == NVS_FILE_CONST && @@ -136,8 +134,6 @@ pass2_add_instruction(nvsPtr nvs, nvsInstruction *inst, } reg = pass2_mangle_reg(nvs, inst, inst->dest); - if (reg.file == NVS_FILE_RESULT) - nvs->outputs_written |= (1 << reg.index); shader->SetResult(shader, ®, inst->mask, slot); } diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index f916912c7e..c9bfac8c4a 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -476,9 +476,6 @@ static void nv10ChooseVertexState( GLcontext *ctx ) * is up to date */ nvsUpdateShader(ctx, nmesa->passthrough_vp); - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_IN_REG, 2); - OUT_RING_CACHE (0xff09); /*IN : POS, COL, TC0-7 */ - OUT_RING_CACHE (0x3fc001); /*OUT: COL, TC0-7, POS implied */ /* Update texenv shader / user fragprog */ nvsUpdateShader(ctx, (nouveauShader*)ctx->FragmentProgram._Current); diff --git a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c index cd7c955c9e..3c7501dd62 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c +++ b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c @@ -46,6 +46,8 @@ NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs) */ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM, 1); OUT_RING (offset | 1); + BEGIN_RING_SIZE(NvSub3D, 0x1d60, 1); + OUT_RING (nvs->card_priv.NV30FP.fp_control | 0x03000000); } static void @@ -92,6 +94,8 @@ NV30FPSupportsOpcode(nvsFunc *shader, nvsOpcode op) static void NV30FPSetOpcode(nvsFunc *shader, unsigned int opcode, int slot) { + if (opcode == NV30_FP_OP_OPCODE_KIL) + shader->card_priv->NV30FP.fp_control |= (1<<7); shader->inst[0] &= ~NV30_FP_OP_OPCODE_MASK; shader->inst[0] |= (opcode << NV30_FP_OP_OPCODE_SHIFT); } diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 9bb4f14909..9b0d7425c8 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -862,9 +862,6 @@ static GLboolean nv40InitCard(nouveauContextPtr nmesa) BEGIN_RING_SIZE(NvSub3D, 0x1e94, 1); OUT_RING(0x00000001); - BEGIN_RING_SIZE(NvSub3D, 0x1d60, 1); - OUT_RING(0x03008000); - return GL_TRUE; } diff --git a/src/mesa/drivers/dri/nouveau/nv30_vertprog.c b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c index 0b7678f55d..afcacf36c2 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_vertprog.c +++ b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c @@ -29,6 +29,10 @@ NV30VPUploadToHW(GLcontext *ctx, nouveauShader *nvs) } BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_PROGRAM_START_ID, 1); OUT_RING(0); + + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_IN_REG, 2); + OUT_RING(nvs->card_priv.NV30VP.vp_in_reg); + OUT_RING(nvs->card_priv.NV30VP.vp_out_reg); } static void diff --git a/src/mesa/drivers/dri/nouveau/nv40_vertprog.c b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c index 1ba1cfd155..6cb7e1cfd6 100644 --- a/src/mesa/drivers/dri/nouveau/nv40_vertprog.c +++ b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c @@ -66,6 +66,96 @@ NV40VPSetCondition(nvsFunc *shader, int on, nvsCond cond, int reg, shader->inst[0] |= (swizzle[NVS_SWZ_W] << NV40_VP_INST_COND_SWZ_W_SHIFT); } +/* these just exist here until nouveau_reg.h has them. */ +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_COL0 (1<<0) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_COL1 (1<<1) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_BFC0 (1<<2) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_BFC1 (1<<3) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_FOGC (1<<4) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_PSZ (1<<5) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP0 (1<<6) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP1 (1<<7) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP2 (1<<8) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP3 (1<<9) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP4 (1<<10) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP5 (1<<11) +#define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_TEX0 (1<<14) + +static unsigned int +NV40VPTranslateResultReg(nvsFunc *shader, nvsFixedReg result, + unsigned int *mask_ret) +{ + unsigned int *out_reg = &shader->card_priv->NV30VP.vp_out_reg; + + *mask_ret = 0xf; + + switch (result) { + case NVS_FR_POSITION: + /* out_reg POS implied */ + return NV40_VP_INST_DEST_POS; + case NVS_FR_COL0: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_COL0; + return NV40_VP_INST_DEST_COL0; + case NVS_FR_COL1: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_COL1; + return NV40_VP_INST_DEST_COL1; + case NVS_FR_BFC0: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_BFC0; + return NV40_VP_INST_DEST_BFC0; + case NVS_FR_BFC1: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_BFC1; + return NV40_VP_INST_DEST_BFC1; + case NVS_FR_FOGCOORD: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_FOGC; + *mask_ret = 0x8; + return NV40_VP_INST_DEST_FOGC; + case NVS_FR_CLIP0: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP0; + *mask_ret = 0x4; + return NV40_VP_INST_DEST_FOGC; + case NVS_FR_CLIP1: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP1; + *mask_ret = 0x2; + return NV40_VP_INST_DEST_FOGC; + case NVS_FR_CLIP2: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP2; + *mask_ret = 0x1; + return NV40_VP_INST_DEST_FOGC; + case NVS_FR_POINTSZ: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_PSZ; + *mask_ret = 0x8; + return NV40_VP_INST_DEST_PSZ; + case NVS_FR_CLIP3: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP3; + *mask_ret = 0x4; + return NV40_VP_INST_DEST_PSZ; + case NVS_FR_CLIP4: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP4; + *mask_ret = 0x2; + return NV40_VP_INST_DEST_PSZ; + case NVS_FR_CLIP5: + (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP5; + *mask_ret = 0x1; + return NV40_VP_INST_DEST_PSZ; + case NVS_FR_TEXCOORD0: + case NVS_FR_TEXCOORD1: + case NVS_FR_TEXCOORD2: + case NVS_FR_TEXCOORD3: + case NVS_FR_TEXCOORD4: + case NVS_FR_TEXCOORD5: + case NVS_FR_TEXCOORD6: + case NVS_FR_TEXCOORD7: + { + int unit = result - NVS_FR_TEXCOORD0; + (*out_reg) |= (NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_TEX0 << unit); + return NV40_VP_INST_DEST_TC(unit); + } + default: + WARN_ONCE("unknown vp output %d\n", result); + return NV40_VP_INST_DEST_POS; + } +} + static void NV40VPSetResult(nvsFunc *shader, nvsRegister * dest, unsigned int mask, int slot) @@ -78,29 +168,14 @@ NV40VPSetResult(nvsFunc *shader, nvsRegister * dest, unsigned int mask, if (mask & SMASK_W) hwmask |= (1 << 0); if (dest->file == NVS_FILE_RESULT) { + unsigned int valid_mask; int hwidx; - switch (dest->index) { - case NVS_FR_POSITION : hwidx = NV40_VP_INST_DEST_POS; break; - case NVS_FR_COL0 : hwidx = NV40_VP_INST_DEST_COL0; break; - case NVS_FR_COL1 : hwidx = NV40_VP_INST_DEST_COL1; break; - case NVS_FR_BFC0 : hwidx = NV40_VP_INST_DEST_BFC0; break; - case NVS_FR_BFC1 : hwidx = NV40_VP_INST_DEST_BFC1; break; - case NVS_FR_FOGCOORD : hwidx = NV40_VP_INST_DEST_FOGC; break; - case NVS_FR_POINTSZ : hwidx = NV40_VP_INST_DEST_PSZ; break; - case NVS_FR_TEXCOORD0: hwidx = NV40_VP_INST_DEST_TC(0); break; - case NVS_FR_TEXCOORD1: hwidx = NV40_VP_INST_DEST_TC(1); break; - case NVS_FR_TEXCOORD2: hwidx = NV40_VP_INST_DEST_TC(2); break; - case NVS_FR_TEXCOORD3: hwidx = NV40_VP_INST_DEST_TC(3); break; - case NVS_FR_TEXCOORD4: hwidx = NV40_VP_INST_DEST_TC(4); break; - case NVS_FR_TEXCOORD5: hwidx = NV40_VP_INST_DEST_TC(5); break; - case NVS_FR_TEXCOORD6: hwidx = NV40_VP_INST_DEST_TC(6); break; - case NVS_FR_TEXCOORD7: hwidx = NV40_VP_INST_DEST_TC(7); break; - default: - WARN_ONCE("unknown vtxprog output %d\n", dest->index); - hwidx = 0; - break; - } + hwidx = NV40VPTranslateResultReg(shader, dest->index, &valid_mask); + if (hwmask & ~valid_mask) + WARN_ONCE("writing invalid components of result reg\n"); + hwmask &= valid_mask; + shader->inst[3] &= ~NV40_VP_INST_DEST_MASK; shader->inst[3] |= (hwidx << NV40_VP_INST_DEST_SHIFT); @@ -174,6 +249,7 @@ NV40VPSetSource(nvsFunc *shader, nvsRegister * src, int pos) shader->inst[1] &= ~NV40_VP_INST_INPUT_SRC_MASK; shader->inst[1] |= (src->index << NV40_VP_INST_INPUT_SRC_SHIFT); + shader->card_priv->NV30VP.vp_in_reg |= (1 << src->index); if (src->indexed) { shader->inst[0] |= NV40_VP_INST_INDEX_INPUT; if (src->addr_reg) -- cgit v1.2.3 From 60c28739aa4afe543e0293c15a7aaf84ec2183ea Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 23 Jan 2007 16:25:25 +1100 Subject: nouveau: DPH and CMP for NV40 which doesn't do it natively. --- src/mesa/drivers/dri/nouveau/nouveau_shader_0.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c index 3e542ea9c0..28c6ad803b 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -594,6 +594,30 @@ pass0_emulate_instruction(nouveauShader *nvs, ARITH(NVS_OP_MAX, dest, mask, sat, src[0], nvsNegate(src[0]), nvr_unused); break; + case OPCODE_CMP: + /*XXX: this will clobber CC0... */ + ARITH (NVS_OP_MOV, dest, mask, sat, + src[2], nvr_unused, nvr_unused); + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + ARITHu(NVS_OP_MOV, temp, SMASK_ALL, 0, + src[0], nvr_unused, nvr_unused); + nvsinst->cond_update = 1; + nvsinst->cond_reg = 0; + ARITH (NVS_OP_MOV, dest, mask, sat, + src[1], nvr_unused, nvr_unused); + nvsinst->cond = COND_LT; + nvsinst->cond_reg = 0; + nvsinst->cond_test = 1; + break; + case OPCODE_DPH: + pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); + ARITHu(NVS_OP_DP3, temp, SMASK_X, 0, + src[0], src[1], nvr_unused); + ARITH (NVS_OP_ADD, dest, mask, sat, + nvsSwizzle(temp, X, X, X, X), + nvsSwizzle(src[1], W, W, W, W), + nvr_unused); + break; case OPCODE_KIL: /* This is only in ARB shaders, so we don't have to worry * about clobbering a CC reg as they aren't supported anyway. -- cgit v1.2.3 From fe9fef2cec2f9ed13370612a9a58df04b0075f15 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 23 Jan 2007 08:57:38 +0100 Subject: i915tex: Fix randr resizing. Rotation still broken. --- src/mesa/drivers/dri/i915tex/intel_context.c | 22 ++++++++++++++++++++-- src/mesa/drivers/dri/i915tex/intel_context.h | 9 +++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c index c77d365360..c7ab621919 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.c +++ b/src/mesa/drivers/dri/i915tex/intel_context.c @@ -357,6 +357,10 @@ intelInitContext(struct intel_context *intel, intel->driScreen = sPriv; intel->sarea = saPriv; + intel->width = intelScreen->width; + intel->height = intelScreen->height; + intel->current_rotation = intelScreen->current_rotation; + if (!lockMutexInit) { lockMutexInit = GL_TRUE; _glthread_INIT_MUTEX(lockMutex); @@ -635,12 +639,22 @@ intelContendedLock(struct intel_context *intel, GLuint flags) sarea->rotation != intelScreen->current_rotation) { intelUpdateScreenRotation(sPriv, sarea); + } + + if (sarea->width != intel->width || + sarea->height != intel->height || + sarea->rotation != intel->current_rotation) { - /* + /* + * FIXME: Really only need to do this when drawing to a + * common back- or front buffer. + */ + + /* * This will drop the outstanding batchbuffer on the floor - * FIXME: This should be done for all contexts? */ + driBOUnmap(intel->batch->buffer); intel_batchbuffer_reset(intel->batch); /* lose all primitives */ @@ -653,6 +667,10 @@ intelContendedLock(struct intel_context *intel, GLuint flags) /* force window update */ intel->lastStamp = 0; + + intel->width = sarea->width; + intel->height = sarea->height; + intel->current_rotation = sarea->rotation; } diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h index 7654e4ecd5..96b911501f 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.h +++ b/src/mesa/drivers/dri/i915tex/intel_context.h @@ -286,6 +286,15 @@ struct intel_context GLuint swap_missed_count; GLuint swap_scheduled; + + /* Rotation. Need to match that of the + * current screen. + */ + + int width; + int height; + int current_rotation; + }; /* These are functions now: -- cgit v1.2.3 From d46093b8d56f6d89b341d7437c5185ca6be597af Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 23 Jan 2007 09:04:58 +0100 Subject: i915tex: Relocation fixes: Increase the number of allowed relocations per batchbuffer. Fix an assert to avoid an array index overflow. (Reported by Steve Wilkins) --- src/mesa/drivers/dri/i915tex/intel_batchbuffer.c | 2 +- src/mesa/drivers/dri/i915tex/intel_batchbuffer.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c index be2750d041..c92b83bcb3 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c @@ -311,7 +311,7 @@ intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch, struct _DriBufferObject *buffer, GLuint flags, GLuint mask, GLuint delta) { - assert(batch->nr_relocs <= MAX_RELOCS); + assert(batch->nr_relocs < MAX_RELOCS); driBOAddListItem(&batch->list, buffer, flags, mask); diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h index a83dbf423d..59261f7274 100644 --- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h +++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.h @@ -9,7 +9,7 @@ struct intel_context; #define BATCH_SZ 16384 #define BATCH_RESERVED 16 -#define MAX_RELOCS 100 +#define MAX_RELOCS 400 #define INTEL_BATCH_NO_CLIPRECTS 0x1 #define INTEL_BATCH_CLIPRECTS 0x2 -- cgit v1.2.3 From bdc5394d22d7bc1215c9a38f735a419c9063ab05 Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Wed, 24 Jan 2007 15:47:15 +0800 Subject: 965 ARB_Occlusion_query fix --- src/mesa/drivers/dri/i965/intel_context.c | 27 ++++++++++++++++----------- src/mesa/drivers/dri/i965/intel_context.h | 2 +- src/mesa/drivers/dri/i965/intel_screen.c | 6 ++---- 3 files changed, 19 insertions(+), 16 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 459ed109ed..388600dbbe 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -184,9 +184,17 @@ const struct dri_extension card_extensions[] = { NULL, NULL } }; -static const struct dri_extension arb_oc_extension = +const struct dri_extension arb_oc_extension = { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions}; +void intelInitExtensions(GLcontext *ctx, GLboolean enable_imaging) +{ + struct intel_context *intel = ctx?intel_context(ctx):NULL; + driInitExtensions(ctx, card_extensions, enable_imaging); + if (!ctx || intel->intelScreen->drmMinor >= 8) + driInitSingleExtension (ctx, &arb_oc_extension); +} + static const struct dri_debug_control debug_control[] = { { "fall", DEBUG_FALLBACKS }, @@ -248,28 +256,29 @@ static void intelBeginQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) { struct intel_context *intel = intel_context( ctx ); - GLuint64EXT tmp = 0; drmI830MMIO io = { .read_write = MMIO_WRITE, .reg = MMIO_REGS_PS_DEPTH_COUNT, - .data = &tmp + .data = &q->Result }; intel->stats_wm = GL_TRUE; intelFinish(&intel->ctx); - drmCommandWrite(intel->driFd, DRM_I830_MMIO, &io, sizeof(io)); + drmCommandRead(intel->driFd, DRM_I830_MMIO, &io, sizeof(io)); } static void intelEndQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) { struct intel_context *intel = intel_context( ctx ); + GLuint64EXT tmp; drmI830MMIO io = { .read_write = MMIO_READ, .reg = MMIO_REGS_PS_DEPTH_COUNT, - .data = &q->Result + .data = &tmp }; intelFinish(&intel->ctx); drmCommandRead(intel->driFd, DRM_I830_MMIO, &io, sizeof(io)); + q->Result = tmp - q->Result; q->Ready = GL_TRUE; intel->stats_wm = GL_FALSE; } @@ -409,12 +418,7 @@ GLboolean intelInitContext( struct intel_context *intel, _mesa_printf("IRQs not active. Exiting\n"); exit(1); } - - driInitExtensions( ctx, card_extensions, - GL_TRUE ); - - if (intel->intelScreen->drmMinor >= 8) - driInitSingleExtension (ctx, &arb_oc_extension); + intelInitExtensions(ctx, GL_TRUE); INTEL_DEBUG = driParseDebugString( getenv( "INTEL_DEBUG" ), debug_control ); @@ -693,3 +697,4 @@ void UNLOCK_HARDWARE( struct intel_context *intel ) _glthread_UNLOCK_MUTEX(lockMutex); } + diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h index fe7ee382a1..d51536c3fe 100644 --- a/src/mesa/drivers/dri/i965/intel_context.h +++ b/src/mesa/drivers/dri/i965/intel_context.h @@ -500,6 +500,7 @@ void intelBitmap(GLcontext * ctx, const struct gl_pixelstore_attrib *unpack, const GLubyte * pixels); +void intelInitExtensions(GLcontext *ctx, GLboolean enable_imaging); #define _NEW_WINDOW_POS 0x40000000 @@ -522,6 +523,5 @@ static inline struct intel_texture_image *intel_texture_image( struct gl_texture return (struct intel_texture_image *)img; } - #endif diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c index 8269deba66..08f0bb340f 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.c +++ b/src/mesa/drivers/dri/i965/intel_screen.c @@ -38,6 +38,7 @@ #include "intel_screen.h" +#include "intel_context.h" #include "intel_tex.h" #include "intel_span.h" #include "intel_ioctl.h" @@ -61,8 +62,6 @@ const GLuint __driNConfigOptions = 4; static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; #endif /*USE_NEW_INTERFACE*/ -extern const struct dri_extension card_extensions[]; - /** * Map all the memory regions described by the screen. * \return GL_TRUE if success, GL_FALSE if error. @@ -687,7 +686,6 @@ void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIsc (dri_priv->cpp == 2) ? 16 : 24, (dri_priv->cpp == 2) ? 0 : 8, GL_TRUE ); - /* Calling driInitExtensions here, with a NULL context pointer, does not actually * enable the extensions. It just makes sure that all the dispatch offsets for all * the extensions that *might* be enables are known. This is needed because the @@ -696,7 +694,7 @@ void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIsc * * Hello chicken. Hello egg. How are you two today? */ - driInitExtensions( NULL, card_extensions, GL_FALSE ); + intelInitExtensions(NULL, GL_FALSE); } return (void *) psp; -- cgit v1.2.3 From 844e5610de6ffe6966072d120b50db541ea85104 Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Wed, 24 Jan 2007 16:07:43 +0800 Subject: 965 glxswapcontrol fix --- src/mesa/drivers/dri/i965/intel_context.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 388600dbbe..f7ab7d3b7d 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -61,6 +61,7 @@ #include "bufmgr.h" #include "utils.h" +#include "vblank.h" #ifndef INTEL_DEBUG int INTEL_DEBUG = (0); #endif @@ -336,6 +337,11 @@ GLboolean intelInitContext( struct intel_context *intel, intel->driScreen = sPriv; intel->sarea = saPriv; + driParseConfigFiles (&intel->optionCache, &intelScreen->optionCache, + intel->driScreen->myNum, "i965"); + + intel->vblank_flags = (intel->intelScreen->irq_active != 0) + ? driGetDefaultVBlankFlags(&intel->optionCache) : VBLANK_FLAG_NO_IRQ; ctx->Const.MaxTextureMaxAnisotropy = 2.0; @@ -563,6 +569,9 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv, if ( intel->driDrawable != driDrawPriv ) { /* Shouldn't the readbuffer be stored also? */ + driDrawableInitVBlank( driDrawPriv, intel->vblank_flags, + &intel->vbl_seq ); + intel->driDrawable = driDrawPriv; intelWindowMoved( intel ); } -- cgit v1.2.3 From 42bd32dad7f2bd9b4c4df8a7394328d31748f1f5 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 25 Jan 2007 11:56:45 +1100 Subject: nouveau: some extra debug output --- src/mesa/drivers/dri/nouveau/nouveau_screen.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index 781ba0113f..2d14a9d84d 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -339,8 +339,11 @@ void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIsc } // temporary lock step versioning - if (drm_expected.patch!=drm_version->patch) + if (drm_expected.patch!=drm_version->patch) { + __driUtilMessage("%s: wrong DRM version, expected %d, got %d\n", + drm_expected.patch, drm_version->patch); return NULL; + } psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, ddx_version, dri_version, drm_version, -- cgit v1.2.3 From 2d7687865e8831e365756f1270c03ee70298ba4c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 25 Jan 2007 12:08:49 +1100 Subject: nouveau: and here's the "oops, I suck" commit :) --- src/mesa/drivers/dri/nouveau/nouveau_screen.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index 2d14a9d84d..881b20149f 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -341,6 +341,7 @@ void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIsc // temporary lock step versioning if (drm_expected.patch!=drm_version->patch) { __driUtilMessage("%s: wrong DRM version, expected %d, got %d\n", + __func__, drm_expected.patch, drm_version->patch); return NULL; } -- cgit v1.2.3 From 86996dfe32fccd5777dd0e410b5dbe964fb206d1 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 25 Jan 2007 13:40:51 +1100 Subject: nouveau: add result scaling to shader backend, use it in RSQ emul for NV40. --- src/mesa/drivers/dri/nouveau/nouveau_shader.c | 2 +- src/mesa/drivers/dri/nouveau/nouveau_shader.h | 13 ++++++++++++ src/mesa/drivers/dri/nouveau/nouveau_shader_0.c | 17 +++------------- src/mesa/drivers/dri/nouveau/nouveau_shader_2.c | 4 ++++ src/mesa/drivers/dri/nouveau/nv40_fragprog.c | 27 +++++++++++++++++++++++++ src/mesa/drivers/dri/nouveau/nv40_shader.h | 4 ++-- 6 files changed, 50 insertions(+), 17 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.c b/src/mesa/drivers/dri/nouveau/nouveau_shader.c index f911347d62..cdb79fca1e 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.c @@ -179,7 +179,7 @@ nvsBuildTextShader(GLcontext *ctx, GLenum target, const char *text) strlen(text), &nvs->mesa.vp); } else if (target == GL_FRAGMENT_PROGRAM_ARB) { - _mesa_init_fragment_program(ctx, &nvs->mesa.fp, GL_VERTEX_PROGRAM_ARB, 0); + _mesa_init_fragment_program(ctx, &nvs->mesa.fp, GL_FRAGMENT_PROGRAM_ARB, 0); _mesa_parse_arb_fragment_program(ctx, GL_FRAGMENT_PROGRAM_ARB, text, diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h index 8b4be9dfe7..7329ccd9ea 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -194,6 +194,16 @@ typedef enum { NVS_TEX_TARGET_UNKNOWN = 0 } nvsTexTarget; +typedef enum { + NVS_SCALE_1X = 0, + NVS_SCALE_2X = 1, + NVS_SCALE_4X = 2, + NVS_SCALE_8X = 3, + NVS_SCALE_INV_2X = 5, + NVS_SCALE_INV_4X = 6, + NVS_SCALE_INV_8X = 7, +} nvsScale; + /* Arith/TEX instructions */ typedef struct nvs_instruction { nvsFragmentHeader header; @@ -203,6 +213,7 @@ typedef struct nvs_instruction { nvsRegister dest; unsigned int mask; + nvsScale dest_scale; nvsRegister src[3]; @@ -307,6 +318,7 @@ struct _nvsFunc { void (*InitInstruction) (nvsFunc *); int (*SupportsOpcode) (nvsFunc *, nvsOpcode); + int (*SupportsResultScale) (nvsFunc *, nvsScale); void (*SetOpcode) (nvsFunc *, unsigned int opcode, int slot); void (*SetCCUpdate) (nvsFunc *); @@ -314,6 +326,7 @@ struct _nvsFunc { nvsSwzComp *swizzle); void (*SetResult) (nvsFunc *, nvsRegister *, unsigned int mask, int slot); + void (*SetResultScale) (nvsFunc *, nvsScale); void (*SetSource) (nvsFunc *, nvsRegister *, int pos); void (*SetTexImageUnit) (nvsFunc *, int unit); void (*SetSaturate) (nvsFunc *); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c index 28c6ad803b..3bcc2ba755 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -402,6 +402,7 @@ pass0_emit(nouveauShader *nvs, nvsFragmentHeader *parent, int fpos, sif->saturate = saturate; sif->dest = dst; sif->mask = mask; + sif->dest_scale = NVS_SCALE_1X; sif->src[0] = src0; sif->src[1] = src1; sif->src[2] = src2; @@ -667,25 +668,13 @@ pass0_emulate_instruction(nouveauShader *nvs, } break; case OPCODE_RSQ: - if (rec->const_half.file != NVS_FILE_CONST) { - GLfloat const_half[4] = { 0.5, 0.0, 0.0, 0.0 }; - pass0_make_reg(nvs, &rec->const_half, NVS_FILE_CONST, - _mesa_add_unnamed_constant( - nvs->mesa.vp.Base.Parameters, - const_half, 4)); - COPY_4V(nvs->params[rec->const_half.index].val, - const_half); - } pass0_make_reg(nvs, &temp, NVS_FILE_TEMP, -1); ARITHu(NVS_OP_LG2, temp, SMASK_X, 0, nvsAbs(nvsSwizzle(src[0], X, X, X, X)), nvr_unused, nvr_unused); - ARITHu(NVS_OP_MUL, temp, SMASK_X, 0, - nvsSwizzle(temp, X, X, X, X), - nvsNegate(rec->const_half), - nvr_unused); + nvsinst->dest_scale = NVS_SCALE_INV_2X; ARITH (NVS_OP_EX2, dest, mask, sat, - nvsSwizzle(temp, X, X, X, X), + nvsNegate(nvsSwizzle(temp, X, X, X, X)), nvr_unused, nvr_unused); break; case OPCODE_SCS: diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c index c106fd2d94..b043f877e4 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c @@ -135,6 +135,10 @@ pass2_add_instruction(nvsPtr nvs, nvsInstruction *inst, reg = pass2_mangle_reg(nvs, inst, inst->dest); shader->SetResult(shader, ®, inst->mask, slot); + + if (inst->dest_scale != NVS_SCALE_1X) { + shader->SetResultScale(shader, inst->dest_scale); + } } static int diff --git a/src/mesa/drivers/dri/nouveau/nv40_fragprog.c b/src/mesa/drivers/dri/nouveau/nv40_fragprog.c index 8bca6ae938..3e4ae0496e 100644 --- a/src/mesa/drivers/dri/nouveau/nv40_fragprog.c +++ b/src/mesa/drivers/dri/nouveau/nv40_fragprog.c @@ -11,6 +11,30 @@ struct _op_xlat NVFP_TX_BOP[64]; * - These extend the NV30 routines, which are almost identical. NV40 * just has branching hacked into the instruction set. */ +static int +NV40FPSupportsResultScale(nvsFunc *shader, nvsScale scale) +{ + switch (scale) { + case NVS_SCALE_1X: + case NVS_SCALE_2X: + case NVS_SCALE_4X: + case NVS_SCALE_8X: + case NVS_SCALE_INV_2X: + case NVS_SCALE_INV_4X: + case NVS_SCALE_INV_8X: + return 1; + default: + return 0; + } +} + +static void +NV40FPSetResultScale(nvsFunc *shader, nvsScale scale) +{ + shader->inst[2] &= ~NV40_FP_OP_DST_SCALE_MASK; + shader->inst[2] |= ((unsigned int)scale << NV40_FP_OP_DST_SCALE_SHIFT); +} + static void NV40FPSetBranchTarget(nvsFunc *shader, int addr) { @@ -179,6 +203,9 @@ NV40FPInitShaderFuncs(nvsFunc * shader) MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_REP , NVS_OP_REP , -1, -1, -1); MOD_OPCODE(NVFP_TX_BOP, NV40_FP_OP_BRA_OPCODE_RET , NVS_OP_RET , -1, -1, -1); + shader->SupportsResultScale = NV40FPSupportsResultScale; + shader->SetResultScale = NV40FPSetResultScale; + /* fragment.facing */ shader->GetSourceID = NV40FPGetSourceID; diff --git a/src/mesa/drivers/dri/nouveau/nv40_shader.h b/src/mesa/drivers/dri/nouveau/nv40_shader.h index 2a2b5639b6..584f4c23e0 100644 --- a/src/mesa/drivers/dri/nouveau/nv40_shader.h +++ b/src/mesa/drivers/dri/nouveau/nv40_shader.h @@ -399,8 +399,8 @@ /* high order bits of SRC1 */ #define NV40_FP_OP_OPCODE_IS_BRANCH (1<<31) -#define NV40_FP_OP_SRC_SCALE_SHIFT 28 -#define NV40_FP_OP_SRC_SCALE_MASK (3 << 28) +#define NV40_FP_OP_DST_SCALE_SHIFT 28 +#define NV40_FP_OP_DST_SCALE_MASK (3 << 28) /* SRC1 LOOP */ #define NV40_FP_OP_LOOP_INCR_SHIFT 19 -- cgit v1.2.3 From d5db167c2cf9243c3153efb29582df72d819e7ac Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 25 Jan 2007 15:12:49 +1100 Subject: nouveau: unbreak NOUVEAU_RING_DEBUG --- src/mesa/drivers/dri/nouveau/nouveau_sync.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.c b/src/mesa/drivers/dri/nouveau/nouveau_sync.c index 0bf20e723b..e7bc4fcd5e 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.c @@ -14,6 +14,10 @@ nouveau_notifier_new(GLcontext *ctx, GLuint handle) nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); nouveau_notifier *notifier; +#ifdef NOUVEAU_RING_DEBUG + return NULL; +#endif + notifier = CALLOC_STRUCT(nouveau_notifier_t); if (!notifier) return NULL; @@ -53,6 +57,10 @@ nouveau_notifier_reset(nouveau_notifier *notifier) { volatile GLuint *n = notifier->mem->map; +#ifdef NOUVEAU_RING_DEBUG + return; +#endif + n[NV_NOTIFY_TIME_0 /4] = 0x00000000; n[NV_NOTIFY_TIME_1 /4] = 0x00000000; n[NV_NOTIFY_RETURN_VALUE/4] = 0x00000000; @@ -67,6 +75,10 @@ nouveau_notifier_wait_status(nouveau_notifier *notifier, GLuint status, volatile GLuint *n = notifier->mem->map; unsigned int time = 0; +#ifdef NOUVEAU_RING_DEBUG + return GL_TRUE; +#endif + while (time <= timeout) { if (n[NV_NOTIFY_STATE/4] & NV_NOTIFY_STATE_ERROR_CODE_MASK) { MESSAGE("Notifier returned error: 0x%04x\n", @@ -114,6 +126,10 @@ GLboolean nouveauSyncInitFuncs(GLcontext *ctx) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); +#ifdef NOUVEAU_RING_DEBUG + return GL_TRUE; +#endif + nmesa->syncNotifier = nouveau_notifier_new(ctx, NvSyncNotify); if (!nmesa->syncNotifier) { MESSAGE("Failed to create channel sync notifier\n"); -- cgit v1.2.3 From 6aa62ba43f64f617c608e52b63c7eaa7aae16fb4 Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Fri, 26 Jan 2007 07:04:15 +0800 Subject: ARB_Occlusion_query should support multiple query at same time --- src/mesa/drivers/dri/i965/intel_context.c | 6 +++--- src/mesa/drivers/dri/i965/intel_context.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index f7ab7d3b7d..3f8c2c0890 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -258,11 +258,11 @@ intelBeginQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) { struct intel_context *intel = intel_context( ctx ); drmI830MMIO io = { - .read_write = MMIO_WRITE, + .read_write = MMIO_READ, .reg = MMIO_REGS_PS_DEPTH_COUNT, .data = &q->Result }; - intel->stats_wm = GL_TRUE; + intel->stats_wm++; intelFinish(&intel->ctx); drmCommandRead(intel->driFd, DRM_I830_MMIO, &io, sizeof(io)); } @@ -281,7 +281,7 @@ intelEndQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) drmCommandRead(intel->driFd, DRM_I830_MMIO, &io, sizeof(io)); q->Result = tmp - q->Result; q->Ready = GL_TRUE; - intel->stats_wm = GL_FALSE; + intel->stats_wm--; } diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h index d51536c3fe..a0f392f935 100644 --- a/src/mesa/drivers/dri/i965/intel_context.h +++ b/src/mesa/drivers/dri/i965/intel_context.h @@ -177,7 +177,7 @@ struct intel_context GLuint second_last_swap_fence; GLboolean aub_wrap; - GLboolean stats_wm; + GLuint stats_wm; struct intel_batchbuffer *batch; -- cgit v1.2.3 From dbb54b234cd919b8ef7e36e0603ec69f3ed3fc7f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 20 Jan 2007 17:59:08 -0800 Subject: Remove dead code causing a warning. --- src/mesa/drivers/dri/i965/intel_context.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 3f8c2c0890..63809e0aa8 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -87,11 +87,6 @@ int INTEL_DEBUG = (0); int VERBOSE = 0; #endif -#if DEBUG_LOCKING -char *prevLockFile; -int prevLockLine; -#endif - /*************************************** * Mesa's Driver Functions ***************************************/ -- cgit v1.2.3 From 869b8ad499717eda4a1be04de4e516134123402c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 20 Jan 2007 18:06:38 -0800 Subject: Add _mesa_ffsll() for compatibility on OSes without ffsll(), and use it. --- src/mesa/drivers/dri/i965/brw_draw_upload.c | 2 +- src/mesa/main/imports.c | 21 +++++++++++++++++++++ src/mesa/main/imports.h | 3 +++ 3 files changed, 25 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 57ee294f0c..08741ad90f 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -414,7 +414,7 @@ GLboolean brw_upload_vertices( struct brw_context *brw, */ while (tmp) { - GLuint i = ffsll(tmp)-1; + GLuint i = _mesa_ffsll(tmp)-1; struct brw_vertex_element *input = &brw->vb.inputs[i]; tmp &= ~((GLuint64EXT)1<> 32); + if (bit != 0) + return 32 + bit; + + return 0; +#endif +} /** * Return number of bits set in given GLuint. diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h index 19a9478f76..d9885dbeec 100644 --- a/src/mesa/main/imports.h +++ b/src/mesa/main/imports.h @@ -688,6 +688,9 @@ _mesa_pow(double x, double y); extern int _mesa_ffs(int i); +extern int +_mesa_ffsll(long long i); + extern unsigned int _mesa_bitcount(unsigned int n); -- cgit v1.2.3 From 5a3d9853958993174f13c8cff6bcf11993a48f65 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 20 Jan 2007 18:09:32 -0800 Subject: Bug #9604: Fix a static buffer allocation failure. The pool that the static buffer got allocated from was sized by pitch * height, but the buffer generated from it had its size aligned to a tile boundary, so allocation failed if pitch * height wasn't aligned. However, the 2d driver ensures that the size ends at a tile boundary, so just pass the 2d driver's buffer size rather than calculating it. --- src/mesa/drivers/dri/i965/intel_context.c | 6 ++++-- src/mesa/drivers/dri/i965/intel_regions.c | 2 +- src/mesa/drivers/dri/i965/intel_regions.h | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 63809e0aa8..4486a28adc 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -446,8 +446,8 @@ GLboolean intelInitContext( struct intel_context *intel, intelScreen->cpp, intelScreen->front.pitch / intelScreen->cpp, intelScreen->height, - intelScreen->front.tiled != 0); /* 0: LINEAR */ - + intelScreen->front.size, + intelScreen->front.tiled != 0); intel->back_region = intel_region_create_static(intel, @@ -457,6 +457,7 @@ GLboolean intelInitContext( struct intel_context *intel, intelScreen->cpp, intelScreen->back.pitch / intelScreen->cpp, intelScreen->height, + intelScreen->back.size, intelScreen->back.tiled != 0); /* Still assuming front.cpp == depth.cpp @@ -473,6 +474,7 @@ GLboolean intelInitContext( struct intel_context *intel, intelScreen->cpp, intelScreen->depth.pitch / intelScreen->cpp, intelScreen->height, + intelScreen->depth.size, intelScreen->depth.tiled != 0); intel_bufferobj_init( intel ); diff --git a/src/mesa/drivers/dri/i965/intel_regions.c b/src/mesa/drivers/dri/i965/intel_regions.c index 398b0a0a3b..835ecdd725 100644 --- a/src/mesa/drivers/dri/i965/intel_regions.c +++ b/src/mesa/drivers/dri/i965/intel_regions.c @@ -122,10 +122,10 @@ struct intel_region *intel_region_create_static( struct intel_context *intel, GLuint cpp, GLuint pitch, GLuint height, + GLuint size, GLboolean tiled ) { struct intel_region *region = calloc(sizeof(*region), 1); - GLuint size = cpp * pitch * height; GLint pool; DBG("%s\n", __FUNCTION__); diff --git a/src/mesa/drivers/dri/i965/intel_regions.h b/src/mesa/drivers/dri/i965/intel_regions.h index 2413f0de33..d2235f1275 100644 --- a/src/mesa/drivers/dri/i965/intel_regions.h +++ b/src/mesa/drivers/dri/i965/intel_regions.h @@ -78,6 +78,7 @@ struct intel_region *intel_region_create_static( struct intel_context *intel, GLuint cpp, GLuint pitch, GLuint height, + GLuint size, GLboolean tiled ); /* Map/unmap regions. This is refcounted also: -- cgit v1.2.3 From 0931e21eb62af217564f450e9e56bc7b6f0e15c7 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sat, 27 Jan 2007 03:03:25 +0100 Subject: nouveau: more work on nv04, this time buffer format/pitches/... --- src/mesa/drivers/dri/nouveau/nouveau_object.c | 2 ++ src/mesa/drivers/dri/nouveau/nouveau_object.h | 2 ++ src/mesa/drivers/dri/nouveau/nv04_state.c | 45 +++++++++++++++++++++++++-- 3 files changed, 47 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.c b/src/mesa/drivers/dri/nouveau/nouveau_object.c index 26086e16e4..302009c8b1 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.c @@ -70,6 +70,8 @@ void nouveauObjectInit(nouveauContextPtr nmesa) } else { nouveauCreateContextObject(nmesa, NvCtxSurf2D, NV04_CONTEXT_SURFACES_2D, 0, 0, 0, 0); + nouveauCreateContextObject(nmesa, NvCtxSurf3D, NV04_CONTEXT_SURFACES_3D, + 0, 0, 0, 0); nouveauCreateContextObject(nmesa, NvImageBlit, NV_IMAGE_BLIT, NV_DMA_CONTEXT_FLAGS_PATCH_SRCCOPY, 0, 0, 0); } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.h b/src/mesa/drivers/dri/nouveau/nouveau_object.h index b1ff5a5d0d..e154e0acff 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.h @@ -12,6 +12,7 @@ enum DMAObjects { NvCtxSurf2D = 0x80000020, NvImageBlit = 0x80000021, NvMemFormat = 0x80000022, + NvCtxSurf3D = 0x80000023, NvDmaFB = 0xD0FB0001, NvDmaAGP = 0xD0AA0001, NvSyncNotify = 0xD0000001 @@ -21,6 +22,7 @@ enum DMASubchannel { NvSubCtxSurf2D = 0, NvSubImageBlit = 1, NvSubMemFormat = 2, + NvSubCtxSurf3D = 3, NvSub3D = 7, }; diff --git a/src/mesa/drivers/dri/nouveau/nv04_state.c b/src/mesa/drivers/dri/nouveau/nv04_state.c index 83ad8ae432..ec4cd40d87 100644 --- a/src/mesa/drivers/dri/nouveau/nv04_state.c +++ b/src/mesa/drivers/dri/nouveau/nv04_state.c @@ -267,6 +267,7 @@ static void nv04Enable(GLcontext *ctx, GLenum cap, GLboolean state) break; case GL_FOG: nv04_emit_blend(ctx); + nv04_emit_fog_color(ctx); break; // case GL_HISTOGRAM: // case GL_INDEX_LOGIC_OP: @@ -436,14 +437,54 @@ static void nv04WindowMoved(nouveauContextPtr nmesa) /* Initialise any card-specific non-GL related state */ static GLboolean nv04InitCard(nouveauContextPtr nmesa) { + nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); + nouveauObjectOnSubchannel(nmesa, NvSubCtxSurf3D, NvCtxSurf3D); + + BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_DMA_NOTIFY, 3); + OUT_RING(NvDmaFB); + OUT_RING(NvDmaFB); + OUT_RING(NvDmaFB); + BEGIN_RING_SIZE(NvSub3D, NV04_DX5_TEXTURED_TRIANGLE_SURFACE, 1); + OUT_RING(NvCtxSurf3D); return GL_TRUE; } /* Update buffer offset/pitch/format */ static GLboolean nv04BindBuffers(nouveauContextPtr nmesa, int num_color, - nouveau_renderbuffer **color, - nouveau_renderbuffer *depth) + nouveau_renderbuffer **color, + nouveau_renderbuffer *depth) { + GLuint x, y, w, h; + + w = color[0]->mesa.Width; + h = color[0]->mesa.Height; + x = nmesa->drawX; + y = nmesa->drawY; + + /* FIXME pitches have to be aligned ! */ + BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_PITCH, 2); + OUT_RING(color[0]->pitch|(depth->pitch<<16)); + OUT_RING(color[0]->offset); + + if (depth) { + BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1); + OUT_RING(depth->offset); + } + + BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_CLIP_HORIZONTAL, 2); + OUT_RING((w<<16)|x); + OUT_RING((h<<16)|y); + + /* FIXME not sure... */ + BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_CLIP_SIZE, 1); + OUT_RING((h<<16)|w); + + BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_FORMAT, 1); + if (color[0]->mesa._ActualFormat == GL_RGBA8) + OUT_RING(108/*A8R8G8B8*/); + else + OUT_RING(103/*R5G6B5*/); + return GL_TRUE; } -- cgit v1.2.3 From c00169fd25336c1425c5457fcd925ba10464f3cf Mon Sep 17 00:00:00 2001 From: George Sapountzis Date: Sat, 27 Jan 2007 08:16:10 +0200 Subject: Bug 9628: no entry for GetVertexAttribPointerv This is because (in glX_API.xml) GetVertexAttribPointerv is aliased to GetVertexAttribPointervARB which is then aliased to GetVertexAttribPointervNV. Make GetVertexAttribPointerv alias GetVertexAttribPointervNV directly. Patch by Ian Romanick and regenerate. --- src/mesa/drivers/dri/common/extension_helper.h | 22 ++++++++-------------- src/mesa/glapi/gl_API.xml | 2 +- src/mesa/glapi/glapitemp.h | 6 ++++++ src/mesa/glapi/glprocs.h | 12 +++++++----- src/mesa/main/enums.c | 2 +- src/mesa/sparc/glapi_sparc.S | 1 + src/mesa/x86-64/glapi_x86-64.S | 1 + src/mesa/x86/glapi_x86.S | 1 + 8 files changed, 26 insertions(+), 21 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/common/extension_helper.h b/src/mesa/drivers/dri/common/extension_helper.h index d6d51cdd16..c798496425 100644 --- a/src/mesa/drivers/dri/common/extension_helper.h +++ b/src/mesa/drivers/dri/common/extension_helper.h @@ -2466,10 +2466,10 @@ static const char MultiTexCoord4ivARB_names[] = ""; #endif -#if defined(need_GL_VERSION_2_0) -static const char GetVertexAttribPointervARB_names[] = - "iip\0" /* Parameter signature */ - "glGetVertexAttribPointerv\0" +#if defined(need_GL_EXT_gpu_program_parameters) +static const char ProgramLocalParameters4fvEXT_names[] = + "iiip\0" /* Parameter signature */ + "glProgramLocalParameters4fvEXT\0" ""; #endif @@ -3152,13 +3152,6 @@ static const char VertexAttribPointerNV_names[] = ""; #endif -#if defined(need_GL_EXT_gpu_program_parameters) -static const char ProgramLocalParameters4fvEXT_names[] = - "iiip\0" /* Parameter signature */ - "glProgramLocalParameters4fvEXT\0" - ""; -#endif - #if defined(need_GL_EXT_framebuffer_object) static const char GetFramebufferAttachmentParameterivEXT_names[] = "iiip\0" /* Parameter signature */ @@ -3781,9 +3774,10 @@ static const char ReplacementCodeuiColor3fVertex3fSUN_names[] = ""; #endif -#if defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program) +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program) static const char GetVertexAttribPointervNV_names[] = "iip\0" /* Parameter signature */ + "glGetVertexAttribPointerv\0" "glGetVertexAttribPointervARB\0" "glGetVertexAttribPointervNV\0" ""; @@ -5343,8 +5337,8 @@ static const struct dri_extension_function GL_EXT_framebuffer_object_functions[] #if defined(need_GL_EXT_gpu_program_parameters) static const struct dri_extension_function GL_EXT_gpu_program_parameters_functions[] = { - { ProgramEnvParameters4fvEXT_names, ProgramEnvParameters4fvEXT_remap_index, -1 }, { ProgramLocalParameters4fvEXT_names, ProgramLocalParameters4fvEXT_remap_index, -1 }, + { ProgramEnvParameters4fvEXT_names, ProgramEnvParameters4fvEXT_remap_index, -1 }, { NULL, 0, 0 } }; #endif @@ -6263,7 +6257,6 @@ static const struct dri_extension_function GL_VERSION_2_0_functions[] = { { GetVertexAttribfvARB_names, GetVertexAttribfvARB_remap_index, -1 }, { GetAttribLocationARB_names, GetAttribLocationARB_remap_index, -1 }, { Uniform3ivARB_names, Uniform3ivARB_remap_index, -1 }, - { GetVertexAttribPointervARB_names, GetVertexAttribPointervARB_remap_index, -1 }, { VertexAttrib4sARB_names, VertexAttrib4sARB_remap_index, -1 }, { VertexAttrib2dvARB_names, VertexAttrib2dvARB_remap_index, -1 }, { VertexAttrib2fvARB_names, VertexAttrib2fvARB_remap_index, -1 }, @@ -6295,6 +6288,7 @@ static const struct dri_extension_function GL_VERSION_2_0_functions[] = { { Uniform4iARB_names, Uniform4iARB_remap_index, -1 }, { UseProgramObjectARB_names, UseProgramObjectARB_remap_index, -1 }, { DeleteProgram_names, DeleteProgram_remap_index, -1 }, + { GetVertexAttribPointervNV_names, GetVertexAttribPointervNV_remap_index, -1 }, { Uniform2iARB_names, Uniform2iARB_remap_index, -1 }, { VertexAttrib4dARB_names, VertexAttrib4dARB_remap_index, -1 }, { GetUniformLocationARB_names, GetUniformLocationARB_remap_index, -1 }, diff --git a/src/mesa/glapi/gl_API.xml b/src/mesa/glapi/gl_API.xml index 905c4a03a6..687dffbcac 100644 --- a/src/mesa/glapi/gl_API.xml +++ b/src/mesa/glapi/gl_API.xml @@ -5318,7 +5318,7 @@ - + diff --git a/src/mesa/glapi/glapitemp.h b/src/mesa/glapi/glapitemp.h index 340a4f6a04..f67611abb4 100644 --- a/src/mesa/glapi/glapitemp.h +++ b/src/mesa/glapi/glapitemp.h @@ -4865,6 +4865,11 @@ KEYWORD1 void KEYWORD2 NAME(GetTrackMatrixivNV)(GLenum target, GLuint address, G DISPATCH(GetTrackMatrixivNV, (target, address, pname, params), (F, "glGetTrackMatrixivNV(0x%x, %d, 0x%x, %p);\n", target, address, pname, (const void *) params)); } +KEYWORD1 void KEYWORD2 NAME(GetVertexAttribPointerv)(GLuint index, GLenum pname, GLvoid ** pointer) +{ + DISPATCH(GetVertexAttribPointervNV, (index, pname, params), (F, "glGetVertexAttribPointerv(%d, 0x%x, %p);\n", index, pname, (const void *) params)); +} + KEYWORD1 void KEYWORD2 NAME(GetVertexAttribPointervARB)(GLuint index, GLenum pname, GLvoid ** params) { DISPATCH(GetVertexAttribPointervNV, (index, pname, params), (F, "glGetVertexAttribPointervARB(%d, 0x%x, %p);\n", index, pname, (const void *) params)); @@ -6577,6 +6582,7 @@ static _glapi_proc UNUSED_TABLE_NAME[] = { TABLE_ENTRY(BindProgramARB), TABLE_ENTRY(DeleteProgramsARB), TABLE_ENTRY(GenProgramsARB), + TABLE_ENTRY(GetVertexAttribPointerv), TABLE_ENTRY(GetVertexAttribPointervARB), TABLE_ENTRY(IsProgramARB), TABLE_ENTRY(PointParameteri), diff --git a/src/mesa/glapi/glprocs.h b/src/mesa/glapi/glprocs.h index 905c65862d..190d9ed149 100644 --- a/src/mesa/glapi/glprocs.h +++ b/src/mesa/glapi/glprocs.h @@ -1086,6 +1086,7 @@ static const char gl_string_table[] = "glBindProgramARB\0" "glDeleteProgramsARB\0" "glGenProgramsARB\0" + "glGetVertexAttribPointerv\0" "glGetVertexAttribPointervARB\0" "glIsProgramARB\0" "glPointParameteri\0" @@ -2229,11 +2230,12 @@ static const glprocs_table_t static_functions[] = { NAME_FUNC_OFFSET(18432, glDeleteProgramsNV, glDeleteProgramsNV, NULL, _gloffset_DeleteProgramsNV), NAME_FUNC_OFFSET(18452, glGenProgramsNV, glGenProgramsNV, NULL, _gloffset_GenProgramsNV), NAME_FUNC_OFFSET(18469, glGetVertexAttribPointervNV, glGetVertexAttribPointervNV, NULL, _gloffset_GetVertexAttribPointervNV), - NAME_FUNC_OFFSET(18498, glIsProgramNV, glIsProgramNV, NULL, _gloffset_IsProgramNV), - NAME_FUNC_OFFSET(18513, glPointParameteriNV, glPointParameteriNV, NULL, _gloffset_PointParameteriNV), - NAME_FUNC_OFFSET(18531, glPointParameterivNV, glPointParameterivNV, NULL, _gloffset_PointParameterivNV), - NAME_FUNC_OFFSET(18550, gl_dispatch_stub_749, gl_dispatch_stub_749, NULL, _gloffset_BlendEquationSeparateEXT), - NAME_FUNC_OFFSET(18574, gl_dispatch_stub_749, gl_dispatch_stub_749, NULL, _gloffset_BlendEquationSeparateEXT), + NAME_FUNC_OFFSET(18495, glGetVertexAttribPointervNV, glGetVertexAttribPointervNV, NULL, _gloffset_GetVertexAttribPointervNV), + NAME_FUNC_OFFSET(18524, glIsProgramNV, glIsProgramNV, NULL, _gloffset_IsProgramNV), + NAME_FUNC_OFFSET(18539, glPointParameteriNV, glPointParameteriNV, NULL, _gloffset_PointParameteriNV), + NAME_FUNC_OFFSET(18557, glPointParameterivNV, glPointParameterivNV, NULL, _gloffset_PointParameterivNV), + NAME_FUNC_OFFSET(18576, gl_dispatch_stub_749, gl_dispatch_stub_749, NULL, _gloffset_BlendEquationSeparateEXT), + NAME_FUNC_OFFSET(18600, gl_dispatch_stub_749, gl_dispatch_stub_749, NULL, _gloffset_BlendEquationSeparateEXT), NAME_FUNC_OFFSET(-1, NULL, NULL, NULL, 0) }; diff --git a/src/mesa/main/enums.c b/src/mesa/main/enums.c index fc56809e97..8c1b785aab 100644 --- a/src/mesa/main/enums.c +++ b/src/mesa/main/enums.c @@ -3517,7 +3517,6 @@ static const enum_elt all_enums[1737] = static const unsigned reduced_enums[1277] = { - 30, /* GL_ALL_CLIENT_ATTRIB_BITS */ 435, /* GL_FALSE */ 643, /* GL_LINES */ 645, /* GL_LINE_LOOP */ @@ -4794,6 +4793,7 @@ static const unsigned reduced_enums[1277] = 1314, /* GL_SCISSOR_BIT */ 29, /* GL_ALL_ATTRIB_BITS */ 938, /* GL_MULTISAMPLE_BIT */ + 30, /* GL_ALL_CLIENT_ATTRIB_BITS */ }; #define Elements(x) sizeof(x)/sizeof(*x) diff --git a/src/mesa/sparc/glapi_sparc.S b/src/mesa/sparc/glapi_sparc.S index c2a8ca6154..86c9f30e14 100644 --- a/src/mesa/sparc/glapi_sparc.S +++ b/src/mesa/sparc/glapi_sparc.S @@ -1855,6 +1855,7 @@ _mesa_sparc_glapi_end: .globl glBindProgramARB ; .type glBindProgramARB,#function ; glBindProgramARB = glBindProgramNV .globl glDeleteProgramsARB ; .type glDeleteProgramsARB,#function ; glDeleteProgramsARB = glDeleteProgramsNV .globl glGenProgramsARB ; .type glGenProgramsARB,#function ; glGenProgramsARB = glGenProgramsNV + .globl glGetVertexAttribPointerv ; .type glGetVertexAttribPointerv,#function ; glGetVertexAttribPointerv = glGetVertexAttribPointervNV .globl glGetVertexAttribPointervARB ; .type glGetVertexAttribPointervARB,#function ; glGetVertexAttribPointervARB = glGetVertexAttribPointervNV .globl glIsProgramARB ; .type glIsProgramARB,#function ; glIsProgramARB = glIsProgramNV .globl glPointParameteri ; .type glPointParameteri,#function ; glPointParameteri = glPointParameteriNV diff --git a/src/mesa/x86-64/glapi_x86-64.S b/src/mesa/x86-64/glapi_x86-64.S index d8ef5eae09..eb54ba4848 100644 --- a/src/mesa/x86-64/glapi_x86-64.S +++ b/src/mesa/x86-64/glapi_x86-64.S @@ -29477,6 +29477,7 @@ GL_PREFIX(_dispatch_stub_771): .globl GL_PREFIX(BindProgramARB) ; .set GL_PREFIX(BindProgramARB), GL_PREFIX(BindProgramNV) .globl GL_PREFIX(DeleteProgramsARB) ; .set GL_PREFIX(DeleteProgramsARB), GL_PREFIX(DeleteProgramsNV) .globl GL_PREFIX(GenProgramsARB) ; .set GL_PREFIX(GenProgramsARB), GL_PREFIX(GenProgramsNV) + .globl GL_PREFIX(GetVertexAttribPointerv) ; .set GL_PREFIX(GetVertexAttribPointerv), GL_PREFIX(GetVertexAttribPointervNV) .globl GL_PREFIX(GetVertexAttribPointervARB) ; .set GL_PREFIX(GetVertexAttribPointervARB), GL_PREFIX(GetVertexAttribPointervNV) .globl GL_PREFIX(IsProgramARB) ; .set GL_PREFIX(IsProgramARB), GL_PREFIX(IsProgramNV) .globl GL_PREFIX(PointParameteri) ; .set GL_PREFIX(PointParameteri), GL_PREFIX(PointParameteriNV) diff --git a/src/mesa/x86/glapi_x86.S b/src/mesa/x86/glapi_x86.S index 2c01b38aeb..1106eeede8 100644 --- a/src/mesa/x86/glapi_x86.S +++ b/src/mesa/x86/glapi_x86.S @@ -1246,6 +1246,7 @@ GLNAME(gl_dispatch_functions_start): GL_STUB_ALIAS(BindProgramARB, _gloffset_BindProgramNV, BindProgramARB@8, BindProgramNV, BindProgramNV@8) GL_STUB_ALIAS(DeleteProgramsARB, _gloffset_DeleteProgramsNV, DeleteProgramsARB@8, DeleteProgramsNV, DeleteProgramsNV@8) GL_STUB_ALIAS(GenProgramsARB, _gloffset_GenProgramsNV, GenProgramsARB@8, GenProgramsNV, GenProgramsNV@8) + GL_STUB_ALIAS(GetVertexAttribPointerv, _gloffset_GetVertexAttribPointervNV, GetVertexAttribPointerv@12, GetVertexAttribPointervNV, GetVertexAttribPointervNV@12) GL_STUB_ALIAS(GetVertexAttribPointervARB, _gloffset_GetVertexAttribPointervNV, GetVertexAttribPointervARB@12, GetVertexAttribPointervNV, GetVertexAttribPointervNV@12) GL_STUB_ALIAS(IsProgramARB, _gloffset_IsProgramNV, IsProgramARB@4, IsProgramNV, IsProgramNV@4) GL_STUB_ALIAS(PointParameteri, _gloffset_PointParameteriNV, PointParameteri@8, PointParameteriNV, PointParameteriNV@8) -- cgit v1.2.3 From 1879069eab58a80a27ff1ee0e34b7940643539ab Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 28 Jan 2007 16:35:32 +1100 Subject: nouveau: extend notifier interface to allow multiple notifiers in a memory block. --- src/mesa/drivers/dri/nouveau/nouveau_sync.c | 36 +++++++++++++++++++++-------- src/mesa/drivers/dri/nouveau/nouveau_sync.h | 10 +++++--- 2 files changed, 33 insertions(+), 13 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.c b/src/mesa/drivers/dri/nouveau/nouveau_sync.c index e7bc4fcd5e..5fb8dec7d8 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.c @@ -9,7 +9,7 @@ #include "nouveau_sync.h" nouveau_notifier * -nouveau_notifier_new(GLcontext *ctx, GLuint handle) +nouveau_notifier_new(GLcontext *ctx, GLuint handle, GLuint count) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); nouveau_notifier *notifier; @@ -24,7 +24,7 @@ nouveau_notifier_new(GLcontext *ctx, GLuint handle) notifier->mem = nouveau_mem_alloc(ctx, NOUVEAU_MEM_FB | NOUVEAU_MEM_MAPPED, - 32, + count * NV_NOTIFIER_SIZE, 0); if (!notifier->mem) { FREE(notifier); @@ -53,9 +53,9 @@ nouveau_notifier_destroy(GLcontext *ctx, nouveau_notifier *notifier) } void -nouveau_notifier_reset(nouveau_notifier *notifier) +nouveau_notifier_reset(nouveau_notifier *notifier, GLuint id) { - volatile GLuint *n = notifier->mem->map; + volatile GLuint *n = notifier->mem->map + (id * NV_NOTIFIER_SIZE); #ifdef NOUVEAU_RING_DEBUG return; @@ -68,11 +68,27 @@ nouveau_notifier_reset(nouveau_notifier *notifier) NV_NOTIFY_STATE_STATUS_SHIFT); } +GLuint +nouveau_notifier_status(nouveau_notifier *notifier, GLuint id) +{ + volatile GLuint *n = notifier->mem->map + (id * NV_NOTIFIER_SIZE); + + return n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT; +} + +GLuint +nouveau_notifier_return_val(nouveau_notifier *notifier, GLuint id) +{ + volatile GLuint *n = notifier->mem->map + (id * NV_NOTIFIER_SIZE); + + return n[NV_NOTIFY_RETURN_VALUE/4]; +} + GLboolean -nouveau_notifier_wait_status(nouveau_notifier *notifier, GLuint status, - GLuint timeout) +nouveau_notifier_wait_status(nouveau_notifier *notifier, GLuint id, + GLuint status, GLuint timeout) { - volatile GLuint *n = notifier->mem->map; + volatile GLuint *n = notifier->mem->map + (id * NV_NOTIFIER_SIZE); unsigned int time = 0; #ifdef NOUVEAU_RING_DEBUG @@ -108,7 +124,7 @@ nouveau_notifier_wait_nop(GLcontext *ctx, nouveau_notifier *notifier, nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); GLboolean ret; - nouveau_notifier_reset(notifier); + nouveau_notifier_reset(notifier, 0); BEGIN_RING_SIZE(subc, NV_NOTIFY, 1); OUT_RING (NV_NOTIFY_STYLE_WRITE_ONLY); @@ -116,7 +132,7 @@ nouveau_notifier_wait_nop(GLcontext *ctx, nouveau_notifier *notifier, OUT_RING (0); FIRE_RING(); - ret = nouveau_notifier_wait_status(notifier, + ret = nouveau_notifier_wait_status(notifier, 0, NV_NOTIFY_STATE_STATUS_COMPLETED, 0 /* no timeout */); if (ret == GL_FALSE) MESSAGE("wait on notifier failed\n"); @@ -130,7 +146,7 @@ GLboolean nouveauSyncInitFuncs(GLcontext *ctx) return GL_TRUE; #endif - nmesa->syncNotifier = nouveau_notifier_new(ctx, NvSyncNotify); + nmesa->syncNotifier = nouveau_notifier_new(ctx, NvSyncNotify, 1); if (!nmesa->syncNotifier) { MESSAGE("Failed to create channel sync notifier\n"); return GL_FALSE; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.h b/src/mesa/drivers/dri/nouveau/nouveau_sync.h index d9e3d4b80c..5c941bbb1c 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.h @@ -3,6 +3,7 @@ #include "nouveau_buffers.h" +#define NV_NOTIFIER_SIZE 32 #define NV_NOTIFY_TIME_0 0x00000000 #define NV_NOTIFY_TIME_1 0x00000004 #define NV_NOTIFY_RETURN_VALUE 0x00000008 @@ -24,10 +25,13 @@ typedef struct nouveau_notifier_t { nouveau_mem *mem; } nouveau_notifier; -extern nouveau_notifier *nouveau_notifier_new(GLcontext *, GLuint handle); +extern nouveau_notifier *nouveau_notifier_new(GLcontext *, GLuint handle, + GLuint count); extern void nouveau_notifier_destroy(GLcontext *, nouveau_notifier *); -extern void nouveau_notifier_reset(nouveau_notifier *); -extern GLboolean nouveau_notifier_wait_status(nouveau_notifier *r, +extern void nouveau_notifier_reset(nouveau_notifier *, GLuint id); +extern GLuint nouveau_notifier_status(nouveau_notifier *, GLuint id); +extern GLuint nouveau_notifier_return_val(nouveau_notifier *, GLuint id); +extern GLboolean nouveau_notifier_wait_status(nouveau_notifier *r, GLuint id, GLuint status, GLuint timeout); extern void nouveau_notifier_wait_nop(GLcontext *ctx, nouveau_notifier *, GLuint subc); -- cgit v1.2.3 From aacea5218199b6fb614c75d4f6ee14dd27af70b3 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 28 Jan 2007 17:02:40 +1100 Subject: nouveau: initial GL_ARB_occlusion_query support Only enabled on NV40, NV20/NV30 code is untested.. However, NV30 should be identical to NV40. --- src/mesa/drivers/dri/nouveau/Makefile | 1 + src/mesa/drivers/dri/nouveau/nouveau_context.c | 4 + src/mesa/drivers/dri/nouveau/nouveau_context.h | 5 + src/mesa/drivers/dri/nouveau/nouveau_object.h | 3 +- src/mesa/drivers/dri/nouveau/nouveau_query.c | 198 +++++++++++++++++++++++++ src/mesa/drivers/dri/nouveau/nouveau_query.h | 38 +++++ src/mesa/drivers/dri/nouveau/nouveau_sync.c | 27 ++++ src/mesa/drivers/dri/nouveau/nouveau_sync.h | 27 ++++ 8 files changed, 302 insertions(+), 1 deletion(-) create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_query.c create mode 100644 src/mesa/drivers/dri/nouveau/nouveau_query.h (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile index 492e743360..20d2de5eef 100644 --- a/src/mesa/drivers/dri/nouveau/Makefile +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -27,6 +27,7 @@ DRIVER_SOURCES = \ nouveau_tex.c \ nouveau_swtcl.c \ nouveau_sync.c \ + nouveau_query.c \ nv04_state.c \ nv04_swtcl.c \ nv10_state.c \ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index 5db93eb012..e18cebcd29 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -50,6 +50,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_msg.h" #include "nouveau_reg.h" #include "nouveau_lock.h" +#include "nouveau_query.h" #include "nv04_swtcl.h" #include "nv10_swtcl.h" @@ -71,6 +72,7 @@ static const struct dri_debug_control debug_control[] = }; #define need_GL_ARB_vertex_program +#define need_GL_ARB_occlusion_query #include "extension_helper.h" const struct dri_extension common_extensions[] = @@ -100,6 +102,7 @@ const struct dri_extension nv40_extensions[] = * written for those cards. */ { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions }, + { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions}, { NULL, 0 } }; @@ -229,6 +232,7 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, nouveauInitBufferObjects(ctx); if (!nouveauSyncInitFuncs(ctx)) return GL_FALSE; + nouveauQueryInitFuncs(ctx); nmesa->hw_func.InitCard(nmesa); nouveauInitState(ctx); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index bcfbb9fb8d..c1d06654ee 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -105,6 +105,11 @@ typedef struct nouveau_context { /* Channel synchronisation */ nouveau_notifier *syncNotifier; + /* ARB_occlusion_query / EXT_timer_query */ + GLuint query_object_max; + GLboolean * query_alloc; + nouveau_notifier *queryNotifier; + /* Additional hw-specific functions */ nouveau_hw_func hw_func; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_object.h b/src/mesa/drivers/dri/nouveau/nouveau_object.h index e154e0acff..daad281029 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_object.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_object.h @@ -15,7 +15,8 @@ enum DMAObjects { NvCtxSurf3D = 0x80000023, NvDmaFB = 0xD0FB0001, NvDmaAGP = 0xD0AA0001, - NvSyncNotify = 0xD0000001 + NvSyncNotify = 0xD0000001, + NvQueryNotify = 0xD0000002 }; enum DMASubchannel { diff --git a/src/mesa/drivers/dri/nouveau/nouveau_query.c b/src/mesa/drivers/dri/nouveau/nouveau_query.c new file mode 100644 index 0000000000..de3f5b0378 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_query.c @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2007 Ben Skeggs. + * + * 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, 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. + * + */ + +/* GL_ARB_occlusion_query support for NV20/30/40 */ + +#include "mtypes.h" + +#include "nouveau_fifo.h" +#include "nouveau_msg.h" +#include "nouveau_object.h" +#include "nouveau_reg.h" +#include "nouveau_sync.h" +#include "nouveau_query.h" + +static struct gl_query_object * +nouveauNewQueryObject(GLcontext *ctx, GLuint id) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_query_object *nq; + int i; + + for (i=0; iquery_object_max; i++) + if (nmesa->query_alloc[i] == GL_FALSE) + break; + if (i==nmesa->query_object_max) + return NULL; + + nq = CALLOC_STRUCT(nouveau_query_object_t); + if (nq) { + nq->notifier_id = i; + + nq->mesa.Id = id; + nq->mesa.Result = 0; + nq->mesa.Active = GL_FALSE; + nq->mesa.Ready = GL_TRUE; + } + + return (struct gl_query_object *)nq; +} + +static void +nouveauBeginQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_query_object *nq = (nouveau_query_object *)q; + + nouveau_notifier_reset(nmesa->queryNotifier, nq->notifier_id); + + switch (nmesa->screen->card->type) { + case NV_20: + BEGIN_RING_CACHE(NvSub3D, 0x17c8, 1); + OUT_RING_CACHE (1); + BEGIN_RING_CACHE(NvSub3D, 0x17cc, 1); + OUT_RING_CACHE (1); + break; + case NV_30: + case NV_40: + case NV_44: + /* I don't think this is OCC_QUERY enable, but it *is* needed to make + * the SET_OBJECT7 notifier block work with STORE_RESULT. + * + * Also, this appears to reset the pixel pass counter */ + BEGIN_RING_SIZE(NvSub3D, + NV30_TCL_PRIMITIVE_3D_OCC_QUERY_OR_COLOR_BUFF_ENABLE, + 1); + OUT_RING (1); + /* Probably OCC_QUERY_ENABLE */ + BEGIN_RING_CACHE(NvSub3D, 0x17cc, 1); + OUT_RING_CACHE (1); + break; + default: + WARN_ONCE("no support for this card\n"); + break; + } +} + +static void +nouveauUpdateQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_query_object *nq = (nouveau_query_object *)q; + int status; + + status = nouveau_notifier_status(nmesa->queryNotifier, + nq->notifier_id); + + q->Ready = (status == NV_NOTIFY_STATE_STATUS_COMPLETED); + if (q->Ready) + q->Result = nouveau_notifier_return_val(nmesa->queryNotifier, + nq->notifier_id); +} + +static void +nouveauWaitQueryResult(GLcontext *ctx, GLenum target, struct gl_query_object *q) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_query_object *nq = (nouveau_query_object *)q; + + nouveau_notifier_wait_status(nmesa->queryNotifier, nq->notifier_id, + NV_NOTIFY_STATE_STATUS_COMPLETED, 0); + nouveauUpdateQuery(ctx, target, q); +} + +static void +nouveauEndQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q) +{ + nouveau_query_object *nq = (nouveau_query_object *)q; + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + switch (nmesa->screen->card->type) { + case NV_20: + BEGIN_RING_SIZE(NvSub3D, 0x17d0, 1); + OUT_RING (0x01000000 | nq->notifier_id*32); + break; + case NV_30: + case NV_40: + case NV_44: + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STORE_RESULT, 1); + OUT_RING (0x01000000 | nq->notifier_id*32); + break; + default: + WARN_ONCE("no support for this card\n"); + break; + } + FIRE_RING(); + + /*XXX: wait for query to complete, mesa doesn't give the driver + * an interface to query the status of a query object so + * this has to stall the channel. + */ + nouveauWaitQueryResult(ctx, target, q); + + BEGIN_RING_CACHE(NvSub3D, 0x17cc, 1); + OUT_RING_CACHE (0); +} + +void +nouveauQueryInitFuncs(GLcontext *ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (nmesa->screen->card->type < NV_20) + return; + + nmesa->query_object_max = (0x4000 / 32); + nmesa->queryNotifier = + nouveau_notifier_new(ctx, NvQueryNotify, + nmesa->query_object_max); + nmesa->query_alloc = calloc(nmesa->query_object_max, sizeof(GLboolean)); + + switch (nmesa->screen->card->type) { + case NV_20: + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SET_OBJECT8, 1); + OUT_RING_CACHE (NvQueryNotify); + break; + case NV_30: + case NV_40: + case NV_44: + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT7, 1); + OUT_RING_CACHE (NvQueryNotify); + break; + default: + break; + }; + + ctx->Driver.NewQueryObject = nouveauNewQueryObject; + ctx->Driver.BeginQuery = nouveauBeginQuery; + ctx->Driver.EndQuery = nouveauEndQuery; +#if 0 + ctx->Driver.UpdateQuery = nouveauUpdateQuery; + ctx->Driver.WaitQueryResult = nouveauWaitQueryResult; +#endif +} + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_query.h b/src/mesa/drivers/dri/nouveau/nouveau_query.h new file mode 100644 index 0000000000..3ded41417e --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_query.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2007 Ben Skeggs. + * + * 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, 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. + * + */ + +#ifndef __NOUVEAU_QUERY_H__ +#define __NOUVEAU_QUERY_H__ + +typedef struct nouveau_query_object_t { + struct gl_query_object mesa; + + int notifier_id; +} nouveau_query_object; + +extern void nouveauQueryInitFuncs(GLcontext *ctx); +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.c b/src/mesa/drivers/dri/nouveau/nouveau_sync.c index 5fb8dec7d8..c47ff3a985 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.c @@ -1,3 +1,30 @@ +/* + * Copyright (C) 2007 Ben Skeggs. + * + * 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, 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. + * + */ + #include "vblank.h" /* for DO_USLEEP */ #include "nouveau_context.h" diff --git a/src/mesa/drivers/dri/nouveau/nouveau_sync.h b/src/mesa/drivers/dri/nouveau/nouveau_sync.h index 5c941bbb1c..019d5f6629 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_sync.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_sync.h @@ -1,3 +1,30 @@ +/* + * Copyright (C) 2007 Ben Skeggs. + * + * 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, 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. + * + */ + #ifndef __NOUVEAU_SYNC_H__ #define __NOUVEAU_SYNC_H__ -- cgit v1.2.3 From b0e86b2dbd11b3ff515172cf1741600c0879ad3f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 28 Jan 2007 22:55:35 +1100 Subject: nouveau: fix nv30 line width --- src/mesa/drivers/dri/nouveau/nv30_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 9b0d7425c8..55b6463781 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -559,7 +559,7 @@ static void nv30LineWidth(GLcontext *ctx, GLfloat width) nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); GLubyte ubWidth; - CLAMPED_FLOAT_TO_UBYTE(ubWidth, width); + ubWidth = (GLubyte)(width * 8.0) & 0xFF; BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_LINE_WIDTH_SMOOTH, 1); OUT_RING_CACHE(ubWidth); -- cgit v1.2.3 From c7c0a6ddcddc8d91fde0a7cb5a2bce85c708d438 Mon Sep 17 00:00:00 2001 From: Matthieu Castet Date: Sun, 28 Jan 2007 23:26:21 +0100 Subject: nouveau : nv10 mixing cached stuff with not cached stuff is bad. --- src/mesa/drivers/dri/nouveau/nv10_state.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 0e912e73ff..4e9bccb243 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -688,10 +688,10 @@ static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color, if (color[0]->mesa._ActualFormat != GL_RGBA8) { format = 0x103; /* R5G6B5 color buffer */ } - OUT_RING(format); - OUT_RING(pitch); - OUT_RING(color[0]->offset); - OUT_RING(depth ? depth->offset : color[0]->offset); + OUT_RING_CACHE(format); + OUT_RING_CACHE(pitch); + OUT_RING_CACHE(color[0]->offset); + OUT_RING_CACHE(depth ? depth->offset : color[0]->offset); return GL_TRUE; } -- cgit v1.2.3 From c97540065c6dce20dd6ace9a15d9872a3a66f71c Mon Sep 17 00:00:00 2001 From: Matthieu Castet Date: Mon, 29 Jan 2007 23:19:12 +0100 Subject: nouveau : nv10 comment icomplete command --- src/mesa/drivers/dri/nouveau/nv10_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 4e9bccb243..f6e47b7f48 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -322,7 +322,7 @@ static void nv10Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *params) switch(pname) { case GL_FOG_MODE: - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FOG_MODE, 1); + //BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_FOG_MODE, 1); //OUT_RING_CACHE (params); break; /* TODO: unsure about the rest.*/ -- cgit v1.2.3 From aa397fe47212d7686efe423aedd10f2c57f2c2b9 Mon Sep 17 00:00:00 2001 From: Matthieu Castet Date: Mon, 29 Jan 2007 23:26:35 +0100 Subject: nouveau : NOUVEAU_RING_TRACE allow to print what we are really sending to the fifo. --- src/mesa/drivers/dri/nouveau/nouveau_fifo.h | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h index 9056bfb255..490089f71a 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fifo.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.h @@ -33,15 +33,30 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "nouveau_ctrlreg.h" #include "nouveau_state_cache.h" +//#define NOUVEAU_RING_TRACE //#define NOUVEAU_RING_DEBUG //#define NOUVEAU_STATE_CACHE_DISABLE +#ifndef NOUVEAU_RING_TRACE +#define NOUVEAU_RING_TRACE 0 +#else +#undef NOUVEAU_RING_TRACE +#define NOUVEAU_RING_TRACE 1 +#endif + #define NV_READ(reg) *(volatile u_int32_t *)(nmesa->mmio + (reg)) #define NV_FIFO_READ(reg) *(volatile u_int32_t *)(nmesa->fifo.mmio + (reg/4)) #define NV_FIFO_WRITE(reg,value) *(volatile u_int32_t *)(nmesa->fifo.mmio + (reg/4)) = value; #define NV_FIFO_READ_GET() ((NV_FIFO_READ(NV03_FIFO_REGS_DMAGET) - nmesa->fifo.put_base) >> 2) -#define NV_FIFO_WRITE_PUT(val) NV_FIFO_WRITE(NV03_FIFO_REGS_DMAPUT, ((val)<<2) + nmesa->fifo.put_base) +#define NV_FIFO_WRITE_PUT(val) do { \ + if (NOUVEAU_RING_TRACE) {\ + printf("FIRE_RING : 0x%08x\n", nmesa->fifo.current << 2); \ + fflush(stdout); \ + sleep(1); \ + } \ + NV_FIFO_WRITE(NV03_FIFO_REGS_DMAPUT, ((val)<<2) + nmesa->fifo.put_base); \ +} while(0) /* * Ring/fifo interface @@ -75,15 +90,23 @@ int i; printf("OUT_RINGp: (size 0x%x dwords)\n",sz); for(i=0;ififo.current+i) << 2, *(p+i), *((float*)(p+i))); \ + } \ memcpy(nmesa->fifo.buffer+nmesa->fifo.current,ptr,(sz)*4); \ nmesa->fifo.current+=(sz); \ }while(0) #define OUT_RING(n) do { \ +if (NOUVEAU_RING_TRACE) \ + printf("OUT_RINGn: [0x%08x] 0x%08x (%s)\n", nmesa->fifo.current << 2, n, __func__); \ nmesa->fifo.buffer[nmesa->fifo.current++]=(n); \ }while(0) #define OUT_RINGf(n) do { \ +if (NOUVEAU_RING_TRACE) \ + printf("OUT_RINGf: [0x%08x] %.04f (%s)\n", nmesa->fifo.current << 2, n, __func__); \ *((float*)(nmesa->fifo.buffer+nmesa->fifo.current++))=(n); \ }while(0) -- cgit v1.2.3 From 0c5b42a99182be05a72c78fa9340b75f3be81220 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 29 Jan 2007 16:39:19 +1100 Subject: nouveau: unhardcode some more NV30TCL_FP_CONTROL values --- src/mesa/drivers/dri/nouveau/nouveau_shader.h | 3 ++- src/mesa/drivers/dri/nouveau/nv30_fragprog.c | 20 +++++++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h index 7329ccd9ea..82eb27b053 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -26,7 +26,8 @@ typedef struct _nvs_fragment_header { typedef union { struct { - uint32_t fp_control; + GLboolean uses_kil; + GLuint num_regs; } NV30FP; struct { uint32_t vp_in_reg; diff --git a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c index 3c7501dd62..02bd8014cc 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c +++ b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c @@ -24,6 +24,7 @@ static void NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nvsCardPriv *priv = &nvs->card_priv; uint32_t offset; if (!nvs->program_buffer) @@ -46,8 +47,9 @@ NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs) */ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM, 1); OUT_RING (offset | 1); - BEGIN_RING_SIZE(NvSub3D, 0x1d60, 1); - OUT_RING (nvs->card_priv.NV30FP.fp_control | 0x03000000); + BEGIN_RING_SIZE(NvSub3D, 0x1d60 /*NV30_TCL_PRIMITIVE_3D_FP_CONTROL*/, 1); + OUT_RING ((priv->NV30FP.uses_kil << 7) | + (priv->NV30FP.num_regs << 24)); } static void @@ -95,7 +97,7 @@ static void NV30FPSetOpcode(nvsFunc *shader, unsigned int opcode, int slot) { if (opcode == NV30_FP_OP_OPCODE_KIL) - shader->card_priv->NV30FP.fp_control |= (1<<7); + shader->card_priv->NV30FP.uses_kil = GL_TRUE; shader->inst[0] &= ~NV30_FP_OP_OPCODE_MASK; shader->inst[0] |= (opcode << NV30_FP_OP_OPCODE_SHIFT); } @@ -145,6 +147,16 @@ NV30FPSetCondition(nvsFunc *shader, int on, nvsCond cond, int reg, shader->inst[1] |= (swz[NVS_SWZ_W] << NV30_FP_OP_COND_SWZ_W_SHIFT); } +static void +NV30FPSetHighReg(nvsFunc *shader, int id) +{ + if (shader->card_priv->NV30FP.num_regs < (id+1)) { + if (id == 0) + id = 1; /* necessary? */ + shader->card_priv->NV30FP.num_regs = (id+1); + } +} + static void NV30FPSetResult(nvsFunc *shader, nvsRegister *reg, unsigned int mask, int slot) { @@ -163,6 +175,7 @@ NV30FPSetResult(nvsFunc *shader, nvsRegister *reg, unsigned int mask, int slot) shader->inst[0] &= ~NV30_FP_OP_UNK0_7; hwreg = reg->index; } + NV30FPSetHighReg(shader, hwreg); shader->inst[0] &= ~NV30_FP_OP_OUT_REG_SHIFT; shader->inst[0] |= (hwreg << NV30_FP_OP_OUT_REG_SHIFT); } @@ -176,6 +189,7 @@ NV30FPSetSource(nvsFunc *shader, nvsRegister *reg, int pos) case NVS_FILE_TEMP: hwsrc |= (NV30_FP_REG_TYPE_TEMP << NV30_FP_REG_TYPE_SHIFT); hwsrc |= (reg->index << NV30_FP_REG_SRC_SHIFT); + NV30FPSetHighReg(shader, reg->index); break; case NVS_FILE_ATTRIB: { -- cgit v1.2.3 From cafbc459f51ce6645e1fc4b6b2b7ec34efedd874 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 27 Jan 2007 18:36:01 +1100 Subject: nouveau: maintain a map of which vtxprog input corresponds to which array --- src/mesa/drivers/dri/nouveau/nouveau_shader.h | 1 + src/mesa/drivers/dri/nouveau/nouveau_shader_0.c | 46 +++++++++++++++++++++++++ 2 files changed, 47 insertions(+) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h index 82eb27b053..e2515c1c79 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -55,6 +55,7 @@ typedef struct _nouveauShader { int inst_count; nvsCardPriv card_priv; + int vp_attrib_map[NVS_MAX_ATTRIBS]; struct { GLfloat *source_val; /* NULL if invariant */ diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c index 3bcc2ba755..81ed012c78 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -787,6 +787,50 @@ pass0_translate_instructions(nouveauShader *nvs, int ipos, int fpos, return GL_TRUE; } +static void +pass0_build_attrib_map(nouveauShader *nvs, struct gl_vertex_program *vp) +{ + GLuint inputs_read = vp->Base.InputsRead; + GLuint input_alloc = ~0xFFFF; + int i; + + for (i=0; ivp_attrib_map[i] = -1; + + while (inputs_read) { + int in = ffs(inputs_read) - 1; + int hw; + inputs_read &= ~(1<IsNVProgram) { + /* NVvp: must alias */ + if (in >= VERT_ATTRIB_GENERIC0) + hw = in - VERT_ATTRIB_GENERIC0; + else + hw = in; + } else { + /* ARBvp: may alias + * GL2.0: must not alias + */ + if (in >= VERT_ATTRIB_GENERIC0) + hw = ffs(~input_alloc) - 1; + else + hw = in; + input_alloc |= (1<vp_attrib_map[hw] = in; + } + + if (NOUVEAU_DEBUG & DEBUG_SHADERS) { + printf("vtxprog attrib map:\n"); + for (i=0; ivp_attrib_map[i]); + } + } +} + GLboolean nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) { @@ -801,6 +845,8 @@ nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) case GL_VERTEX_PROGRAM_ARB: nvs->func = &nmesa->VPfunc; + pass0_build_attrib_map(nvs, vp); + if (vp->IsPositionInvariant) _mesa_insert_mvp_code(ctx, vp); #if 0 -- cgit v1.2.3 From 7fbf8d3324868e6920243e3b1abdeb6e398ea715 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 27 Jan 2007 18:51:19 +1100 Subject: nouveau: oops --- src/mesa/drivers/dri/nouveau/nouveau_shader_0.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c index 81ed012c78..fc55056854 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -322,6 +322,7 @@ pass0_make_src_reg(nvsPtr nvs, nvsRegister *reg, struct prog_src_register *src) { struct gl_program *mesa = (struct gl_program *)&nvs->mesa.vp.Base; struct gl_program_parameter_list *p = mesa->Parameters; + int i; *reg = nvr_unused; @@ -329,9 +330,14 @@ pass0_make_src_reg(nvsPtr nvs, nvsRegister *reg, struct prog_src_register *src) case PROGRAM_INPUT: reg->file = NVS_FILE_ATTRIB; if (mesa->Target == GL_VERTEX_PROGRAM_ARB) { - reg->index = (src->Index < VERT_ATTRIB_MAX) ? - _tx_mesa_vp_src_reg[src->Index] : - NVS_FR_UNKNOWN; + for (i=0; ivp_attrib_map[i] == src->Index) { + reg->index = i; + break; + } + } + if (i==NVS_MAX_ATTRIBS) + reg->index = NVS_FR_UNKNOWN; } else { reg->index = (src->Index < FRAG_ATTRIB_MAX) ? _tx_mesa_fp_src_reg[src->Index] : -- cgit v1.2.3 From 2d8b31610917e5e14a242725b047a21f6d2c14e0 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 27 Jan 2007 18:54:42 +1100 Subject: nouveau: remove an unused table --- src/mesa/drivers/dri/nouveau/nouveau_shader_0.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c index fc55056854..b96cf95939 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -54,18 +54,6 @@ static nvsFixedReg _tx_mesa_fp_dst_reg[FRAG_RESULT_MAX] = { NVS_FR_UNKNOWN /* DEPR */ }; -static nvsFixedReg _tx_mesa_vp_src_reg[VERT_ATTRIB_MAX] = { - NVS_FR_POSITION, NVS_FR_WEIGHT, NVS_FR_NORMAL, NVS_FR_COL0, NVS_FR_COL1, - NVS_FR_FOGCOORD, NVS_FR_UNKNOWN /* COLOR_INDEX */, NVS_FR_UNKNOWN, - NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, - NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7, -/* Generic attribs 0-15, aliased to the above */ - NVS_FR_POSITION, NVS_FR_WEIGHT, NVS_FR_NORMAL, NVS_FR_COL0, NVS_FR_COL1, - NVS_FR_FOGCOORD, NVS_FR_UNKNOWN /* COLOR_INDEX */, NVS_FR_UNKNOWN, - NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, - NVS_FR_TEXCOORD4, NVS_FR_TEXCOORD5, NVS_FR_TEXCOORD6, NVS_FR_TEXCOORD7 -}; - static nvsFixedReg _tx_mesa_fp_src_reg[FRAG_ATTRIB_MAX] = { NVS_FR_POSITION, NVS_FR_COL0, NVS_FR_COL1, NVS_FR_FOGCOORD, NVS_FR_TEXCOORD0, NVS_FR_TEXCOORD1, NVS_FR_TEXCOORD2, NVS_FR_TEXCOORD3, @@ -815,7 +803,7 @@ pass0_build_attrib_map(nouveauShader *nvs, struct gl_vertex_program *vp) else hw = in; } else { - /* ARBvp: may alias + /* ARBvp: may alias (but we won't) * GL2.0: must not alias */ if (in >= VERT_ATTRIB_GENERIC0) -- cgit v1.2.3 From de0cf18b096822cf8e113a46f12740ebeb10f8df Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 29 Jan 2007 17:08:45 +1100 Subject: nouveau: oops, build attrib map after we know how the final shader will look.. --- src/mesa/drivers/dri/nouveau/nouveau_shader_0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c index b96cf95939..9f32cd8c11 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -839,14 +839,14 @@ nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) case GL_VERTEX_PROGRAM_ARB: nvs->func = &nmesa->VPfunc; - pass0_build_attrib_map(nvs, vp); - if (vp->IsPositionInvariant) _mesa_insert_mvp_code(ctx, vp); #if 0 if (IS_FIXEDFUNCTION_PROG && CLIP_PLANES_USED) pass0_insert_ff_clip_planes(); #endif + + pass0_build_attrib_map(nvs, vp); break; case GL_FRAGMENT_PROGRAM_ARB: nvs->func = &nmesa->FPfunc; -- cgit v1.2.3 From ede8017d2c6c2f6da4c75c9ce0cc4d748e870973 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 30 Jan 2007 12:33:00 +1100 Subject: nouveau: rework shader param handling Conflicts: src/mesa/drivers/dri/nouveau/nouveau_shader_0.c --- src/mesa/drivers/dri/nouveau/nouveau_shader.c | 9 +- src/mesa/drivers/dri/nouveau/nouveau_shader.h | 3 + src/mesa/drivers/dri/nouveau/nouveau_shader_0.c | 145 +++++++++++++++++------- 3 files changed, 110 insertions(+), 47 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.c b/src/mesa/drivers/dri/nouveau/nouveau_shader.c index cdb79fca1e..c78b72bd11 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.c @@ -126,15 +126,16 @@ nvsUpdateShader(GLcontext *ctx, nouveauShader *nvs) /* Update state parameters */ plist = nvs->mesa.vp.Base.Parameters; _mesa_load_state_parameters(ctx, plist); - for (i=0; iNumParameters; i++) { + for (i=0; iparam_high; i++) { + if (!nvs->params[i].in_use) + continue; + if (!nvs->on_hardware) { /* if we've been kicked off the hardware there's no guarantee our * consts are still there.. reupload them all */ nvs->func->UpdateConst(ctx, nvs, i); - } else if (plist->Parameters[i].Type == PROGRAM_STATE_VAR) { - if (!nvs->params[i].source_val) /* this is a workaround when consts aren't alloc'd from id=0.. */ - continue; + } else if (nvs->params[i].source_val) { /* update any changed state parameters */ if (!TEST_EQ_4V(nvs->params[i].val, nvs->params[i].source_val)) nvs->func->UpdateConst(ctx, nvs, i); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h index e2515c1c79..68007dd1ea 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -58,6 +58,8 @@ typedef struct _nouveauShader { int vp_attrib_map[NVS_MAX_ATTRIBS]; struct { + GLboolean in_use; + GLfloat *source_val; /* NULL if invariant */ float val[4]; /* Hardware-specific tracking, currently only nv30_fragprog @@ -66,6 +68,7 @@ typedef struct _nouveauShader { int *hw_index; int hw_index_cnt; } params[NVS_MAX_CONSTS]; + int param_high; /* Pass-private data */ void *pass_rec; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c index 9f32cd8c11..fb6e0b05c3 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -113,6 +113,10 @@ static nvsCond _tx_mesa_condmask[] = { struct pass0_rec { int nvs_ipos; int next_temp; + + int mesa_const_base; + int mesa_const_last; + int swzconst_done; int swzconst_id; nvsRegister const_half; @@ -308,8 +312,8 @@ pass0_make_dst_reg(nvsPtr nvs, nvsRegister *reg, static void pass0_make_src_reg(nvsPtr nvs, nvsRegister *reg, struct prog_src_register *src) { + struct pass0_rec *rec = nvs->pass_rec; struct gl_program *mesa = (struct gl_program *)&nvs->mesa.vp.Base; - struct gl_program_parameter_list *p = mesa->Parameters; int i; *reg = nvr_unused; @@ -332,34 +336,16 @@ pass0_make_src_reg(nvsPtr nvs, nvsRegister *reg, struct prog_src_register *src) NVS_FR_UNKNOWN; } break; - /* All const types seem to get shoved into here, not really sure why */ case PROGRAM_STATE_VAR: - switch (p->Parameters[src->Index].Type) { - case PROGRAM_NAMED_PARAM: - case PROGRAM_CONSTANT: - nvs->params[src->Index].source_val = NULL; - COPY_4V(nvs->params[src->Index].val, - p->ParameterValues[src->Index]); - break; - case PROGRAM_STATE_VAR: - nvs->params[src->Index].source_val = - p->ParameterValues[src->Index]; - break; - default: - fprintf(stderr, "Unknown parameter type %d\n", - p->Parameters[src->Index].Type); - assert(0); - break; + case PROGRAM_NAMED_PARAM: + case PROGRAM_CONSTANT: + reg->file = NVS_FILE_CONST; + reg->index = src->Index + rec->mesa_const_base; + reg->indexed = src->RelAddr; + if (reg->indexed) { + reg->addr_reg = 0; + reg->addr_comp = NVS_SWZ_X; } - - if (src->RelAddr) { - reg->indexed = 1; - reg->addr_reg = 0; - reg->addr_comp = NVS_SWZ_X; - } else - reg->indexed = 0; - reg->file = NVS_FILE_CONST; - reg->index = src->Index; break; case PROGRAM_TEMPORARY: reg->file = NVS_FILE_TEMP; @@ -568,7 +554,6 @@ pass0_emulate_instruction(nouveauShader *nvs, nvsFunc *shader = nvs->func; nvsRegister src[3], dest, temp; nvsInstruction *nvsinst; - struct pass0_rec *rec = nvs->pass_rec; unsigned int mask = pass0_make_mask(inst->DstReg.WriteMask); int i, sat; @@ -825,6 +810,73 @@ pass0_build_attrib_map(nouveauShader *nvs, struct gl_vertex_program *vp) } } +static void +pass0_prealloc_mesa_consts(nouveauShader *nvs) +{ + struct pass0_rec *rec = nvs->pass_rec; + struct gl_program *prog = &nvs->mesa.vp.Base; + struct prog_instruction *inst = prog->Instructions; + struct gl_program_parameter_list *plist = prog->Parameters; + int i; + + /*XXX: not a good idea, params->hw_index is malloc'd */ + memset(nvs->params, 0x00, sizeof(nvs->params)); + + /* When doing relative addressing on constants, the hardware needs us + * to fill the "const id" field with a positive value. Determine the + * most negative index that is used so that all accesses to a + * mesa-provided constant can be rebased to a positive index. + */ + while (inst->Opcode != OPCODE_END) { + for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++) { + struct prog_src_register *src = &inst->SrcReg[i]; + + switch (src->File) { + case PROGRAM_STATE_VAR: + case PROGRAM_CONSTANT: + case PROGRAM_NAMED_PARAM: + if (src->RelAddr && src->Index < 0) { + int base = src->Index * -1; + if (rec->mesa_const_base < base) + rec->mesa_const_base = base; + } + break; + default: + break; + } + } + + inst++; + } + + /* Init all const tracking/alloc info from the parameter list, rather + * than doing it as we translate the program. Otherwise we can't get + * at the correct constant info when relative addressing is being used. + */ + rec->mesa_const_last = plist->NumParameters + rec->mesa_const_base; + nvs->param_high = rec->mesa_const_last; + for (i=0; iNumParameters; i++) { + int hw = rec->mesa_const_base + i; + + switch (plist->Parameters[i].Type) { + case PROGRAM_NAMED_PARAM: + case PROGRAM_STATE_VAR: + nvs->params[hw].in_use = GL_TRUE; + nvs->params[hw].source_val = plist->ParameterValues[i]; + COPY_4V(nvs->params[hw].val, plist->ParameterValues[i]); + break; + case PROGRAM_CONSTANT: + nvs->params[hw].in_use = GL_TRUE; + nvs->params[hw].source_val = NULL; + COPY_4V(nvs->params[hw].val, plist->ParameterValues[i]); + break; + default: + assert(0); + break; + } + } +} + GLboolean nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) { @@ -835,12 +887,28 @@ nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) struct pass0_rec *rec; int ret = GL_FALSE; + rec = CALLOC_STRUCT(pass0_rec); + if (!rec) + return GL_FALSE; + + rec->next_temp = prog->NumTemporaries; + nvs->pass_rec = rec; + + nvs->program_tree = (nvsFragmentHeader*) + pass0_create_subroutine(nvs, "program body"); + if (!nvs->program_tree) { + FREE(rec); + return GL_FALSE; + } + switch (prog->Target) { case GL_VERTEX_PROGRAM_ARB: nvs->func = &nmesa->VPfunc; if (vp->IsPositionInvariant) _mesa_insert_mvp_code(ctx, vp); + pass0_prealloc_mesa_consts(nvs); + #if 0 if (IS_FIXEDFUNCTION_PROG && CLIP_PLANES_USED) pass0_insert_ff_clip_planes(); @@ -853,29 +921,20 @@ nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) if (fp->FogOption != GL_NONE) _mesa_append_fog_code(ctx, fp); + pass0_prealloc_mesa_consts(nvs); break; default: fprintf(stderr, "Unknown program type %d", prog->Target); + FREE(rec); + /* DESTROY TREE!! */ return GL_FALSE; } nvs->func->card_priv = &nvs->card_priv; - rec = CALLOC_STRUCT(pass0_rec); - if (rec) { - rec->next_temp = prog->NumTemporaries; - nvs->pass_rec = rec; - - nvs->program_tree = (nvsFragmentHeader*) - pass0_create_subroutine(nvs, "program body"); - if (nvs->program_tree) { - ret = pass0_translate_instructions(nvs, - 0, 0, - nvs->program_tree); - /*XXX: if (!ret) DESTROY TREE!!! */ - } - FREE(rec); - } + ret = pass0_translate_instructions(nvs, 0, 0, nvs->program_tree); + /*XXX: if (!ret) DESTROY TREE!!! */ + FREE(rec); return ret; } -- cgit v1.2.3 From d2c4d9ff9beb36895bb8ee7aabb65e70c3068816 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 30 Jan 2007 16:00:20 +1100 Subject: nouveau: NV40 glClipPlane support. --- src/mesa/drivers/dri/nouveau/nouveau_shader.h | 1 + src/mesa/drivers/dri/nouveau/nouveau_shader_0.c | 88 +++++++++++++++++++++---- src/mesa/drivers/dri/nouveau/nv30_state.c | 15 ++++- src/mesa/drivers/dri/nouveau/nv30_vertprog.c | 3 + src/mesa/drivers/dri/nouveau/nv40_vertprog.c | 7 ++ 5 files changed, 101 insertions(+), 13 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.h b/src/mesa/drivers/dri/nouveau/nouveau_shader.h index 68007dd1ea..b2df3546f6 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.h @@ -32,6 +32,7 @@ typedef union { struct { uint32_t vp_in_reg; uint32_t vp_out_reg; + uint32_t clip_enables; } NV30VP; } nvsCardPriv; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c index fb6e0b05c3..73c1f7c2a5 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -811,12 +811,65 @@ pass0_build_attrib_map(nouveauShader *nvs, struct gl_vertex_program *vp) } static void -pass0_prealloc_mesa_consts(nouveauShader *nvs) +pass0_vp_insert_ff_clip_planes(GLcontext *ctx, nouveauShader *nvs) +{ + struct gl_program *prog = &nvs->mesa.vp.Base; + nvsFragmentHeader *parent = nvs->program_tree; + nvsInstruction *nvsinst; + GLuint fpos = 0; + nvsRegister opos, epos, eqn, mv[4]; + GLint tokens[6] = { STATE_MATRIX, STATE_MODELVIEW, 0, 0, 0, 0 }; + GLint id; + int i; + + /* modelview transform */ + pass0_make_reg(nvs, &opos, NVS_FILE_ATTRIB, NVS_FR_POSITION); + pass0_make_reg(nvs, &epos, NVS_FILE_TEMP , -1); + for (i=0; i<4; i++) { + tokens[3] = tokens[4] = i; + id = _mesa_add_state_reference(prog->Parameters, tokens); + pass0_make_reg(nvs, &mv[i], NVS_FILE_CONST, id); + } + ARITHu(NVS_OP_DP4, epos, SMASK_X, 0, opos, mv[0], nvr_unused); + ARITHu(NVS_OP_DP4, epos, SMASK_Y, 0, opos, mv[1], nvr_unused); + ARITHu(NVS_OP_DP4, epos, SMASK_Z, 0, opos, mv[2], nvr_unused); + ARITHu(NVS_OP_DP4, epos, SMASK_W, 0, opos, mv[3], nvr_unused); + + /* Emit code to emulate fixed-function glClipPlane */ + for (i=0; i<6; i++) { + GLuint clipmask = SMASK_X; + nvsRegister clip; + + if (!(ctx->Transform.ClipPlanesEnabled & (1<Parameters, tokens); + pass0_make_reg(nvs, &eqn , NVS_FILE_CONST , id); + pass0_make_reg(nvs, &clip, NVS_FILE_RESULT, NVS_FR_CLIP0 + i); + + /*XXX: something else needs to take care of modifying the + * instructions to write to the correct hw clip register. + */ + switch (i) { + case 0: case 3: clipmask = SMASK_Y; break; + case 1: case 4: clipmask = SMASK_Z; break; + case 2: case 5: clipmask = SMASK_W; break; + } + + /* Emit transform */ + ARITHu(NVS_OP_DP4, clip, clipmask, 0, epos, eqn, nvr_unused); + } +} + +static void +pass0_rebase_mesa_consts(nouveauShader *nvs) { struct pass0_rec *rec = nvs->pass_rec; struct gl_program *prog = &nvs->mesa.vp.Base; struct prog_instruction *inst = prog->Instructions; - struct gl_program_parameter_list *plist = prog->Parameters; int i; /*XXX: not a good idea, params->hw_index is malloc'd */ @@ -848,10 +901,23 @@ pass0_prealloc_mesa_consts(nouveauShader *nvs) inst++; } - +} + +static void +pass0_resolve_mesa_consts(nouveauShader *nvs) +{ + struct pass0_rec *rec = nvs->pass_rec; + struct gl_program *prog = &nvs->mesa.vp.Base; + struct gl_program_parameter_list *plist = prog->Parameters; + int i; + /* Init all const tracking/alloc info from the parameter list, rather - * than doing it as we translate the program. Otherwise we can't get - * at the correct constant info when relative addressing is being used. + * than doing it as we translate the program. Otherwise: + * 1) we can't get at the correct constant info when relative + * addressing is being used due to src->Index not pointing + * at the exact const; + * 2) as we add extra consts to the program, mesa will call realloc() + * and we get invalid pointers to the const data. */ rec->mesa_const_last = plist->NumParameters + rec->mesa_const_base; nvs->param_high = rec->mesa_const_last; @@ -907,12 +973,10 @@ nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) if (vp->IsPositionInvariant) _mesa_insert_mvp_code(ctx, vp); - pass0_prealloc_mesa_consts(nvs); + pass0_rebase_mesa_consts(nvs); -#if 0 - if (IS_FIXEDFUNCTION_PROG && CLIP_PLANES_USED) - pass0_insert_ff_clip_planes(); -#endif + if (!prog->String && ctx->Transform.ClipPlanesEnabled) + pass0_vp_insert_ff_clip_planes(ctx, nvs); pass0_build_attrib_map(nvs, vp); break; @@ -921,7 +985,7 @@ nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) if (fp->FogOption != GL_NONE) _mesa_append_fog_code(ctx, fp); - pass0_prealloc_mesa_consts(nvs); + pass0_rebase_mesa_consts(nvs); break; default: fprintf(stderr, "Unknown program type %d", prog->Target); @@ -932,6 +996,8 @@ nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs) nvs->func->card_priv = &nvs->card_priv; ret = pass0_translate_instructions(nvs, 0, 0, nvs->program_tree); + if (ret) + pass0_resolve_mesa_consts(nvs); /*XXX: if (!ret) DESTROY TREE!!! */ FREE(rec); diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 55b6463781..db13ec70b4 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -127,6 +127,11 @@ static void nv30ClearStencil(GLcontext *ctx, GLint s) static void nv30ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + if (NOUVEAU_CARD_USING_SHADERS) + return; + + plane -= GL_CLIP_PLANE0; BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_A(plane), 4); OUT_RING_CACHEf(equation[0]); OUT_RING_CACHEf(equation[1]); @@ -208,8 +213,14 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) case GL_CLIP_PLANE3: case GL_CLIP_PLANE4: case GL_CLIP_PLANE5: - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1); - OUT_RING_CACHE(state); + if (NOUVEAU_CARD_USING_SHADERS) { + nouveauShader *nvs = (nouveauShader *)ctx->VertexProgram._Current; + if (nvs) + nvs->translated = GL_FALSE; + } else { + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_CLIP_PLANE_ENABLE(cap-GL_CLIP_PLANE0), 1); + OUT_RING_CACHE(state); + } break; case GL_COLOR_LOGIC_OP: BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_LOGIC_OP_ENABLE, 1); diff --git a/src/mesa/drivers/dri/nouveau/nv30_vertprog.c b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c index afcacf36c2..d023e8439e 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_vertprog.c +++ b/src/mesa/drivers/dri/nouveau/nv30_vertprog.c @@ -33,6 +33,9 @@ NV30VPUploadToHW(GLcontext *ctx, nouveauShader *nvs) BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_IN_REG, 2); OUT_RING(nvs->card_priv.NV30VP.vp_in_reg); OUT_RING(nvs->card_priv.NV30VP.vp_out_reg); + + BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_CLIPPING_PLANES, 1); + OUT_RING_CACHE (nvs->card_priv.NV30VP.clip_enables); } static void diff --git a/src/mesa/drivers/dri/nouveau/nv40_vertprog.c b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c index 6cb7e1cfd6..d054140bcd 100644 --- a/src/mesa/drivers/dri/nouveau/nv40_vertprog.c +++ b/src/mesa/drivers/dri/nouveau/nv40_vertprog.c @@ -86,6 +86,7 @@ NV40VPTranslateResultReg(nvsFunc *shader, nvsFixedReg result, unsigned int *mask_ret) { unsigned int *out_reg = &shader->card_priv->NV30VP.vp_out_reg; + unsigned int *clip_en = &shader->card_priv->NV30VP.clip_enables; *mask_ret = 0xf; @@ -111,14 +112,17 @@ NV40VPTranslateResultReg(nvsFunc *shader, nvsFixedReg result, return NV40_VP_INST_DEST_FOGC; case NVS_FR_CLIP0: (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP0; + (*clip_en) |= 0x00000002; *mask_ret = 0x4; return NV40_VP_INST_DEST_FOGC; case NVS_FR_CLIP1: (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP1; + (*clip_en) |= 0x00000020; *mask_ret = 0x2; return NV40_VP_INST_DEST_FOGC; case NVS_FR_CLIP2: (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP2; + (*clip_en) |= 0x00000200; *mask_ret = 0x1; return NV40_VP_INST_DEST_FOGC; case NVS_FR_POINTSZ: @@ -127,13 +131,16 @@ NV40VPTranslateResultReg(nvsFunc *shader, nvsFixedReg result, return NV40_VP_INST_DEST_PSZ; case NVS_FR_CLIP3: (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP3; + (*clip_en) |= 0x00002000; *mask_ret = 0x4; return NV40_VP_INST_DEST_PSZ; case NVS_FR_CLIP4: + (*clip_en) |= 0x00020000; (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP4; *mask_ret = 0x2; return NV40_VP_INST_DEST_PSZ; case NVS_FR_CLIP5: + (*clip_en) |= 0x00200000; (*out_reg) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP5; *mask_ret = 0x1; return NV40_VP_INST_DEST_PSZ; -- cgit v1.2.3 From f9345c7c4e22cd40d2efda73f1b044ab808f2c78 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 30 Jan 2007 16:49:27 +1100 Subject: nouveau: misc NV40 fixes --- src/mesa/drivers/dri/nouveau/nv30_state.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index db13ec70b4..e1e0da98d4 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -244,6 +244,8 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) OUT_RING_CACHE(state); break; case GL_FOG: + if (!NOUVEAU_CARD_USING_SHADERS) + break; BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_ENABLE, 1); OUT_RING_CACHE(state); break; @@ -736,9 +738,13 @@ void (*TexParameter)(GLcontext *ctx, GLenum target, static void nv30TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16); - /*XXX: This SHOULD work.*/ - OUT_RING_CACHEp(mat->m, 16); + + if (!NOUVEAU_CARD_USING_SHADERS) { + BEGIN_RING_CACHE(NvSub3D, + NV30_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16); + /*XXX: This SHOULD work.*/ + OUT_RING_CACHEp(mat->m, 16); + } } static void nv30WindowMoved(nouveauContextPtr nmesa) -- cgit v1.2.3 From a4ddd64f3659b9db7719d3746c1469ece6bb44c5 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 30 Jan 2007 16:51:50 +1100 Subject: nouveau: argh --- src/mesa/drivers/dri/nouveau/nv30_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index e1e0da98d4..96a07fd536 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -244,7 +244,7 @@ static void nv30Enable(GLcontext *ctx, GLenum cap, GLboolean state) OUT_RING_CACHE(state); break; case GL_FOG: - if (!NOUVEAU_CARD_USING_SHADERS) + if (NOUVEAU_CARD_USING_SHADERS) break; BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FOG_ENABLE, 1); OUT_RING_CACHE(state); -- cgit v1.2.3 From 893526b8a823fe1b88f2b46376155afb91c84016 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 30 Jan 2007 20:22:55 +0000 Subject: Use new rebase helper. Remove other rebase code. --- src/mesa/drivers/dri/i965/brw_draw.c | 53 +++++++++- src/mesa/drivers/dri/i965/brw_draw_upload.c | 105 ++++---------------- src/mesa/tnl/t_draw.c | 108 ++++++++------------ src/mesa/vbo/vbo.h | 1 - src/mesa/vbo/vbo_exec_array.c | 146 +++++++++++++++------------- src/mesa/vbo/vbo_rebase.c | 3 +- src/mesa/vbo/vbo_split_copy.c | 1 - src/mesa/vbo/vbo_split_inplace.c | 1 - 8 files changed, 185 insertions(+), 233 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index 63cb079ec9..7d8f837093 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -198,7 +198,9 @@ static void brw_merge_inputs( struct brw_context *brw, brw->state.dirty.brw |= BRW_NEW_INPUT_VARYING; } - +/* XXX: could split the primitive list to fallback only on the + * non-conformant primitives. + */ static GLboolean check_fallbacks( struct brw_context *brw, const struct _mesa_prim *prim, GLuint nr_prims ) @@ -251,7 +253,9 @@ static GLboolean check_fallbacks( struct brw_context *brw, return GL_FALSE; } - +/* May fail if out of video memory for texture or vbo upload, or on + * fallback conditions. + */ static GLboolean brw_try_draw_prims( GLcontext *ctx, const struct gl_client_array *arrays[], const struct _mesa_prim *prim, @@ -376,6 +380,33 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx, return retval; } +static GLboolean brw_need_rebase( GLcontext *ctx, + const struct gl_client_array *arrays[], + const struct _mesa_index_buffer *ib, + GLuint min_index ) +{ + if (min_index == 0) + return GL_FALSE; + + if (ib) { + if (!vbo_all_varyings_in_vbos(arrays)) + return GL_TRUE; + else + return GL_FALSE; + } + else { + /* Hmm. This isn't quite what I wanted. BRW can actually + * handle the mixed case well enough that we shouldn't need to + * rebase. However, it's probably not very common, nor hugely + * expensive to do it this way: + */ + if (!vbo_all_varyings_in_vbos(arrays)) + return GL_TRUE; + else + return GL_FALSE; + } +} + void brw_draw_prims( GLcontext *ctx, const struct gl_client_array *arrays[], @@ -388,6 +419,21 @@ void brw_draw_prims( GLcontext *ctx, struct intel_context *intel = intel_context(ctx); GLboolean retval; + /* Decide if we want to rebase. If so we end up recursing once + * only into this function. + */ + if (brw_need_rebase( ctx, arrays, ib, min_index )) { + vbo_rebase_prims( ctx, arrays, + prim, nr_prims, + ib, min_index, max_index, + brw_draw_prims ); + + return; + } + + + /* Make a first attempt at drawing: + */ retval = brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); @@ -440,14 +486,13 @@ void brw_draw_init( struct brw_context *brw ) for (i = 0; i < BRW_NR_UPLOAD_BUFS; i++) { brw->vb.upload.vbo[i] = ctx->Driver.NewBufferObject(ctx, 1, GL_ARRAY_BUFFER_ARB); - /* XXX: Set these to no-backing-store + /* NOTE: These are set to no-backing-store. */ bmBufferSetInvalidateCB(&brw->intel, intel_bufferobj_buffer(intel_buffer_object(brw->vb.upload.vbo[i])), brw_invalidate_vbo_cb, &brw->intel, GL_TRUE); - } ctx->Driver.BufferData( ctx, diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 90637d16ea..6968d745c1 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -309,7 +309,6 @@ copy_array_to_vbo_array( struct brw_context *brw, GLuint i, const struct gl_client_array *array, GLuint element_size, - GLuint min_index, GLuint count) { GLcontext *ctx = &brw->intel.ctx; @@ -347,7 +346,7 @@ copy_array_to_vbo_array( struct brw_context *brw, map += offset; copy_strided_array( map, - array->Ptr + min_index * array->StrideB, + array->Ptr, element_size, array->StrideB, count); @@ -438,10 +437,8 @@ GLboolean brw_upload_vertices( struct brw_context *brw, } upload[nr_uploads++] = input; - input->vbo_rebase_offset = 0; + assert(min_index == 0); } - else - input->vbo_rebase_offset = min_index * input->glarray->StrideB; } /* Upload interleaved arrays if all uploads are interleaved @@ -454,7 +451,6 @@ GLboolean brw_upload_vertices( struct brw_context *brw, input0->glarray = copy_array_to_vbo_array(brw, 0, input0->glarray, interleave, - min_index, input0->count); for (i = 1; i < nr_uploads; i++) { @@ -472,7 +468,6 @@ GLboolean brw_upload_vertices( struct brw_context *brw, input->glarray = copy_array_to_vbo_array(brw, i, input->glarray, input->element_size, - min_index, input->count); } @@ -520,9 +515,9 @@ GLboolean brw_upload_vertices( struct brw_context *brw, vbp.vb[i].vb0.bits.pad = 0; vbp.vb[i].vb0.bits.access_type = BRW_VERTEXBUFFER_ACCESS_VERTEXDATA; vbp.vb[i].vb0.bits.vb_index = i; - vbp.vb[i].offset = (GLuint)input->glarray->Ptr + input->vbo_rebase_offset; + vbp.vb[i].offset = (GLuint)input->glarray->Ptr; vbp.vb[i].buffer = array_buffer(input->glarray); - vbp.vb[i].max_index = max_index - min_index; + vbp.vb[i].max_index = max_index; } @@ -563,94 +558,32 @@ static GLuint element_size( GLenum type ) - -static void rebase_indices_to_vbo_indices( struct brw_context *brw, - const struct _mesa_index_buffer *index_buffer, - struct gl_buffer_object **vbo_return, - GLuint *offset_return ) +void brw_upload_indices( struct brw_context *brw, + const struct _mesa_index_buffer *index_buffer ) { GLcontext *ctx = &brw->intel.ctx; - GLuint min_index = index_buffer->rebase; - const void *indices = index_buffer->ptr; - GLsizei count = index_buffer->count; - GLenum type = index_buffer->type; - GLuint size = element_size(type) * count; - struct gl_buffer_object *bufferobj; - GLuint offset; - GLuint i; - - get_space(brw, size, &bufferobj, &offset); + struct intel_context *intel = &brw->intel; + GLuint ib_size = get_size(index_buffer->type) * index_buffer->count; + struct gl_buffer_object *bufferobj = index_buffer->obj; + GLuint offset = (GLuint)index_buffer->ptr; - *vbo_return = bufferobj; - *offset_return = offset; + /* Turn into a proper VBO: + */ + if (!bufferobj->Name) { + + /* Get new bufferobj, offset: + */ + get_space(brw, ib_size, &bufferobj, &offset); - if (min_index == 0) { /* Straight upload */ ctx->Driver.BufferSubData( ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, offset, - size, - indices, + ib_size, + index_buffer->ptr, bufferobj); } - else { - void *map = ctx->Driver.MapBuffer(ctx, - GL_ELEMENT_ARRAY_BUFFER_ARB, - GL_DYNAMIC_DRAW_ARB, - bufferobj); - - map += offset; - - switch (type) { - case GL_UNSIGNED_INT: { - GLuint *ui_map = (GLuint *)map; - const GLuint *ui_indices = (const GLuint *)indices; - - for (i = 0; i < count; i++) - ui_map[i] = ui_indices[i] - min_index; - break; - } - case GL_UNSIGNED_SHORT: { - GLushort *us_map = (GLushort *)map; - const GLushort *us_indices = (const GLushort *)indices; - - for (i = 0; i < count; i++) - us_map[i] = us_indices[i] - min_index; - break; - } - case GL_UNSIGNED_BYTE: { - GLubyte *ub_map = (GLubyte *)map; - const GLubyte *ub_indices = (const GLubyte *)indices; - - for (i = 0; i < count; i++) - ub_map[i] = ub_indices[i] - min_index; - break; - } - } - - ctx->Driver.UnmapBuffer(ctx, - GL_ELEMENT_ARRAY_BUFFER_ARB, - bufferobj); - - } -} - - - -void brw_upload_indices( struct brw_context *brw, - const struct _mesa_index_buffer *index_buffer) -{ - struct intel_context *intel = &brw->intel; - GLuint ib_size = get_size(index_buffer->type) * index_buffer->count; - struct gl_buffer_object *bufferobj = index_buffer->obj; - GLuint offset = (GLuint)index_buffer->ptr; - - /* Already turned into a proper VBO: - */ - if (!index_buffer->obj->Name) { - rebase_indices_to_vbo_indices(brw, index_buffer, &bufferobj, &offset ); - } /* Emit the indexbuffer packet: */ diff --git a/src/mesa/tnl/t_draw.c b/src/mesa/tnl/t_draw.c index 0e7c2b6a68..c97cf5f7b2 100644 --- a/src/mesa/tnl/t_draw.c +++ b/src/mesa/tnl/t_draw.c @@ -95,18 +95,14 @@ static void free_space(GLcontext *ctx) */ static void _tnl_import_array( GLcontext *ctx, GLuint attrib, - GLuint start, - GLuint end, + GLuint count, const struct gl_client_array *input, const GLubyte *ptr ) { TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; - const GLuint count = end - start; GLuint stride = input->StrideB; - ptr += start * stride; - if (input->Type != GL_FLOAT) { const GLuint sz = input->Size; GLubyte *buf = get_space(ctx, count * sz * sizeof(GLfloat)); @@ -183,7 +179,7 @@ static GLboolean *_tnl_import_edgeflag( GLcontext *ctx, static void bind_inputs( GLcontext *ctx, const struct gl_client_array *inputs[], - GLint min_index, GLint max_index, + GLint count, struct gl_buffer_object **bo, GLuint *nr_bo ) { @@ -215,18 +211,17 @@ static void bind_inputs( GLcontext *ctx, ptr = inputs[i]->Ptr; /* Just make sure the array is floating point, otherwise convert to - * temporary storage. Rebase arrays so that 'min_index' becomes - * element zero. + * temporary storage. * * XXX: remove the GLvector4f type at some stage and just use * client arrays. */ - _tnl_import_array(ctx, i, min_index, max_index, inputs[i], ptr); + _tnl_import_array(ctx, i, count, inputs[i], ptr); } /* We process only the vertices between min & max index: */ - VB->Count = max_index - min_index; + VB->Count = count; /* Legacy pointers -- remove one day. @@ -264,7 +259,6 @@ static void bind_inputs( GLcontext *ctx, */ static void bind_indices( GLcontext *ctx, const struct _mesa_index_buffer *ib, - GLuint min_index, struct gl_buffer_object **bo, GLuint *nr_bo) { @@ -273,8 +267,10 @@ static void bind_indices( GLcontext *ctx, GLuint i; void *ptr; - if (!ib) + if (!ib) { + VB->Elts = NULL; return; + } if (ib->obj->Name && !ib->obj->Pointer) { bo[*nr_bo] = ib->obj; @@ -289,60 +285,34 @@ static void bind_indices( GLcontext *ctx, ptr = ADD_POINTERS(ib->obj->Pointer, ib->ptr); - if (ib->type == GL_UNSIGNED_INT && min_index == 0) { + if (ib->type == GL_UNSIGNED_INT) { VB->Elts = (GLuint *) ptr; - VB->Elts += ib->rebase; } else { GLuint *elts = (GLuint *)get_space(ctx, ib->count * sizeof(GLuint)); VB->Elts = elts; - switch (ib->type) { - case GL_UNSIGNED_INT: { - const GLuint *in = ((GLuint *)ptr) + ib->rebase; - for (i = 0; i < ib->count; i++) - *elts++ = *in++ - min_index; - break; - } - case GL_UNSIGNED_SHORT: { - const GLushort *in = ((GLushort *)ptr) + ib->rebase; + if (ib->type == GL_UNSIGNED_SHORT) { + const GLushort *in = (GLushort *)ptr; for (i = 0; i < ib->count; i++) - *elts++ = (GLuint)(*in++) - min_index; - break; + *elts++ = (GLuint)(*in++); } - case GL_UNSIGNED_BYTE: { - const GLubyte *in = ((GLubyte *)ptr) + ib->rebase; + else { + const GLubyte *in = (GLubyte *)ptr; for (i = 0; i < ib->count; i++) - *elts++ = (GLuint)(*in++) - min_index; - break; + *elts++ = (GLuint)(*in++); } - } } } static void bind_prims( GLcontext *ctx, const struct _mesa_prim *prim, - GLuint nr_prims, - GLuint min_index ) + GLuint nr_prims ) { TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; - GLuint i; - - if (min_index != 0) { - struct _mesa_prim *tmp = (struct _mesa_prim *)get_space(ctx, nr_prims * sizeof(*prim)); - - for (i = 0; i < nr_prims; i++) { - tmp[i] = prim[i]; - tmp[i].start -= min_index; - } - - VB->Primitive = tmp; - } - else { - VB->Primitive = prim; - } + VB->Primitive = prim; VB->PrimitiveCount = nr_prims; } @@ -373,19 +343,10 @@ void _tnl_draw_prims( GLcontext *ctx, GLuint max_index) { TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - GLint max = VB->Size; - -#ifdef TEST_SPLIT - max = 8 + MAX_CLIPPED_VERTICES; -#endif - - assert(max_index > min_index); - assert(!(max_index & 0x80000000)); + const GLuint TEST_SPLIT = 0; + const GLint max = TEST_SPLIT ? 8 : tnl->vb.Size - MAX_CLIPPED_VERTICES; - VB->Elts = NULL; - -#if 0 + if (0) { GLuint i; _mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index); @@ -395,15 +356,22 @@ void _tnl_draw_prims( GLcontext *ctx, prim[i].start, prim[i].count); } -#endif - /* The software TNL pipeline has a fixed amount of storage for - * vertices and it is necessary to split incoming drawing commands - * if they exceed that limit. - */ - if (max_index - min_index >= max - MAX_CLIPPED_VERTICES) { + if (min_index) { + /* We always translate away calls with min_index != 0. + */ + vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib, + min_index, max_index, + _tnl_draw_prims ); + return; + } + else if (max_index >= max) { + /* The software TNL pipeline has a fixed amount of storage for + * vertices and it is necessary to split incoming drawing commands + * if they exceed that limit. + */ struct split_limits limits; - limits.max_verts = max - MAX_CLIPPED_VERTICES; + limits.max_verts = max; limits.max_vb_size = ~0; limits.max_indices = ~0; @@ -411,7 +379,7 @@ void _tnl_draw_prims( GLcontext *ctx, * recursively call back into this function. */ vbo_split_prims( ctx, arrays, prim, nr_prims, ib, - min_index, max_index, + 0, max_index, _tnl_draw_prims, &limits ); } @@ -425,9 +393,9 @@ void _tnl_draw_prims( GLcontext *ctx, /* Binding inputs may imply mapping some vertex buffer objects. * They will need to be unmapped below. */ - bind_inputs(ctx, arrays, min_index, max_index+1, bo, &nr_bo); - bind_indices(ctx, ib, min_index, bo, &nr_bo); - bind_prims(ctx, prim, nr_prims, VB->Elts ? 0 : min_index ); + bind_inputs(ctx, arrays, max_index+1, bo, &nr_bo); + bind_indices(ctx, ib, bo, &nr_bo); + bind_prims(ctx, prim, nr_prims ); TNL_CONTEXT(ctx)->Driver.RunPipeline(ctx); diff --git a/src/mesa/vbo/vbo.h b/src/mesa/vbo/vbo.h index 6a6fb28173..874a5f9e0e 100644 --- a/src/mesa/vbo/vbo.h +++ b/src/mesa/vbo/vbo.h @@ -55,7 +55,6 @@ struct _mesa_index_buffer { GLenum type; struct gl_buffer_object *obj; const void *ptr; - GLuint rebase; }; diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index 5a3a7488ed..f96df5f164 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -34,45 +34,55 @@ #include "vbo_context.h" -static GLuint get_max_index( GLuint count, GLuint type, - const GLvoid *indices ) +/* Compute min and max elements for drawelements calls. + */ +static void get_minmax_index( GLuint count, GLuint type, + const GLvoid *indices, + GLuint *min_index, + GLuint *max_index) { GLint i; - /* Compute max element. This is only needed for upload of non-VBO, - * non-constant data elements. - * - * XXX: Postpone this calculation until it is known that it is - * needed. Otherwise could scan this pointlessly in the all-vbo - * case. - */ switch(type) { case GL_UNSIGNED_INT: { const GLuint *ui_indices = (const GLuint *)indices; - GLuint max_ui = 0; - for (i = 0; i < count; i++) - if (ui_indices[i] > max_ui) - max_ui = ui_indices[i]; - return max_ui; + GLuint max_ui = ui_indices[0]; + GLuint min_ui = ui_indices[0]; + for (i = 1; i < count; i++) { + if (ui_indices[i] > max_ui) max_ui = ui_indices[i]; + if (ui_indices[i] < min_ui) min_ui = ui_indices[i]; + } + *min_index = min_ui; + *max_index = max_ui; + break; } case GL_UNSIGNED_SHORT: { const GLushort *us_indices = (const GLushort *)indices; - GLuint max_us = 0; - for (i = 0; i < count; i++) - if (us_indices[i] > max_us) - max_us = us_indices[i]; - return max_us; + GLuint max_us = us_indices[0]; + GLuint min_us = us_indices[0]; + for (i = 1; i < count; i++) { + if (us_indices[i] > max_us) max_us = us_indices[i]; + if (us_indices[i] < min_us) min_us = us_indices[i]; + } + *min_index = min_us; + *max_index = max_us; + break; } case GL_UNSIGNED_BYTE: { const GLubyte *ub_indices = (const GLubyte *)indices; - GLuint max_ub = 0; - for (i = 0; i < count; i++) - if (ub_indices[i] > max_ub) - max_ub = ub_indices[i]; - return max_ub; + GLuint max_ub = ub_indices[0]; + GLuint min_ub = ub_indices[0]; + for (i = 1; i < count; i++) { + if (ub_indices[i] > max_ub) max_ub = ub_indices[i]; + if (ub_indices[i] < min_ub) min_ub = ub_indices[i]; + } + *min_index = min_ub; + *max_index = max_ub; + break; } default: - return 0; + assert(0); + break; } } @@ -241,31 +251,12 @@ vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count) prim[0].end = 1; prim[0].weak = 0; prim[0].pad = 0; + prim[0].mode = mode; + prim[0].start = start; + prim[0].count = count; + prim[0].indexed = 0; - if (exec->array.inputs[0]->BufferObj->Name) { - /* Use vertex attribute as a hint to tell us if we expect all - * arrays to be in VBO's and if so, don't worry about avoiding - * the upload of elements < start. - */ - prim[0].mode = mode; - prim[0].start = start; - prim[0].count = count; - prim[0].indexed = 0; - - vbo->draw_prims( ctx, exec->array.inputs, prim, 1, NULL, 0, start + count ); - } - else { - /* If not using VBO's, we don't want to upload any more elements - * than necessary from the arrays as they will not be valid next - * time the application tries to draw with them. - */ - prim[0].mode = mode; - prim[0].start = 0; - prim[0].count = count; - prim[0].indexed = 0; - - vbo->draw_prims( ctx, exec->array.inputs, prim, 1, NULL, start, start + count ); - } + vbo->draw_prims( ctx, exec->array.inputs, prim, 1, NULL, start, start + count - 1 ); } @@ -296,20 +287,6 @@ vbo_exec_DrawRangeElements(GLenum mode, ib.obj = ctx->Array.ElementArrayBufferObj; ib.ptr = indices; - if (ctx->Array.ElementArrayBufferObj->Name) { - /* Use the fact that indices are in a VBO as a hint that the - * program has put all the arrays in VBO's and we don't have to - * worry about performance implications of start > 0. - * - * XXX: consider passing start as min_index to draw_prims instead. - * XXX: don't rebase because it didn't work. - */ - ib.rebase = 0; - } - else { - ib.rebase = /*start*/ 0; - } - prim[0].begin = 1; prim[0].end = 1; prim[0].weak = 0; @@ -319,15 +296,46 @@ vbo_exec_DrawRangeElements(GLenum mode, prim[0].count = count; prim[0].indexed = 1; - vbo->draw_prims( ctx, exec->array.inputs, prim, 1, &ib, /*ib.rebase*/ start, end+1 ); -} + /* Need to give special consideration to rendering a range of + * indices starting somewhere above zero. Typically the + * application is issuing multiple DrawRangeElements() to draw + * successive primitives layed out linearly in the vertex arrays. + * Unless the vertex arrays are all in a VBO (or locked as with + * CVA), the OpenGL semantics imply that we need to re-read or + * re-upload the vertex data on each draw call. + * + * In the case of hardware tnl, we want to avoid starting the + * upload at zero, as it will mean every draw call uploads an + * increasing amount of not-used vertex data. Worse - in the + * software tnl module, all those vertices might be transformed and + * lit but never rendered. + * + * If we just upload or transform the vertices in start..end, + * however, the indices will be incorrect. + * + * At this level, we don't know exactly what the requirements of + * the backend are going to be, though it will likely boil down to + * either: + * + * 1) Do nothing, everything is in a VBO and is processed once + * only. + * + * 2) Adjust the indices and vertex arrays so that start becomes + * zero. + * + * Rather than doing anything here, I'll provide a helper function + * for the latter case elsewhere. + */ + vbo->draw_prims( ctx, exec->array.inputs, prim, 1, &ib, start, end ); +} static void GLAPIENTRY vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) { GET_CURRENT_CONTEXT(ctx); - GLuint max_index; + GLuint min_index = 0; + GLuint max_index = 0; if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) return; @@ -338,17 +346,17 @@ vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *ind GL_READ_ONLY, ctx->Array.ElementArrayBufferObj); - max_index = get_max_index(count, type, ADD_POINTERS(map, indices)); + get_minmax_index(count, type, ADD_POINTERS(map, indices), &min_index, &max_index); ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, ctx->Array.ElementArrayBufferObj); } else { - max_index = get_max_index(count, type, indices); + get_minmax_index(count, type, indices, &min_index, &max_index); } - vbo_exec_DrawRangeElements(mode, 0, max_index, count, type, indices); + vbo_exec_DrawRangeElements(mode, min_index, max_index, count, type, indices); } diff --git a/src/mesa/vbo/vbo_rebase.c b/src/mesa/vbo/vbo_rebase.c index 2a6f03797a..bc4211d852 100644 --- a/src/mesa/vbo/vbo_rebase.c +++ b/src/mesa/vbo/vbo_rebase.c @@ -123,7 +123,8 @@ void vbo_rebase_prims( GLcontext *ctx, assert(min_index != 0); - _mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index); + if (0) + _mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index); if (ib) { /* Unfortunately need to adjust each index individually. diff --git a/src/mesa/vbo/vbo_split_copy.c b/src/mesa/vbo/vbo_split_copy.c index d9c5853782..ef97acbce7 100644 --- a/src/mesa/vbo/vbo_split_copy.c +++ b/src/mesa/vbo/vbo_split_copy.c @@ -479,7 +479,6 @@ static void replay_init( struct copy_context *copy ) copy->dstib.type = GL_UNSIGNED_INT; copy->dstib.obj = ctx->Array.NullBufferObj; copy->dstib.ptr = copy->dstelt; - copy->dstib.rebase = 0; } diff --git a/src/mesa/vbo/vbo_split_inplace.c b/src/mesa/vbo/vbo_split_inplace.c index d3649c59db..ea62866e7c 100644 --- a/src/mesa/vbo/vbo_split_inplace.c +++ b/src/mesa/vbo/vbo_split_inplace.c @@ -223,7 +223,6 @@ static void split_prims( struct split_context *split) ib.type = GL_UNSIGNED_INT; ib.obj = split->ctx->Array.NullBufferObj; ib.ptr = elts; - ib.rebase = 0; /* ? */ tmpprim = *prim; tmpprim.indexed = 1; -- cgit v1.2.3 From a2104dc6e18879ed3ba2108a09b6779e461eaa17 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Thu, 1 Feb 2007 01:09:26 +0100 Subject: fix unitialized values in radeonClear --- src/mesa/drivers/dri/radeon/radeon_ioctl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c index 737490fcde..4c64bc201a 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c @@ -1087,10 +1087,6 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask ) } } - /* Flip top to bottom */ - cx += dPriv->x; - cy = dPriv->y + dPriv->h - cy - ch; - LOCK_HARDWARE( rmesa ); /* compute region after locking: */ @@ -1099,6 +1095,10 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask ) cw = ctx->DrawBuffer->_Xmax - cx; ch = ctx->DrawBuffer->_Ymax - cy; + /* Flip top to bottom */ + cx += dPriv->x; + cy = dPriv->y + dPriv->h - cy - ch; + /* Throttle the number of clear ioctls we do. */ while ( 1 ) { -- cgit v1.2.3 From 605d428d20819ac3f46aaeb4a66707febec7ded2 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 Feb 2007 14:20:31 +0000 Subject: Cope with internally-generated null inputs. --- src/mesa/drivers/dri/i965/brw_draw.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index 7d8f837093..092c6bafc2 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -183,10 +183,13 @@ static void brw_merge_inputs( struct brw_context *brw, for (i = 0; i < VERT_ATTRIB_MAX; i++) { brw->vb.inputs[i].glarray = arrays[i]; - if (arrays[i]->StrideB != 0) - brw->vb.info.varying |= 1 << i; + /* XXX: metaops passes null arrays */ + if (arrays[i]) { + if (arrays[i]->StrideB != 0) + brw->vb.info.varying |= 1 << i; - brw->vb.info.sizes[i/16] |= (inputs[i].glarray->Size - 1) << ((i%16) * 2); + brw->vb.info.sizes[i/16] |= (inputs[i].glarray->Size - 1) << ((i%16) * 2); + } } /* Raise statechanges if input sizes and varying have changed: -- cgit v1.2.3 From 5368ae5ec329ddad5963d55b17cd4eccbc83d32f Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 1 Feb 2007 14:21:14 +0000 Subject: Correct usage/meaning of max_index parameter. --- src/mesa/drivers/dri/i965/brw_draw_upload.c | 4 +++- src/mesa/drivers/dri/i965/brw_metaops.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 6968d745c1..803a524324 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -408,6 +408,8 @@ GLboolean brw_upload_vertices( struct brw_context *brw, /* First build an array of pointers to ve's in vb.inputs_read */ + if (0) + _mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index); while (tmp) { GLuint i = ffsll(tmp)-1; @@ -418,7 +420,7 @@ GLboolean brw_upload_vertices( struct brw_context *brw, input->index = i; input->element_size = get_size(input->glarray->Type) * input->glarray->Size; - input->count = input->glarray->StrideB ? max_index - min_index : 1; + input->count = input->glarray->StrideB ? max_index + 1 - min_index : 1; if (!input->glarray->BufferObj->Name) { if (i == 0) { diff --git a/src/mesa/drivers/dri/i965/brw_metaops.c b/src/mesa/drivers/dri/i965/brw_metaops.c index 1728fc8f56..1579762b6d 100644 --- a/src/mesa/drivers/dri/i965/brw_metaops.c +++ b/src/mesa/drivers/dri/i965/brw_metaops.c @@ -480,7 +480,7 @@ static void meta_draw_quad(struct intel_context *intel, prim, 1, NULL, 0, - 4 ); + 3 ); } -- cgit v1.2.3 From 2dfb3a217f730d6783fb2ac8b73248dc682f923c Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Fri, 2 Feb 2007 09:35:17 +0800 Subject: Fix fd.o #9686, when fall into vertex fog, fog factors are precomputed in t_vb_fog.c compute_fog_blend_factors, which is incompatible with appended fragment fog code. That will make GoogleEarth display abnormally. always use pixel fog. --- src/mesa/drivers/dri/i915/i915_state.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c index 3cec6a2ddf..fd11e10652 100644 --- a/src/mesa/drivers/dri/i915/i915_state.c +++ b/src/mesa/drivers/dri/i915/i915_state.c @@ -611,10 +611,12 @@ void i915_update_fog( GLcontext *ctx ) i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_FOG_ENABLE; } - if (enabled) { - _tnl_allow_vertex_fog( ctx, (i915->vertex_fog == I915_FOG_VERTEX) ); - _tnl_allow_pixel_fog( ctx, (i915->vertex_fog != I915_FOG_VERTEX) ); - } + /* always enbale pixel fog + * vertex fog use precaculted fog coord will conflict with appended + * fog program + */ + _tnl_allow_vertex_fog( ctx, 0 ); + _tnl_allow_pixel_fog( ctx, 1 ); } static void i915Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) -- cgit v1.2.3 From 325196f548f8e46aa8fcc7b030e81ba939e7f6b7 Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Fri, 2 Feb 2007 14:37:24 +0800 Subject: push commit 2dfb3a217f730d6783fb2ac8b73248dc682f923c to i915tex --- src/mesa/drivers/dri/i915tex/i915_state.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/i915_state.c b/src/mesa/drivers/dri/i915tex/i915_state.c index 7c742a7bd9..78ae4bdb5f 100644 --- a/src/mesa/drivers/dri/i915tex/i915_state.c +++ b/src/mesa/drivers/dri/i915tex/i915_state.c @@ -645,10 +645,12 @@ i915_update_fog(GLcontext * ctx) i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_FOG_ENABLE; } - if (enabled) { - _tnl_allow_vertex_fog(ctx, (i915->vertex_fog == I915_FOG_VERTEX)); - _tnl_allow_pixel_fog(ctx, (i915->vertex_fog != I915_FOG_VERTEX)); - } + /* always enbale pixel fog + * vertex fog use precaculted fog coord will conflict with appended + * fog program + */ + _tnl_allow_vertex_fog( ctx, 0 ); + _tnl_allow_pixel_fog( ctx, 1 ); } static void -- cgit v1.2.3 From 47d463e954efcd15d20ab2c96a455aa16ddffdcc Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 2 Feb 2007 10:59:58 +0000 Subject: Modify assert to reflect rebase criteria --- src/mesa/drivers/dri/i965/brw_draw_upload.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c index 803a524324..feb0901d12 100644 --- a/src/mesa/drivers/dri/i965/brw_draw_upload.c +++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c @@ -439,7 +439,15 @@ GLboolean brw_upload_vertices( struct brw_context *brw, } upload[nr_uploads++] = input; - assert(min_index == 0); + + /* We rebase drawing to start at element zero only when + * varyings are not in vbos, which means we can end up + * uploading non-varying arrays (stride != 0) when min_index + * is zero. This doesn't matter as the amount to upload is + * the same for these arrays whether the draw call is rebased + * or not - we just have to upload the one element. + */ + assert(min_index == 0 || input->glarray->StrideB == 0); } } -- cgit v1.2.3 From 09e4df2c65c1bca0d04c6ffd076ea7808e61c4ae Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Sat, 3 Feb 2007 03:15:14 +0100 Subject: fix errorneously adding fog state params to all vertex programs... --- src/mesa/drivers/dri/r200/r200_vertprog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/r200/r200_vertprog.c b/src/mesa/drivers/dri/r200/r200_vertprog.c index 491701b796..713e2f9eca 100644 --- a/src/mesa/drivers/dri/r200/r200_vertprog.c +++ b/src/mesa/drivers/dri/r200/r200_vertprog.c @@ -461,7 +461,7 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte /* for fogc, can't change mesa_vp, as it would hose swtnl, and exp with base e isn't directly available neither. */ - if (mesa_vp->Base.OutputsWritten & VERT_RESULT_FOGC && !vp->fogpidx) { + if ((mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_FOGC)) && !vp->fogpidx) { struct gl_program_parameter_list *paramList; GLint tokens[6] = { STATE_FOG_PARAMS, 0, 0, 0, 0, 0 }; paramList = mesa_vp->Base.Parameters; -- cgit v1.2.3 From f697308ae583dbcdf0268e98232c32be7f25fac6 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Sat, 3 Feb 2007 03:15:45 +0100 Subject: remove now unused vtxfmt stuff from radeon/r200 header files --- src/mesa/drivers/dri/r200/r200_context.h | 124 --------------------------- src/mesa/drivers/dri/r200/r200_maos_arrays.c | 7 +- src/mesa/drivers/dri/radeon/radeon_context.h | 111 ------------------------ 3 files changed, 3 insertions(+), 239 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h index 44c67b68cb..26a43d20dd 100644 --- a/src/mesa/drivers/dri/r200/r200_context.h +++ b/src/mesa/drivers/dri/r200/r200_context.h @@ -724,8 +724,6 @@ struct r200_store { /* r200_tcl.c */ struct r200_tcl_info { - GLuint vertex_format; - GLint last_offset; GLuint hw_primitive; /* hw can handle 12 components max */ @@ -812,87 +810,6 @@ struct r200_ioctl { #define R200_MAX_PRIMS 64 -/* Want to keep a cache of these around. Each is parameterized by - * only a single value which has only a small range. Only expect a - * few, so just rescan the list each time? - */ -struct dynfn { - struct dynfn *next, *prev; - int key[2]; - char *code; -}; - -struct dfn_lists { - struct dynfn Vertex2f; - struct dynfn Vertex2fv; - struct dynfn Vertex3f; - struct dynfn Vertex3fv; - struct dynfn Color4ub; - struct dynfn Color4ubv; - struct dynfn Color3ub; - struct dynfn Color3ubv; - struct dynfn Color4f; - struct dynfn Color4fv; - struct dynfn Color3f; - struct dynfn Color3fv; - struct dynfn SecondaryColor3ubEXT; - struct dynfn SecondaryColor3ubvEXT; - struct dynfn SecondaryColor3fEXT; - struct dynfn SecondaryColor3fvEXT; - struct dynfn Normal3f; - struct dynfn Normal3fv; - struct dynfn TexCoord3f; - struct dynfn TexCoord3fv; - struct dynfn TexCoord2f; - struct dynfn TexCoord2fv; - struct dynfn TexCoord1f; - struct dynfn TexCoord1fv; - struct dynfn MultiTexCoord3fARB; - struct dynfn MultiTexCoord3fvARB; - struct dynfn MultiTexCoord2fARB; - struct dynfn MultiTexCoord2fvARB; - struct dynfn MultiTexCoord1fARB; - struct dynfn MultiTexCoord1fvARB; - struct dynfn FogCoordfEXT; - struct dynfn FogCoordfvEXT; -}; - -struct dfn_generators { - struct dynfn *(*Vertex2f)( GLcontext *, const int * ); - struct dynfn *(*Vertex2fv)( GLcontext *, const int * ); - struct dynfn *(*Vertex3f)( GLcontext *, const int * ); - struct dynfn *(*Vertex3fv)( GLcontext *, const int * ); - struct dynfn *(*Color4ub)( GLcontext *, const int * ); - struct dynfn *(*Color4ubv)( GLcontext *, const int * ); - struct dynfn *(*Color3ub)( GLcontext *, const int * ); - struct dynfn *(*Color3ubv)( GLcontext *, const int * ); - struct dynfn *(*Color4f)( GLcontext *, const int * ); - struct dynfn *(*Color4fv)( GLcontext *, const int * ); - struct dynfn *(*Color3f)( GLcontext *, const int * ); - struct dynfn *(*Color3fv)( GLcontext *, const int * ); - struct dynfn *(*SecondaryColor3ubEXT)( GLcontext *, const int * ); - struct dynfn *(*SecondaryColor3ubvEXT)( GLcontext *, const int * ); - struct dynfn *(*SecondaryColor3fEXT)( GLcontext *, const int * ); - struct dynfn *(*SecondaryColor3fvEXT)( GLcontext *, const int * ); - struct dynfn *(*Normal3f)( GLcontext *, const int * ); - struct dynfn *(*Normal3fv)( GLcontext *, const int * ); - struct dynfn *(*TexCoord3f)( GLcontext *, const int * ); - struct dynfn *(*TexCoord3fv)( GLcontext *, const int * ); - struct dynfn *(*TexCoord2f)( GLcontext *, const int * ); - struct dynfn *(*TexCoord2fv)( GLcontext *, const int * ); - struct dynfn *(*TexCoord1f)( GLcontext *, const int * ); - struct dynfn *(*TexCoord1fv)( GLcontext *, const int * ); - struct dynfn *(*MultiTexCoord3fARB)( GLcontext *, const int * ); - struct dynfn *(*MultiTexCoord3fvARB)( GLcontext *, const int * ); - struct dynfn *(*MultiTexCoord2fARB)( GLcontext *, const int * ); - struct dynfn *(*MultiTexCoord2fvARB)( GLcontext *, const int * ); - struct dynfn *(*MultiTexCoord1fARB)( GLcontext *, const int * ); - struct dynfn *(*MultiTexCoord1fvARB)( GLcontext *, const int * ); - struct dynfn *(*FogCoordfEXT)( GLcontext *, const int * ); - struct dynfn *(*FogCoordfvEXT)( GLcontext *, const int * ); -}; - - struct r200_prim { GLuint start; @@ -913,43 +830,6 @@ struct r200_prim { #define R200_MAX_VERTEX_SIZE ((3*6)+11) -struct r200_vbinfo { - GLint counter, initial_counter; - GLint *dmaptr; - void (*notify)( void ); - GLint vertex_size; - - union { float f; int i; r200_color_t color; } vertex[R200_MAX_VERTEX_SIZE]; - - GLfloat *normalptr; - GLfloat *floatcolorptr; - GLfloat *fogptr; - r200_color_t *colorptr; - GLfloat *floatspecptr; - r200_color_t *specptr; - GLfloat *texcoordptr[8]; /* 6 (TMU) + 2 for r200_vtxfmt_c.c when GL_TEXTURE6/7 */ - - - GLenum *prim; /* &ctx->Driver.CurrentExecPrimitive */ - GLuint primflags; - GLboolean enabled; /* *_NO_VTXFMT / *_NO_TCL env vars */ - GLboolean installed; - GLboolean fell_back; - GLboolean recheck; - GLint nrverts; - GLuint vtxfmt_0, vtxfmt_1; - - GLuint installed_vertex_format; - GLuint installed_color_3f_sz; - - struct r200_prim primlist[R200_MAX_PRIMS]; - int nrprims; - - struct dfn_lists dfn_cache; - struct dfn_generators codegen; - GLvertexformat vtxfmt; -}; - struct r200_context { GLcontext *glCtx; /* Mesa context */ @@ -1041,10 +921,6 @@ struct r200_context { */ struct r200_swtcl_info swtcl; - /* r200_vtxfmt.c - */ - struct r200_vbinfo vb; - /* Mirrors of some DRI state */ struct r200_dri_mirror dri; diff --git a/src/mesa/drivers/dri/r200/r200_maos_arrays.c b/src/mesa/drivers/dri/r200/r200_maos_arrays.c index 270dc35a46..db5ac6fc8a 100644 --- a/src/mesa/drivers/dri/r200/r200_maos_arrays.c +++ b/src/mesa/drivers/dri/r200/r200_maos_arrays.c @@ -664,14 +664,13 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs ) */ if (vfmt0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] || - vfmt1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) { - R200_STATECHANGE( rmesa, vtx ); + vfmt1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) { + R200_STATECHANGE( rmesa, vtx ); rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = vfmt0; rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = vfmt1; - } + } rmesa->tcl.nr_aos_components = nr; - rmesa->tcl.vertex_format = vfmt0; } diff --git a/src/mesa/drivers/dri/radeon/radeon_context.h b/src/mesa/drivers/dri/radeon/radeon_context.h index 0a7c3b2f54..02cea2f4e3 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_context.h @@ -529,7 +529,6 @@ struct radeon_store { */ struct radeon_tcl_info { GLuint vertex_format; - GLint last_offset; GLuint hw_primitive; /* Temporary for cases where incoming vertex data is incompatible @@ -600,75 +599,6 @@ struct radeon_ioctl { #define RADEON_MAX_PRIMS 64 -/* Want to keep a cache of these around. Each is parameterized by - * only a single value which has only a small range. Only expect a - * few, so just rescan the list each time? - */ -struct dynfn { - struct dynfn *next, *prev; - int key; - char *code; -}; - -struct dfn_lists { - struct dynfn Vertex2f; - struct dynfn Vertex2fv; - struct dynfn Vertex3f; - struct dynfn Vertex3fv; - struct dynfn Color4ub; - struct dynfn Color4ubv; - struct dynfn Color3ub; - struct dynfn Color3ubv; - struct dynfn Color4f; - struct dynfn Color4fv; - struct dynfn Color3f; - struct dynfn Color3fv; - struct dynfn SecondaryColor3ubEXT; - struct dynfn SecondaryColor3ubvEXT; - struct dynfn SecondaryColor3fEXT; - struct dynfn SecondaryColor3fvEXT; - struct dynfn Normal3f; - struct dynfn Normal3fv; - struct dynfn TexCoord2f; - struct dynfn TexCoord2fv; - struct dynfn TexCoord1f; - struct dynfn TexCoord1fv; - struct dynfn MultiTexCoord2fARB; - struct dynfn MultiTexCoord2fvARB; - struct dynfn MultiTexCoord1fARB; - struct dynfn MultiTexCoord1fvARB; -}; - -struct dfn_generators { - struct dynfn *(*Vertex2f)( GLcontext *, int ); - struct dynfn *(*Vertex2fv)( GLcontext *, int ); - struct dynfn *(*Vertex3f)( GLcontext *, int ); - struct dynfn *(*Vertex3fv)( GLcontext *, int ); - struct dynfn *(*Color4ub)( GLcontext *, int ); - struct dynfn *(*Color4ubv)( GLcontext *, int ); - struct dynfn *(*Color3ub)( GLcontext *, int ); - struct dynfn *(*Color3ubv)( GLcontext *, int ); - struct dynfn *(*Color4f)( GLcontext *, int ); - struct dynfn *(*Color4fv)( GLcontext *, int ); - struct dynfn *(*Color3f)( GLcontext *, int ); - struct dynfn *(*Color3fv)( GLcontext *, int ); - struct dynfn *(*SecondaryColor3ubEXT)( GLcontext *, int ); - struct dynfn *(*SecondaryColor3ubvEXT)( GLcontext *, int ); - struct dynfn *(*SecondaryColor3fEXT)( GLcontext *, int ); - struct dynfn *(*SecondaryColor3fvEXT)( GLcontext *, int ); - struct dynfn *(*Normal3f)( GLcontext *, int ); - struct dynfn *(*Normal3fv)( GLcontext *, int ); - struct dynfn *(*TexCoord2f)( GLcontext *, int ); - struct dynfn *(*TexCoord2fv)( GLcontext *, int ); - struct dynfn *(*TexCoord1f)( GLcontext *, int ); - struct dynfn *(*TexCoord1fv)( GLcontext *, int ); - struct dynfn *(*MultiTexCoord2fARB)( GLcontext *, int ); - struct dynfn *(*MultiTexCoord2fvARB)( GLcontext *, int ); - struct dynfn *(*MultiTexCoord1fARB)( GLcontext *, int ); - struct dynfn *(*MultiTexCoord1fvARB)( GLcontext *, int ); -}; - - struct radeon_prim { GLuint start; @@ -685,43 +615,6 @@ struct radeon_prim { */ #define RADEON_MAX_VERTEX_SIZE 20 -struct radeon_vbinfo { - GLint counter, initial_counter; - GLint *dmaptr; - void (*notify)( void ); - GLint vertex_size; - - union { float f; int i; radeon_color_t color; } vertex[RADEON_MAX_VERTEX_SIZE]; - - GLfloat *normalptr; - GLfloat *floatcolorptr; - radeon_color_t *colorptr; - GLfloat *floatspecptr; - radeon_color_t *specptr; - GLfloat *texcoordptr[4]; /* 3 (TMU) + 1 for radeon_vtxfmt_c.c when GL_TEXTURE3 */ - - GLenum *prim; /* &ctx->Driver.CurrentExecPrimitive */ - GLuint primflags; - GLboolean enabled; /* *_NO_VTXFMT / *_NO_TCL env vars */ - GLboolean installed; - GLboolean fell_back; - GLboolean recheck; - GLint nrverts; - GLuint vertex_format; - - GLuint installed_vertex_format; - GLuint installed_color_3f_sz; - - struct radeon_prim primlist[RADEON_MAX_PRIMS]; - int nrprims; - - struct dfn_lists dfn_cache; - struct dfn_generators codegen; - GLvertexformat vtxfmt; -}; - - - struct radeon_context { GLcontext *glCtx; /* Mesa context */ @@ -808,10 +701,6 @@ struct radeon_context { */ struct radeon_swtcl_info swtcl; - /* radeon_vtxfmt.c - */ - struct radeon_vbinfo vb; - /* Mirrors of some DRI state */ struct radeon_dri_mirror dri; -- cgit v1.2.3 From 2a441c488f4bcf11fe032ea7ba448bbfb7449c66 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Sat, 3 Feb 2007 03:31:31 +0100 Subject: disable r200 materials-between-begin-end check if vertex progs are enabled --- src/mesa/drivers/dri/r200/r200_state.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c index bab767838d..bdb487f2b9 100644 --- a/src/mesa/drivers/dri/r200/r200_state.c +++ b/src/mesa/drivers/dri/r200/r200_state.c @@ -2542,15 +2542,17 @@ static void r200InvalidateState( GLcontext *ctx, GLuint new_state ) } /* A hack. The r200 can actually cope just fine with materials - * between begin/ends, so fix this. But how ? + * between begin/ends, so fix this. + * Should map to inputs just like the generic vertex arrays for vertex progs. + * In theory there could still be too many and we'd still need a fallback. */ static GLboolean check_material( GLcontext *ctx ) { TNLcontext *tnl = TNL_CONTEXT(ctx); GLint i; - for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT; - i < _TNL_ATTRIB_MAT_BACK_INDEXES; + for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT; + i < _TNL_ATTRIB_MAT_BACK_INDEXES; i++) if (tnl->vb.AttribPtr[i] && tnl->vb.AttribPtr[i]->stride) @@ -2558,7 +2560,7 @@ static GLboolean check_material( GLcontext *ctx ) return GL_FALSE; } - + static void r200WrapRunPipeline( GLcontext *ctx ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); @@ -2572,7 +2574,7 @@ static void r200WrapRunPipeline( GLcontext *ctx ) if (rmesa->NewGLState) r200ValidateState( ctx ); - has_material = (ctx->Light.Enabled && check_material( ctx )); + has_material = !ctx->VertexProgram._Enabled && ctx->Light.Enabled && check_material( ctx ); if (has_material) { TCL_FALLBACK( ctx, R200_TCL_FALLBACK_MATERIAL, GL_TRUE ); -- cgit v1.2.3 From 1c25561e30ada8036d00aa84344377aa2a4f791a Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 3 Feb 2007 13:20:16 +0100 Subject: nouveau: use color pitch as depth pitch if depth disabled --- src/mesa/drivers/dri/nouveau/nv10_state.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index f6e47b7f48..055f538a3a 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -667,7 +667,7 @@ static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color, nouveau_renderbuffer *depth) { GLuint x, y, w, h; - GLuint pitch, format; + GLuint pitch, format, depth_pitch; w = color[0]->mesa.Width; h = color[0]->mesa.Height; @@ -680,10 +680,8 @@ static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color, BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 6); OUT_RING_CACHE((w << 16) | x); OUT_RING_CACHE((h << 16) | y); - pitch = color[0]->pitch; - if (depth) { - pitch |= (depth->pitch << 16); - } + depth_pitch = (depth ? depth->pitch : color[0]->pitch); + pitch = (depth_pitch<<16) | color[0]->pitch; format = 0x108; if (color[0]->mesa._ActualFormat != GL_RGBA8) { format = 0x103; /* R5G6B5 color buffer */ -- cgit v1.2.3 From de24b01b05d4c7402c06851dd7dbbb5854b1ff41 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 3 Feb 2007 13:22:42 +0100 Subject: nouveau: fix viewport clipping initialization --- src/mesa/drivers/dri/nouveau/nv10_state.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 055f538a3a..88c1d7d9e1 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -612,10 +612,13 @@ static void nv10WindowMoved(nouveauContextPtr nmesa) OUT_RING_CACHE((h << 16) | y); /* something to do with clears, possibly doesn't belong here */ + BEGIN_RING_SIZE(NvSub3D, 0x02b4, 1); + OUT_RING(0); + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 2); - OUT_RING_CACHE(((w+x) << 16) | x | 0x800); - OUT_RING_CACHE(((h+y) << 16) | y | 0x800); + OUT_RING_CACHE(((w+x-1) << 16) | x | 0x08000800); + OUT_RING_CACHE(((h+y-1) << 16) | y | 0x08000800); for (i=1; i<7; i++) { BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 1); @@ -651,14 +654,12 @@ static GLboolean nv10InitCard(nouveauContextPtr nmesa) OUT_RING(NvDmaFB); /* 194 dma_in_memory2 */ OUT_RING(NvDmaFB); /* 198 dma_in_memory3 */ - BEGIN_RING_SIZE(NvSub3D, 0x02b4, 1); - OUT_RING(0); BEGIN_RING_SIZE(NvSub3D, 0x0290, 1); OUT_RING(0x00100001); BEGIN_RING_SIZE(NvSub3D, 0x03f4, 1); OUT_RING(0); - return GL_FALSE; + return GL_TRUE; } /* Update buffer offset/pitch/format */ -- cgit v1.2.3 From 0afc2d37c32540b90bcb7861186b80a781dc0a4a Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Sat, 3 Feb 2007 17:23:19 +0100 Subject: r300CreateContext: Really initialize r300->initialMaxAnisotropy. --- src/mesa/drivers/dri/r300/r300_context.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index 00489ba14e..d10a9d87d3 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -200,6 +200,8 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, */ driParseConfigFiles(&r300->radeon.optionCache, &screen->optionCache, screen->driScreen->myNum, "r300"); + r300->initialMaxAnisotropy = driQueryOptionf(&r300->radeon.optionCache, + "def_max_anisotropy"); //r300->texmicrotile = GL_TRUE; -- cgit v1.2.3 From beffa17bb984b29696a99a0c54922ff6a7d0b386 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Sat, 3 Feb 2007 17:24:22 +0100 Subject: Remove unused r200 files from r300 driver directory. --- src/mesa/drivers/dri/r300/r200_context.h | 822 ----------------- src/mesa/drivers/dri/r300/r200_ioctl.h | 204 ----- src/mesa/drivers/dri/r300/r200_reg.h | 1423 ------------------------------ src/mesa/drivers/dri/r300/r200_state.h | 58 -- 4 files changed, 2507 deletions(-) delete mode 100644 src/mesa/drivers/dri/r300/r200_context.h delete mode 100644 src/mesa/drivers/dri/r300/r200_ioctl.h delete mode 100644 src/mesa/drivers/dri/r300/r200_reg.h delete mode 100644 src/mesa/drivers/dri/r300/r200_state.h (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/r300/r200_context.h b/src/mesa/drivers/dri/r300/r200_context.h deleted file mode 100644 index a06d7152d7..0000000000 --- a/src/mesa/drivers/dri/r300/r200_context.h +++ /dev/null @@ -1,822 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_context.h,v 1.2 2002/12/16 16:18:54 dawes Exp $ */ -/* -Copyright (C) The Weather Channel, Inc. 2002. 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 - */ - -#ifndef __R200_CONTEXT_H__ -#define __R200_CONTEXT_H__ - -#ifdef GLX_DIRECT_RENDERING - -#include "tnl/t_vertex.h" -#include "drm.h" -#include "radeon_drm.h" -#include "dri_util.h" -#include "texmem.h" - -#include "macros.h" -#include "mtypes.h" -#include "colormac.h" -#include "r200_reg.h" -#include "radeon_context.h" - -#define ENABLE_HW_3D_TEXTURE 1 /* XXX this is temporary! */ - -struct r200_context; -typedef struct r200_context r200ContextRec; -typedef struct r200_context *r200ContextPtr; - -#include "mm.h" - -/* The blit width for texture uploads - */ -#define BLIT_WIDTH_BYTES 1024 - -/* Use the templated vertex format: - */ -#define COLOR_IS_RGBA -#define TAG(x) r200##x -#include "tnl_dd/t_dd_vertex.h" -#undef TAG - -typedef void (*r200_tri_func) (r200ContextPtr, - r200Vertex *, r200Vertex *, r200Vertex *); - -typedef void (*r200_line_func) (r200ContextPtr, r200Vertex *, r200Vertex *); - -typedef void (*r200_point_func) (r200ContextPtr, r200Vertex *); - -struct r200_depthbuffer_state { - GLfloat scale; -}; - -struct r200_stencilbuffer_state { - GLboolean hwBuffer; - GLuint clear; /* rb3d_stencilrefmask value */ -}; - -struct r200_stipple_state { - GLuint mask[32]; -}; - -typedef struct r200_tex_obj r200TexObj, *r200TexObjPtr; - -/* Texture object in locally shared texture space. - */ -struct r200_tex_obj { - driTextureObject base; - - GLuint bufAddr; /* Offset to start of locally - shared texture block */ - - GLuint dirty_state; /* Flags (1 per texunit) for - whether or not this texobj - has dirty hardware state - (pp_*) that needs to be - brought into the - texunit. */ - - drm_radeon_tex_image_t image[6][RADEON_MAX_TEXTURE_LEVELS]; - /* Six, for the cube faces */ - - GLuint pp_txfilter; /* hardware register values */ - GLuint pp_txformat; - GLuint pp_txformat_x; - GLuint pp_txoffset; /* Image location in texmem. - All cube faces follow. */ - GLuint pp_txsize; /* npot only */ - GLuint pp_txpitch; /* npot only */ - GLuint pp_border_color; - GLuint pp_cubic_faces; /* cube face 1,2,3,4 log2 sizes */ - - GLboolean border_fallback; -}; - -struct r200_texture_env_state { - r200TexObjPtr texobj; - GLenum format; - GLenum envMode; -}; - -#define R200_MAX_TEXTURE_UNITS 6 - -struct r200_texture_state { - struct r200_texture_env_state unit[R200_MAX_TEXTURE_UNITS]; -}; - -struct r200_state_atom { - struct r200_state_atom *next, *prev; - const char *name; /* for debug */ - int cmd_size; /* size in bytes */ - GLuint idx; - int *cmd; /* one or more cmd's */ - int *lastcmd; /* one or more cmd's */ - int *savedcmd; /* one or more cmd's */ - GLboolean dirty; - GLboolean(*check) (GLcontext *, int); /* is this state active? */ -}; - -/* Trying to keep these relatively short as the variables are becoming - * extravagently long. Drop the driver name prefix off the front of - * everything - I think we know which driver we're in by now, and keep the - * prefix to 3 letters unless absolutely impossible. - */ - -#define CTX_CMD_0 0 -#define CTX_PP_MISC 1 -#define CTX_PP_FOG_COLOR 2 -#define CTX_RE_SOLID_COLOR 3 -#define CTX_RB3D_BLENDCNTL 4 -#define CTX_RB3D_DEPTHOFFSET 5 -#define CTX_RB3D_DEPTHPITCH 6 -#define CTX_RB3D_ZSTENCILCNTL 7 -#define CTX_CMD_1 8 -#define CTX_PP_CNTL 9 -#define CTX_RB3D_CNTL 10 -#define CTX_RB3D_COLOROFFSET 11 -#define CTX_CMD_2 12 /* why */ -#define CTX_RB3D_COLORPITCH 13 /* why */ -#define CTX_STATE_SIZE_OLDDRM 14 -#define CTX_CMD_3 14 -#define CTX_RB3D_BLENDCOLOR 15 -#define CTX_RB3D_ABLENDCNTL 16 -#define CTX_RB3D_CBLENDCNTL 17 -#define CTX_STATE_SIZE_NEWDRM 18 - -#define SET_CMD_0 0 -#define SET_SE_CNTL 1 -#define SET_RE_CNTL 2 /* replace se_coord_fmt */ -#define SET_STATE_SIZE 3 - -#define VTE_CMD_0 0 -#define VTE_SE_VTE_CNTL 1 -#define VTE_STATE_SIZE 2 - -#define LIN_CMD_0 0 -#define LIN_RE_LINE_PATTERN 1 -#define LIN_RE_LINE_STATE 2 -#define LIN_CMD_1 3 -#define LIN_SE_LINE_WIDTH 4 -#define LIN_STATE_SIZE 5 - -#define MSK_CMD_0 0 -#define MSK_RB3D_STENCILREFMASK 1 -#define MSK_RB3D_ROPCNTL 2 -#define MSK_RB3D_PLANEMASK 3 -#define MSK_STATE_SIZE 4 - -#define VPT_CMD_0 0 -#define VPT_SE_VPORT_XSCALE 1 -#define VPT_SE_VPORT_XOFFSET 2 -#define VPT_SE_VPORT_YSCALE 3 -#define VPT_SE_VPORT_YOFFSET 4 -#define VPT_SE_VPORT_ZSCALE 5 -#define VPT_SE_VPORT_ZOFFSET 6 -#define VPT_STATE_SIZE 7 - -#define ZBS_CMD_0 0 -#define ZBS_SE_ZBIAS_FACTOR 1 -#define ZBS_SE_ZBIAS_CONSTANT 2 -#define ZBS_STATE_SIZE 3 - -#define MSC_CMD_0 0 -#define MSC_RE_MISC 1 -#define MSC_STATE_SIZE 2 - -#define TAM_CMD_0 0 -#define TAM_DEBUG3 1 -#define TAM_STATE_SIZE 2 - -#define TEX_CMD_0 0 -#define TEX_PP_TXFILTER 1 /*2c00 */ -#define TEX_PP_TXFORMAT 2 /*2c04 */ -#define TEX_PP_TXFORMAT_X 3 /*2c08 */ -#define TEX_PP_TXSIZE 4 /*2c0c */ -#define TEX_PP_TXPITCH 5 /*2c10 */ -#define TEX_PP_BORDER_COLOR 6 /*2c14 */ -#define TEX_CMD_1 7 -#define TEX_PP_TXOFFSET 8 /*2d00 */ -#define TEX_STATE_SIZE 9 - -#define CUBE_CMD_0 0 /* 1 register follows */ -#define CUBE_PP_CUBIC_FACES 1 /* 0x2c18 */ -#define CUBE_CMD_1 2 /* 5 registers follow */ -#define CUBE_PP_CUBIC_OFFSET_F1 3 /* 0x2d04 */ -#define CUBE_PP_CUBIC_OFFSET_F2 4 /* 0x2d08 */ -#define CUBE_PP_CUBIC_OFFSET_F3 5 /* 0x2d0c */ -#define CUBE_PP_CUBIC_OFFSET_F4 6 /* 0x2d10 */ -#define CUBE_PP_CUBIC_OFFSET_F5 7 /* 0x2d14 */ -#define CUBE_STATE_SIZE 8 - -#define PIX_CMD_0 0 -#define PIX_PP_TXCBLEND 1 -#define PIX_PP_TXCBLEND2 2 -#define PIX_PP_TXABLEND 3 -#define PIX_PP_TXABLEND2 4 -#define PIX_STATE_SIZE 5 - -#define TF_CMD_0 0 -#define TF_TFACTOR_0 1 -#define TF_TFACTOR_1 2 -#define TF_TFACTOR_2 3 -#define TF_TFACTOR_3 4 -#define TF_TFACTOR_4 5 -#define TF_TFACTOR_5 6 -#define TF_STATE_SIZE 7 - -#define TCL_CMD_0 0 -#define TCL_LIGHT_MODEL_CTL_0 1 -#define TCL_LIGHT_MODEL_CTL_1 2 -#define TCL_PER_LIGHT_CTL_0 3 -#define TCL_PER_LIGHT_CTL_1 4 -#define TCL_PER_LIGHT_CTL_2 5 -#define TCL_PER_LIGHT_CTL_3 6 -#define TCL_CMD_1 7 -#define TCL_UCP_VERT_BLEND_CTL 8 -#define TCL_STATE_SIZE 9 - -#define MSL_CMD_0 0 -#define MSL_MATRIX_SELECT_0 1 -#define MSL_MATRIX_SELECT_1 2 -#define MSL_MATRIX_SELECT_2 3 -#define MSL_MATRIX_SELECT_3 4 -#define MSL_MATRIX_SELECT_4 5 -#define MSL_STATE_SIZE 6 - -#define TCG_CMD_0 0 -#define TCG_TEX_PROC_CTL_2 1 -#define TCG_TEX_PROC_CTL_3 2 -#define TCG_TEX_PROC_CTL_0 3 -#define TCG_TEX_PROC_CTL_1 4 -#define TCG_TEX_CYL_WRAP_CTL 5 -#define TCG_STATE_SIZE 6 - -#define MTL_CMD_0 0 -#define MTL_EMMISSIVE_RED 1 -#define MTL_EMMISSIVE_GREEN 2 -#define MTL_EMMISSIVE_BLUE 3 -#define MTL_EMMISSIVE_ALPHA 4 -#define MTL_AMBIENT_RED 5 -#define MTL_AMBIENT_GREEN 6 -#define MTL_AMBIENT_BLUE 7 -#define MTL_AMBIENT_ALPHA 8 -#define MTL_DIFFUSE_RED 9 -#define MTL_DIFFUSE_GREEN 10 -#define MTL_DIFFUSE_BLUE 11 -#define MTL_DIFFUSE_ALPHA 12 -#define MTL_SPECULAR_RED 13 -#define MTL_SPECULAR_GREEN 14 -#define MTL_SPECULAR_BLUE 15 -#define MTL_SPECULAR_ALPHA 16 -#define MTL_CMD_1 17 -#define MTL_SHININESS 18 -#define MTL_STATE_SIZE 19 - -#define VAP_CMD_0 0 -#define VAP_SE_VAP_CNTL 1 -#define VAP_STATE_SIZE 2 - -/* Replaces a lot of packet info from radeon - */ -#define VTX_CMD_0 0 -#define VTX_VTXFMT_0 1 -#define VTX_VTXFMT_1 2 -#define VTX_TCL_OUTPUT_VTXFMT_0 3 -#define VTX_TCL_OUTPUT_VTXFMT_1 4 -#define VTX_CMD_1 5 -#define VTX_TCL_OUTPUT_COMPSEL 6 -#define VTX_CMD_2 7 -#define VTX_STATE_CNTL 8 -#define VTX_STATE_SIZE 9 - -#define VTX_COLOR(v,n) (((v)>>(R200_VTX_COLOR_0_SHIFT+(n)*2))&\ - R200_VTX_COLOR_MASK) - -/** - * Given the \c R200_SE_VTX_FMT_1 for the current vertex state, determine - * how many components are in texture coordinate \c n. - */ -#define VTX_TEXn_COUNT(v,n) (((v) >> (3 * n)) & 0x07) - -#define MAT_CMD_0 0 -#define MAT_ELT_0 1 -#define MAT_STATE_SIZE 17 - -#define GRD_CMD_0 0 -#define GRD_VERT_GUARD_CLIP_ADJ 1 -#define GRD_VERT_GUARD_DISCARD_ADJ 2 -#define GRD_HORZ_GUARD_CLIP_ADJ 3 -#define GRD_HORZ_GUARD_DISCARD_ADJ 4 -#define GRD_STATE_SIZE 5 - -/* position changes frequently when lighting in modelpos - separate - * out to new state item? - */ -#define LIT_CMD_0 0 -#define LIT_AMBIENT_RED 1 -#define LIT_AMBIENT_GREEN 2 -#define LIT_AMBIENT_BLUE 3 -#define LIT_AMBIENT_ALPHA 4 -#define LIT_DIFFUSE_RED 5 -#define LIT_DIFFUSE_GREEN 6 -#define LIT_DIFFUSE_BLUE 7 -#define LIT_DIFFUSE_ALPHA 8 -#define LIT_SPECULAR_RED 9 -#define LIT_SPECULAR_GREEN 10 -#define LIT_SPECULAR_BLUE 11 -#define LIT_SPECULAR_ALPHA 12 -#define LIT_POSITION_X 13 -#define LIT_POSITION_Y 14 -#define LIT_POSITION_Z 15 -#define LIT_POSITION_W 16 -#define LIT_DIRECTION_X 17 -#define LIT_DIRECTION_Y 18 -#define LIT_DIRECTION_Z 19 -#define LIT_DIRECTION_W 20 -#define LIT_ATTEN_QUADRATIC 21 -#define LIT_ATTEN_LINEAR 22 -#define LIT_ATTEN_CONST 23 -#define LIT_ATTEN_XXX 24 -#define LIT_CMD_1 25 -#define LIT_SPOT_DCD 26 -#define LIT_SPOT_DCM 27 -#define LIT_SPOT_EXPONENT 28 -#define LIT_SPOT_CUTOFF 29 -#define LIT_SPECULAR_THRESH 30 -#define LIT_RANGE_CUTOFF 31 /* ? */ -#define LIT_ATTEN_CONST_INV 32 -#define LIT_STATE_SIZE 33 - -/* Fog - */ -#define FOG_CMD_0 0 -#define FOG_R 1 -#define FOG_C 2 -#define FOG_D 3 -#define FOG_PAD 4 -#define FOG_STATE_SIZE 5 - -/* UCP - */ -#define UCP_CMD_0 0 -#define UCP_X 1 -#define UCP_Y 2 -#define UCP_Z 3 -#define UCP_W 4 -#define UCP_STATE_SIZE 5 - -/* GLT - Global ambient - */ -#define GLT_CMD_0 0 -#define GLT_RED 1 -#define GLT_GREEN 2 -#define GLT_BLUE 3 -#define GLT_ALPHA 4 -#define GLT_STATE_SIZE 5 - -/* EYE - */ -#define EYE_CMD_0 0 -#define EYE_X 1 -#define EYE_Y 2 -#define EYE_Z 3 -#define EYE_RESCALE_FACTOR 4 -#define EYE_STATE_SIZE 5 - -/* CST - constant state - */ -#define CST_CMD_0 0 -#define CST_PP_CNTL_X 1 -#define CST_CMD_1 2 -#define CST_RB3D_DEPTHXY_OFFSET 3 -#define CST_CMD_2 4 -#define CST_RE_AUX_SCISSOR_CNTL 5 -#define CST_CMD_3 6 -#define CST_RE_SCISSOR_TL_0 7 -#define CST_RE_SCISSOR_BR_0 8 -#define CST_CMD_4 9 -#define CST_SE_VAP_CNTL_STATUS 10 -#define CST_CMD_5 11 -#define CST_RE_POINTSIZE 12 -#define CST_CMD_6 13 -#define CST_SE_TCL_INPUT_VTX_0 14 -#define CST_SE_TCL_INPUT_VTX_1 15 -#define CST_SE_TCL_INPUT_VTX_2 16 -#define CST_SE_TCL_INPUT_VTX_3 17 -#define CST_STATE_SIZE 18 - -struct r200_hw_state { - /* Head of the linked list of state atoms. */ - struct r200_state_atom atomlist; - - /* Hardware state, stored as cmdbuf commands: - * -- Need to doublebuffer for - * - reviving state after loss of context - * - eliding noop statechange loops? (except line stipple count) - */ - struct r200_state_atom ctx; - struct r200_state_atom set; - struct r200_state_atom vte; - struct r200_state_atom lin; - struct r200_state_atom msk; - struct r200_state_atom vpt; - struct r200_state_atom vap; - struct r200_state_atom vtx; - struct r200_state_atom tcl; - struct r200_state_atom msl; - struct r200_state_atom tcg; - struct r200_state_atom msc; - struct r200_state_atom cst; - struct r200_state_atom tam; - struct r200_state_atom tf; - struct r200_state_atom tex[6]; - struct r200_state_atom cube[6]; - struct r200_state_atom zbs; - struct r200_state_atom mtl[2]; - struct r200_state_atom mat[9]; - struct r200_state_atom lit[8]; /* includes vec, scl commands */ - struct r200_state_atom ucp[6]; - struct r200_state_atom pix[6]; /* pixshader stages */ - struct r200_state_atom eye; /* eye pos */ - struct r200_state_atom grd; /* guard band clipping */ - struct r200_state_atom fog; - struct r200_state_atom glt; - - int max_state_size; /* Number of bytes necessary for a full state emit. */ - GLboolean is_dirty, all_dirty; -}; - -struct r200_colorbuffer_state { - int roundEnable; -}; - -struct r200_state { - /* Derived state for internal purposes: - */ - struct r200_colorbuffer_state color; - struct r200_depthbuffer_state depth; - struct r200_stencilbuffer_state stencil; - struct r200_stipple_state stipple; - struct r200_texture_state texture; -}; - -/* Need refcounting on dma buffers: - */ -struct r200_dma_buffer { - int refcount; /* the number of retained regions in buf */ - drmBufPtr buf; -}; - -#define GET_START(rvb) (rmesa->radeon.radeonScreen->gart_buffer_offset + \ - (rvb)->address - rmesa->dma.buf0_address + \ - (rvb)->start) - -/* A retained region, eg vertices for indexed vertices. - */ -struct r200_dma_region { - struct r200_dma_buffer *buf; - char *address; /* == buf->address */ - int start, end, ptr; /* offsets from start of buf */ - int aos_start; - int aos_stride; - int aos_size; -}; - -struct r200_dma { - /* Active dma region. Allocations for vertices and retained - * regions come from here. Also used for emitting random vertices, - * these may be flushed by calling flush_current(); - */ - struct r200_dma_region current; - - void (*flush) (r200ContextPtr); - - char *buf0_address; /* start of buf[0], for index calcs */ - GLuint nr_released_bufs; /* flush after so many buffers released */ -}; - -#define R200_CMD_BUF_SZ (8*1024) - -struct r200_store { - GLuint statenr; - GLuint primnr; - char cmd_buf[R200_CMD_BUF_SZ]; - int cmd_used; - int elts_start; -}; - -/* r200_tcl.c - */ -struct r200_tcl_info { - GLuint vertex_format; - GLint last_offset; - GLuint hw_primitive; - - struct r200_dma_region *aos_components[8]; - GLuint nr_aos_components; - - GLuint *Elts; - - struct r200_dma_region indexed_verts; - struct r200_dma_region obj; - struct r200_dma_region rgba; - struct r200_dma_region spec; - struct r200_dma_region fog; - struct r200_dma_region tex[R200_MAX_TEXTURE_UNITS]; - struct r200_dma_region norm; -}; - -/* r200_swtcl.c - */ -struct r200_swtcl_info { - GLuint RenderIndex; - - /** - * Size of a hardware vertex. This is calculated when \c ::vertex_attrs is - * installed in the Mesa state vector. - */ - GLuint vertex_size; - - /** - * Attributes instructing the Mesa TCL pipeline where / how to put vertex - * data in the hardware buffer. - */ - struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; - - /** - * Number of elements of \c ::vertex_attrs that are actually used. - */ - GLuint vertex_attr_count; - - /** - * Cached pointer to the buffer where Mesa will store vertex data. - */ - GLubyte *verts; - - /* Fallback rasterization functions - */ - r200_point_func draw_point; - r200_line_func draw_line; - r200_tri_func draw_tri; - - GLuint hw_primitive; - GLenum render_primitive; - GLuint numverts; - - /** - * Offset of the 4UB color data within a hardware (swtcl) vertex. - */ - GLuint coloroffset; - - /** - * Offset of the 3UB specular color data within a hardware (swtcl) vertex. - */ - GLuint specoffset; - - /** - * Should Mesa project vertex data or will the hardware do it? - */ - GLboolean needproj; - - struct r200_dma_region indexed_verts; -}; - -struct r200_ioctl { - GLuint vertex_offset; - GLuint vertex_size; -}; - -#define R200_MAX_PRIMS 64 - -/* Want to keep a cache of these around. Each is parameterized by - * only a single value which has only a small range. Only expect a - * few, so just rescan the list each time? - */ -struct dynfn { - struct dynfn *next, *prev; - int key[2]; - char *code; -}; - -struct dfn_lists { - struct dynfn Vertex2f; - struct dynfn Vertex2fv; - struct dynfn Vertex3f; - struct dynfn Vertex3fv; - struct dynfn Color4ub; - struct dynfn Color4ubv; - struct dynfn Color3ub; - struct dynfn Color3ubv; - struct dynfn Color4f; - struct dynfn Color4fv; - struct dynfn Color3f; - struct dynfn Color3fv; - struct dynfn SecondaryColor3ubEXT; - struct dynfn SecondaryColor3ubvEXT; - struct dynfn SecondaryColor3fEXT; - struct dynfn SecondaryColor3fvEXT; - struct dynfn Normal3f; - struct dynfn Normal3fv; - struct dynfn TexCoord3f; - struct dynfn TexCoord3fv; - struct dynfn TexCoord2f; - struct dynfn TexCoord2fv; - struct dynfn TexCoord1f; - struct dynfn TexCoord1fv; - struct dynfn MultiTexCoord3fARB; - struct dynfn MultiTexCoord3fvARB; - struct dynfn MultiTexCoord2fARB; - struct dynfn MultiTexCoord2fvARB; - struct dynfn MultiTexCoord1fARB; - struct dynfn MultiTexCoord1fvARB; -}; - -struct dfn_generators { - struct dynfn *(*Vertex2f) (GLcontext *, const int *); - struct dynfn *(*Vertex2fv) (GLcontext *, const int *); - struct dynfn *(*Vertex3f) (GLcontext *, const int *); - struct dynfn *(*Vertex3fv) (GLcontext *, const int *); - struct dynfn *(*Color4ub) (GLcontext *, const int *); - struct dynfn *(*Color4ubv) (GLcontext *, const int *); - struct dynfn *(*Color3ub) (GLcontext *, const int *); - struct dynfn *(*Color3ubv) (GLcontext *, const int *); - struct dynfn *(*Color4f) (GLcontext *, const int *); - struct dynfn *(*Color4fv) (GLcontext *, const int *); - struct dynfn *(*Color3f) (GLcontext *, const int *); - struct dynfn *(*Color3fv) (GLcontext *, const int *); - struct dynfn *(*SecondaryColor3ubEXT) (GLcontext *, const int *); - struct dynfn *(*SecondaryColor3ubvEXT) (GLcontext *, const int *); - struct dynfn *(*SecondaryColor3fEXT) (GLcontext *, const int *); - struct dynfn *(*SecondaryColor3fvEXT) (GLcontext *, const int *); - struct dynfn *(*Normal3f) (GLcontext *, const int *); - struct dynfn *(*Normal3fv) (GLcontext *, const int *); - struct dynfn *(*TexCoord3f) (GLcontext *, const int *); - struct dynfn *(*TexCoord3fv) (GLcontext *, const int *); - struct dynfn *(*TexCoord2f) (GLcontext *, const int *); - struct dynfn *(*TexCoord2fv) (GLcontext *, const int *); - struct dynfn *(*TexCoord1f) (GLcontext *, const int *); - struct dynfn *(*TexCoord1fv) (GLcontext *, const int *); - struct dynfn *(*MultiTexCoord3fARB) (GLcontext *, const int *); - struct dynfn *(*MultiTexCoord3fvARB) (GLcontext *, const int *); - struct dynfn *(*MultiTexCoord2fARB) (GLcontext *, const int *); - struct dynfn *(*MultiTexCoord2fvARB) (GLcontext *, const int *); - struct dynfn *(*MultiTexCoord1fARB) (GLcontext *, const int *); - struct dynfn *(*MultiTexCoord1fvARB) (GLcontext *, const int *); -}; - -struct r200_prim { - GLuint start; - GLuint end; - GLuint prim; -}; - - /* A maximum total of 29 elements per vertex: 3 floats for position, 3 - * floats for normal, 4 floats for color, 4 bytes for secondary color, - * 3 floats for each texture unit (18 floats total). - * - * we maybe need add. 4 to prevent segfault if someone specifies - * GL_TEXTURE6/GL_TEXTURE7 (esp. for the codegen-path) (FIXME: ) - * - * The position data is never actually stored here, so 3 elements could be - * trimmed out of the buffer. - */ - -#define R200_MAX_VERTEX_SIZE ((3*6)+11) - -struct r200_vbinfo { - GLint counter, initial_counter; - GLint *dmaptr; - void (*notify) (void); - GLint vertex_size; - - union { - float f; - int i; - r200_color_t color; - } vertex[R200_MAX_VERTEX_SIZE]; - - GLfloat *normalptr; - GLfloat *floatcolorptr; - r200_color_t *colorptr; - GLfloat *floatspecptr; - r200_color_t *specptr; - GLfloat *texcoordptr[8]; /* 6 (TMU) + 2 for r200_vtxfmt_c.c when GL_TEXTURE6/7 */ - - GLenum *prim; /* &ctx->Driver.CurrentExecPrimitive */ - GLuint primflags; - GLboolean enabled; /* *_NO_VTXFMT / *_NO_TCL env vars */ - GLboolean installed; - GLboolean fell_back; - GLboolean recheck; - GLint nrverts; - GLuint vtxfmt_0, vtxfmt_1; - - GLuint installed_vertex_format; - GLuint installed_color_3f_sz; - - struct r200_prim primlist[R200_MAX_PRIMS]; - int nrprims; - - struct dfn_lists dfn_cache; - struct dfn_generators codegen; - GLvertexformat vtxfmt; -}; - -/** - * R200 context structure. - */ -struct r200_context { - struct radeon_context radeon; /* parent class, must be first */ - - /* Driver and hardware state management - */ - struct r200_hw_state hw; - struct r200_state state; - - /* Texture object bookkeeping - */ - unsigned nr_heaps; - driTexHeap *texture_heaps[RADEON_NR_TEX_HEAPS]; - driTextureObject swapped; - int texture_depth; - float initialMaxAnisotropy; - - /* Rasterization and vertex state: - */ - GLuint NewGLState; - - /* Vertex buffers - */ - struct r200_ioctl ioctl; - struct r200_dma dma; - struct r200_store store; - GLboolean save_on_next_unlock; - - /* Clientdata textures; - */ - GLuint prefer_gart_client_texturing; - - /* TCL stuff - */ - GLmatrix TexGenMatrix[R200_MAX_TEXTURE_UNITS]; - GLboolean recheck_texgen[R200_MAX_TEXTURE_UNITS]; - GLboolean TexGenNeedNormals[R200_MAX_TEXTURE_UNITS]; - GLuint TexMatEnabled; - GLuint TexMatCompSel; - GLuint TexGenEnabled; - GLuint TexGenInputs; - GLuint TexGenCompSel; - GLmatrix tmpmat; - - /* r200_tcl.c - */ - struct r200_tcl_info tcl; - - /* r200_swtcl.c - */ - struct r200_swtcl_info swtcl; - - /* r200_vtxfmt.c - */ - struct r200_vbinfo vb; -}; - -#define R200_CONTEXT(ctx) ((r200ContextPtr)(ctx->DriverCtx)) - -extern void r200DestroyContext(__DRIcontextPrivate * driContextPriv); -extern GLboolean r200CreateContext(const __GLcontextModes * glVisual, - __DRIcontextPrivate * driContextPriv, - void *sharedContextPrivate); - -#endif -#endif /* __R200_CONTEXT_H__ */ diff --git a/src/mesa/drivers/dri/r300/r200_ioctl.h b/src/mesa/drivers/dri/r300/r200_ioctl.h deleted file mode 100644 index db7bd7697f..0000000000 --- a/src/mesa/drivers/dri/r300/r200_ioctl.h +++ /dev/null @@ -1,204 +0,0 @@ -/* -Copyright (C) The Weather Channel, Inc. 2002. 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 - */ - -#ifndef __R200_IOCTL_H__ -#define __R200_IOCTL_H__ - -#include "simple_list.h" -#include "radeon_dri.h" -#include "radeon_lock.h" - -#include "xf86drm.h" -#include "drm.h" -#include "r200_context.h" -#include "radeon_drm.h" - -extern void r200EmitState(r200ContextPtr rmesa); -extern void r200EmitVertexAOS(r200ContextPtr rmesa, - GLuint vertex_size, GLuint offset); - -extern void r200EmitVbufPrim(r200ContextPtr rmesa, - GLuint primitive, GLuint vertex_nr); - -extern void r200FlushElts(r200ContextPtr rmesa); - -extern GLushort *r200AllocEltsOpenEnded(r200ContextPtr rmesa, - GLuint primitive, GLuint min_nr); - -extern void r200EmitAOS(r200ContextPtr rmesa, - struct r200_dma_region **regions, - GLuint n, GLuint offset); - -extern void r200EmitBlit(r200ContextPtr rmesa, - GLuint color_fmt, - GLuint src_pitch, - GLuint src_offset, - GLuint dst_pitch, - GLuint dst_offset, - GLint srcx, GLint srcy, - GLint dstx, GLint dsty, GLuint w, GLuint h); - -extern void r200EmitWait(r200ContextPtr rmesa, GLuint flags); - -extern void r200FlushCmdBuf(r200ContextPtr rmesa, const char *); -extern int r200FlushCmdBufLocked(r200ContextPtr rmesa, const char *caller); -extern void r200Flush(GLcontext * ctx); - -extern void r200RefillCurrentDmaRegion(r200ContextPtr rmesa); - -extern void r200AllocDmaRegion(r200ContextPtr rmesa, - struct r200_dma_region *region, - int bytes, int alignment); - -extern void r200AllocDmaRegionVerts(r200ContextPtr rmesa, - struct r200_dma_region *region, - int numverts, int vertsize, int alignment); - -extern void r200ReleaseDmaRegion(r200ContextPtr rmesa, - struct r200_dma_region *region, - const char *caller); - -extern void r200WaitForVBlank(r200ContextPtr rmesa); -extern void r200InitIoctlFuncs(struct dd_function_table *functions); - -extern void *r200AllocateMemoryMESA(__DRInativeDisplay * dpy, int scrn, - GLsizei size, GLfloat readfreq, - GLfloat writefreq, GLfloat priority); -extern void r200FreeMemoryMESA(__DRInativeDisplay * dpy, int scrn, - GLvoid * pointer); -extern GLuint r200GetMemoryOffsetMESA(__DRInativeDisplay * dpy, int scrn, - const GLvoid * pointer); - -extern GLboolean r200IsGartMemory(r200ContextPtr rmesa, const GLvoid * pointer, - GLint size); - -extern GLuint r200GartOffsetFromVirtual(r200ContextPtr rmesa, - const GLvoid * pointer); - -void r200SaveHwState(r200ContextPtr radeon); -void r200SetUpAtomList(r200ContextPtr rmesa); - -/* ================================================================ - * Helper macros: - */ - -/* Close off the last primitive, if it exists. - */ -#define R200_NEWPRIM( rmesa ) \ -do { \ - if ( rmesa->dma.flush ) \ - rmesa->dma.flush( rmesa ); \ -} while (0) - -/* Can accomodate several state changes and primitive changes without - * actually firing the buffer. - */ -#define R200_STATECHANGE( rmesa, ATOM ) \ -do { \ - R200_NEWPRIM( rmesa ); \ - rmesa->hw.ATOM.dirty = GL_TRUE; \ - rmesa->hw.is_dirty = GL_TRUE; \ -} while (0) - -#define R200_DB_STATE( ATOM ) \ - memcpy( rmesa->hw.ATOM.lastcmd, rmesa->hw.ATOM.cmd, \ - rmesa->hw.ATOM.cmd_size * 4) - -static __inline int R200_DB_STATECHANGE(r200ContextPtr rmesa, - struct r200_state_atom *atom) -{ - if (memcmp(atom->cmd, atom->lastcmd, atom->cmd_size * 4)) { - int *tmp; - R200_NEWPRIM(rmesa); - atom->dirty = GL_TRUE; - rmesa->hw.is_dirty = GL_TRUE; - tmp = atom->cmd; - atom->cmd = atom->lastcmd; - atom->lastcmd = tmp; - return 1; - } else - return 0; -} - -/* Fire the buffered vertices no matter what. - */ -#define R200_FIREVERTICES( r200 ) \ -do { \ - if ( (r200)->store.cmd_used || (r200)->dma.flush ) { \ - radeonFlush( (r200)->radeon.glCtx ); \ - } \ -} while (0) - -/* Command lengths. Note that any time you ensure ELTS_BUFSZ or VBUF_BUFSZ - * are available, you will also be adding an rmesa->state.max_state_size because - * r200EmitState is called from within r200EmitVbufPrim and r200FlushElts. - */ -#define AOS_BUFSZ(nr) ((3 + ((nr / 2) * 3) + ((nr & 1) * 2)) * sizeof(int)) -#define VERT_AOS_BUFSZ (5 * sizeof(int)) -#define ELTS_BUFSZ(nr) (12 + nr * 2) -#define VBUF_BUFSZ (3 * sizeof(int)) - -/* Ensure that a minimum amount of space is available in the command buffer. - * This is used to ensure atomicity of state updates with the rendering requests - * that rely on them. - * - * An alternative would be to implement a "soft lock" such that when the buffer - * wraps at an inopportune time, we grab the lock, flush the current buffer, - * and hang on to the lock until the critical section is finished and we flush - * the buffer again and unlock. - */ -static __inline void r200EnsureCmdBufSpace(r200ContextPtr rmesa, int bytes) -{ - if (rmesa->store.cmd_used + bytes > R200_CMD_BUF_SZ) - r200FlushCmdBuf(rmesa, __FUNCTION__); - assert(bytes <= R200_CMD_BUF_SZ); -} - -/* Alloc space in the command buffer - */ -static __inline char *r200AllocCmdBuf(r200ContextPtr rmesa, - int bytes, const char *where) -{ - char *head; - - if (rmesa->store.cmd_used + bytes > R200_CMD_BUF_SZ) - r200FlushCmdBuf(rmesa, where); - - head = rmesa->store.cmd_buf + rmesa->store.cmd_used; - rmesa->store.cmd_used += bytes; - assert(rmesa->store.cmd_used <= R200_CMD_BUF_SZ); - return head; -} - -#endif /* __R200_IOCTL_H__ */ diff --git a/src/mesa/drivers/dri/r300/r200_reg.h b/src/mesa/drivers/dri/r300/r200_reg.h deleted file mode 100644 index 1336e961ac..0000000000 --- a/src/mesa/drivers/dri/r300/r200_reg.h +++ /dev/null @@ -1,1423 +0,0 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_reg.h,v 1.2 2002/12/16 16:18:54 dawes Exp $ */ -/* -Copyright (C) The Weather Channel, Inc. 2002. 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. -*/ - -#ifndef _R200_REG_H_ -#define _R200_REG_H_ - -#define R200_PP_MISC 0x1c14 -#define R200_REF_ALPHA_MASK 0x000000ff -#define R200_ALPHA_TEST_FAIL (0 << 8) -#define R200_ALPHA_TEST_LESS (1 << 8) -#define R200_ALPHA_TEST_LEQUAL (2 << 8) -#define R200_ALPHA_TEST_EQUAL (3 << 8) -#define R200_ALPHA_TEST_GEQUAL (4 << 8) -#define R200_ALPHA_TEST_GREATER (5 << 8) -#define R200_ALPHA_TEST_NEQUAL (6 << 8) -#define R200_ALPHA_TEST_PASS (7 << 8) -#define R200_ALPHA_TEST_OP_MASK (7 << 8) -#define R200_CHROMA_FUNC_FAIL (0 << 16) -#define R200_CHROMA_FUNC_PASS (1 << 16) -#define R200_CHROMA_FUNC_NEQUAL (2 << 16) -#define R200_CHROMA_FUNC_EQUAL (3 << 16) -#define R200_CHROMA_KEY_NEAREST (0 << 18) -#define R200_CHROMA_KEY_ZERO (1 << 18) -#define R200_RIGHT_HAND_CUBE_D3D (0 << 24) -#define R200_RIGHT_HAND_CUBE_OGL (1 << 24) -#define R200_PP_FOG_COLOR 0x1c18 -#define R200_FOG_COLOR_MASK 0x00ffffff -#define R200_FOG_VERTEX (0 << 24) -#define R200_FOG_TABLE (1 << 24) -#define R200_FOG_USE_DEPTH (0 << 25) -#define R200_FOG_USE_W (1 << 25) -#define R200_FOG_USE_DIFFUSE_ALPHA (2 << 25) -#define R200_FOG_USE_SPEC_ALPHA (3 << 25) -#define R200_FOG_USE_VTX_FOG (4 << 25) -#define R200_FOG_USE_MASK (7 << 25) -#define R200_RE_SOLID_COLOR 0x1c1c -#define R200_RB3D_BLENDCNTL 0x1c20 -#define R200_COMB_FCN_MASK (7 << 12) -#define R200_COMB_FCN_ADD_CLAMP (0 << 12) -#define R200_COMB_FCN_ADD_NOCLAMP (1 << 12) -#define R200_COMB_FCN_SUB_CLAMP (2 << 12) -#define R200_COMB_FCN_SUB_NOCLAMP (3 << 12) -#define R200_COMB_FCN_MIN (4 << 12) -#define R200_COMB_FCN_MAX (5 << 12) -#define R200_COMB_FCN_RSUB_CLAMP (6 << 12) -#define R200_COMB_FCN_RSUB_NOCLAMP (7 << 12) -#define R200_BLEND_GL_ZERO (32) -#define R200_BLEND_GL_ONE (33) -#define R200_BLEND_GL_SRC_COLOR (34) -#define R200_BLEND_GL_ONE_MINUS_SRC_COLOR (35) -#define R200_BLEND_GL_DST_COLOR (36) -#define R200_BLEND_GL_ONE_MINUS_DST_COLOR (37) -#define R200_BLEND_GL_SRC_ALPHA (38) -#define R200_BLEND_GL_ONE_MINUS_SRC_ALPHA (39) -#define R200_BLEND_GL_DST_ALPHA (40) -#define R200_BLEND_GL_ONE_MINUS_DST_ALPHA (41) -#define R200_BLEND_GL_SRC_ALPHA_SATURATE (42) /* src factor only */ -#define R200_BLEND_GL_CONST_COLOR (43) -#define R200_BLEND_GL_ONE_MINUS_CONST_COLOR (44) -#define R200_BLEND_GL_CONST_ALPHA (45) -#define R200_BLEND_GL_ONE_MINUS_CONST_ALPHA (46) -#define R200_BLEND_MASK (63) -#define R200_SRC_BLEND_SHIFT (16) -#define R200_DST_BLEND_SHIFT (24) -#define R200_RB3D_DEPTHOFFSET 0x1c24 -#define R200_RB3D_DEPTHPITCH 0x1c28 -#define R200_DEPTHPITCH_MASK 0x00001ff8 -#define R200_DEPTH_ENDIAN_NO_SWAP (0 << 18) -#define R200_DEPTH_ENDIAN_WORD_SWAP (1 << 18) -#define R200_DEPTH_ENDIAN_DWORD_SWAP (2 << 18) -#define R200_RB3D_ZSTENCILCNTL 0x1c2c -#define R200_DEPTH_FORMAT_MASK (0xf << 0) -#define R200_DEPTH_FORMAT_16BIT_INT_Z (0 << 0) -#define R200_DEPTH_FORMAT_24BIT_INT_Z (2 << 0) -#define R200_DEPTH_FORMAT_24BIT_FLOAT_Z (3 << 0) -#define R200_DEPTH_FORMAT_32BIT_INT_Z (4 << 0) -#define R200_DEPTH_FORMAT_32BIT_FLOAT_Z (5 << 0) -#define R200_DEPTH_FORMAT_24BIT_FLOAT_W (9 << 0) -#define R200_DEPTH_FORMAT_32BIT_FLOAT_W (11 << 0) -#define R200_Z_TEST_NEVER (0 << 4) -#define R200_Z_TEST_LESS (1 << 4) -#define R200_Z_TEST_LEQUAL (2 << 4) -#define R200_Z_TEST_EQUAL (3 << 4) -#define R200_Z_TEST_GEQUAL (4 << 4) -#define R200_Z_TEST_GREATER (5 << 4) -#define R200_Z_TEST_NEQUAL (6 << 4) -#define R200_Z_TEST_ALWAYS (7 << 4) -#define R200_Z_TEST_MASK (7 << 4) -#define R200_STENCIL_TEST_NEVER (0 << 12) -#define R200_STENCIL_TEST_LESS (1 << 12) -#define R200_STENCIL_TEST_LEQUAL (2 << 12) -#define R200_STENCIL_TEST_EQUAL (3 << 12) -#define R200_STENCIL_TEST_GEQUAL (4 << 12) -#define R200_STENCIL_TEST_GREATER (5 << 12) -#define R200_STENCIL_TEST_NEQUAL (6 << 12) -#define R200_STENCIL_TEST_ALWAYS (7 << 12) -#define R200_STENCIL_TEST_MASK (0x7 << 12) -#define R200_STENCIL_FAIL_KEEP (0 << 16) -#define R200_STENCIL_FAIL_ZERO (1 << 16) -#define R200_STENCIL_FAIL_REPLACE (2 << 16) -#define R200_STENCIL_FAIL_INC (3 << 16) -#define R200_STENCIL_FAIL_DEC (4 << 16) -#define R200_STENCIL_FAIL_INVERT (5 << 16) -#define R200_STENCIL_FAIL_INC_WRAP (6 << 16) -#define R200_STENCIL_FAIL_DEC_WRAP (7 << 16) -#define R200_STENCIL_FAIL_MASK (0x7 << 16) -#define R200_STENCIL_ZPASS_KEEP (0 << 20) -#define R200_STENCIL_ZPASS_ZERO (1 << 20) -#define R200_STENCIL_ZPASS_REPLACE (2 << 20) -#define R200_STENCIL_ZPASS_INC (3 << 20) -#define R200_STENCIL_ZPASS_DEC (4 << 20) -#define R200_STENCIL_ZPASS_INVERT (5 << 20) -#define R200_STENCIL_ZPASS_INC_WRAP (6 << 20) -#define R200_STENCIL_ZPASS_DEC_WRAP (7 << 20) -#define R200_STENCIL_ZPASS_MASK (0x7 << 20) -#define R200_STENCIL_ZFAIL_KEEP (0 << 24) -#define R200_STENCIL_ZFAIL_ZERO (1 << 24) -#define R200_STENCIL_ZFAIL_REPLACE (2 << 24) -#define R200_STENCIL_ZFAIL_INC (3 << 24) -#define R200_STENCIL_ZFAIL_DEC (4 << 24) -#define R200_STENCIL_ZFAIL_INVERT (5 << 24) -#define R200_STENCIL_ZFAIL_INC_WRAP (6 << 24) -#define R200_STENCIL_ZFAIL_DEC_WRAP (7 << 24) -#define R200_STENCIL_ZFAIL_MASK (0x7 << 24) -#define R200_Z_WRITE_ENABLE (1 << 30) -/*gap*/ -#define R200_PP_CNTL 0x1c38 -#define R200_TEX_0_ENABLE 0x00000010 -#define R200_TEX_1_ENABLE 0x00000020 -#define R200_TEX_2_ENABLE 0x00000040 -#define R200_TEX_3_ENABLE 0x00000080 -#define R200_TEX_4_ENABLE 0x00000100 -#define R200_TEX_5_ENABLE 0x00000200 -#define R200_TEX_ENABLE_MASK 0x000003f0 -#define R200_FILTER_ROUND_MODE_MASK 0x00000400 -#define R200_TEX_BLEND_7_ENABLE 0x00000800 -#define R200_TEX_BLEND_0_ENABLE 0x00001000 -#define R200_TEX_BLEND_1_ENABLE 0x00002000 -#define R200_TEX_BLEND_2_ENABLE 0x00004000 -#define R200_TEX_BLEND_3_ENABLE 0x00008000 -#define R200_TEX_BLEND_4_ENABLE 0x00010000 -#define R200_TEX_BLEND_5_ENABLE 0x00020000 -#define R200_TEX_BLEND_6_ENABLE 0x00040000 -#define R200_MULTI_PASS_ENABLE 0x00080000 -#define R200_SPECULAR_ENABLE 0x00200000 -#define R200_FOG_ENABLE 0x00400000 -#define R200_ALPHA_TEST_ENABLE 0x00800000 -#define R200_ANTI_ALIAS_NONE 0x00000000 -#define R200_ANTI_ALIAS_LINE 0x01000000 -#define R200_ANTI_ALIAS_POLY 0x02000000 -#define R200_ANTI_ALIAS_MASK 0x03000000 -#define R200_RB3D_CNTL 0x1c3c -#define R200_ALPHA_BLEND_ENABLE (1 << 0) -#define R200_PLANE_MASK_ENABLE (1 << 1) -#define R200_DITHER_ENABLE (1 << 2) -#define R200_ROUND_ENABLE (1 << 3) -#define R200_SCALE_DITHER_ENABLE (1 << 4) -#define R200_DITHER_INIT (1 << 5) -#define R200_ROP_ENABLE (1 << 6) -#define R200_STENCIL_ENABLE (1 << 7) -#define R200_Z_ENABLE (1 << 8) -#define R200_DEPTH_XZ_OFFEST_ENABLE (1 << 9) -#define R200_COLOR_FORMAT_ARGB1555 (3 << 10) -#define R200_COLOR_FORMAT_RGB565 (4 << 10) -#define R200_COLOR_FORMAT_ARGB8888 (6 << 10) -#define R200_COLOR_FORMAT_RGB332 (7 << 10) -#define R200_COLOR_FORMAT_Y8 (8 << 10) -#define R200_COLOR_FORMAT_RGB8 (9 << 10) -#define R200_COLOR_FORMAT_YUV422_VYUY (11 << 10) -#define R200_COLOR_FORMAT_YUV422_YVYU (12 << 10) -#define R200_COLOR_FORMAT_aYUV444 (14 << 10) -#define R200_COLOR_FORMAT_ARGB4444 (15 << 10) -#define R200_CLRCMP_FLIP_ENABLE (1 << 14) -#define R200_SEPARATE_ALPHA_ENABLE (1 << 16) -#define R200_RB3D_COLOROFFSET 0x1c40 -#define R200_COLOROFFSET_MASK 0xfffffff0 -#define R200_RE_WIDTH_HEIGHT 0x1c44 -#define R200_RE_WIDTH_SHIFT 0 -#define R200_RE_HEIGHT_SHIFT 16 -#define R200_RB3D_COLORPITCH 0x1c48 -#define R200_COLORPITCH_MASK 0x000001ff8 -#define R200_COLOR_ENDIAN_NO_SWAP (0 << 18) -#define R200_COLOR_ENDIAN_WORD_SWAP (1 << 18) -#define R200_COLOR_ENDIAN_DWORD_SWAP (2 << 18) -#define R200_SE_CNTL 0x1c4c -#define R200_FFACE_CULL_CW (0 << 0) -#define R200_FFACE_CULL_CCW (1 << 0) -#define R200_FFACE_CULL_DIR_MASK (1 << 0) -#define R200_BFACE_CULL (0 << 1) -#define R200_BFACE_SOLID (3 << 1) -#define R200_FFACE_CULL (0 << 3) -#define R200_FFACE_SOLID (3 << 3) -#define R200_FFACE_CULL_MASK (3 << 3) -#define R200_FLAT_SHADE_VTX_0 (0 << 6) -#define R200_FLAT_SHADE_VTX_1 (1 << 6) -#define R200_FLAT_SHADE_VTX_2 (2 << 6) -#define R200_FLAT_SHADE_VTX_LAST (3 << 6) -#define R200_DIFFUSE_SHADE_SOLID (0 << 8) -#define R200_DIFFUSE_SHADE_FLAT (1 << 8) -#define R200_DIFFUSE_SHADE_GOURAUD (2 << 8) -#define R200_DIFFUSE_SHADE_MASK (3 << 8) -#define R200_ALPHA_SHADE_SOLID (0 << 10) -#define R200_ALPHA_SHADE_FLAT (1 << 10) -#define R200_ALPHA_SHADE_GOURAUD (2 << 10) -#define R200_ALPHA_SHADE_MASK (3 << 10) -#define R200_SPECULAR_SHADE_SOLID (0 << 12) -#define R200_SPECULAR_SHADE_FLAT (1 << 12) -#define R200_SPECULAR_SHADE_GOURAUD (2 << 12) -#define R200_SPECULAR_SHADE_MASK (3 << 12) -#define R200_FOG_SHADE_SOLID (0 << 14) -#define R200_FOG_SHADE_FLAT (1 << 14) -#define R200_FOG_SHADE_GOURAUD (2 << 14) -#define R200_FOG_SHADE_MASK (3 << 14) -#define R200_ZBIAS_ENABLE_POINT (1 << 16) -#define R200_ZBIAS_ENABLE_LINE (1 << 17) -#define R200_ZBIAS_ENABLE_TRI (1 << 18) -#define R200_WIDELINE_ENABLE (1 << 20) -#define R200_VTX_PIX_CENTER_D3D (0 << 27) -#define R200_VTX_PIX_CENTER_OGL (1 << 27) -#define R200_ROUND_MODE_TRUNC (0 << 28) -#define R200_ROUND_MODE_ROUND (1 << 28) -#define R200_ROUND_MODE_ROUND_EVEN (2 << 28) -#define R200_ROUND_MODE_ROUND_ODD (3 << 28) -#define R200_ROUND_PREC_16TH_PIX (0 << 30) -#define R200_ROUND_PREC_8TH_PIX (1 << 30) -#define R200_ROUND_PREC_4TH_PIX (2 << 30) -#define R200_ROUND_PREC_HALF_PIX (3 << 30) -#define R200_RE_CNTL 0x1c50 -#define R200_STIPPLE_ENABLE 0x1 -#define R200_SCISSOR_ENABLE 0x2 -#define R200_PATTERN_ENABLE 0x4 -#define R200_PERSPECTIVE_ENABLE 0x8 -#define R200_POINT_SMOOTH 0x20 -#define R200_VTX_STQ0_D3D 0x00010000 -#define R200_VTX_STQ1_D3D 0x00040000 -#define R200_VTX_STQ2_D3D 0x00100000 -#define R200_VTX_STQ3_D3D 0x00400000 -#define R200_VTX_STQ4_D3D 0x01000000 -#define R200_VTX_STQ5_D3D 0x04000000 -/* gap */ -#define R200_RE_STIPPLE_ADDR 0x1cc8 -#define R200_RE_STIPPLE_DATA 0x1ccc -#define R200_RE_LINE_PATTERN 0x1cd0 -#define R200_LINE_PATTERN_MASK 0x0000ffff -#define R200_LINE_REPEAT_COUNT_SHIFT 16 -#define R200_LINE_PATTERN_START_SHIFT 24 -#define R200_LINE_PATTERN_LITTLE_BIT_ORDER (0 << 28) -#define R200_LINE_PATTERN_BIG_BIT_ORDER (1 << 28) -#define R200_LINE_PATTERN_AUTO_RESET (1 << 29) -#define R200_RE_LINE_STATE 0x1cd4 -#define R200_LINE_CURRENT_PTR_SHIFT 0 -#define R200_LINE_CURRENT_COUNT_SHIFT 8 -#define R200_RE_SCISSOR_TL_0 0x1cd8 -#define R200_RE_SCISSOR_BR_0 0x1cdc -#define R200_RE_SCISSOR_TL_1 0x1ce0 -#define R200_RE_SCISSOR_BR_1 0x1ce4 -#define R200_RE_SCISSOR_TL_2 0x1ce8 -#define R200_RE_SCISSOR_BR_2 0x1cec -/* gap */ -#define R200_RB3D_DEPTHXY_OFFSET 0x1d60 -#define R200_DEPTHX_SHIFT 0 -#define R200_DEPTHY_SHIFT 16 -/* gap */ -#define R200_RB3D_STENCILREFMASK 0x1d7c -#define R200_STENCIL_REF_SHIFT 0 -#define R200_STENCIL_REF_MASK (0xff << 0) -#define R200_STENCIL_MASK_SHIFT 16 -#define R200_STENCIL_VALUE_MASK (0xff << 16) -#define R200_STENCIL_WRITEMASK_SHIFT 24 -#define R200_STENCIL_WRITE_MASK (0xff << 24) -#define R200_RB3D_ROPCNTL 0x1d80 -#define R200_ROP_MASK (15 << 8) -#define R200_ROP_CLEAR (0 << 8) -#define R200_ROP_NOR (1 << 8) -#define R200_ROP_AND_INVERTED (2 << 8) -#define R200_ROP_COPY_INVERTED (3 << 8) -#define R200_ROP_AND_REVERSE (4 << 8) -#define R200_ROP_INVERT (5 << 8) -#define R200_ROP_XOR (6 << 8) -#define R200_ROP_NAND (7 << 8) -#define R200_ROP_AND (8 << 8) -#define R200_ROP_EQUIV (9 << 8) -#define R200_ROP_NOOP (10 << 8) -#define R200_ROP_OR_INVERTED (11 << 8) -#define R200_ROP_COPY (12 << 8) -#define R200_ROP_OR_REVERSE (13 << 8) -#define R200_ROP_OR (14 << 8) -#define R200_ROP_SET (15 << 8) -#define R200_RB3D_PLANEMASK 0x1d84 -/* gap */ -#define R200_SE_VPORT_XSCALE 0x1d98 -#define R200_SE_VPORT_XOFFSET 0x1d9c -#define R200_SE_VPORT_YSCALE 0x1da0 -#define R200_SE_VPORT_YOFFSET 0x1da4 -#define R200_SE_VPORT_ZSCALE 0x1da8 -#define R200_SE_VPORT_ZOFFSET 0x1dac -#define R200_SE_ZBIAS_FACTOR 0x1db0 -#define R200_SE_ZBIAS_CONSTANT 0x1db4 -#define R200_SE_LINE_WIDTH 0x1db8 -#define R200_LINE_WIDTH_SHIFT 0x00000000 -#define R200_MINPOINTSIZE_SHIFT 0x00000010 -/* gap */ -#define R200_SE_VAP_CNTL 0x2080 -#define R200_VAP_TCL_ENABLE 0x00000001 -#define R200_VAP_SINGLE_BUF_STATE_ENABLE 0x00000010 -#define R200_VAP_FORCE_W_TO_ONE 0x00010000 -#define R200_VAP_D3D_TEX_DEFAULT 0x00020000 -#define R200_VAP_VF_MAX_VTX_NUM__SHIFT 18 -#define R200_VAP_DX_CLIP_SPACE_DEF 0x00400000 -#define R200_SE_VF_CNTL 0x2084 -#define R200_VF_PRIM_NONE 0x00000000 -#define R200_VF_PRIM_POINTS 0x00000001 -#define R200_VF_PRIM_LINES 0x00000002 -#define R200_VF_PRIM_LINE_STRIP 0x00000003 -#define R200_VF_PRIM_TRIANGLES 0x00000004 -#define R200_VF_PRIM_TRIANGLE_FAN 0x00000005 -#define R200_VF_PRIM_TRIANGLE_STRIP 0x00000006 -#define R200_VF_PRIM_RECT_LIST 0x00000008 -#define R200_VF_PRIM_3VRT_POINTS 0x00000009 -#define R200_VF_PRIM_3VRT_LINES 0x0000000a -#define R200_VF_PRIM_POINT_SPRITES 0x0000000b -#define R200_VF_PRIM_LINE_LOOP 0x0000000c -#define R200_VF_PRIM_QUADS 0x0000000d -#define R200_VF_PRIM_QUAD_STRIP 0x0000000e -#define R200_VF_PRIM_POLYGON 0x0000000f -#define R200_VF_PRIM_MASK 0x0000000f -#define R200_VF_PRIM_WALK_IND 0x00000010 -#define R200_VF_PRIM_WALK_LIST 0x00000020 -#define R200_VF_PRIM_WALK_RING 0x00000030 -#define R200_VF_PRIM_WALK_MASK 0x00000030 -#define R200_VF_COLOR_ORDER_RGBA 0x00000040 -#define R200_VF_TCL_OUTPUT_VTX_ENABLE 0x00000200 -#define R200_VF_INDEX_SZ_4 0x00000800 -#define R200_VF_VERTEX_NUMBER_MASK 0xffff0000 -#define R200_VF_VERTEX_NUMBER_SHIFT 16 -#define R200_SE_VTX_FMT_0 0x2088 -#define R200_VTX_XY 0 /* always have xy */ -#define R200_VTX_Z0 (1<<0) -#define R200_VTX_W0 (1<<1) -#define R200_VTX_WEIGHT_COUNT_SHIFT (2) -#define R200_VTX_PV_MATRIX_SEL (1<<5) -#define R200_VTX_N0 (1<<6) -#define R200_VTX_POINT_SIZE (1<<7) -#define R200_VTX_DISCRETE_FOG (1<<8) -#define R200_VTX_SHININESS_0 (1<<9) -#define R200_VTX_SHININESS_1 (1<<10) -#define R200_VTX_COLOR_NOT_PRESENT 0 -#define R200_VTX_PK_RGBA 1 -#define R200_VTX_FP_RGB 2 -#define R200_VTX_FP_RGBA 3 -#define R200_VTX_COLOR_MASK 3 -#define R200_VTX_COLOR_0_SHIFT 11 -#define R200_VTX_COLOR_1_SHIFT 13 -#define R200_VTX_COLOR_2_SHIFT 15 -#define R200_VTX_COLOR_3_SHIFT 17 -#define R200_VTX_COLOR_4_SHIFT 19 -#define R200_VTX_COLOR_5_SHIFT 21 -#define R200_VTX_COLOR_6_SHIFT 23 -#define R200_VTX_COLOR_7_SHIFT 25 -#define R200_VTX_XY1 (1<<28) -#define R200_VTX_Z1 (1<<29) -#define R200_VTX_W1 (1<<30) -#define R200_VTX_N1 (1<<31) -#define R200_SE_VTX_FMT_1 0x208c -#define R200_VTX_TEX0_COMP_CNT_SHIFT 0 -#define R200_VTX_TEX1_COMP_CNT_SHIFT 3 -#define R200_VTX_TEX2_COMP_CNT_SHIFT 6 -#define R200_VTX_TEX3_COMP_CNT_SHIFT 9 -#define R200_VTX_TEX4_COMP_CNT_SHIFT 12 -#define R200_VTX_TEX5_COMP_CNT_SHIFT 15 -#define R200_SE_TCL_OUTPUT_VTX_FMT_0 0x2090 -#define R200_SE_TCL_OUTPUT_VTX_FMT_1 0x2094 -/* gap */ -#define R200_SE_VTE_CNTL 0x20b0 -#define R200_VPORT_X_SCALE_ENA 0x00000001 -#define R200_VPORT_X_OFFSET_ENA 0x00000002 -#define R200_VPORT_Y_SCALE_ENA 0x00000004 -#define R200_VPORT_Y_OFFSET_ENA 0x00000008 -#define R200_VPORT_Z_SCALE_ENA 0x00000010 -#define R200_VPORT_Z_OFFSET_ENA 0x00000020 -#define R200_VTX_XY_FMT 0x00000100 -#define R200_VTX_Z_FMT 0x00000200 -#define R200_VTX_W0_FMT 0x00000400 -#define R200_VTX_W0_NORMALIZE 0x00000800 -#define R200_VTX_ST_DENORMALIZED 0x00001000 -/* gap */ -#define R200_SE_VTX_NUM_ARRAYS 0x20c0 -#define R200_SE_VTX_AOS_ATTR01 0x20c4 -#define R200_SE_VTX_AOS_ADDR0 0x20c8 -#define R200_SE_VTX_AOS_ADDR1 0x20cc -#define R200_SE_VTX_AOS_ATTR23 0x20d0 -#define R200_SE_VTX_AOS_ADDR2 0x20d4 -#define R200_SE_VTX_AOS_ADDR3 0x20d8 -#define R200_SE_VTX_AOS_ATTR45 0x20dc -#define R200_SE_VTX_AOS_ADDR4 0x20e0 -#define R200_SE_VTX_AOS_ADDR5 0x20e4 -#define R200_SE_VTX_AOS_ATTR67 0x20e8 -#define R200_SE_VTX_AOS_ADDR6 0x20ec -#define R200_SE_VTX_AOS_ADDR7 0x20f0 -#define R200_SE_VTX_AOS_ATTR89 0x20f4 -#define R200_SE_VTX_AOS_ADDR8 0x20f8 -#define R200_SE_VTX_AOS_ADDR9 0x20fc -#define R200_SE_VTX_AOS_ATTR1011 0x2100 -#define R200_SE_VTX_AOS_ADDR10 0x2104 -#define R200_SE_VTX_AOS_ADDR11 0x2108 -#define R200_SE_VF_MAX_VTX_INDX 0x210c -#define R200_SE_VF_MIN_VTX_INDX 0x2110 -/* gap */ -#define R200_SE_VAP_CNTL_STATUS 0x2140 -#define R200_VC_NO_SWAP (0 << 0) -#define R200_VC_16BIT_SWAP (1 << 0) -#define R200_VC_32BIT_SWAP (2 << 0) -/* gap */ -#define R200_SE_VTX_STATE_CNTL 0x2180 -#define R200_VSC_COLOR_0_ASSEMBLY_CNTL_SHIFT 0x00000000 -#define R200_VSC_COLOR_1_ASSEMBLY_CNTL_SHIFT 0x00000002 -#define R200_VSC_COLOR_2_ASSEMBLY_CNTL_SHIFT 0x00000004 -#define R200_VSC_COLOR_3_ASSEMBLY_CNTL_SHIFT 0x00000006 -#define R200_VSC_COLOR_4_ASSEMBLY_CNTL_SHIFT 0x00000008 -#define R200_VSC_COLOR_5_ASSEMBLY_CNTL_SHIFT 0x0000000a -#define R200_VSC_COLOR_6_ASSEMBLY_CNTL_SHIFT 0x0000000c -#define R200_VSC_COLOR_7_ASSEMBLY_CNTL_SHIFT 0x0000000e -#define R200_VSC_UPDATE_USER_COLOR_0_ENABLE 0x00010000 -#define R200_VSC_UPDATE_USER_COLOR_1_ENABLE 0x00020000 -/* gap */ -#define R200_SE_TCL_VECTOR_INDX_REG 0x2200 -#define R200_SE_TCL_VECTOR_DATA_REG 0x2204 -#define R200_SE_TCL_SCALAR_INDX_REG 0x2208 -#define R200_SE_TCL_SCALAR_DATA_REG 0x220c -/* gap */ -#define R200_SE_TCL_MATRIX_SEL_0 0x2230 -#define R200_MODELVIEW_0_SHIFT (0) -#define R200_MODELVIEW_1_SHIFT (8) -#define R200_MODELVIEW_2_SHIFT (16) -#define R200_MODELVIEW_3_SHIFT (24) -#define R200_SE_TCL_MATRIX_SEL_1 0x2234 -#define R200_IT_MODELVIEW_0_SHIFT (0) -#define R200_IT_MODELVIEW_1_SHIFT (8) -#define R200_IT_MODELVIEW_2_SHIFT (16) -#define R200_IT_MODELVIEW_3_SHIFT (24) -#define R200_SE_TCL_MATRIX_SEL_2 0x2238 -#define R200_MODELPROJECT_0_SHIFT (0) -#define R200_MODELPROJECT_1_SHIFT (8) -#define R200_MODELPROJECT_2_SHIFT (16) -#define R200_MODELPROJECT_3_SHIFT (24) -#define R200_SE_TCL_MATRIX_SEL_3 0x223c -#define R200_TEXMAT_0_SHIFT 0 -#define R200_TEXMAT_1_SHIFT 8 -#define R200_TEXMAT_2_SHIFT 16 -#define R200_TEXMAT_3_SHIFT 24 -#define R200_SE_TCL_MATRIX_SEL_4 0x2240 -#define R200_TEXMAT_4_SHIFT 0 -#define R200_TEXMAT_5_SHIFT 8 -/* gap */ -#define R200_SE_TCL_OUTPUT_VTX_COMP_SEL 0x2250 -#define R200_OUTPUT_XYZW (1<<0) -#define R200_OUTPUT_COLOR_0 (1<<8) -#define R200_OUTPUT_COLOR_1 (1<<9) -#define R200_OUTPUT_TEX_0 (1<<16) -#define R200_OUTPUT_TEX_1 (1<<17) -#define R200_OUTPUT_TEX_2 (1<<18) -#define R200_OUTPUT_TEX_3 (1<<19) -#define R200_OUTPUT_TEX_4 (1<<20) -#define R200_OUTPUT_TEX_5 (1<<21) -#define R200_OUTPUT_TEX_MASK (0x3f<<16) -#define R200_OUTPUT_DISCRETE_FOG (1<<24) -#define R200_OUTPUT_PT_SIZE (1<<25) -#define R200_FORCE_INORDER_PROC (1<<31) -#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0 0x2254 -#define R200_VERTEX_POSITION_ADDR__SHIFT 0x00000000 -#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_1 0x2258 -#define R200_VTX_COLOR_0_ADDR__SHIFT 0x00000000 -#define R200_VTX_COLOR_1_ADDR__SHIFT 0x00000008 -#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_2 0x225c -#define R200_VTX_TEX_0_ADDR__SHIFT 0x00000000 -#define R200_VTX_TEX_1_ADDR__SHIFT 0x00000008 -#define R200_VTX_TEX_2_ADDR__SHIFT 0x00000010 -#define R200_VTX_TEX_3_ADDR__SHIFT 0x00000018 -#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_3 0x2260 -#define R200_VTX_TEX_4_ADDR__SHIFT 0x00000000 -#define R200_VTX_TEX_5_ADDR__SHIFT 0x00000008 - -/* gap */ -#define R200_SE_TCL_LIGHT_MODEL_CTL_0 0x2268 -#define R200_LIGHTING_ENABLE (1<<0) -#define R200_LIGHT_IN_MODELSPACE (1<<1) -#define R200_LOCAL_VIEWER (1<<2) -#define R200_NORMALIZE_NORMALS (1<<3) -#define R200_RESCALE_NORMALS (1<<4) -#define R200_SPECULAR_LIGHTS (1<<5) -#define R200_DIFFUSE_SPECULAR_COMBINE (1<<6) -#define R200_LIGHT_ALPHA (1<<7) -#define R200_LOCAL_LIGHT_VEC_GL (1<<8) -#define R200_LIGHT_NO_NORMAL_AMBIENT_ONLY (1<<9) -#define R200_LIGHT_TWOSIDE (1<<10) -#define R200_FRONT_SHININESS_SOURCE_SHIFT (0xb) -#define R200_BACK_SHININESS_SOURCE_SHIFT (0xd) -#define R200_LM0_SOURCE_MATERIAL_0 (0) -#define R200_LM0_SOURCE_MATERIAL_1 (1) -#define R200_LM0_SOURCE_VERTEX_SHININESS_0 (2) -#define R200_LM0_SOURCE_VERTEX_SHININESS_1 (3) -#define R200_SE_TCL_LIGHT_MODEL_CTL_1 0x226c -#define R200_LM1_SOURCE_LIGHT_PREMULT (0) -#define R200_LM1_SOURCE_MATERIAL_0 (1) -#define R200_LM1_SOURCE_VERTEX_COLOR_0 (2) -#define R200_LM1_SOURCE_VERTEX_COLOR_1 (3) -#define R200_LM1_SOURCE_VERTEX_COLOR_2 (4) -#define R200_LM1_SOURCE_VERTEX_COLOR_3 (5) -#define R200_LM1_SOURCE_VERTEX_COLOR_4 (6) -#define R200_LM1_SOURCE_VERTEX_COLOR_5 (7) -#define R200_LM1_SOURCE_VERTEX_COLOR_6 (8) -#define R200_LM1_SOURCE_VERTEX_COLOR_7 (9) -#define R200_LM1_SOURCE_MATERIAL_1 (0xf) -#define R200_FRONT_EMISSIVE_SOURCE_SHIFT (0) -#define R200_FRONT_AMBIENT_SOURCE_SHIFT (4) -#define R200_FRONT_DIFFUSE_SOURCE_SHIFT (8) -#define R200_FRONT_SPECULAR_SOURCE_SHIFT (12) -#define R200_BACK_EMISSIVE_SOURCE_SHIFT (16) -#define R200_BACK_AMBIENT_SOURCE_SHIFT (20) -#define R200_BACK_DIFFUSE_SOURCE_SHIFT (24) -#define R200_BACK_SPECULAR_SOURCE_SHIFT (28) -#define R200_SE_TCL_PER_LIGHT_CTL_0 0x2270 -#define R200_LIGHT_0_ENABLE (1<<0) -#define R200_LIGHT_0_ENABLE_AMBIENT (1<<1) -#define R200_LIGHT_0_ENABLE_SPECULAR (1<<2) -#define R200_LIGHT_0_IS_LOCAL (1<<3) -#define R200_LIGHT_0_IS_SPOT (1<<4) -#define R200_LIGHT_0_DUAL_CONE (1<<5) -#define R200_LIGHT_0_ENABLE_RANGE_ATTEN (1<<6) -#define R200_LIGHT_0_CONSTANT_RANGE_ATTEN (1<<7) -#define R200_LIGHT_1_ENABLE (1<<16) -#define R200_LIGHT_1_ENABLE_AMBIENT (1<<17) -#define R200_LIGHT_1_ENABLE_SPECULAR (1<<18) -#define R200_LIGHT_1_IS_LOCAL (1<<19) -#define R200_LIGHT_1_IS_SPOT (1<<20) -#define R200_LIGHT_1_DUAL_CONE (1<<21) -#define R200_LIGHT_1_ENABLE_RANGE_ATTEN (1<<22) -#define R200_LIGHT_1_CONSTANT_RANGE_ATTEN (1<<23) -#define R200_LIGHT_0_SHIFT (0) -#define R200_LIGHT_1_SHIFT (16) -#define R200_SE_TCL_PER_LIGHT_CTL_1 0x2274 -#define R200_LIGHT_2_SHIFT (0) -#define R200_LIGHT_3_SHIFT (16) -#define R200_SE_TCL_PER_LIGHT_CTL_2 0x2278 -#define R200_LIGHT_4_SHIFT (0) -#define R200_LIGHT_5_SHIFT (16) -#define R200_SE_TCL_PER_LIGHT_CTL_3 0x227c -#define R200_LIGHT_6_SHIFT (0) -#define R200_LIGHT_7_SHIFT (16) -/* gap */ -#define R200_SE_TCL_TEX_PROC_CTL_2 0x22a8 -#define R200_TEXGEN_0_COMP_MASK_SHIFT (0) -#define R200_TEXGEN_1_COMP_MASK_SHIFT (4) -#define R200_TEXGEN_2_COMP_MASK_SHIFT (8) -#define R200_TEXGEN_3_COMP_MASK_SHIFT (12) -#define R200_TEXGEN_4_COMP_MASK_SHIFT (16) -#define R200_TEXGEN_5_COMP_MASK_SHIFT (20) -#define R200_SE_TCL_TEX_PROC_CTL_3 0x22ac -#define R200_TEXGEN_0_INPUT_TEX_SHIFT (0) -#define R200_TEXGEN_1_INPUT_TEX_SHIFT (4) -#define R200_TEXGEN_2_INPUT_TEX_SHIFT (8) -#define R200_TEXGEN_3_INPUT_TEX_SHIFT (12) -#define R200_TEXGEN_4_INPUT_TEX_SHIFT (16) -#define R200_TEXGEN_5_INPUT_TEX_SHIFT (20) -#define R200_SE_TCL_TEX_PROC_CTL_0 0x22b0 -#define R200_TEXGEN_TEXMAT_0_ENABLE (1<<0) -#define R200_TEXGEN_TEXMAT_1_ENABLE (1<<1) -#define R200_TEXGEN_TEXMAT_2_ENABLE (1<<2) -#define R200_TEXGEN_TEXMAT_3_ENABLE (1<<3) -#define R200_TEXGEN_TEXMAT_4_ENABLE (1<<4) -#define R200_TEXGEN_TEXMAT_5_ENABLE (1<<5) -#define R200_TEXMAT_0_ENABLE (1<<8) -#define R200_TEXMAT_1_ENABLE (1<<9) -#define R200_TEXMAT_2_ENABLE (1<<10) -#define R200_TEXMAT_3_ENABLE (1<<11) -#define R200_TEXMAT_4_ENABLE (1<<12) -#define R200_TEXMAT_5_ENABLE (1<<13) -#define R200_TEXGEN_FORCE_W_TO_ONE (1<<16) -#define R200_SE_TCL_TEX_PROC_CTL_1 0x22b4 -#define R200_TEXGEN_INPUT_MASK (0xf) -#define R200_TEXGEN_INPUT_TEXCOORD_0 (0) -#define R200_TEXGEN_INPUT_TEXCOORD_1 (1) -#define R200_TEXGEN_INPUT_TEXCOORD_2 (2) -#define R200_TEXGEN_INPUT_TEXCOORD_3 (3) -#define R200_TEXGEN_INPUT_TEXCOORD_4 (4) -#define R200_TEXGEN_INPUT_TEXCOORD_5 (5) -#define R200_TEXGEN_INPUT_OBJ (8) -#define R200_TEXGEN_INPUT_EYE (9) -#define R200_TEXGEN_INPUT_EYE_NORMAL (0xa) -#define R200_TEXGEN_INPUT_EYE_REFLECT (0xb) -#define R200_TEXGEN_INPUT_SPHERE (0xd) -#define R200_TEXGEN_0_INPUT_SHIFT (0) -#define R200_TEXGEN_1_INPUT_SHIFT (4) -#define R200_TEXGEN_2_INPUT_SHIFT (8) -#define R200_TEXGEN_3_INPUT_SHIFT (12) -#define R200_TEXGEN_4_INPUT_SHIFT (16) -#define R200_TEXGEN_5_INPUT_SHIFT (20) -#define R200_SE_TC_TEX_CYL_WRAP_CTL 0x22b8 -/* gap */ -#define R200_SE_TCL_UCP_VERT_BLEND_CTL 0x22c0 -#define R200_UCP_IN_CLIP_SPACE (1<<0) -#define R200_UCP_IN_MODEL_SPACE (1<<1) -#define R200_UCP_ENABLE_0 (1<<2) -#define R200_UCP_ENABLE_1 (1<<3) -#define R200_UCP_ENABLE_2 (1<<4) -#define R200_UCP_ENABLE_3 (1<<5) -#define R200_UCP_ENABLE_4 (1<<6) -#define R200_UCP_ENABLE_5 (1<<7) -#define R200_TCL_FOG_MASK (3<<8) -#define R200_TCL_FOG_DISABLE (0<<8) -#define R200_TCL_FOG_EXP (1<<8) -#define R200_TCL_FOG_EXP2 (2<<8) -#define R200_TCL_FOG_LINEAR (3<<8) -#define R200_RNG_BASED_FOG (1<<10) -#define R200_CLIP_DISABLE (1<<11) -#define R200_CULL_FRONT_IS_CW (0<<28) -#define R200_CULL_FRONT_IS_CCW (1<<28) -#define R200_CULL_FRONT (1<<29) -#define R200_CULL_BACK (1<<30) -#define R200_SE_TCL_POINT_SPRITE_CNTL 0x22c4 -/* gap */ -#define R200_SE_VTX_ST_POS_0_X_4 0x2300 -#define R200_SE_VTX_ST_POS_0_Y_4 0x2304 -#define R200_SE_VTX_ST_POS_0_Z_4 0x2308 -#define R200_SE_VTX_ST_POS_0_W_4 0x230c -#define R200_SE_VTX_ST_NORM_0_X 0x2310 -#define R200_SE_VTX_ST_NORM_0_Y 0x2314 -#define R200_SE_VTX_ST_NORM_0_Z 0x2318 -#define R200_SE_VTX_ST_PVMS 0x231c -#define R200_SE_VTX_ST_CLR_0_R 0x2320 -#define R200_SE_VTX_ST_CLR_0_G 0x2324 -#define R200_SE_VTX_ST_CLR_0_B 0x2328 -#define R200_SE_VTX_ST_CLR_0_A 0x232c -#define R200_SE_VTX_ST_CLR_1_R 0x2330 -#define R200_SE_VTX_ST_CLR_1_G 0x2334 -#define R200_SE_VTX_ST_CLR_1_B 0x2338 -#define R200_SE_VTX_ST_CLR_1_A 0x233c -#define R200_SE_VTX_ST_CLR_2_R 0x2340 -#define R200_SE_VTX_ST_CLR_2_G 0x2344 -#define R200_SE_VTX_ST_CLR_2_B 0x2348 -#define R200_SE_VTX_ST_CLR_2_A 0x234c -#define R200_SE_VTX_ST_CLR_3_R 0x2350 -#define R200_SE_VTX_ST_CLR_3_G 0x2354 -#define R200_SE_VTX_ST_CLR_3_B 0x2358 -#define R200_SE_VTX_ST_CLR_3_A 0x235c -#define R200_SE_VTX_ST_CLR_4_R 0x2360 -#define R200_SE_VTX_ST_CLR_4_G 0x2364 -#define R200_SE_VTX_ST_CLR_4_B 0x2368 -#define R200_SE_VTX_ST_CLR_4_A 0x236c -#define R200_SE_VTX_ST_CLR_5_R 0x2370 -#define R200_SE_VTX_ST_CLR_5_G 0x2374 -#define R200_SE_VTX_ST_CLR_5_B 0x2378 -#define R200_SE_VTX_ST_CLR_5_A 0x237c -#define R200_SE_VTX_ST_CLR_6_R 0x2380 -#define R200_SE_VTX_ST_CLR_6_G 0x2384 -#define R200_SE_VTX_ST_CLR_6_B 0x2388 -#define R200_SE_VTX_ST_CLR_6_A 0x238c -#define R200_SE_VTX_ST_CLR_7_R 0x2390 -#define R200_SE_VTX_ST_CLR_7_G 0x2394 -#define R200_SE_VTX_ST_CLR_7_B 0x2398 -#define R200_SE_VTX_ST_CLR_7_A 0x239c -#define R200_SE_VTX_ST_TEX_0_S 0x23a0 -#define R200_SE_VTX_ST_TEX_0_T 0x23a4 -#define R200_SE_VTX_ST_TEX_0_R 0x23a8 -#define R200_SE_VTX_ST_TEX_0_Q 0x23ac -#define R200_SE_VTX_ST_TEX_1_S 0x23b0 -#define R200_SE_VTX_ST_TEX_1_T 0x23b4 -#define R200_SE_VTX_ST_TEX_1_R 0x23b8 -#define R200_SE_VTX_ST_TEX_1_Q 0x23bc -#define R200_SE_VTX_ST_TEX_2_S 0x23c0 -#define R200_SE_VTX_ST_TEX_2_T 0x23c4 -#define R200_SE_VTX_ST_TEX_2_R 0x23c8 -#define R200_SE_VTX_ST_TEX_2_Q 0x23cc -#define R200_SE_VTX_ST_TEX_3_S 0x23d0 -#define R200_SE_VTX_ST_TEX_3_T 0x23d4 -#define R200_SE_VTX_ST_TEX_3_R 0x23d8 -#define R200_SE_VTX_ST_TEX_3_Q 0x23dc -#define R200_SE_VTX_ST_TEX_4_S 0x23e0 -#define R200_SE_VTX_ST_TEX_4_T 0x23e4 -#define R200_SE_VTX_ST_TEX_4_R 0x23e8 -#define R200_SE_VTX_ST_TEX_4_Q 0x23ec -#define R200_SE_VTX_ST_TEX_5_S 0x23f0 -#define R200_SE_VTX_ST_TEX_5_T 0x23f4 -#define R200_SE_VTX_ST_TEX_5_R 0x23f8 -#define R200_SE_VTX_ST_TEX_5_Q 0x23fc -#define R200_SE_VTX_ST_PNT_SPRT_SZ 0x2400 -#define R200_SE_VTX_ST_DISC_FOG 0x2404 -#define R200_SE_VTX_ST_SHININESS_0 0x2408 -#define R200_SE_VTX_ST_SHININESS_1 0x240c -#define R200_SE_VTX_ST_BLND_WT_0 0x2410 -#define R200_SE_VTX_ST_BLND_WT_1 0x2414 -#define R200_SE_VTX_ST_BLND_WT_2 0x2418 -#define R200_SE_VTX_ST_BLND_WT_3 0x241c -#define R200_SE_VTX_ST_POS_1_X 0x2420 -#define R200_SE_VTX_ST_POS_1_Y 0x2424 -#define R200_SE_VTX_ST_POS_1_Z 0x2428 -#define R200_SE_VTX_ST_POS_1_W 0x242c -#define R200_SE_VTX_ST_NORM_1_X 0x2430 -#define R200_SE_VTX_ST_NORM_1_Y 0x2434 -#define R200_SE_VTX_ST_NORM_1_Z 0x2438 -#define R200_SE_VTX_ST_USR_CLR_0_R 0x2440 -#define R200_SE_VTX_ST_USR_CLR_0_G 0x2444 -#define R200_SE_VTX_ST_USR_CLR_0_B 0x2448 -#define R200_SE_VTX_ST_USR_CLR_0_A 0x244c -#define R200_SE_VTX_ST_USR_CLR_1_R 0x2450 -#define R200_SE_VTX_ST_USR_CLR_1_G 0x2454 -#define R200_SE_VTX_ST_USR_CLR_1_B 0x2458 -#define R200_SE_VTX_ST_USR_CLR_1_A 0x245c -#define R200_SE_VTX_ST_CLR_0_PKD 0x2460 -#define R200_SE_VTX_ST_CLR_1_PKD 0x2464 -#define R200_SE_VTX_ST_CLR_2_PKD 0x2468 -#define R200_SE_VTX_ST_CLR_3_PKD 0x246c -#define R200_SE_VTX_ST_CLR_4_PKD 0x2470 -#define R200_SE_VTX_ST_CLR_5_PKD 0x2474 -#define R200_SE_VTX_ST_CLR_6_PKD 0x2478 -#define R200_SE_VTX_ST_CLR_7_PKD 0x247c -#define R200_SE_VTX_ST_POS_0_X_2 0x2480 -#define R200_SE_VTX_ST_POS_0_Y_2 0x2484 -#define R200_SE_VTX_ST_PAR_CLR_LD 0x2488 -#define R200_SE_VTX_ST_USR_CLR_PKD 0x248c -#define R200_SE_VTX_ST_POS_0_X_3 0x2490 -#define R200_SE_VTX_ST_POS_0_Y_3 0x2494 -#define R200_SE_VTX_ST_POS_0_Z_3 0x2498 -#define R200_SE_VTX_ST_END_OF_PKT 0x249c -/* gap */ -#define R200_RE_POINTSIZE 0x2648 -#define R200_POINTSIZE_SHIFT 0 -#define R200_MAXPOINTSIZE_SHIFT 16 -/* gap */ -#define R200_RE_TOP_LEFT 0x26c0 -#define R200_RE_LEFT_SHIFT 0 -#define R200_RE_TOP_SHIFT 16 -#define R200_RE_MISC 0x26c4 -#define R200_STIPPLE_COORD_MASK 0x1f -#define R200_STIPPLE_X_OFFSET_SHIFT 0 -#define R200_STIPPLE_X_OFFSET_MASK (0x1f << 0) -#define R200_STIPPLE_Y_OFFSET_SHIFT 8 -#define R200_STIPPLE_Y_OFFSET_MASK (0x1f << 8) -#define R200_STIPPLE_LITTLE_BIT_ORDER (0 << 16) -#define R200_STIPPLE_BIG_BIT_ORDER (1 << 16) -/* gap */ -#define R200_RE_AUX_SCISSOR_CNTL 0x26f0 -#define R200_EXCLUSIVE_SCISSOR_0 0x01000000 -#define R200_EXCLUSIVE_SCISSOR_1 0x02000000 -#define R200_EXCLUSIVE_SCISSOR_2 0x04000000 -#define R200_SCISSOR_ENABLE_0 0x10000000 -#define R200_SCISSOR_ENABLE_1 0x20000000 -#define R200_SCISSOR_ENABLE_2 0x40000000 -/* gap */ -#define R200_PP_TXFILTER_0 0x2c00 -#define R200_MAG_FILTER_NEAREST (0 << 0) -#define R200_MAG_FILTER_LINEAR (1 << 0) -#define R200_MAG_FILTER_MASK (1 << 0) -#define R200_MIN_FILTER_NEAREST (0 << 1) -#define R200_MIN_FILTER_LINEAR (1 << 1) -#define R200_MIN_FILTER_NEAREST_MIP_NEAREST (2 << 1) -#define R200_MIN_FILTER_NEAREST_MIP_LINEAR (3 << 1) -#define R200_MIN_FILTER_LINEAR_MIP_NEAREST (6 << 1) -#define R200_MIN_FILTER_LINEAR_MIP_LINEAR (7 << 1) -#define R200_MIN_FILTER_ANISO_NEAREST (8 << 1) -#define R200_MIN_FILTER_ANISO_LINEAR (9 << 1) -#define R200_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST (10 << 1) -#define R200_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR (11 << 1) -#define R200_MIN_FILTER_MASK (15 << 1) -#define R200_MAX_ANISO_1_TO_1 (0 << 5) -#define R200_MAX_ANISO_2_TO_1 (1 << 5) -#define R200_MAX_ANISO_4_TO_1 (2 << 5) -#define R200_MAX_ANISO_8_TO_1 (3 << 5) -#define R200_MAX_ANISO_16_TO_1 (4 << 5) -#define R200_MAX_ANISO_MASK (7 << 5) -#define R200_MAX_MIP_LEVEL_MASK (0x0f << 16) -#define R200_MAX_MIP_LEVEL_SHIFT 16 -#define R200_YUV_TO_RGB (1 << 20) -#define R200_YUV_TEMPERATURE_COOL (0 << 21) -#define R200_YUV_TEMPERATURE_HOT (1 << 21) -#define R200_YUV_TEMPERATURE_MASK (1 << 21) -#define R200_WRAPEN_S (1 << 22) -#define R200_CLAMP_S_WRAP (0 << 23) -#define R200_CLAMP_S_MIRROR (1 << 23) -#define R200_CLAMP_S_CLAMP_LAST (2 << 23) -#define R200_CLAMP_S_MIRROR_CLAMP_LAST (3 << 23) -#define R200_CLAMP_S_CLAMP_BORDER (4 << 23) -#define R200_CLAMP_S_MIRROR_CLAMP_BORDER (5 << 23) -#define R200_CLAMP_S_CLAMP_GL (6 << 23) -#define R200_CLAMP_S_MIRROR_CLAMP_GL (7 << 23) -#define R200_CLAMP_S_MASK (7 << 23) -#define R200_WRAPEN_T (1 << 26) -#define R200_CLAMP_T_WRAP (0 << 27) -#define R200_CLAMP_T_MIRROR (1 << 27) -#define R200_CLAMP_T_CLAMP_LAST (2 << 27) -#define R200_CLAMP_T_MIRROR_CLAMP_LAST (3 << 27) -#define R200_CLAMP_T_CLAMP_BORDER (4 << 27) -#define R200_CLAMP_T_MIRROR_CLAMP_BORDER (5 << 27) -#define R200_CLAMP_T_CLAMP_GL (6 << 27) -#define R200_CLAMP_T_MIRROR_CLAMP_GL (7 << 27) -#define R200_CLAMP_T_MASK (7 << 27) -#define R200_KILL_LT_ZERO (1 << 30) -#define R200_BORDER_MODE_OGL (0 << 31) -#define R200_BORDER_MODE_D3D (1 << 31) -#define R200_PP_TXFORMAT_0 0x2c04 -#define R200_TXFORMAT_I8 (0 << 0) -#define R200_TXFORMAT_AI88 (1 << 0) -#define R200_TXFORMAT_RGB332 (2 << 0) -#define R200_TXFORMAT_ARGB1555 (3 << 0) -#define R200_TXFORMAT_RGB565 (4 << 0) -#define R200_TXFORMAT_ARGB4444 (5 << 0) -#define R200_TXFORMAT_ARGB8888 (6 << 0) -#define R200_TXFORMAT_RGBA8888 (7 << 0) -#define R200_TXFORMAT_Y8 (8 << 0) -#define R200_TXFORMAT_AVYU4444 (9 << 0) -#define R200_TXFORMAT_VYUY422 (10 << 0) -#define R200_TXFORMAT_YVYU422 (11 << 0) -#define R200_TXFORMAT_DXT1 (12 << 0) -#define R200_TXFORMAT_DXT23 (14 << 0) -#define R200_TXFORMAT_DXT45 (15 << 0) -#define R200_TXFORMAT_FORMAT_MASK (31 << 0) -#define R200_TXFORMAT_FORMAT_SHIFT 0 -#define R200_TXFORMAT_ALPHA_IN_MAP (1 << 6) -#define R200_TXFORMAT_NON_POWER2 (1 << 7) -#define R200_TXFORMAT_WIDTH_MASK (15 << 8) -#define R200_TXFORMAT_WIDTH_SHIFT 8 -#define R200_TXFORMAT_HEIGHT_MASK (15 << 12) -#define R200_TXFORMAT_HEIGHT_SHIFT 12 -#define R200_TXFORMAT_F5_WIDTH_MASK (15 << 16) /* cube face 5 */ -#define R200_TXFORMAT_F5_WIDTH_SHIFT 16 -#define R200_TXFORMAT_F5_HEIGHT_MASK (15 << 20) -#define R200_TXFORMAT_F5_HEIGHT_SHIFT 20 -#define R200_TXFORMAT_ST_ROUTE_STQ0 (0 << 24) -#define R200_TXFORMAT_ST_ROUTE_STQ1 (1 << 24) -#define R200_TXFORMAT_ST_ROUTE_STQ2 (2 << 24) -#define R200_TXFORMAT_ST_ROUTE_STQ3 (3 << 24) -#define R200_TXFORMAT_ST_ROUTE_STQ4 (4 << 24) -#define R200_TXFORMAT_ST_ROUTE_STQ5 (5 << 24) -#define R200_TXFORMAT_ST_ROUTE_MASK (7 << 24) -#define R200_TXFORMAT_ST_ROUTE_SHIFT 24 -#define R200_TXFORMAT_ALPHA_MASK_ENABLE (1 << 28) -#define R200_TXFORMAT_CHROMA_KEY_ENABLE (1 << 29) -#define R200_TXFORMAT_CUBIC_MAP_ENABLE (1 << 30) -#define R200_PP_TXFORMAT_X_0 0x2c08 -#define R200_DEPTH_LOG2_MASK (0xf << 0) -#define R200_DEPTH_LOG2_SHIFT 0 -#define R200_VOLUME_FILTER_SHIFT 4 -#define R200_VOLUME_FILTER_MASK (1 << 4) -#define R200_VOLUME_FILTER_NEAREST (0 << 4) -#define R200_VOLUME_FILTER_LINEAR (1 << 4) -#define R200_WRAPEN_Q (1 << 8) -#define R200_CLAMP_Q_WRAP (0 << 9) -#define R200_CLAMP_Q_MIRROR (1 << 9) -#define R200_CLAMP_Q_CLAMP_LAST (2 << 9) -#define R200_CLAMP_Q_MIRROR_CLAMP_LAST (3 << 9) -#define R200_CLAMP_Q_CLAMP_BORDER (4 << 9) -#define R200_CLAMP_Q_MIRROR_CLAMP_BORDER (5 << 9) -#define R200_CLAMP_Q_CLAMP_GL (6 << 9) -#define R200_CLAMP_Q_MIRROR_CLAMP_GL (7 << 9) -#define R200_CLAMP_Q_MASK (7 << 9) -#define R200_MIN_MIP_LEVEL_MASK (0xff << 12) -#define R200_MIN_MIP_LEVEL_SHIFT 12 -#define R200_TEXCOORD_NONPROJ (0 << 16) -#define R200_TEXCOORD_CUBIC_ENV (1 << 16) -#define R200_TEXCOORD_VOLUME (2 << 16) -#define R200_TEXCOORD_PROJ (3 << 16) -#define R200_TEXCOORD_DEPTH (4 << 16) -#define R200_TEXCOORD_1D_PROJ (5 << 16) -#define R200_TEXCOORD_1D (6 << 16) -#define R200_TEXCOORD_ZERO (7 << 16) -#define R200_TEXCOORD_MASK (7 << 16) -#define R200_LOD_BIAS_MASK (0xfff80000) -#define R200_LOD_BIAS_SHIFT 19 -#define R200_PP_TXSIZE_0 0x2c0c /* NPOT only */ -#define R200_PP_TXPITCH_0 0x2c10 /* NPOT only */ -#define R200_PP_BORDER_COLOR_0 0x2c14 -#define R200_PP_CUBIC_FACES_0 0x2c18 -#define R200_FACE_WIDTH_1_SHIFT 0 -#define R200_FACE_HEIGHT_1_SHIFT 4 -#define R200_FACE_WIDTH_1_MASK (0xf << 0) -#define R200_FACE_HEIGHT_1_MASK (0xf << 4) -#define R200_FACE_WIDTH_2_SHIFT 8 -#define R200_FACE_HEIGHT_2_SHIFT 12 -#define R200_FACE_WIDTH_2_MASK (0xf << 8) -#define R200_FACE_HEIGHT_2_MASK (0xf << 12) -#define R200_FACE_WIDTH_3_SHIFT 16 -#define R200_FACE_HEIGHT_3_SHIFT 20 -#define R200_FACE_WIDTH_3_MASK (0xf << 16) -#define R200_FACE_HEIGHT_3_MASK (0xf << 20) -#define R200_FACE_WIDTH_4_SHIFT 24 -#define R200_FACE_HEIGHT_4_SHIFT 28 -#define R200_FACE_WIDTH_4_MASK (0xf << 24) -#define R200_FACE_HEIGHT_4_MASK (0xf << 28) -#define R200_PP_TXFILTER_1 0x2c20 -#define R200_PP_TXFORMAT_1 0x2c24 -#define R200_PP_TXFORMAT_X_1 0x2c28 -#define R200_PP_TXSIZE_1 0x2c2c -#define R200_PP_TXPITCH_1 0x2c30 -#define R200_PP_BORDER_COLOR_1 0x2c34 -#define R200_PP_CUBIC_FACES_1 0x2c38 -#define R200_PP_TXFILTER_2 0x2c40 -#define R200_PP_TXFORMAT_2 0x2c44 -#define R200_PP_TXSIZE_2 0x2c4c -#define R200_PP_TXFORMAT_X_2 0x2c48 -#define R200_PP_TXPITCH_2 0x2c50 -#define R200_PP_BORDER_COLOR_2 0x2c54 -#define R200_PP_CUBIC_FACES_2 0x2c58 -#define R200_PP_TXFILTER_3 0x2c60 -#define R200_PP_TXFORMAT_3 0x2c64 -#define R200_PP_TXSIZE_3 0x2c6c -#define R200_PP_TXFORMAT_X_3 0x2c68 -#define R200_PP_TXPITCH_3 0x2c70 -#define R200_PP_BORDER_COLOR_3 0x2c74 -#define R200_PP_CUBIC_FACES_3 0x2c78 -#define R200_PP_TXFILTER_4 0x2c80 -#define R200_PP_TXFORMAT_4 0x2c84 -#define R200_PP_TXSIZE_4 0x2c8c -#define R200_PP_TXFORMAT_X_4 0x2c88 -#define R200_PP_TXPITCH_4 0x2c90 -#define R200_PP_BORDER_COLOR_4 0x2c94 -#define R200_PP_CUBIC_FACES_4 0x2c98 -#define R200_PP_TXFILTER_5 0x2ca0 -#define R200_PP_TXFORMAT_5 0x2ca4 -#define R200_PP_TXSIZE_5 0x2cac -#define R200_PP_TXFORMAT_X_5 0x2ca8 -#define R200_PP_TXPITCH_5 0x2cb0 -#define R200_PP_BORDER_COLOR_5 0x2cb4 -#define R200_PP_CUBIC_FACES_5 0x2cb8 -/* gap */ -#define R200_PP_CNTL_X 0x2cc4 -/* gap */ -#define R200_PP_TXOFFSET_0 0x2d00 -#define R200_TXO_ENDIAN_NO_SWAP (0 << 0) -#define R200_TXO_ENDIAN_BYTE_SWAP (1 << 0) -#define R200_TXO_ENDIAN_WORD_SWAP (2 << 0) -#define R200_TXO_ENDIAN_HALFDW_SWAP (3 << 0) -#define R200_TXO_OFFSET_MASK 0xffffffe0 -#define R200_TXO_OFFSET_SHIFT 5 -#define R200_PP_CUBIC_OFFSET_F1_0 0x2d04 -#define R200_PP_CUBIC_OFFSET_F2_0 0x2d08 -#define R200_PP_CUBIC_OFFSET_F3_0 0x2d0c -#define R200_PP_CUBIC_OFFSET_F4_0 0x2d10 -#define R200_PP_CUBIC_OFFSET_F5_0 0x2d14 -#define R200_PP_TXOFFSET_1 0x2d18 -#define R200_PP_CUBIC_OFFSET_F1_1 0x2d1c -#define R200_PP_CUBIC_OFFSET_F2_1 0x2d20 -#define R200_PP_CUBIC_OFFSET_F3_1 0x2d24 -#define R200_PP_CUBIC_OFFSET_F4_1 0x2d28 -#define R200_PP_CUBIC_OFFSET_F5_1 0x2d2c -#define R200_PP_TXOFFSET_2 0x2d30 -#define R200_PP_CUBIC_OFFSET_F1_2 0x2d34 -#define R200_PP_CUBIC_OFFSET_F2_2 0x2d38 -#define R200_PP_CUBIC_OFFSET_F3_2 0x2d3c -#define R200_PP_CUBIC_OFFSET_F4_2 0x2d40 -#define R200_PP_CUBIC_OFFSET_F5_2 0x2d44 -#define R200_PP_TXOFFSET_3 0x2d48 -#define R200_PP_CUBIC_OFFSET_F1_3 0x2d4c -#define R200_PP_CUBIC_OFFSET_F2_3 0x2d50 -#define R200_PP_CUBIC_OFFSET_F3_3 0x2d54 -#define R200_PP_CUBIC_OFFSET_F4_3 0x2d58 -#define R200_PP_CUBIC_OFFSET_F5_3 0x2d5c -#define R200_PP_TXOFFSET_4 0x2d60 -#define R200_PP_CUBIC_OFFSET_F1_4 0x2d64 -#define R200_PP_CUBIC_OFFSET_F2_4 0x2d68 -#define R200_PP_CUBIC_OFFSET_F3_4 0x2d6c -#define R200_PP_CUBIC_OFFSET_F4_4 0x2d70 -#define R200_PP_CUBIC_OFFSET_F5_4 0x2d74 -#define R200_PP_TXOFFSET_5 0x2d78 -#define R200_PP_CUBIC_OFFSET_F1_5 0x2d7c -#define R200_PP_CUBIC_OFFSET_F2_5 0x2d80 -#define R200_PP_CUBIC_OFFSET_F3_5 0x2d84 -#define R200_PP_CUBIC_OFFSET_F4_5 0x2d88 -#define R200_PP_CUBIC_OFFSET_F5_5 0x2d8c -/* gap */ -#define R200_PP_TAM_DEBUG3 0x2d9c -/* gap */ -#define R200_PP_TFACTOR_0 0x2ee0 -#define R200_PP_TFACTOR_1 0x2ee4 -#define R200_PP_TFACTOR_2 0x2ee8 -#define R200_PP_TFACTOR_3 0x2eec -#define R200_PP_TFACTOR_4 0x2ef0 -#define R200_PP_TFACTOR_5 0x2ef4 -/* gap */ -#define R200_PP_TXCBLEND_0 0x2f00 -#define R200_TXC_ARG_A_ZERO (0) -#define R200_TXC_ARG_A_CURRENT_COLOR (2) -#define R200_TXC_ARG_A_CURRENT_ALPHA (3) -#define R200_TXC_ARG_A_DIFFUSE_COLOR (4) -#define R200_TXC_ARG_A_DIFFUSE_ALPHA (5) -#define R200_TXC_ARG_A_SPECULAR_COLOR (6) -#define R200_TXC_ARG_A_SPECULAR_ALPHA (7) -#define R200_TXC_ARG_A_TFACTOR_COLOR (8) -#define R200_TXC_ARG_A_TFACTOR_ALPHA (9) -#define R200_TXC_ARG_A_R0_COLOR (10) -#define R200_TXC_ARG_A_R0_ALPHA (11) -#define R200_TXC_ARG_A_R1_COLOR (12) -#define R200_TXC_ARG_A_R1_ALPHA (13) -#define R200_TXC_ARG_A_R2_COLOR (14) -#define R200_TXC_ARG_A_R2_ALPHA (15) -#define R200_TXC_ARG_A_R3_COLOR (16) -#define R200_TXC_ARG_A_R3_ALPHA (17) -#define R200_TXC_ARG_A_R4_COLOR (18) -#define R200_TXC_ARG_A_R4_ALPHA (19) -#define R200_TXC_ARG_A_R5_COLOR (20) -#define R200_TXC_ARG_A_R5_ALPHA (21) -#define R200_TXC_ARG_A_TFACTOR1_COLOR (26) -#define R200_TXC_ARG_A_TFACTOR1_ALPHA (27) -#define R200_TXC_ARG_A_MASK (31 << 0) -#define R200_TXC_ARG_A_SHIFT 0 -#define R200_TXC_ARG_B_ZERO (0<<5) -#define R200_TXC_ARG_B_CURRENT_COLOR (2<<5) -#define R200_TXC_ARG_B_CURRENT_ALPHA (3<<5) -#define R200_TXC_ARG_B_DIFFUSE_COLOR (4<<5) -#define R200_TXC_ARG_B_DIFFUSE_ALPHA (5<<5) -#define R200_TXC_ARG_B_SPECULAR_COLOR (6<<5) -#define R200_TXC_ARG_B_SPECULAR_ALPHA (7<<5) -#define R200_TXC_ARG_B_TFACTOR_COLOR (8<<5) -#define R200_TXC_ARG_B_TFACTOR_ALPHA (9<<5) -#define R200_TXC_ARG_B_R0_COLOR (10<<5) -#define R200_TXC_ARG_B_R0_ALPHA (11<<5) -#define R200_TXC_ARG_B_R1_COLOR (12<<5) -#define R200_TXC_ARG_B_R1_ALPHA (13<<5) -#define R200_TXC_ARG_B_R2_COLOR (14<<5) -#define R200_TXC_ARG_B_R2_ALPHA (15<<5) -#define R200_TXC_ARG_B_R3_COLOR (16<<5) -#define R200_TXC_ARG_B_R3_ALPHA (17<<5) -#define R200_TXC_ARG_B_R4_COLOR (18<<5) -#define R200_TXC_ARG_B_R4_ALPHA (19<<5) -#define R200_TXC_ARG_B_R5_COLOR (20<<5) -#define R200_TXC_ARG_B_R5_ALPHA (21<<5) -#define R200_TXC_ARG_B_TFACTOR1_COLOR (26<<5) -#define R200_TXC_ARG_B_TFACTOR1_ALPHA (27<<5) -#define R200_TXC_ARG_B_MASK (31 << 5) -#define R200_TXC_ARG_B_SHIFT 5 -#define R200_TXC_ARG_C_ZERO (0<<10) -#define R200_TXC_ARG_C_CURRENT_COLOR (2<<10) -#define R200_TXC_ARG_C_CURRENT_ALPHA (3<<10) -#define R200_TXC_ARG_C_DIFFUSE_COLOR (4<<10) -#define R200_TXC_ARG_C_DIFFUSE_ALPHA (5<<10) -#define R200_TXC_ARG_C_SPECULAR_COLOR (6<<10) -#define R200_TXC_ARG_C_SPECULAR_ALPHA (7<<10) -#define R200_TXC_ARG_C_TFACTOR_COLOR (8<<10) -#define R200_TXC_ARG_C_TFACTOR_ALPHA (9<<10) -#define R200_TXC_ARG_C_R0_COLOR (10<<10) -#define R200_TXC_ARG_C_R0_ALPHA (11<<10) -#define R200_TXC_ARG_C_R1_COLOR (12<<10) -#define R200_TXC_ARG_C_R1_ALPHA (13<<10) -#define R200_TXC_ARG_C_R2_COLOR (14<<10) -#define R200_TXC_ARG_C_R2_ALPHA (15<<10) -#define R200_TXC_ARG_C_R3_COLOR (16<<10) -#define R200_TXC_ARG_C_R3_ALPHA (17<<10) -#define R200_TXC_ARG_C_R4_COLOR (18<<10) -#define R200_TXC_ARG_C_R4_ALPHA (19<<10) -#define R200_TXC_ARG_C_R5_COLOR (20<<10) -#define R200_TXC_ARG_C_R5_ALPHA (21<<10) -#define R200_TXC_ARG_C_TFACTOR1_COLOR (26<<10) -#define R200_TXC_ARG_C_TFACTOR1_ALPHA (27<<10) -#define R200_TXC_ARG_C_MASK (31 << 10) -#define R200_TXC_ARG_C_SHIFT 10 -#define R200_TXC_COMP_ARG_A (1 << 16) -#define R200_TXC_COMP_ARG_A_SHIFT (16) -#define R200_TXC_BIAS_ARG_A (1 << 17) -#define R200_TXC_SCALE_ARG_A (1 << 18) -#define R200_TXC_NEG_ARG_A (1 << 19) -#define R200_TXC_COMP_ARG_B (1 << 20) -#define R200_TXC_COMP_ARG_B_SHIFT (20) -#define R200_TXC_BIAS_ARG_B (1 << 21) -#define R200_TXC_SCALE_ARG_B (1 << 22) -#define R200_TXC_NEG_ARG_B (1 << 23) -#define R200_TXC_COMP_ARG_C (1 << 24) -#define R200_TXC_COMP_ARG_C_SHIFT (24) -#define R200_TXC_BIAS_ARG_C (1 << 25) -#define R200_TXC_SCALE_ARG_C (1 << 26) -#define R200_TXC_NEG_ARG_C (1 << 27) -#define R200_TXC_OP_MADD (0 << 28) -#define R200_TXC_OP_CND0 (2 << 28) -#define R200_TXC_OP_LERP (3 << 28) -#define R200_TXC_OP_DOT3 (4 << 28) -#define R200_TXC_OP_DOT4 (5 << 28) -#define R200_TXC_OP_CONDITIONAL (6 << 28) -#define R200_TXC_OP_DOT2_ADD (7 << 28) -#define R200_TXC_OP_MASK (7 << 28) -#define R200_PP_TXCBLEND2_0 0x2f04 -#define R200_TXC_TFACTOR_SEL_SHIFT 0 -#define R200_TXC_TFACTOR_SEL_MASK 0x7 -#define R200_TXC_TFACTOR1_SEL_SHIFT 4 -#define R200_TXC_TFACTOR1_SEL_MASK (0x7 << 4) -#define R200_TXC_SCALE_SHIFT 8 -#define R200_TXC_SCALE_MASK (7 << 8) -#define R200_TXC_SCALE_1X (0 << 8) -#define R200_TXC_SCALE_2X (1 << 8) -#define R200_TXC_SCALE_4X (2 << 8) -#define R200_TXC_SCALE_8X (3 << 8) -#define R200_TXC_SCALE_INV2 (5 << 8) -#define R200_TXC_SCALE_INV4 (6 << 8) -#define R200_TXC_SCALE_INV8 (7 << 8) -#define R200_TXC_CLAMP_SHIFT 12 -#define R200_TXC_CLAMP_MASK (3 << 12) -#define R200_TXC_CLAMP_WRAP (0 << 12) -#define R200_TXC_CLAMP_0_1 (1 << 12) -#define R200_TXC_CLAMP_8_8 (2 << 12) -#define R200_TXC_OUTPUT_REG_MASK (7 << 16) -#define R200_TXC_OUTPUT_REG_NONE (0 << 16) -#define R200_TXC_OUTPUT_REG_R0 (1 << 16) -#define R200_TXC_OUTPUT_REG_R1 (2 << 16) -#define R200_TXC_OUTPUT_REG_R2 (3 << 16) -#define R200_TXC_OUTPUT_REG_R3 (4 << 16) -#define R200_TXC_OUTPUT_REG_R4 (5 << 16) -#define R200_TXC_OUTPUT_REG_R5 (6 << 16) -#define R200_TXC_OUTPUT_MASK_MASK (7 << 20) -#define R200_TXC_OUTPUT_MASK_RGB (0 << 20) -#define R200_TXC_OUTPUT_MASK_RG (1 << 20) -#define R200_TXC_OUTPUT_MASK_RB (2 << 20) -#define R200_TXC_OUTPUT_MASK_R (3 << 20) -#define R200_TXC_OUTPUT_MASK_GB (4 << 20) -#define R200_TXC_OUTPUT_MASK_G (5 << 20) -#define R200_TXC_OUTPUT_MASK_B (6 << 20) -#define R200_TXC_OUTPUT_MASK_NONE (7 << 20) -#define R200_TXC_REPL_NORMAL 0 -#define R200_TXC_REPL_RED 1 -#define R200_TXC_REPL_GREEN 2 -#define R200_TXC_REPL_BLUE 3 -#define R200_TXC_REPL_ARG_A_SHIFT 26 -#define R200_TXC_REPL_ARG_A_MASK (3 << 26) -#define R200_TXC_REPL_ARG_B_SHIFT 28 -#define R200_TXC_REPL_ARG_B_MASK (3 << 28) -#define R200_TXC_REPL_ARG_C_SHIFT 30 -#define R200_TXC_REPL_ARG_C_MASK (3 << 30) -#define R200_PP_TXABLEND_0 0x2f08 -#define R200_TXA_ARG_A_ZERO (0) -#define R200_TXA_ARG_A_CURRENT_ALPHA (2) /* guess */ -#define R200_TXA_ARG_A_CURRENT_BLUE (3) /* guess */ -#define R200_TXA_ARG_A_DIFFUSE_ALPHA (4) -#define R200_TXA_ARG_A_DIFFUSE_BLUE (5) -#define R200_TXA_ARG_A_SPECULAR_ALPHA (6) -#define R200_TXA_ARG_A_SPECULAR_BLUE (7) -#define R200_TXA_ARG_A_TFACTOR_ALPHA (8) -#define R200_TXA_ARG_A_TFACTOR_BLUE (9) -#define R200_TXA_ARG_A_R0_ALPHA (10) -#define R200_TXA_ARG_A_R0_BLUE (11) -#define R200_TXA_ARG_A_R1_ALPHA (12) -#define R200_TXA_ARG_A_R1_BLUE (13) -#define R200_TXA_ARG_A_R2_ALPHA (14) -#define R200_TXA_ARG_A_R2_BLUE (15) -#define R200_TXA_ARG_A_R3_ALPHA (16) -#define R200_TXA_ARG_A_R3_BLUE (17) -#define R200_TXA_ARG_A_R4_ALPHA (18) -#define R200_TXA_ARG_A_R4_BLUE (19) -#define R200_TXA_ARG_A_R5_ALPHA (20) -#define R200_TXA_ARG_A_R5_BLUE (21) -#define R200_TXA_ARG_A_TFACTOR1_ALPHA (26) -#define R200_TXA_ARG_A_TFACTOR1_BLUE (27) -#define R200_TXA_ARG_A_MASK (31 << 0) -#define R200_TXA_ARG_A_SHIFT 0 -#define R200_TXA_ARG_B_ZERO (0<<5) -#define R200_TXA_ARG_B_CURRENT_ALPHA (2<<5) /* guess */ -#define R200_TXA_ARG_B_CURRENT_BLUE (3<<5) /* guess */ -#define R200_TXA_ARG_B_DIFFUSE_ALPHA (4<<5) -#define R200_TXA_ARG_B_DIFFUSE_BLUE (5<<5) -#define R200_TXA_ARG_B_SPECULAR_ALPHA (6<<5) -#define R200_TXA_ARG_B_SPECULAR_BLUE (7<<5) -#define R200_TXA_ARG_B_TFACTOR_ALPHA (8<<5) -#define R200_TXA_ARG_B_TFACTOR_BLUE (9<<5) -#define R200_TXA_ARG_B_R0_ALPHA (10<<5) -#define R200_TXA_ARG_B_R0_BLUE (11<<5) -#define R200_TXA_ARG_B_R1_ALPHA (12<<5) -#define R200_TXA_ARG_B_R1_BLUE (13<<5) -#define R200_TXA_ARG_B_R2_ALPHA (14<<5) -#define R200_TXA_ARG_B_R2_BLUE (15<<5) -#define R200_TXA_ARG_B_R3_ALPHA (16<<5) -#define R200_TXA_ARG_B_R3_BLUE (17<<5) -#define R200_TXA_ARG_B_R4_ALPHA (18<<5) -#define R200_TXA_ARG_B_R4_BLUE (19<<5) -#define R200_TXA_ARG_B_R5_ALPHA (20<<5) -#define R200_TXA_ARG_B_R5_BLUE (21<<5) -#define R200_TXA_ARG_B_TFACTOR1_ALPHA (26<<5) -#define R200_TXA_ARG_B_TFACTOR1_BLUE (27<<5) -#define R200_TXA_ARG_B_MASK (31 << 5) -#define R200_TXA_ARG_B_SHIFT 5 -#define R200_TXA_ARG_C_ZERO (0<<10) -#define R200_TXA_ARG_C_CURRENT_ALPHA (2<<10) /* guess */ -#define R200_TXA_ARG_C_CURRENT_BLUE (3<<10) /* guess */ -#define R200_TXA_ARG_C_DIFFUSE_ALPHA (4<<10) -#define R200_TXA_ARG_C_DIFFUSE_BLUE (5<<10) -#define R200_TXA_ARG_C_SPECULAR_ALPHA (6<<10) -#define R200_TXA_ARG_C_SPECULAR_BLUE (7<<10) -#define R200_TXA_ARG_C_TFACTOR_ALPHA (8<<10) -#define R200_TXA_ARG_C_TFACTOR_BLUE (9<<10) -#define R200_TXA_ARG_C_R0_ALPHA (10<<10) -#define R200_TXA_ARG_C_R0_BLUE (11<<10) -#define R200_TXA_ARG_C_R1_ALPHA (12<<10) -#define R200_TXA_ARG_C_R1_BLUE (13<<10) -#define R200_TXA_ARG_C_R2_ALPHA (14<<10) -#define R200_TXA_ARG_C_R2_BLUE (15<<10) -#define R200_TXA_ARG_C_R3_ALPHA (16<<10) -#define R200_TXA_ARG_C_R3_BLUE (17<<10) -#define R200_TXA_ARG_C_R4_ALPHA (18<<10) -#define R200_TXA_ARG_C_R4_BLUE (19<<10) -#define R200_TXA_ARG_C_R5_ALPHA (20<<10) -#define R200_TXA_ARG_C_R5_BLUE (21<<10) -#define R200_TXA_ARG_C_TFACTOR1_ALPHA (26<<10) -#define R200_TXA_ARG_C_TFACTOR1_BLUE (27<<10) -#define R200_TXA_ARG_C_MASK (31 << 10) -#define R200_TXA_ARG_C_SHIFT 10 -#define R200_TXA_COMP_ARG_A (1 << 16) -#define R200_TXA_COMP_ARG_A_SHIFT (16) -#define R200_TXA_BIAS_ARG_A (1 << 17) -#define R200_TXA_SCALE_ARG_A (1 << 18) -#define R200_TXA_NEG_ARG_A (1 << 19) -#define R200_TXA_COMP_ARG_B (1 << 20) -#define R200_TXA_COMP_ARG_B_SHIFT (20) -#define R200_TXA_BIAS_ARG_B (1 << 21) -#define R200_TXA_SCALE_ARG_B (1 << 22) -#define R200_TXA_NEG_ARG_B (1 << 23) -#define R200_TXA_COMP_ARG_C (1 << 24) -#define R200_TXA_COMP_ARG_C_SHIFT (24) -#define R200_TXA_BIAS_ARG_C (1 << 25) -#define R200_TXA_SCALE_ARG_C (1 << 26) -#define R200_TXA_NEG_ARG_C (1 << 27) -#define R200_TXA_OP_MADD (0 << 28) -#define R200_TXA_OP_CND0 (2 << 28) -#define R200_TXA_OP_LERP (3 << 28) -#define R200_TXA_OP_CONDITIONAL (6 << 28) -#define R200_TXA_OP_MASK (7 << 28) -#define R200_PP_TXABLEND2_0 0x2f0c -#define R200_TXA_TFACTOR_SEL_SHIFT 0 -#define R200_TXA_TFACTOR_SEL_MASK 0x7 -#define R200_TXA_TFACTOR1_SEL_SHIFT 4 -#define R200_TXA_TFACTOR1_SEL_MASK (0x7 << 4) -#define R200_TXA_SCALE_SHIFT 8 -#define R200_TXA_SCALE_MASK (7 << 8) -#define R200_TXA_SCALE_1X (0 << 8) -#define R200_TXA_SCALE_2X (1 << 8) -#define R200_TXA_SCALE_4X (2 << 8) -#define R200_TXA_SCALE_8X (3 << 8) -#define R200_TXA_SCALE_INV2 (5 << 8) -#define R200_TXA_SCALE_INV4 (6 << 8) -#define R200_TXA_SCALE_INV8 (7 << 8) -#define R200_TXA_CLAMP_SHIFT 12 -#define R200_TXA_CLAMP_MASK (3 << 12) -#define R200_TXA_CLAMP_WRAP (0 << 12) -#define R200_TXA_CLAMP_0_1 (1 << 12) -#define R200_TXA_CLAMP_8_8 (2 << 12) -#define R200_TXA_OUTPUT_REG_MASK (7 << 16) -#define R200_TXA_OUTPUT_REG_NONE (0 << 16) -#define R200_TXA_OUTPUT_REG_R0 (1 << 16) -#define R200_TXA_OUTPUT_REG_R1 (2 << 16) -#define R200_TXA_OUTPUT_REG_R2 (3 << 16) -#define R200_TXA_OUTPUT_REG_R3 (4 << 16) -#define R200_TXA_OUTPUT_REG_R4 (5 << 16) -#define R200_TXA_OUTPUT_REG_R5 (6 << 16) -#define R200_TXA_DOT_ALPHA (1 << 20) -#define R200_TXA_REPL_NORMAL 0 -#define R200_TXA_REPL_RED 1 -#define R200_TXA_REPL_GREEN 2 -#define R200_TXA_REPL_ARG_A_SHIFT 26 -#define R200_TXA_REPL_ARG_A_MASK (3 << 26) -#define R200_TXA_REPL_ARG_B_SHIFT 28 -#define R200_TXA_REPL_ARG_B_MASK (3 << 28) -#define R200_TXA_REPL_ARG_C_SHIFT 30 -#define R200_TXA_REPL_ARG_C_MASK (3 << 30) -#define R200_PP_TXCBLEND_1 0x2f10 -#define R200_PP_TXCBLEND2_1 0x2f14 -#define R200_PP_TXABLEND_1 0x2f18 -#define R200_PP_TXABLEND2_1 0x2f1c -#define R200_PP_TXCBLEND_2 0x2f20 -#define R200_PP_TXCBLEND2_2 0x2f24 -#define R200_PP_TXABLEND_2 0x2f28 -#define R200_PP_TXABLEND2_2 0x2f2c -#define R200_PP_TXCBLEND_3 0x2f30 -#define R200_PP_TXCBLEND2_3 0x2f34 -#define R200_PP_TXABLEND_3 0x2f38 -#define R200_PP_TXABLEND2_3 0x2f3c -#define R200_PP_TXCBLEND_4 0x2f40 -#define R200_PP_TXCBLEND2_4 0x2f44 -#define R200_PP_TXABLEND_4 0x2f48 -#define R200_PP_TXABLEND2_4 0x2f4c -#define R200_PP_TXCBLEND_5 0x2f50 -#define R200_PP_TXCBLEND2_5 0x2f54 -#define R200_PP_TXABLEND_5 0x2f58 -#define R200_PP_TXABLEND2_5 0x2f5c -#define R200_PP_TXCBLEND_6 0x2f60 -#define R200_PP_TXCBLEND2_6 0x2f64 -#define R200_PP_TXABLEND_6 0x2f68 -#define R200_PP_TXABLEND2_6 0x2f6c -#define R200_PP_TXCBLEND_7 0x2f70 -#define R200_PP_TXCBLEND2_7 0x2f74 -#define R200_PP_TXABLEND_7 0x2f78 -#define R200_PP_TXABLEND2_7 0x2f7c -/* gap */ -#define R200_RB3D_BLENDCOLOR 0x3218 /* ARGB 8888 */ -#define R200_RB3D_ABLENDCNTL 0x321C /* see BLENDCTL */ -#define R200_RB3D_CBLENDCNTL 0x3220 /* see BLENDCTL */ - -/* - * Offsets in TCL vector state. NOTE: Hardwiring matrix positions. - * Multiple contexts could collaberate to eliminate state bouncing. - */ -#define R200_VS_LIGHT_AMBIENT_ADDR 0x00000028 -#define R200_VS_LIGHT_DIFFUSE_ADDR 0x00000030 -#define R200_VS_LIGHT_SPECULAR_ADDR 0x00000038 -#define R200_VS_LIGHT_DIRPOS_ADDR 0x00000040 -#define R200_VS_LIGHT_HWVSPOT_ADDR 0x00000048 -#define R200_VS_LIGHT_ATTENUATION_ADDR 0x00000050 -#define R200_VS_SPOT_DUAL_CONE 0x00000058 -#define R200_VS_GLOBAL_AMBIENT_ADDR 0x0000005C -#define R200_VS_FOG_PARAM_ADDR 0x0000005D -#define R200_VS_EYE_VECTOR_ADDR 0x0000005E -#define R200_VS_UCP_ADDR 0x00000060 -#define R200_VS_PNT_SPRITE_VPORT_SCALE 0x00000068 -#define R200_VS_MATRIX_0_MV 0x00000080 -#define R200_VS_MATRIX_1_INV_MV 0x00000084 -#define R200_VS_MATRIX_2_MVP 0x00000088 -#define R200_VS_MATRIX_3_TEX0 0x0000008C -#define R200_VS_MATRIX_4_TEX1 0x00000090 -#define R200_VS_MATRIX_5_TEX2 0x00000094 -#define R200_VS_MATRIX_6_TEX3 0x00000098 -#define R200_VS_MATRIX_7_TEX4 0x0000009C -#define R200_VS_MATRIX_8_TEX5 0x000000A0 -#define R200_VS_MAT_0_EMISS 0x000000B0 -#define R200_VS_MAT_0_AMB 0x000000B1 -#define R200_VS_MAT_0_DIF 0x000000B2 -#define R200_VS_MAT_0_SPEC 0x000000B3 -#define R200_VS_MAT_1_EMISS 0x000000B4 -#define R200_VS_MAT_1_AMB 0x000000B5 -#define R200_VS_MAT_1_DIF 0x000000B6 -#define R200_VS_MAT_1_SPEC 0x000000B7 -#define R200_VS_EYE2CLIP_MTX 0x000000B8 -#define R200_VS_PNT_SPRITE_ATT_CONST 0x000000BC -#define R200_VS_PNT_SPRITE_EYE_IN_MODEL 0x000000BD -#define R200_VS_PNT_SPRITE_CLAMP 0x000000BE -#define R200_VS_MAX 0x000001C0 - -/* - * Offsets in TCL scalar state - */ -#define R200_SS_LIGHT_DCD_ADDR 0x00000000 -#define R200_SS_LIGHT_DCM_ADDR 0x00000008 -#define R200_SS_LIGHT_SPOT_EXPONENT_ADDR 0x00000010 -#define R200_SS_LIGHT_SPOT_CUTOFF_ADDR 0x00000018 -#define R200_SS_LIGHT_SPECULAR_THRESH_ADDR 0x00000020 -#define R200_SS_LIGHT_RANGE_CUTOFF_SQRD 0x00000028 -#define R200_SS_LIGHT_RANGE_ATT_CONST 0x00000030 -#define R200_SS_VERT_GUARD_CLIP_ADJ_ADDR 0x00000080 -#define R200_SS_VERT_GUARD_DISCARD_ADJ_ADDR 0x00000081 -#define R200_SS_HORZ_GUARD_CLIP_ADJ_ADDR 0x00000082 -#define R200_SS_HORZ_GUARD_DISCARD_ADJ_ADDR 0x00000083 -#define R200_SS_MAT_0_SHININESS 0x00000100 -#define R200_SS_MAT_1_SHININESS 0x00000101 - -/* - * Matrix indices - */ -#define R200_MTX_MV 0 -#define R200_MTX_IMV 1 -#define R200_MTX_MVP 2 -#define R200_MTX_TEX0 3 -#define R200_MTX_TEX1 4 -#define R200_MTX_TEX2 5 -#define R200_MTX_TEX3 6 -#define R200_MTX_TEX4 7 -#define R200_MTX_TEX5 8 - -/* Color formats for 2d packets - */ -#define R200_CP_COLOR_FORMAT_CI8 2 -#define R200_CP_COLOR_FORMAT_ARGB1555 3 -#define R200_CP_COLOR_FORMAT_RGB565 4 -#define R200_CP_COLOR_FORMAT_ARGB8888 6 -#define R200_CP_COLOR_FORMAT_RGB332 7 -#define R200_CP_COLOR_FORMAT_RGB8 9 -#define R200_CP_COLOR_FORMAT_ARGB4444 15 - -/* - * CP type-3 packets - */ -#define R200_CP_CMD_NOP 0xC0001000 -#define R200_CP_CMD_NEXT_CHAR 0xC0001900 -#define R200_CP_CMD_PLY_NEXTSCAN 0xC0001D00 -#define R200_CP_CMD_SET_SCISSORS 0xC0001E00 -#define R200_CP_CMD_LOAD_MICROCODE 0xC0002400 -#define R200_CP_CMD_WAIT_FOR_IDLE 0xC0002600 -#define R200_CP_CMD_3D_DRAW_VBUF 0xC0002800 -#define R200_CP_CMD_3D_DRAW_IMMD 0xC0002900 -#define R200_CP_CMD_3D_DRAW_INDX 0xC0002A00 -#define R200_CP_CMD_LOAD_PALETTE 0xC0002C00 -#define R200_CP_CMD_3D_LOAD_VBPNTR 0xC0002F00 -#define R200_CP_CMD_INDX_BUFFER 0xC0003300 -#define R200_CP_CMD_3D_DRAW_VBUF_2 0xC0003400 -#define R200_CP_CMD_3D_DRAW_IMMD_2 0xC0003500 -#define R200_CP_CMD_3D_DRAW_INDX_2 0xC0003600 -#define R200_CP_CMD_PAINT 0xC0009100 -#define R200_CP_CMD_BITBLT 0xC0009200 -#define R200_CP_CMD_SMALLTEXT 0xC0009300 -#define R200_CP_CMD_HOSTDATA_BLT 0xC0009400 -#define R200_CP_CMD_POLYLINE 0xC0009500 -#define R200_CP_CMD_POLYSCANLINES 0xC0009800 -#define R200_CP_CMD_PAINT_MULTI 0xC0009A00 -#define R200_CP_CMD_BITBLT_MULTI 0xC0009B00 -#define R200_CP_CMD_TRANS_BITBLT 0xC0009C00 - -#endif diff --git a/src/mesa/drivers/dri/r300/r200_state.h b/src/mesa/drivers/dri/r300/r200_state.h deleted file mode 100644 index 3e1a9c8ba1..0000000000 --- a/src/mesa/drivers/dri/r300/r200_state.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -Copyright (C) The Weather Channel, Inc. 2002. 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 - */ - -#ifndef __R200_STATE_H__ -#define __R200_STATE_H__ - -#ifdef GLX_DIRECT_RENDERING - -#include "r200_context.h" - -extern void r200InitState(r200ContextPtr rmesa); -extern void r200InitStateFuncs(struct dd_function_table *functions); -extern void r200InitTnlFuncs(GLcontext * ctx); - -extern void r200UpdateMaterial(GLcontext * ctx); - -extern void r200UpdateViewportOffset(GLcontext * ctx); -extern void r200UpdateWindow(GLcontext * ctx); - -extern void r200ValidateState(GLcontext * ctx); - -extern void r200PrintDirty(r200ContextPtr rmesa, const char *msg); - -extern void r200LightingSpaceChange(GLcontext * ctx); - -#endif -#endif -- cgit v1.2.3 From cf4ccd5020743591b8d2b29df279c729004ca393 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Sat, 3 Feb 2007 17:32:02 +0100 Subject: Fall back to software rasterization if r300_translate_fragment_shader() fails. Aborting immediately is a bad idea with AIGLX. --- src/mesa/drivers/dri/r300/r300_render.c | 10 ++++++++++ src/mesa/drivers/dri/r300/r300_state.c | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index 3d094b9db5..e29df87696 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -385,8 +385,18 @@ GLboolean r300_run_vb_render(GLcontext *ctx, int r300Fallback(GLcontext *ctx) { r300ContextPtr r300 = R300_CONTEXT(ctx); + struct r300_fragment_program *rp = + (struct r300_fragment_program *) + (char *)ctx->FragmentProgram._Current; int i; + if (rp) { + if (!rp->translated) + r300_translate_fragment_shader(rp); + + FALLBACK_IF(!rp->translated); + } + /* We do not do SELECT or FEEDBACK (yet ?) * Is it worth doing them ? */ diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index e06999aa26..a12f3bb531 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -1823,7 +1823,7 @@ void r300SetupPixelShader(r300ContextPtr rmesa) r300_translate_fragment_shader(rp); if (!rp->translated) { fprintf(stderr, "%s: No valid fragment shader, exiting\n", __func__); - exit(-1); + return; } #define OUTPUT_FIELD(st, reg, field) \ -- cgit v1.2.3 From be85770f148a0b3cac1720f843b2fa34dd74295f Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 3 Feb 2007 23:32:12 +0100 Subject: nouveau: nv50: use nv50 state --- src/mesa/drivers/dri/nouveau/nouveau_state.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c index aef1f63494..e9fd188d73 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -170,9 +170,11 @@ void nouveauDDInitState(nouveauContextPtr nmesa) case NV_30: case NV_40: case NV_44: - case NV_50: nv30InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver); break; + case NV_50: + nv50InitStateFuncs(nmesa->glCtx, &nmesa->glCtx->Driver); + break; default: break; } -- cgit v1.2.3 From f8ec7f1398e600f4ed2ff3d0fb8d77d706f0fc18 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sat, 3 Feb 2007 23:46:58 +0100 Subject: nouveau: forgot function declaration --- src/mesa/drivers/dri/nouveau/nouveau_state.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.h b/src/mesa/drivers/dri/nouveau/nouveau_state.h index 5b85287445..dbac71760b 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.h @@ -36,6 +36,7 @@ extern void nv04InitStateFuncs(GLcontext *ctx, struct dd_function_table *func); extern void nv10InitStateFuncs(GLcontext *ctx, struct dd_function_table *func); extern void nv20InitStateFuncs(GLcontext *ctx, struct dd_function_table *func); extern void nv30InitStateFuncs(GLcontext *ctx, struct dd_function_table *func); +extern void nv50InitStateFuncs(GLcontext *ctx, struct dd_function_table *func); extern void nouveauInitState(GLcontext *ctx); -- cgit v1.2.3 From 63568745863a54308fecc32dbb96397c35b22496 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sun, 4 Feb 2007 03:17:06 +0100 Subject: nouveau: fix nv04 and nv10 swtcl, more work on nv04 state. --- src/mesa/drivers/dri/nouveau/nouveau_swtcl.c | 4 +- src/mesa/drivers/dri/nouveau/nv04_state.c | 20 +++++----- src/mesa/drivers/dri/nouveau/nv04_swtcl.c | 52 +++++++++++++++++++++++++- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 56 ++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+), 14 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c b/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c index f5c92a1b4e..8a013bd999 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_swtcl.c @@ -84,7 +84,7 @@ void nouveauFallback(struct nouveau_context *nmesa, GLuint bit, GLboolean mode) if (nmesa->screen->card->typescreen->card->typeColor.AlphaFunc ) { + switch ( f ) { case GL_NEVER: return 1; case GL_LESS: return 2; case GL_EQUAL: return 3; @@ -51,9 +51,9 @@ static uint32_t nv04_compare_func(GLcontext *ctx,GLuint f) return 0; } -static uint32_t nv04_blend_func(GLcontext *ctx,GLuint f) +static uint32_t nv04_blend_func(GLuint f) { - switch ( ctx->Color.AlphaFunc ) { + switch ( f ) { case GL_ZERO: return 0x1; case GL_ONE: return 0x2; case GL_SRC_COLOR: return 0x3; @@ -66,7 +66,7 @@ static uint32_t nv04_blend_func(GLcontext *ctx,GLuint f) case GL_ONE_MINUS_DST_COLOR: return 0xA; case GL_SRC_ALPHA_SATURATE: return 0xB; } - WARN_ONCE("Unable to find the function\n"); + WARN_ONCE("Unable to find the function 0x%x\n",f); return 0; } @@ -78,11 +78,11 @@ static void nv04_emit_control(GLcontext *ctx) CLAMPED_FLOAT_TO_UBYTE(alpha_ref, ctx->Color.AlphaRef); control=alpha_ref; - control|=(nv04_compare_func(ctx,ctx->Color.AlphaFunc)<<8); + control|=(nv04_compare_func(ctx->Color.AlphaFunc)<<8); control|=(ctx->Color.AlphaEnabled<<12); control|=(1<<13); control|=(ctx->Depth.Test<<14); - control|=(nv04_compare_func(ctx,ctx->Depth.Func)<<16); + control|=(nv04_compare_func(ctx->Depth.Func)<<16); if ((ctx->Polygon.CullFlag)&&(ctx->Polygon.CullFaceMode!=GL_FRONT_AND_BACK)) { if ((ctx->Polygon.FrontFace==GL_CW)&&(ctx->Polygon.CullFaceMode==GL_FRONT)) @@ -126,8 +126,8 @@ static void nv04_emit_blend(GLcontext *ctx) blend|=(1<<8); blend|=(ctx->Fog.Enabled<<16); blend|=(ctx->Color.BlendEnabled<<20); - blend|=(nv04_blend_func(ctx,ctx->Color.BlendSrcRGB)<<24); - blend|=(nv04_blend_func(ctx,ctx->Color.BlendDstRGB)<<28); + blend|=(nv04_blend_func(ctx->Color.BlendSrcRGB)<<24); + blend|=(nv04_blend_func(ctx->Color.BlendDstRGB)<<28); BEGIN_RING_CACHE(NvSub3D, NV04_DX5_TEXTURED_TRIANGLE_BLEND, 1); OUT_RING_CACHE(blend); @@ -463,7 +463,7 @@ static GLboolean nv04BindBuffers(nouveauContextPtr nmesa, int num_color, /* FIXME pitches have to be aligned ! */ BEGIN_RING_SIZE(NvSubCtxSurf3D, NV04_CONTEXT_SURFACES_3D_PITCH, 2); - OUT_RING(color[0]->pitch|(depth->pitch<<16)); + OUT_RING(color[0]->pitch|(depth?(depth->pitch<<16):0)); OUT_RING(color[0]->offset); if (depth) { diff --git a/src/mesa/drivers/dri/nouveau/nv04_swtcl.c b/src/mesa/drivers/dri/nouveau/nv04_swtcl.c index f31c0d692d..9b5332b77a 100644 --- a/src/mesa/drivers/dri/nouveau/nv04_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv04_swtcl.c @@ -84,6 +84,43 @@ static inline void nv04_1quad(struct nouveau_context *nmesa,nouveauVertex* v0,no OUT_RING(0xFECEDC); } +static inline void nv04_render_points(GLcontext *ctx,GLuint first,GLuint last) +{ + WARN_ONCE("Unimplemented\n"); +} + +static inline void nv04_render_line(GLcontext *ctx,GLuint v1,GLuint v2) +{ + WARN_ONCE("Unimplemented\n"); +} + +static inline void nv04_render_triangle(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + + nv04_1triangle(nmesa, + (nouveauVertex*)(vertptr+v1*vertsize), + (nouveauVertex*)(vertptr+v2*vertsize), + (nouveauVertex*)(vertptr+v3*vertsize) + ); +} + +static inline void nv04_render_quad(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3,GLuint v4) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + + nv04_1quad(nmesa, + (nouveauVertex*)(vertptr+v1*vertsize), + (nouveauVertex*)(vertptr+v2*vertsize), + (nouveauVertex*)(vertptr+v3*vertsize), + (nouveauVertex*)(vertptr+v4*vertsize) + ); +} + /**********************************************************************/ /* Render unclipped begin/end objects */ /**********************************************************************/ @@ -404,6 +441,13 @@ do { \ nmesa->vertex_attr_count++; \ } while (0) +static void nv04_render_clipped_line(GLcontext *ctx,GLuint ii,GLuint jj) +{ +} + +static void nv04_render_clipped_poly(GLcontext *ctx,const GLuint *elts,GLuint n) +{ +} static void nv04ChooseRenderState(GLcontext *ctx) { @@ -411,8 +455,12 @@ static void nv04ChooseRenderState(GLcontext *ctx) tnl->Driver.Render.PrimTabVerts = nv04_render_tab_verts; tnl->Driver.Render.PrimTabElts = nv04_render_tab_elts; - tnl->Driver.Render.ClippedLine = NULL; - tnl->Driver.Render.ClippedPolygon = NULL; + tnl->Driver.Render.ClippedLine = nv04_render_clipped_line; + tnl->Driver.Render.ClippedPolygon = nv04_render_clipped_poly; + tnl->Driver.Render.Points = nv04_render_points; + tnl->Driver.Render.Line = nv04_render_line; + tnl->Driver.Render.Triangle = nv04_render_triangle; + tnl->Driver.Render.Quad = nv04_render_quad; } diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index c9bfac8c4a..9891b363cb 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -303,6 +303,58 @@ static void nv10_render_clipped_poly(GLcontext *ctx,const GLuint *elts,GLuint n) VB->Elts = tmp; } +static inline void nv10_render_points(GLcontext *ctx,GLuint first,GLuint last) +{ + WARN_ONCE("Unimplemented\n"); +} + +static inline void nv10_render_line(GLcontext *ctx,GLuint v1,GLuint v2) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + GLuint size_dword = vertsize*(2)/4; + + nv10ExtendPrimitive(nmesa, size_dword); + nv10StartPrimitive(nmesa,GL_LINES+1,size_dword); + OUT_RINGp((nouveauVertex*)(vertptr+(v1*vertsize)),vertsize); + OUT_RINGp((nouveauVertex*)(vertptr+(v2*vertsize)),vertsize); + nv10FinishPrimitive(nmesa); +} + +static inline void nv10_render_triangle(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + GLuint size_dword = vertsize*(3)/4; + + nv10ExtendPrimitive(nmesa, size_dword); + nv10StartPrimitive(nmesa,GL_TRIANGLES+1,size_dword); + OUT_RINGp((nouveauVertex*)(vertptr+(v1*vertsize)),vertsize); + OUT_RINGp((nouveauVertex*)(vertptr+(v2*vertsize)),vertsize); + OUT_RINGp((nouveauVertex*)(vertptr+(v3*vertsize)),vertsize); + nv10FinishPrimitive(nmesa); +} + +static inline void nv10_render_quad(GLcontext *ctx,GLuint v1,GLuint v2,GLuint v3,GLuint v4) +{ + struct nouveau_context *nmesa = NOUVEAU_CONTEXT(ctx); + GLubyte *vertptr = (GLubyte *)nmesa->verts; + GLuint vertsize = nmesa->vertex_size; + GLuint size_dword = vertsize*(4)/4; + + nv10ExtendPrimitive(nmesa, size_dword); + nv10StartPrimitive(nmesa,GL_QUADS+1,size_dword); + OUT_RINGp((nouveauVertex*)(vertptr+(v1*vertsize)),vertsize); + OUT_RINGp((nouveauVertex*)(vertptr+(v2*vertsize)),vertsize); + OUT_RINGp((nouveauVertex*)(vertptr+(v3*vertsize)),vertsize); + OUT_RINGp((nouveauVertex*)(vertptr+(v4*vertsize)),vertsize); + nv10FinishPrimitive(nmesa); +} + + + static void nv10ChooseRenderState(GLcontext *ctx) { TNLcontext *tnl = TNL_CONTEXT(ctx); @@ -312,6 +364,10 @@ static void nv10ChooseRenderState(GLcontext *ctx) tnl->Driver.Render.PrimTabElts = nv10_render_tab_elts; tnl->Driver.Render.ClippedLine = nv10_render_clipped_line; tnl->Driver.Render.ClippedPolygon = nv10_render_clipped_poly; + tnl->Driver.Render.Points = nv10_render_points; + tnl->Driver.Render.Line = nv10_render_line; + tnl->Driver.Render.Triangle = nv10_render_triangle; + tnl->Driver.Render.Quad = nv10_render_quad; } -- cgit v1.2.3 From 296eeb882fa9fd7528f33ed307f87171dff7ee1c Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Sun, 4 Feb 2007 13:10:23 +0100 Subject: nouveau: nv10: add init for unknown 0x120 --- src/mesa/drivers/dri/nouveau/nv10_state.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 88c1d7d9e1..8fbc76c308 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -659,6 +659,14 @@ static GLboolean nv10InitCard(nouveauContextPtr nmesa) BEGIN_RING_SIZE(NvSub3D, 0x03f4, 1); OUT_RING(0); + /* not for nv10, only for >= nv11 */ + if ((nmesa->screen->card->id>>4) >= 0x11) { + BEGIN_RING_SIZE(NvSub3D, 0x120, 3); + OUT_RING(0); + OUT_RING(1); + OUT_RING(2); + } + return GL_TRUE; } -- cgit v1.2.3 From e7654b22aa02636d17a88a9a5ee1eeb213d81f30 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 6 Feb 2007 00:39:50 +1100 Subject: nouveau: new bufferobj code. The old code suffered from a number of issues, the most severe being that with the Mesa VBO merge even swtcl used the driver's bufferobj interface. On most VBO types (or non-AGP cards) the buffer ended up in vram, and killed swtcl performance greatly. All bufferobj's start in system memory now, until they get referenced as a "real" VBO. The other big change is that only potentially "damaged" areas are uploaded/downloaded to/from the hardware. --- src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c | 662 +++++++++++++++++------ src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h | 64 ++- src/mesa/drivers/dri/nouveau/nv30_fragprog.c | 5 +- 3 files changed, 562 insertions(+), 169 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c index d36196aeef..684ed7b017 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c @@ -8,29 +8,458 @@ #include "nouveau_object.h" #include "nouveau_msg.h" +#define NOUVEAU_MEM_FREE(mem) do { \ + nouveau_mem_free(ctx, (mem)); \ + (mem) = NULL; \ +} while(0) + #define DEBUG(fmt,args...) do { \ if (NOUVEAU_DEBUG & DEBUG_BUFFEROBJ) { \ fprintf(stderr, "%s: "fmt, __func__, ##args); \ } \ } while(0) -/* Wrapper for nouveau_mem_gpu_offset_get() that marks the bufferobj dirty - * if the GPU modifies the data. - */ +static GLboolean +nouveau_bo_download_from_screen(GLcontext *ctx, GLuint offset, GLuint size, + struct gl_buffer_object *bo) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + nouveau_mem *in_mem; + + DEBUG("bo=%p, offset=%d, size=%d\n", bo, offset, size); + + /* If there's a permanent backing store, blit directly into it */ + if (nbo->cpu_mem) { + if (nbo->cpu_mem != nbo->gpu_mem) { + DEBUG("..cpu_mem\n"); + nouveau_memformat_flat_emit(ctx, nbo->cpu_mem, + nbo->gpu_mem, + offset, offset, size); + } + } else { + DEBUG("..sys_mem\n"); + in_mem = nouveau_mem_alloc(ctx, NOUVEAU_MEM_AGP, size, 0); + if (in_mem) { + DEBUG("....via AGP\n"); + /* otherwise, try blitting to faster memory and + * copying from there + */ + nouveau_memformat_flat_emit(ctx, in_mem, nbo->gpu_mem, + 0, offset, size); + nouveau_notifier_wait_nop(ctx, nmesa->syncNotifier, + NvSubMemFormat); + _mesa_memcpy(nbo->cpu_mem_sys + offset, + in_mem->map, size); + NOUVEAU_MEM_FREE(in_mem); + } else { + DEBUG("....direct VRAM copy\n"); + /* worst case, copy directly from vram */ + _mesa_memcpy(nbo->cpu_mem_sys + offset, + nbo->gpu_mem + offset, + size); + } + } + + return GL_TRUE; +} + +static GLboolean +nouveau_bo_upload_to_screen(GLcontext *ctx, GLuint offset, GLuint size, + struct gl_buffer_object *bo) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + nouveau_mem *out_mem; + + DEBUG("bo=%p, offset=%d, size=%d\n", bo, offset, size); + + if (nbo->cpu_mem) { + if (nbo->cpu_mem != nbo->gpu_mem) { + DEBUG("..cpu_mem\n"); + nouveau_memformat_flat_emit(ctx, nbo->gpu_mem, + nbo->cpu_mem, + offset, offset, size); + } + } else { + out_mem = nouveau_mem_alloc(ctx, NOUVEAU_MEM_AGP | + NOUVEAU_MEM_MAPPED, + size, 0); + if (out_mem) { + DEBUG("....via AGP\n"); + _mesa_memcpy(out_mem->map, + nbo->cpu_mem_sys + offset, size); + nouveau_memformat_flat_emit(ctx, nbo->gpu_mem, out_mem, + offset, 0, size); + nouveau_notifier_wait_nop(ctx, nmesa->syncNotifier, + NvSubMemFormat); + NOUVEAU_MEM_FREE(out_mem); + } else { + DEBUG("....direct VRAM copy\n"); + _mesa_memcpy(nbo->gpu_mem->map + offset, + nbo->cpu_mem_sys + offset, + size); + } + } + + return GL_TRUE; +} + +GLboolean +nouveau_bo_move_in(GLcontext *ctx, struct gl_buffer_object *bo) +{ + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + + DEBUG("bo=%p\n", bo); + + if (bo->OnCard) + return GL_TRUE; + assert(nbo->gpu_mem_flags); + + nbo->gpu_mem = nouveau_mem_alloc(ctx, nbo->gpu_mem_flags | + NOUVEAU_MEM_MAPPED, + bo->Size, 0); + assert(nbo->gpu_mem); + + if (nbo->cpu_mem_flags) { + if ((nbo->cpu_mem_flags|NOUVEAU_MEM_MAPPED) != nbo->gpu_mem->type) { + DEBUG("..need cpu_mem buffer\n"); + + nbo->cpu_mem = nouveau_mem_alloc(ctx, + nbo->cpu_mem_flags | + NOUVEAU_MEM_MAPPED, + bo->Size, 0); + + if (nbo->cpu_mem) { + DEBUG("....alloc ok, kill sys_mem buffer\n"); + _mesa_memcpy(nbo->cpu_mem->map, + nbo->cpu_mem_sys, bo->Size); + FREE(nbo->cpu_mem_sys); + } + } else { + DEBUG("..cpu direct access to GPU buffer\n"); + nbo->cpu_mem = nbo->gpu_mem; + } + } + nouveau_bo_upload_to_screen(ctx, 0, bo->Size, bo); + + bo->OnCard = GL_TRUE; + return GL_TRUE; +} + +GLboolean +nouveau_bo_move_out(GLcontext *ctx, struct gl_buffer_object *bo) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + GLuint nr_dirty; + + DEBUG("bo=%p\n", bo); + if (!bo->OnCard) + return GL_TRUE; + + nr_dirty = nouveau_bo_download_dirty(ctx, bo); + if (nbo->cpu_mem) { + if (nr_dirty && nbo->cpu_mem != nbo->gpu_mem) + nouveau_notifier_wait_nop(ctx, nmesa->syncNotifier, + NvSubMemFormat); + DEBUG("..destroy cpu_mem buffer\n"); + nbo->cpu_mem_sys = malloc(bo->Size); + assert(nbo->cpu_mem_sys); + _mesa_memcpy(nbo->cpu_mem_sys, nbo->cpu_mem->map, bo->Size); + if (nbo->cpu_mem == nbo->gpu_mem) + nbo->cpu_mem = NULL; + else + NOUVEAU_MEM_FREE(nbo->cpu_mem); + } + NOUVEAU_MEM_FREE(nbo->gpu_mem); + + bo->OnCard = GL_FALSE; + return GL_TRUE; +} + +static void +nouveau_bo_choose_storage_method(GLcontext *ctx, GLenum usage, + struct gl_buffer_object *bo) +{ + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + GLuint gpu_type = 0; + GLuint cpu_type = 0; + + switch (usage) { + /* Client source, changes often, used by GL many times */ + case GL_DYNAMIC_DRAW_ARB: + gpu_type = NOUVEAU_MEM_AGP | NOUVEAU_MEM_FB_ACCEPTABLE; + cpu_type = NOUVEAU_MEM_AGP; + break; + /* GL source, changes often, client reads many times */ + case GL_DYNAMIC_READ_ARB: + /* Client source, specified once, used by GL many times */ + case GL_STATIC_DRAW_ARB: + /* GL source, specified once, client reads many times */ + case GL_STATIC_READ_ARB: + /* Client source, specified once, used by GL a few times */ + case GL_STREAM_DRAW_ARB: + /* GL source, specified once, client reads a few times */ + case GL_STREAM_READ_ARB: + /* GL source, changes often, used by GL many times*/ + case GL_DYNAMIC_COPY_ARB: + /* GL source, specified once, used by GL many times */ + case GL_STATIC_COPY_ARB: + /* GL source, specified once, used by GL a few times */ + case GL_STREAM_COPY_ARB: + gpu_type = NOUVEAU_MEM_FB; + break; + default: + assert(0); + } + + nbo->gpu_mem_flags = gpu_type; + nbo->cpu_mem_flags = cpu_type; + nbo->usage = usage; +} + +void +nouveau_bo_init_storage(GLcontext *ctx, GLuint valid_gpu_access, + GLsizeiptrARB size, + const GLvoid *data, + GLenum usage, + struct gl_buffer_object *bo) +{ + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + + DEBUG("bo=%p\n", bo); + + /* Free up previous buffers if we can't reuse them */ + if (nbo->usage != usage || + (nbo->gpu_mem && (nbo->gpu_mem->size != size))) { + if (nbo->cpu_mem_sys) + FREE(nbo->cpu_mem_sys); + if (nbo->cpu_mem) { + if (nbo->cpu_mem != nbo->gpu_mem) + NOUVEAU_MEM_FREE(nbo->cpu_mem); + else + nbo->cpu_mem = NULL; + } + if (nbo->gpu_mem) + NOUVEAU_MEM_FREE(nbo->gpu_mem); + + bo->OnCard = GL_FALSE; + nbo->cpu_mem_sys = calloc(1, size); + } + + nouveau_bo_choose_storage_method(ctx, usage, bo); + /* Force off flags that may not be ok for a given buffer */ + nbo->gpu_mem_flags &= valid_gpu_access; + + bo->Usage = usage; + bo->Size = size; + + if (data) { + GLvoid *map = nouveau_bo_map(ctx, GL_WRITE_ONLY_ARB, bo); + _mesa_memcpy(map, data, size); + nouveau_bo_dirty_all(ctx, GL_FALSE, bo); + nouveau_bo_unmap(ctx, bo); + } +} + +void * +nouveau_bo_map(GLcontext *ctx, GLenum access, struct gl_buffer_object *bo) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + + DEBUG("bo=%p, access=%s\n", bo, _mesa_lookup_enum_by_nr(access)); + + if (bo->OnCard && + (access == GL_READ_ONLY_ARB || access == GL_READ_WRITE_ARB)) { + GLuint nr_dirty; + + DEBUG("..on card\n"); + nr_dirty = nouveau_bo_download_dirty(ctx, bo); + + /* nouveau_bo_download_dirty won't wait unless it needs to + * free a temp buffer, which isn't the case if cpu_mem is + * present. + */ + if (nr_dirty && nbo->cpu_mem && nbo->cpu_mem != nbo->gpu_mem) + nouveau_notifier_wait_nop(ctx, nmesa->syncNotifier, + NvSubMemFormat); + } + + if (nbo->cpu_mem) { + DEBUG("..access via cpu_mem\n"); + return nbo->cpu_mem->map; + } else { + DEBUG("..access via cpu_mem_sys\n"); + return nbo->cpu_mem_sys; + } +} + +void +nouveau_bo_unmap(GLcontext *ctx, struct gl_buffer_object *bo) +{ + DEBUG("unmap bo=%p\n", bo); +} + uint32_t -nouveau_bufferobj_gpu_ref(GLcontext *ctx, GLenum access, - struct gl_buffer_object *obj) +nouveau_bo_gpu_ref(GLcontext *ctx, struct gl_buffer_object *bo) { - nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj; + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; - DEBUG("obj=%p, access=%s\n", obj, _mesa_lookup_enum_by_nr(access)); + assert(nbo->mapped == GL_FALSE); - if (access == GL_WRITE_ONLY_ARB || access == GL_READ_WRITE_ARB) - nbo->gpu_dirty = GL_TRUE; + DEBUG("gpu_ref\n"); + + if (!bo->OnCard) { + nouveau_bo_move_in(ctx, bo); + bo->OnCard = GL_TRUE; + } + nouveau_bo_upload_dirty(ctx, bo); return nouveau_mem_gpu_offset_get(ctx, nbo->gpu_mem); } +void +nouveau_bo_dirty_linear(GLcontext *ctx, GLboolean on_card, + uint32_t offset, uint32_t size, + struct gl_buffer_object *bo) +{ + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + nouveau_bufferobj_dirty *dirty; + uint32_t start = offset; + uint32_t end = offset + size; + int i; + + if (nbo->cpu_mem == nbo->gpu_mem) + return; + + dirty = on_card ? &nbo->gpu_dirty : &nbo->cpu_dirty; + + DEBUG("on_card=%d, offset=%d, size=%d, bo=%p\n", + on_card, offset, size, bo); + + for (i=0; inr_dirty; i++) { + nouveau_bufferobj_region *r = &dirty->dirty[i]; + + /* already dirty */ + if (start >= r->start && end <= r->end) { + DEBUG("..already dirty\n"); + return; + } + + /* add to the end of a region */ + if (start >= r->start && start <= r->end) { + if (end > r->end) { + DEBUG("..extend end of region\n"); + r->end = end; + return; + } + } + + /* add to the start of a region */ + if (start < r->start && end >= r->end) { + DEBUG("..extend start of region\n"); + r->start = start; + /* .. and to the end */ + if (end > r->end) { + DEBUG("....and end\n"); + r->end = end; + } + return; + } + } + + /* new region */ + DEBUG("..new dirty\n"); + dirty->nr_dirty++; + dirty->dirty = realloc(dirty->dirty, + sizeof(nouveau_bufferobj_region) * + dirty->nr_dirty); + dirty->dirty[dirty->nr_dirty - 1].start = start; + dirty->dirty[dirty->nr_dirty - 1].end = end; +} + +void +nouveau_bo_dirty_all(GLcontext *ctx, GLboolean on_card, + struct gl_buffer_object *bo) +{ + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + nouveau_bufferobj_dirty *dirty; + + dirty = on_card ? &nbo->gpu_dirty : &nbo->cpu_dirty; + + DEBUG("dirty all\n"); + if (dirty->nr_dirty) { + FREE(dirty->dirty); + dirty->dirty = NULL; + dirty->nr_dirty = 0; + } + + nouveau_bo_dirty_linear(ctx, on_card, 0, bo->Size, bo); +} + +GLuint +nouveau_bo_upload_dirty(GLcontext *ctx, struct gl_buffer_object *bo) +{ + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + nouveau_bufferobj_dirty *dirty = &nbo->cpu_dirty; + GLuint nr_dirty; + int i; + + nr_dirty = dirty->nr_dirty; + if (!nr_dirty) { + DEBUG("clean\n"); + return nr_dirty; + } + + for (i=0; idirty[i]; + + DEBUG("dirty %d: o=0x%08x, s=0x%08x\n", + i, r->start, r->end - r->start); + nouveau_bo_upload_to_screen(ctx, + r->start, r->end - r->start, bo); + } + + FREE(dirty->dirty); + dirty->dirty = NULL; + dirty->nr_dirty = 0; + + return nr_dirty; +} + +GLuint +nouveau_bo_download_dirty(GLcontext *ctx, struct gl_buffer_object *bo) +{ + nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo; + nouveau_bufferobj_dirty *dirty = &nbo->gpu_dirty; + GLuint nr_dirty; + int i; + + nr_dirty = dirty->nr_dirty; + if (nr_dirty) { + DEBUG("clean\n"); + return nr_dirty; + } + + for (i=0; idirty[i]; + + DEBUG("dirty %d: o=0x%08x, s=0x%08x\n", + i, r->start, r->end - r->start); + nouveau_bo_download_from_screen(ctx, + r->start, + r->end - r->start, bo); + } + + FREE(dirty->dirty); + dirty->dirty = NULL; + dirty->nr_dirty = 0; + + return nr_dirty; +} + static void nouveauBindBuffer(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj) { @@ -42,10 +471,11 @@ nouveauNewBufferObject(GLcontext *ctx, GLuint buffer, GLenum target) nouveau_buffer_object *nbo; nbo = CALLOC_STRUCT(nouveau_buffer_object_t); - DEBUG("name=0x%08x, target=%s, obj=%p\n", - buffer, _mesa_lookup_enum_by_nr(target), nbo); - _mesa_initialize_buffer_object(&nbo->mesa, buffer, target); - return &nbo->mesa; + if (nbo) + _mesa_initialize_buffer_object(&nbo->mesa, buffer, target); + DEBUG("bo=%p\n", nbo); + + return nbo ? &nbo->mesa : NULL; } static void @@ -53,11 +483,13 @@ nouveauDeleteBuffer(GLcontext *ctx, struct gl_buffer_object *obj) { nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj; - DEBUG("obj=%p\n", obj); + if (nbo->gpu_dirty.nr_dirty) + FREE(nbo->gpu_dirty.dirty); + if (nbo->cpu_dirty.nr_dirty) + FREE(nbo->cpu_dirty.dirty); + if (nbo->cpu_mem) nouveau_mem_free(ctx, nbo->cpu_mem); + if (nbo->gpu_mem) nouveau_mem_free(ctx, nbo->gpu_mem); - if (nbo->gpu_mem) { - nouveau_mem_free(ctx, nbo->gpu_mem); - } _mesa_delete_buffer_object(ctx, obj); } @@ -66,193 +498,105 @@ nouveauBufferData(GLcontext *ctx, GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage, struct gl_buffer_object *obj) { - nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj; + GLuint gpu_flags; - DEBUG("obj=%p, target=%s, usage=%s, size=%d, data=%p\n", - obj, + DEBUG("target=%s, size=%d, data=%p, usage=%s, obj=%p\n", _mesa_lookup_enum_by_nr(target), + (GLuint)size, data, _mesa_lookup_enum_by_nr(usage), - (unsigned int)size, - data); - - if (nbo->gpu_mem && nbo->gpu_mem->size != size) - nouveau_mem_free(ctx, nbo->gpu_mem); - - /* Always have the GPU access the data from VRAM if possible. For - * some "usage" values it may be better from AGP be default? - * - * TODO: At some point we should drop the NOUVEAU_MEM_MAPPED flag. - * TODO: Use the NOUVEAU_MEM_AGP_ACCEPTABLE flag. - * TODO: What about PCI-E and shared system memory? - */ - if (!nbo->gpu_mem) - nbo->gpu_mem = nouveau_mem_alloc(ctx, - NOUVEAU_MEM_FB | - NOUVEAU_MEM_MAPPED, - size, - 0); - - if (!nbo->gpu_mem) { - MESSAGE("AIII bufferobj malloc failed\n"); - return; + obj); + + switch (target) { + case GL_ELEMENT_ARRAY_BUFFER_ARB: + gpu_flags = 0; + break; + default: + gpu_flags = NOUVEAU_BO_VRAM_OK | NOUVEAU_BO_AGP_OK; + break; } - - obj->Usage = usage; - obj->Size = size; - if (!data) - return; - - ctx->Driver.MapBuffer(ctx, target, GL_WRITE_ONLY_ARB, obj); - _mesa_memcpy(nbo->cpu_mem->map, data, size); - ctx->Driver.UnmapBuffer(ctx, target, obj); + nouveau_bo_init_storage(ctx, gpu_flags, size, data, usage, obj); } -/*TODO: we don't need to DMA the entire buffer like MapBuffer does.. */ static void nouveauBufferSubData(GLcontext *ctx, GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data, struct gl_buffer_object *obj) { - DEBUG("obj=%p, target=%s, offset=0x%x, size=%d, data=%p\n", - obj, + GLvoid *out; + + DEBUG("target=%s, offset=0x%x, size=%d, data=%p, obj=%p\n", _mesa_lookup_enum_by_nr(target), - (unsigned int)offset, - (unsigned int)size, - data); + (GLuint)offset, (GLuint)size, data, obj); - ctx->Driver.MapBuffer(ctx, target, GL_WRITE_ONLY_ARB, obj); - _mesa_memcpy((GLubyte *)obj->Pointer + offset, data, size); - ctx->Driver.UnmapBuffer(ctx, target, obj); + out = nouveau_bo_map(ctx, GL_WRITE_ONLY_ARB, obj); + _mesa_memcpy(out + offset, data, size); + nouveau_bo_dirty_linear(ctx, GL_FALSE, offset, size, obj); + nouveau_bo_unmap(ctx, obj); } -/*TODO: we don't need to DMA the entire buffer like MapBuffer does.. */ static void nouveauGetBufferSubData(GLcontext *ctx, GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data, struct gl_buffer_object *obj) { - DEBUG("obj=%p, target=%s, offset=0x%x, size=%d, data=%p\n", - obj, + const GLvoid *in; + + DEBUG("target=%s, offset=0x%x, size=%d, data=%p, obj=%p\n", _mesa_lookup_enum_by_nr(target), - (unsigned int)offset, - (unsigned int)size, - data); + (GLuint)offset, (GLuint)size, data, obj); - ctx->Driver.MapBuffer(ctx, target, GL_READ_ONLY_ARB, obj); - _mesa_memcpy(data, (GLubyte *)obj->Pointer + offset, size); - ctx->Driver.UnmapBuffer(ctx, target, obj); + in = nouveau_bo_map(ctx, GL_READ_ONLY_ARB, obj); + _mesa_memcpy(data, in + offset, size); + nouveau_bo_unmap(ctx, obj); } static void * nouveauMapBuffer(GLcontext *ctx, GLenum target, GLenum access, struct gl_buffer_object *obj) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj; - - DEBUG("obj=%p, target=%s, access=%s\n", - obj, + DEBUG("target=%s, access=%s, obj=%p\n", _mesa_lookup_enum_by_nr(target), - _mesa_lookup_enum_by_nr(access)); + _mesa_lookup_enum_by_nr(access), + obj + ); - if (obj->Pointer) { - DEBUG("already mapped, return NULL\n"); + /* Already mapped.. */ + if (obj->Pointer) return NULL; - } -#ifdef ALLOW_MULTI_SUBCHANNEL - /* If GPU is accessing the data from VRAM, copy to faster AGP memory - * before CPU access to the buffer. + /* Have to pass READ_WRITE here, nouveau_bo_map will only ensure that + * the cpu_mem buffer is up-to-date if we ask for read access. + * + * However, even if the client only asks for write access, we're still + * forced to reupload the entire buffer. So, we need the cpu_mem buffer + * to have the correct data all the time. */ - if (nbo->gpu_mem->type & NOUVEAU_MEM_FB) { - DEBUG("Data in VRAM, copying to AGP for CPU access\n"); - - /* This can happen if BufferData grows the GPU-access buffer */ - if (nbo->cpu_mem && nbo->cpu_mem->size != nbo->gpu_mem->size) { - nouveau_mem_free(ctx, nbo->cpu_mem); - nbo->cpu_mem = NULL; - } - - if (!nbo->cpu_mem) { - nbo->cpu_mem = nouveau_mem_alloc(ctx, - NOUVEAU_MEM_AGP | - NOUVEAU_MEM_MAPPED, - nbo->gpu_mem->size, - 0); + obj->Pointer = nouveau_bo_map(ctx, GL_READ_WRITE_ARB, obj); - /* Mark GPU data as modified, so it gets copied to - * the new buffer */ - nbo->gpu_dirty = GL_TRUE; - } - - if (nbo->cpu_mem && nbo->gpu_dirty) { - nouveau_memformat_flat_emit(ctx, nbo->cpu_mem, - nbo->gpu_mem, - 0, 0, - nbo->gpu_mem->size); - - nouveau_notifier_wait_nop(ctx, - nmesa->syncNotifier, - NvSubMemFormat); - nbo->gpu_dirty = GL_FALSE; - } - - /* buffer isn't guaranteed to be up-to-date on the card now */ - nbo->cpu_dirty = GL_TRUE; - } -#endif - - /* If the copy to AGP failed for some reason, just return a pointer - * directly to vram.. + /* The GL spec says that a client attempting to write to a bufferobj + * mapped READ_ONLY object may have unpredictable results, possibly + * even program termination. + * + * We're going to use this, and only mark the buffer as dirtied if + * the client asks for write access. */ - if (!nbo->cpu_mem) { - DEBUG("Returning direct pointer to VRAM\n"); - nbo->cpu_mem = nbo->gpu_mem; - nbo->cpu_dirty = GL_FALSE; + if (target != GL_READ_ONLY_ARB) { + /* We have no way of knowing what was modified by the client, + * so the entire buffer gets dirtied. */ + nouveau_bo_dirty_all(ctx, GL_FALSE, obj); } - obj->Pointer = nbo->cpu_mem->map; return obj->Pointer; } static GLboolean nouveauUnmapBuffer(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj) { - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - nouveau_buffer_object *nbo = (nouveau_buffer_object *)obj; - - DEBUG("obj=%p, target=%s\n", obj, _mesa_lookup_enum_by_nr(target)); + DEBUG("target=%s, obj=%p\n", _mesa_lookup_enum_by_nr(target), obj); -#ifdef ALLOW_MULTI_SUBCHANNEL - if (nbo->cpu_dirty && nbo->cpu_mem != nbo->gpu_mem) { - DEBUG("Copying potentially modified data back to GPU\n"); - - /* blit from GPU buffer -> CPU buffer */ - nouveau_memformat_flat_emit(ctx, nbo->gpu_mem, nbo->cpu_mem, - 0, 0, nbo->cpu_mem->size); - - /* buffer is now up-to-date on the hardware (or rather, will - * be by the time any other commands in this channel reference - * the data.) - */ - nbo->cpu_dirty = GL_FALSE; - - /* we can avoid this wait in some cases.. */ - nouveau_notifier_wait_nop(ctx, - nmesa->syncNotifier, - NvSubMemFormat); - - /* If it's likely CPU access to the buffer will occur often, - * keep the cpu_mem around to avoid repeated allocs. - */ - if (obj->Usage != GL_DYNAMIC_DRAW_ARB) { - - nouveau_mem_free(ctx, nbo->cpu_mem); - nbo->cpu_mem = NULL; - } - } -#endif + assert(obj->Pointer); + nouveau_bo_unmap(ctx, obj); obj->Pointer = NULL; return GL_TRUE; } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h index fccc349b83..932450fd87 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h @@ -4,24 +4,74 @@ #include "mtypes.h" #include "nouveau_buffers.h" +#define NOUVEAU_BO_VRAM_OK (NOUVEAU_MEM_FB | NOUVEAU_MEM_FB_ACCEPTABLE) +#define NOUVEAU_BO_AGP_OK (NOUVEAU_MEM_AGP | NOUVEAU_MEM_AGP_ACCEPTABLE) + +typedef struct nouveau_bufferobj_region_t { + uint32_t start; + uint32_t end; +} nouveau_bufferobj_region; + +typedef struct nouveau_bufferobj_dirty_t { + nouveau_bufferobj_region *dirty; + int nr_dirty; +} nouveau_bufferobj_dirty; + typedef struct nouveau_buffer_object_t { /* Base class, must be first */ struct gl_buffer_object mesa; + GLboolean mapped; + GLenum usage; + /* Memory used for GPU access to the buffer*/ + GLuint gpu_mem_flags; nouveau_mem * gpu_mem; - /* Buffer has been dirtied by the GPU */ - GLboolean gpu_dirty; + nouveau_bufferobj_dirty gpu_dirty; /* Memory used for CPU access to the buffer */ + GLuint cpu_mem_flags; nouveau_mem * cpu_mem; - /* Buffer has possibly been dirtied by the CPU */ - GLboolean cpu_dirty; + GLvoid * cpu_mem_sys; + nouveau_bufferobj_dirty cpu_dirty; } nouveau_buffer_object; -extern uint32_t nouveau_bufferobj_gpu_ref(GLcontext *ctx, GLenum access, - struct gl_buffer_object *obj); +extern void +nouveau_bo_init_storage(GLcontext *ctx, GLuint valid_gpu_access, + GLsizeiptrARB size, const GLvoid *data, GLenum usage, + struct gl_buffer_object *bo); + +extern GLboolean +nouveau_bo_move_in(GLcontext *ctx, struct gl_buffer_object *bo); + +extern GLboolean +nouveau_bo_move_out(GLcontext *ctx, struct gl_buffer_object *bo); + +extern void * +nouveau_bo_map(GLcontext *ctx, GLenum usage, struct gl_buffer_object *bo); + +extern void +nouveau_bo_unmap(GLcontext *ctx, struct gl_buffer_object *bo); + +extern uint32_t +nouveau_bo_gpu_ref(GLcontext *ctx, struct gl_buffer_object *bo); + +extern void +nouveau_bo_dirty_linear(GLcontext *ctx, GLboolean on_card, + uint32_t offset, uint32_t size, + struct gl_buffer_object *bo); + +extern void +nouveau_bo_dirty_all(GLcontext *ctx, GLboolean on_card, + struct gl_buffer_object *bo); + +extern GLuint +nouveau_bo_upload_dirty(GLcontext *ctx, struct gl_buffer_object *bo); + +extern GLuint +nouveau_bo_download_dirty(GLcontext *ctx, struct gl_buffer_object *bo); -extern void nouveauInitBufferObjects(GLcontext *ctx); +extern void +nouveauInitBufferObjects(GLcontext *ctx); #endif diff --git a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c index 02bd8014cc..f868ec9293 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c +++ b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c @@ -32,14 +32,13 @@ NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs) GL_ARRAY_BUFFER_ARB); /* Should use STATIC_DRAW_ARB if shader doesn't use changable params */ - ctx->Driver.BufferData(ctx, GL_ARRAY_BUFFER_ARB, + nouveau_bo_init_storage(ctx, NOUVEAU_BO_VRAM_OK, nvs->program_size * sizeof(uint32_t), (const GLvoid *)nvs->program, GL_DYNAMIC_DRAW_ARB, nvs->program_buffer); - offset = nouveau_bufferobj_gpu_ref(ctx, GL_READ_ONLY_ARB, - nvs->program_buffer); + offset = nouveau_bo_gpu_ref(ctx, nvs->program_buffer); /* Not using state cache here, updated programs at the same address don't * seem to take effect unless the ACTIVE_PROGRAM method is called again. -- cgit v1.2.3 From 47bd759fc9a8f886b90af9a5d53cbb896f37358e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 6 Feb 2007 01:57:04 +1100 Subject: nouveau: fix a small bug in nv10 swtcl --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 9891b363cb..6f57b775df 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -196,7 +196,7 @@ static inline void nv10_render_generic_primitive_elts(GLcontext *ctx,GLuint star GLuint j; nv10ExtendPrimitive(nmesa, size_dword); - nv10StartPrimitive(nmesa,prim+1,size_dword); + nv10StartPrimitive(nmesa,prim+1,size_dword*count); for (j=start; j Date: Tue, 6 Feb 2007 02:28:55 +1100 Subject: nouveau: OUT_RINGp expects the size in dwords, not bytes. This fixes the *actual* bug that the previous commit was supposed to fix.. --- src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index 6f57b775df..eec67bd805 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -196,9 +196,9 @@ static inline void nv10_render_generic_primitive_elts(GLcontext *ctx,GLuint star GLuint j; nv10ExtendPrimitive(nmesa, size_dword); - nv10StartPrimitive(nmesa,prim+1,size_dword*count); + nv10StartPrimitive(nmesa,prim+1,size_dword); for (j=start; j Date: Tue, 6 Feb 2007 10:22:47 +1100 Subject: Add support for CN700 chipset in miniglx --- src/mesa/drivers/dri/unichrome/server/via_dri.c | 1 + src/mesa/drivers/dri/unichrome/server/via_regs.h | 1 + 2 files changed, 2 insertions(+) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/unichrome/server/via_dri.c b/src/mesa/drivers/dri/unichrome/server/via_dri.c index 2fe61e4039..6944bd66f9 100644 --- a/src/mesa/drivers/dri/unichrome/server/via_dri.c +++ b/src/mesa/drivers/dri/unichrome/server/via_dri.c @@ -1179,6 +1179,7 @@ static int viaInitFBDev(DRIDriverContext *ctx) pVia->Chipset = VIA_KM400; break; case PCI_CHIP_VT3204: + case PCI_CHIP_VT3344: pVia->Chipset = VIA_K8M800; break; case PCI_CHIP_VT3259: diff --git a/src/mesa/drivers/dri/unichrome/server/via_regs.h b/src/mesa/drivers/dri/unichrome/server/via_regs.h index 5c5eecbe83..87e1e9daa9 100644 --- a/src/mesa/drivers/dri/unichrome/server/via_regs.h +++ b/src/mesa/drivers/dri/unichrome/server/via_regs.h @@ -44,6 +44,7 @@ #define PCI_CHIP_VT7205 0x7205 #define PCI_CHIP_VT3204 0x3108 #define PCI_CHIP_VT3259 0x3118 +#define PCI_CHIP_VT3344 0x3344 #define BIOS_BSIZE 1024 -- cgit v1.2.3 From f46c19d965fb05a49d361aa251e37b5ef32dd839 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 6 Feb 2007 13:49:39 +1100 Subject: nouveau: a couple of NV3x fixes --- src/mesa/drivers/dri/nouveau/nouveau_context.h | 1 + src/mesa/drivers/dri/nouveau/nouveau_shader.c | 19 +++++++++++++++++++ src/mesa/drivers/dri/nouveau/nv10_swtcl.c | 10 ++++++++++ src/mesa/drivers/dri/nouveau/nv30_fragprog.c | 15 ++++++++++++--- src/mesa/drivers/dri/nouveau/nv30_state.c | 5 +++-- 5 files changed, 45 insertions(+), 5 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h index c1d06654ee..f61fcbb48c 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.h +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -159,6 +159,7 @@ typedef struct nouveau_context { nouveauShader *current_fragprog; nouveauShader *current_vertprog; nouveauShader *passthrough_vp; + nouveauShader *passthrough_fp; nouveauScreenRec *screen; drm_nouveau_sarea_t *sarea; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.c b/src/mesa/drivers/dri/nouveau/nouveau_shader.c index c78b72bd11..ba471325aa 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.c @@ -220,6 +220,21 @@ nvsBuildPassthroughVP(GLcontext *ctx) vp_text); } +static void +nvsBuildPassthroughFP(GLcontext *ctx) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + const char *fp_text = + "!!ARBfp1.0\n" + "MOV result.color, fragment.color;\n" + "END"; + + nmesa->passthrough_fp = nvsBuildTextShader(ctx, + GL_FRAGMENT_PROGRAM_ARB, + fp_text); +} + void nouveauShaderInitFuncs(GLcontext * ctx) { @@ -249,6 +264,10 @@ nouveauShaderInitFuncs(GLcontext * ctx) if (nmesa->screen->card->type >= NV_40) nvsBuildPassthroughVP(ctx); + /* Needed on NV30, even when using swtcl, if you want to get colours */ + if (nmesa->screen->card->type >= NV_30) + nvsBuildPassthroughFP(ctx); + ctx->Const.VertexProgram.MaxNativeInstructions = nmesa->VPfunc.MaxInst; ctx->Const.VertexProgram.MaxNativeAluInstructions = nmesa->VPfunc.MaxInst; ctx->Const.VertexProgram.MaxNativeTexInstructions = nmesa->VPfunc.MaxInst; diff --git a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c index eec67bd805..32da40661b 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_swtcl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_swtcl.c @@ -527,6 +527,16 @@ static void nv10ChooseVertexState( GLcontext *ctx ) nv10OutputVertexFormat(nmesa); } + if (nmesa->screen->card->type == NV_30) { + nouveauShader *fp; + + if (ctx->FragmentProgram.Enabled) { + fp = (nouveauShader *) ctx->FragmentProgram.Current; + nvsUpdateShader(ctx, fp); + } else + nvsUpdateShader(ctx, nmesa->passthrough_fp); + } + if (nmesa->screen->card->type >= NV_40) { /* Ensure passthrough shader is being used, and mvp matrix * is up to date diff --git a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c index f868ec9293..e32452361e 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_fragprog.c +++ b/src/mesa/drivers/dri/nouveau/nv30_fragprog.c @@ -46,9 +46,18 @@ NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs) */ BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM, 1); OUT_RING (offset | 1); - BEGIN_RING_SIZE(NvSub3D, 0x1d60 /*NV30_TCL_PRIMITIVE_3D_FP_CONTROL*/, 1); - OUT_RING ((priv->NV30FP.uses_kil << 7) | - (priv->NV30FP.num_regs << 24)); + if (nmesa->screen->card->type == NV_30) { + BEGIN_RING_SIZE(NvSub3D, + 0x1d60 /*NV30_TCL_PRIMITIVE_3D_FP_CONTROL*/, 1); + OUT_RING ((priv->NV30FP.uses_kil << 7)); + BEGIN_RING_SIZE(NvSub3D, 0x1450, 1); + OUT_RING (priv->NV30FP.num_regs << 16); + } else { + BEGIN_RING_SIZE(NvSub3D, + 0x1d60 /*NV30_TCL_PRIMITIVE_3D_FP_CONTROL*/, 1); + OUT_RING ((priv->NV30FP.uses_kil << 7) | + (priv->NV30FP.num_regs << 24)); + } } static void diff --git a/src/mesa/drivers/dri/nouveau/nv30_state.c b/src/mesa/drivers/dri/nouveau/nv30_state.c index 96a07fd536..ad21fa2730 100644 --- a/src/mesa/drivers/dri/nouveau/nv30_state.c +++ b/src/mesa/drivers/dri/nouveau/nv30_state.c @@ -811,8 +811,6 @@ static GLboolean nv30InitCard(nouveauContextPtr nmesa) OUT_RING(0); BEGIN_RING_SIZE(NvSub3D, 0x1d80, 1); OUT_RING(3); - BEGIN_RING_SIZE(NvSub3D, 0x1450, 1); - OUT_RING(0x00030004); /* NEW */ BEGIN_RING_SIZE(NvSub3D, 0x1e98, 1); @@ -840,6 +838,9 @@ static GLboolean nv30InitCard(nouveauContextPtr nmesa) BEGIN_RING_SIZE(NvSub3D, 0x1d88, 1); OUT_RING(0x00001200); + BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_RC_ENABLE, 1); + OUT_RING (0); + return GL_TRUE; } -- cgit v1.2.3 From 6cf892eeb6edd69d4ba77d4ececa21a09ba317c4 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Thu, 8 Feb 2007 23:54:28 +0100 Subject: fix issues in vp when using FRAG_BIT_WPOS in a fragment program (bug #9910) Redirect all VERT_RESULT_HPOS writes to a temp and use that for fixup. The viewport transformation still seems to take some shortcuts, and it still does not seem to work at all... --- src/mesa/drivers/dri/r300/r300_vertexprog.c | 35 +++++++++++++---------------- 1 file changed, 15 insertions(+), 20 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/r300/r300_vertexprog.c b/src/mesa/drivers/dri/r300/r300_vertexprog.c index c08c98767e..2ff92e1328 100644 --- a/src/mesa/drivers/dri/r300/r300_vertexprog.c +++ b/src/mesa/drivers/dri/r300/r300_vertexprog.c @@ -960,26 +960,23 @@ static void position_invariant(struct gl_program *prog) static void insert_wpos(struct r300_vertex_program *vp, struct gl_program *prog, - GLint pos) + GLuint temp_index) { GLint tokens[6] = { STATE_INTERNAL, STATE_R300_WINDOW_DIMENSION, 0, 0, 0, 0 }; struct prog_instruction *vpi; struct prog_instruction *vpi_insert; - GLuint temp_index; GLuint window_index; int i = 0; vpi = malloc((prog->NumInstructions + 5) * sizeof(struct prog_instruction)); - memcpy(vpi, prog->Instructions, (pos+1) * sizeof(struct prog_instruction)); + /* all but END */ + memcpy(vpi, prog->Instructions, (prog->NumInstructions - 1) * sizeof(struct prog_instruction)); + /* END */ + memcpy(&vpi[prog->NumInstructions + 4], &prog->Instructions[prog->NumInstructions - 1], + sizeof(struct prog_instruction)); - vpi_insert = &vpi[pos]; - - /* make a copy before outputting VERT_RESULT_HPOS */ - vpi_insert->DstReg.File = vpi_insert->SrcReg[2].File; - vpi_insert->DstReg.Index = temp_index = vpi_insert->SrcReg[2].Index; - - vpi_insert++; + vpi_insert = &vpi[prog->NumInstructions - 1]; memset(vpi_insert, 0, 5 * sizeof(struct prog_instruction)); vpi_insert[i].Opcode = OPCODE_MOV; @@ -1062,8 +1059,6 @@ static void insert_wpos(struct r300_vertex_program *vp, vpi_insert[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ONE, SWIZZLE_ONE); i++; - memcpy(&vpi_insert[i], &prog->Instructions[pos+1], (prog->NumInstructions-(pos+1)) * sizeof(struct prog_instruction)); - free(prog->Instructions); prog->Instructions = vpi; @@ -1072,24 +1067,24 @@ static void insert_wpos(struct r300_vertex_program *vp, vpi = &prog->Instructions[prog->NumInstructions-1]; assert(vpi->Opcode == OPCODE_END); - /* we need position, don't we ? :) */ - prog->InputsRead |= (1 << VERT_ATTRIB_POS); } static void pos_as_texcoord(struct r300_vertex_program *vp, struct gl_program *prog) { struct prog_instruction *vpi; - int pos = 0; - - for(vpi = prog->Instructions; vpi->Opcode != OPCODE_END; vpi++, pos++){ + GLuint tempregi = prog->NumTemporaries; + /* should do something else if no temps left... */ + prog->NumTemporaries++; + + for(vpi = prog->Instructions; vpi->Opcode != OPCODE_END; vpi++){ if( vpi->DstReg.File == PROGRAM_OUTPUT && vpi->DstReg.Index == VERT_RESULT_HPOS ){ - insert_wpos(vp, prog, pos); - break; + vpi->DstReg.File = PROGRAM_TEMPORARY; + vpi->DstReg.Index = tempregi; } } - + insert_wpos(vp, prog, tempregi); } static struct r300_vertex_program *build_program(struct r300_vertex_program_key *wanted_key, -- cgit v1.2.3 From 421ce180f52ff55b866066fabd861a51dd6d2b26 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Fri, 9 Feb 2007 00:36:53 +0100 Subject: r200: simplify / unify input map handling for vp and fftnl Use the same input map handling for fftnl and vertex programs. It doesn't enable any new functionality (should make it easy to support per-vertex materials though), but the code is much cleaner. --- src/mesa/drivers/dri/r200/r200_context.h | 12 +- src/mesa/drivers/dri/r200/r200_maos.h | 2 +- src/mesa/drivers/dri/r200/r200_maos_arrays.c | 402 +++++++-------------------- src/mesa/drivers/dri/r200/r200_tcl.c | 42 +-- src/mesa/drivers/dri/r200/r200_vertprog.c | 17 +- 5 files changed, 141 insertions(+), 334 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h index 26a43d20dd..e840a502c0 100644 --- a/src/mesa/drivers/dri/r200/r200_context.h +++ b/src/mesa/drivers/dri/r200/r200_context.h @@ -107,8 +107,7 @@ struct r200_vertex_program { VERTEX_SHADER_INSTRUCTION instr[R200_VSF_MAX_INST + 6]; int pos_end; int inputs[VERT_ATTRIB_MAX]; - int rev_inputs[16]; - int gen_inputs_mapped; + GLubyte inputmap_rev[16]; int native; int fogpidx; int fogmode; @@ -733,14 +732,7 @@ struct r200_tcl_info { GLuint *Elts; struct r200_dma_region indexed_verts; - struct r200_dma_region weight; - struct r200_dma_region obj; - struct r200_dma_region rgba; - struct r200_dma_region spec; - struct r200_dma_region fog; - struct r200_dma_region tex[R200_MAX_TEXTURE_UNITS]; - struct r200_dma_region norm; - struct r200_dma_region generic[16]; + struct r200_dma_region vertex_data[15]; }; diff --git a/src/mesa/drivers/dri/r200/r200_maos.h b/src/mesa/drivers/dri/r200/r200_maos.h index b9e4d3c239..4998f67445 100644 --- a/src/mesa/drivers/dri/r200/r200_maos.h +++ b/src/mesa/drivers/dri/r200/r200_maos.h @@ -38,7 +38,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_context.h" -extern void r200EmitArrays( GLcontext *ctx, GLuint inputs ); +extern void r200EmitArrays( GLcontext *ctx, GLubyte *vimap_rev ); extern void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs ); #endif diff --git a/src/mesa/drivers/dri/r200/r200_maos_arrays.c b/src/mesa/drivers/dri/r200/r200_maos_arrays.c index db5ac6fc8a..6a6c30a2b0 100644 --- a/src/mesa/drivers/dri/r200/r200_maos_arrays.c +++ b/src/mesa/drivers/dri/r200/r200_maos_arrays.c @@ -376,7 +376,7 @@ static void emit_vector( GLcontext *ctx, /* Emit any changed arrays to new GART memory, re-emit a packet to * update the arrays. */ -void r200EmitArrays( GLcontext *ctx, GLuint inputs ) +void r200EmitArrays( GLcontext *ctx, GLubyte *vimap_rev ) { r200ContextPtr rmesa = R200_CONTEXT( ctx ); struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb; @@ -384,284 +384,109 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs ) GLuint nr = 0; GLuint vfmt0 = 0, vfmt1 = 0; GLuint count = VB->Count; - GLuint i; - GLuint generic_in_mapped = 0; - struct r200_vertex_program *vp = NULL; - - /* this looks way more complicated than necessary... */ - if (ctx->VertexProgram._Enabled) { - vp = rmesa->curr_vp_hw; - generic_in_mapped = vp->gen_inputs_mapped; - } - - if (inputs & VERT_BIT_POS) { - if (!rmesa->tcl.obj.buf) - emit_vector( ctx, - &rmesa->tcl.obj, - (char *)VB->ObjPtr->data, - VB->ObjPtr->size, - VB->ObjPtr->stride, - count); - - switch( VB->ObjPtr->size ) { - case 4: vfmt0 |= R200_VTX_W0; - case 3: vfmt0 |= R200_VTX_Z0; - case 2: - default: - break; - } - component[nr++] = &rmesa->tcl.obj; - } - else if (generic_in_mapped & (1 << 0)) { - int geninput = vp->rev_inputs[0] - VERT_ATTRIB_GENERIC0; - if (!rmesa->tcl.generic[geninput].buf) { - emit_vector( ctx, - &(rmesa->tcl.generic[geninput]), - (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, - 4, - VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, - count ); - } - component[nr++] = &rmesa->tcl.generic[geninput]; - vfmt0 |= R200_VTX_W0 | R200_VTX_Z0; - } - - if (inputs & VERT_BIT_WEIGHT) { - if (!rmesa->tcl.weight.buf) - emit_vector( ctx, - &rmesa->tcl.weight, - (char *)VB->AttribPtr[VERT_ATTRIB_WEIGHT]->data, - VB->AttribPtr[VERT_ATTRIB_WEIGHT]->size, - VB->AttribPtr[VERT_ATTRIB_WEIGHT]->stride, - count); - - assert(VB->AttribPtr[VERT_ATTRIB_WEIGHT]->size <= 4); - vfmt0 |= VB->AttribPtr[VERT_ATTRIB_WEIGHT]->size << R200_VTX_WEIGHT_COUNT_SHIFT; - component[nr++] = &rmesa->tcl.weight; - } - - if (inputs & VERT_BIT_NORMAL) { - if (!rmesa->tcl.norm.buf) - emit_vector( ctx, - &(rmesa->tcl.norm), - (char *)VB->NormalPtr->data, - 3, - VB->NormalPtr->stride, - count); - - vfmt0 |= R200_VTX_N0; - component[nr++] = &rmesa->tcl.norm; - } - - if (inputs & VERT_BIT_FOG) { - if (!rmesa->tcl.fog.buf) { - if (ctx->VertexProgram._Enabled) - emit_vector( ctx, - &(rmesa->tcl.fog), - (char *)VB->FogCoordPtr->data, + GLuint i, emitsize; + + for ( i = 0; i < 15; i++ ) { + GLubyte attrib = vimap_rev[i]; + if (attrib != 255) { + switch (i) { + case 0: + emitsize = (VB->AttribPtr[attrib]->size); + switch (emitsize) { + case 4: + vfmt0 |= R200_VTX_W0; + /* fallthrough */ + case 3: + vfmt0 |= R200_VTX_Z0; + break; + case 2: + break; + default: assert(0); + } + break; + case 1: + assert(attrib == VERT_ATTRIB_WEIGHT); + emitsize = (VB->AttribPtr[attrib]->size); + vfmt0 |= emitsize << R200_VTX_WEIGHT_COUNT_SHIFT; + break; + case 2: + assert(attrib == VERT_ATTRIB_NORMAL); + emitsize = 3; + vfmt0 |= R200_VTX_N0; + break; + case 3: + /* special handling to fix up fog. Will get us into trouble with vbos...*/ + assert(attrib == VERT_ATTRIB_FOG); + if (!rmesa->tcl.vertex_data[i].buf) { + if (ctx->VertexProgram._Enabled) + emit_vector( ctx, + &(rmesa->tcl.vertex_data[attrib]), + (char *)VB->AttribPtr[attrib]->data, 1, - VB->FogCoordPtr->stride, + VB->AttribPtr[attrib]->stride, count); - else - emit_vecfog( ctx, - &(rmesa->tcl.fog), - (char *)VB->FogCoordPtr->data, - VB->FogCoordPtr->stride, + else + emit_vecfog( ctx, + &(rmesa->tcl.vertex_data[attrib]), + (char *)VB->AttribPtr[attrib]->data, + VB->AttribPtr[attrib]->stride, count); - } - - vfmt0 |= R200_VTX_DISCRETE_FOG; - component[nr++] = &rmesa->tcl.fog; - } - - if (inputs & VERT_BIT_COLOR0) { - int emitsize; - - if (VB->ColorPtr[0]->size == 4 && - (VB->ColorPtr[0]->stride != 0 || - VB->ColorPtr[0]->data[0][3] != 1.0)) { - vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT; - emitsize = 4; - } - else { - vfmt0 |= R200_VTX_FP_RGB << R200_VTX_COLOR_0_SHIFT; - emitsize = 3; - } - - if (!rmesa->tcl.rgba.buf) - emit_vector( ctx, - &(rmesa->tcl.rgba), - (char *)VB->ColorPtr[0]->data, - emitsize, - VB->ColorPtr[0]->stride, - count); - - component[nr++] = &rmesa->tcl.rgba; - } -/* vfmt0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT; - emit_ubyte_rgba( ctx, &rmesa->tcl.rgba, - (char *)VB->ColorPtr[0]->data, 4, - VB->ColorPtr[0]->stride, count);*/ - else if (generic_in_mapped & (1 << 2)) { - int geninput = vp->rev_inputs[2] - VERT_ATTRIB_GENERIC0; - if (!rmesa->tcl.generic[geninput].buf) { - emit_vector( ctx, - &(rmesa->tcl.generic[geninput]), - (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, - 4, - VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, - count ); - } - component[nr++] = &rmesa->tcl.generic[geninput]; - vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT; - } - - - if (inputs & VERT_BIT_COLOR1) { - if (!rmesa->tcl.spec.buf) { - emit_vector( ctx, - &rmesa->tcl.spec, - (char *)VB->SecondaryColorPtr[0]->data, - 3, - VB->SecondaryColorPtr[0]->stride, - count); - } - - /* How does this work? - */ - vfmt0 |= R200_VTX_FP_RGB << R200_VTX_COLOR_1_SHIFT; - component[nr++] = &rmesa->tcl.spec; - } - else if (generic_in_mapped & (1 << 3)) { - int geninput = vp->rev_inputs[3] - VERT_ATTRIB_GENERIC0; - if (!rmesa->tcl.generic[geninput].buf) { - emit_vector( ctx, - &(rmesa->tcl.generic[geninput]), - (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, - 4, - VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, - count ); - } - component[nr++] = &rmesa->tcl.generic[geninput]; - vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT; - } - - if (generic_in_mapped & (1 << 4)) { - int geninput = vp->rev_inputs[4] - VERT_ATTRIB_GENERIC0; - if (!rmesa->tcl.generic[geninput].buf) { - emit_vector( ctx, - &(rmesa->tcl.generic[geninput]), - (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, - 4, - VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, - count ); - } - component[nr++] = &rmesa->tcl.generic[geninput]; - vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_2_SHIFT; - } - - if (generic_in_mapped & (1 << 5)) { - int geninput = vp->rev_inputs[5] - VERT_ATTRIB_GENERIC0; - if (!rmesa->tcl.generic[geninput].buf) { - emit_vector( ctx, - &(rmesa->tcl.generic[geninput]), - (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, - 4, - VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, - count ); - } - component[nr++] = &rmesa->tcl.generic[geninput]; - vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_3_SHIFT; - } - - for ( i = 0 ; i < 6 ; i++ ) { - if (inputs & (VERT_BIT_TEX0 << i)) { - if (!rmesa->tcl.tex[i].buf) - emit_vector( ctx, - &(rmesa->tcl.tex[i]), - (char *)VB->TexCoordPtr[i]->data, - VB->TexCoordPtr[i]->size, - VB->TexCoordPtr[i]->stride, - count ); - - vfmt1 |= VB->TexCoordPtr[i]->size << (i * 3); - component[nr++] = &rmesa->tcl.tex[i]; - } - else if (generic_in_mapped & (1 << (i + 6))) { - int geninput = vp->rev_inputs[i + 6] - VERT_ATTRIB_GENERIC0; - if (!rmesa->tcl.generic[geninput].buf) { - emit_vector( ctx, - &(rmesa->tcl.generic[geninput]), - (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, - 4, - VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, - count ); - } - component[nr++] = &rmesa->tcl.generic[geninput]; - vfmt1 |= 4 << (R200_VTX_TEX0_COMP_CNT_SHIFT + (i * 3)); - } - } - - if (generic_in_mapped & (1 << 13)) { - int geninput = vp->rev_inputs[13] - VERT_ATTRIB_GENERIC0; - if (!rmesa->tcl.generic[geninput].buf) { - emit_vector( ctx, - &(rmesa->tcl.generic[geninput]), - (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, - 4, - VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, - count ); - } - component[nr++] = &rmesa->tcl.generic[geninput]; - vfmt0 |= R200_VTX_XY1 | R200_VTX_Z1 | R200_VTX_W1; - } - -/* doesn't work. Wrong order with mixed generic & conventional! */ -/* - if (ctx->VertexProgram._Enabled) { - int *vp_inputs = rmesa->curr_vp_hw->inputs; - for ( i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++ ) { - if (inputs & (1 << i)) { - int geninput = i - VERT_ATTRIB_GENERIC0; - if (!rmesa->tcl.generic[geninput].buf) { - emit_vector( ctx, - &(rmesa->tcl.generic[geninput]), - (char *)VB->AttribPtr[i]->data, - 4, - VB->AttribPtr[i]->stride, - count ); } - component[nr++] = &rmesa->tcl.generic[geninput]; - switch (vp_inputs[i]) { - case 0: - vfmt0 |= R200_VTX_W0 | R200_VTX_Z0; - break; + vfmt0 |= R200_VTX_DISCRETE_FOG; + goto after_emit; + break; + case 4: + case 5: + case 6: + case 7: + if (VB->AttribPtr[attrib]->size == 4 && + (VB->AttribPtr[attrib]->stride != 0 || + VB->AttribPtr[attrib]->data[0][3] != 1.0)) emitsize = 4; + else emitsize = 3; + if (emitsize == 4) + vfmt0 |= R200_VTX_FP_RGBA << (R200_VTX_COLOR_0_SHIFT + (i - 4) * 2); + else { + vfmt0 |= R200_VTX_FP_RGB << (R200_VTX_COLOR_0_SHIFT + (i - 4) * 2); + } + break; + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + emitsize = VB->AttribPtr[attrib]->size; + vfmt1 |= emitsize << (R200_VTX_TEX0_COMP_CNT_SHIFT + (i - 8) * 3); + break; + case 14: + emitsize = VB->AttribPtr[attrib]->size >= 2 ? VB->AttribPtr[attrib]->size : 2; + switch (emitsize) { case 2: + vfmt0 |= R200_VTX_XY1; + /* fallthrough */ case 3: + vfmt0 |= R200_VTX_Z1; + /* fallthrough */ case 4: - case 5: - vfmt0 |= R200_VTX_FP_RGBA << (R200_VTX_COLOR_0_SHIFT + (vp_inputs[i] - 2) * 2); - break; - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - vfmt1 |= 4 << (R200_VTX_TEX0_COMP_CNT_SHIFT + (vp_inputs[i] - 6) * 3); - break; - case 13: - vfmt0 |= R200_VTX_XY1 | R200_VTX_Z1 | R200_VTX_W1; - break; - case 1: - case 12: - default: - assert(0); + vfmt0 |= R200_VTX_W1; + break; } + default: + assert(0); + } + if (!rmesa->tcl.vertex_data[i].buf) { + emit_vector( ctx, + &(rmesa->tcl.vertex_data[i]), + (char *)VB->AttribPtr[attrib]->data, + emitsize, + VB->AttribPtr[attrib]->stride, + count ); } +after_emit: + assert(nr < 12); + component[nr++] = &rmesa->tcl.vertex_data[i]; } } -*/ if (vfmt0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] || vfmt1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) { @@ -676,42 +501,13 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs ) void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs ) { - GLuint unit; r200ContextPtr rmesa = R200_CONTEXT( ctx ); -/* if (R200_DEBUG & DEBUG_VERTS) */ -/* _tnl_print_vert_flags( __FUNCTION__, newinputs ); */ - - if (newinputs & VERT_BIT_POS) - r200ReleaseDmaRegion( rmesa, &rmesa->tcl.obj, __FUNCTION__ ); - - if (newinputs & VERT_BIT_WEIGHT) - r200ReleaseDmaRegion( rmesa, &rmesa->tcl.weight, __FUNCTION__ ); - - if (newinputs & VERT_BIT_NORMAL) - r200ReleaseDmaRegion( rmesa, &rmesa->tcl.norm, __FUNCTION__ ); - - if (newinputs & VERT_BIT_FOG) - r200ReleaseDmaRegion( rmesa, &rmesa->tcl.fog, __FUNCTION__ ); - - if (newinputs & VERT_BIT_COLOR0) - r200ReleaseDmaRegion( rmesa, &rmesa->tcl.rgba, __FUNCTION__ ); - - if (newinputs & VERT_BIT_COLOR1) - r200ReleaseDmaRegion( rmesa, &rmesa->tcl.spec, __FUNCTION__ ); - - for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) { - if (newinputs & VERT_BIT_TEX(unit)) - r200ReleaseDmaRegion( rmesa, &rmesa->tcl.tex[unit], __FUNCTION__ ); - } - - if (ctx->VertexProgram._Enabled) { - int i; - for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) { - if (newinputs & (1 << i)) - r200ReleaseDmaRegion( rmesa, - &rmesa->tcl.generic[i - VERT_ATTRIB_GENERIC0], __FUNCTION__ ); - } + /* only do it for changed inputs ? */ + int i; + for (i = 0; i < 15; i++) { + if (newinputs & (1 << i)) + r200ReleaseDmaRegion( rmesa, + &rmesa->tcl.vertex_data[i], __FUNCTION__ ); } - } diff --git a/src/mesa/drivers/dri/r200/r200_tcl.c b/src/mesa/drivers/dri/r200/r200_tcl.c index 62c335a707..e0c32b26d9 100644 --- a/src/mesa/drivers/dri/r200/r200_tcl.c +++ b/src/mesa/drivers/dri/r200/r200_tcl.c @@ -384,8 +384,14 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx, r200ContextPtr rmesa = R200_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; - GLuint inputs = 0; GLuint i; + GLubyte *vimap_rev; +/* use hw fixed order for simplicity, pos 0, weight 1, normal 2, fog 3, + color0 - color3 4-7, texcoord0 - texcoord5 8-13, pos 1 14. Must not use + more than 12 of those at the same time. */ + GLubyte map_rev_fixed[15] = {255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255}; + /* TODO: separate this from the swtnl pipeline */ @@ -404,30 +410,40 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx, r200ValidateState( ctx ); if (!ctx->VertexProgram._Enabled) { - inputs = VERT_BIT_POS | VERT_BIT_COLOR0; /* NOTE: inputs != tnl->render_inputs - these are the untransformed * inputs. */ + map_rev_fixed[0] = VERT_ATTRIB_POS; + /* technically there is no reason we always need VA_COLOR0. In theory + could disable it depending on lighting, color materials, texturing... */ + map_rev_fixed[4] = VERT_ATTRIB_COLOR0; + if (ctx->Light.Enabled) { - inputs |= VERT_BIT_NORMAL; + map_rev_fixed[2] = VERT_ATTRIB_NORMAL; } + /* this also enables VA_COLOR1 when using separate specular + lighting model, which is unnecessary. + FIXME: OTOH, we're missing the case where a ATI_fragment_shader accesses + the secondary color (if lighting is disabled). The chip seems + misconfigured for that though elsewhere (tcl output, might lock up) */ if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { - inputs |= VERT_BIT_COLOR1; + map_rev_fixed[5] = VERT_ATTRIB_COLOR1; } if ( (ctx->Fog.FogCoordinateSource == GL_FOG_COORD) && ctx->Fog.Enabled ) { - inputs |= VERT_BIT_FOG; + map_rev_fixed[3] = VERT_ATTRIB_FOG; } for (i = 0 ; i < ctx->Const.MaxTextureUnits; i++) { if (ctx->Texture.Unit[i]._ReallyEnabled) { if (rmesa->TexGenNeedNormals[i]) { - inputs |= VERT_BIT_NORMAL; + map_rev_fixed[2] = VERT_ATTRIB_NORMAL; } - inputs |= VERT_BIT_TEX(i); + map_rev_fixed[8 + i] = VERT_ATTRIB_TEX0 + i; } } + vimap_rev = &map_rev_fixed[0]; } else { /* vtx_tcl_output_vtxfmt_0/1 need to match configuration of "fragment @@ -437,14 +453,8 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx, We only need to change compsel. */ GLuint out_compsel = 0; GLuint vp_out = rmesa->curr_vp_hw->mesa_program.Base.OutputsWritten; -#if 0 - /* can't handle other inputs, generic attribs etc. currently - should never arrive here */ - assert ((rmesa->curr_vp_hw->mesa_program.Base.InputsRead & - ~(VERT_BIT_POS | VERT_BIT_NORMAL | VERT_BIT_COLOR0 | VERT_BIT_COLOR1 | - VERT_BIT_FOG | VERT_BIT_TEX0 | VERT_BIT_TEX1 | VERT_BIT_TEX2 | - VERT_BIT_TEX3 | VERT_BIT_TEX4 | VERT_BIT_TEX5)) == 0); -#endif - inputs |= rmesa->curr_vp_hw->mesa_program.Base.InputsRead; + + vimap_rev = &rmesa->curr_vp_hw->inputmap_rev[0]; assert(vp_out & (1 << VERT_RESULT_HPOS)); out_compsel = R200_OUTPUT_XYZW; if (vp_out & (1 << VERT_RESULT_COL0)) { @@ -473,7 +483,7 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx, /* Do the actual work: */ r200ReleaseArrays( ctx, ~0 /* stage->changed_inputs */ ); - r200EmitArrays( ctx, inputs ); + r200EmitArrays( ctx, vimap_rev ); rmesa->tcl.Elts = VB->Elts; diff --git a/src/mesa/drivers/dri/r200/r200_vertprog.c b/src/mesa/drivers/dri/r200/r200_vertprog.c index 713e2f9eca..4960d481d5 100644 --- a/src/mesa/drivers/dri/r200/r200_vertprog.c +++ b/src/mesa/drivers/dri/r200/r200_vertprog.c @@ -405,7 +405,6 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte int dofogfix = 0; int fog_temp_i = 0; int free_inputs; - int free_inputs_conv; int array_count = 0; vp->native = GL_FALSE; @@ -477,6 +476,8 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte for(i = 0; i < VERT_ATTRIB_MAX; i++) vp->inputs[i] = -1; + for(i = 0; i < 15; i++) + vp->inputmap_rev[i] = 255; free_inputs = 0x2ffd; /* fglrx uses fixed inputs as follows for conventional attribs. @@ -499,38 +500,45 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte /* may look different when using idx buf / input_route instead of se_vtx_fmt? */ if (mesa_vp->Base.InputsRead & VERT_BIT_POS) { vp->inputs[VERT_ATTRIB_POS] = 0; + vp->inputmap_rev[0] = VERT_ATTRIB_POS; free_inputs &= ~(1 << 0); array_count++; } if (mesa_vp->Base.InputsRead & VERT_BIT_WEIGHT) { vp->inputs[VERT_ATTRIB_WEIGHT] = 12; + vp->inputmap_rev[1] = VERT_ATTRIB_WEIGHT; array_count++; } if (mesa_vp->Base.InputsRead & VERT_BIT_NORMAL) { vp->inputs[VERT_ATTRIB_NORMAL] = 1; + vp->inputmap_rev[2] = VERT_ATTRIB_NORMAL; array_count++; } if (mesa_vp->Base.InputsRead & VERT_BIT_COLOR0) { vp->inputs[VERT_ATTRIB_COLOR0] = 2; + vp->inputmap_rev[4] = VERT_ATTRIB_COLOR0; free_inputs &= ~(1 << 2); array_count++; } if (mesa_vp->Base.InputsRead & VERT_BIT_COLOR1) { vp->inputs[VERT_ATTRIB_COLOR1] = 3; + vp->inputmap_rev[5] = VERT_ATTRIB_COLOR1; free_inputs &= ~(1 << 3); array_count++; } if (mesa_vp->Base.InputsRead & VERT_BIT_FOG) { vp->inputs[VERT_ATTRIB_FOG] = 15; array_count++; + vp->inputmap_rev[3] = VERT_ATTRIB_FOG; + array_count++; } for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX5; i++) { if (mesa_vp->Base.InputsRead & (1 << i)) { vp->inputs[i] = i - VERT_ATTRIB_TEX0 + 6; + vp->inputmap_rev[8 + i - VERT_ATTRIB_TEX0] = i; free_inputs &= ~(1 << (i - VERT_ATTRIB_TEX0 + 6)); array_count++; } } - free_inputs_conv = free_inputs; /* using VERT_ATTRIB_TEX6/7 would be illegal */ /* completely ignore aliasing? */ for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) { @@ -549,13 +557,14 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte if (free_inputs & (1 << j)) { free_inputs &= ~(1 << j); vp->inputs[i] = j; - vp->rev_inputs[j] = i; + if (j == 0) vp->inputmap_rev[j] = i; /* mapped to pos */ + else if (j < 12) vp->inputmap_rev[j + 2] = i; /* mapped to col/tex */ + else vp->inputmap_rev[j + 1] = i; /* mapped to pos1 */ break; } } } } - vp->gen_inputs_mapped = free_inputs ^ free_inputs_conv; if (!(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS))) { if (R200_DEBUG & DEBUG_FALLBACKS) { -- cgit v1.2.3 From ee5417bca883d82d618e1c0b65011940253555dd Mon Sep 17 00:00:00 2001 From: Rune Peterson Date: Mon, 12 Feb 2007 00:24:36 +0100 Subject: r300: Add proper support for sin/cos instruction in fragment program Getting proper SIN and COS wasn't as easy as it appeared. I had to make make some changes to the fragment program code. general FP changes: - support HHH swizzle for vector instructions. - don't copy a source to a temp when it is not XYZW swizzled, but combine the two and have the swizzle resolve any issues. (saves temps/instructions with more elaborate shader code) - fix overflow in cnstv[]. --- src/mesa/drivers/dri/r300/r300_context.h | 5 + src/mesa/drivers/dri/r300/r300_fragprog.c | 271 ++++++++++++++++------------ src/mesa/drivers/dri/r300/r300_fragprog.h | 5 +- src/mesa/drivers/dri/r300/r300_render.c | 2 +- src/mesa/drivers/dri/r300/r300_state.c | 2 +- src/mesa/drivers/dri/radeon/radeon_screen.c | 11 +- 6 files changed, 175 insertions(+), 121 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 02f8e9107d..b140235159 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -729,6 +729,11 @@ struct r300_fragment_program { GLboolean params_uptodate; int max_temp_idx; + + /* the index of the sin constant is stored here */ + GLint const_sin; + + GLuint optimization; }; #define R300_MAX_AOS_ARRAYS 16 diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c index 6e85f0b5dd..b00cf9ed33 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog.c @@ -33,7 +33,7 @@ /*TODO'S * - * - COS/SIN/SCS instructions + * - SCS instructions * - Depth write, WPOS/FOGC inputs * - FogOption * - Verify results of opcodes for accuracy, I've only checked them @@ -187,6 +187,10 @@ static const struct { #define SLOT_VECTOR (1<<0) #define SLOT_SCALAR (1<<3) #define SLOT_BOTH (SLOT_VECTOR | SLOT_SCALAR) + +/* mapping from SWIZZLE_* to r300 native values for scalar insns */ +#define SWIZZLE_HALF 6 + #define MAKE_SWZ3(x, y, z) (MAKE_SWIZZLE4(SWIZZLE_##x, \ SWIZZLE_##y, \ SWIZZLE_##z, \ @@ -208,7 +212,7 @@ static const struct r300_pfs_swizzle { { MAKE_SWZ3(W, Z, Y), R300_FPI0_ARGC_SRC0CA_WZY, 1, SLOT_BOTH }, { MAKE_SWZ3(ONE, ONE, ONE), R300_FPI0_ARGC_ONE, 0, 0}, { MAKE_SWZ3(ZERO, ZERO, ZERO), R300_FPI0_ARGC_ZERO, 0, 0}, - { PFS_INVAL, R300_FPI0_ARGC_HALF, 0, 0}, + { MAKE_SWZ3(HALF, HALF, HALF), R300_FPI0_ARGC_HALF, 0, 0}, { PFS_INVAL, 0, 0, 0}, }; @@ -232,8 +236,6 @@ static const struct { { PFS_INVAL, PFS_INVAL, PFS_INVAL} }; -/* mapping from SWIZZLE_* to r300 native values for scalar insns */ -#define SWIZZLE_HALF 6 static const struct { int base; /* hw value of swizzle */ int stride; /* difference between SRC0/1/2 */ @@ -590,6 +592,7 @@ static GLuint do_swizzle(struct r300_fragment_program *rp, /* If swizzling from something without an XYZW native swizzle, * emit result to a temp, and do new swizzle from the temp. */ +#if 0 if (REG_GET_VSWZ(src) != SWIZZLE_XYZ || REG_GET_SSWZ(src) != SWIZZLE_W) { GLuint temp = get_temp_reg(rp); @@ -603,10 +606,30 @@ static GLuint do_swizzle(struct r300_fragment_program *rp, 0); src = temp; } +#endif - /* set scalar swizzling */ - REG_SET_SSWZ(src, GET_SWZ(arbswz, 3)); + if (REG_GET_VSWZ(src) != SWIZZLE_XYZ || + REG_GET_SSWZ(src) != SWIZZLE_W) { + GLuint vsrcswz = (v_swiz[REG_GET_VSWZ(src)].hash & (SWZ_X_MASK|SWZ_Y_MASK|SWZ_Z_MASK)) | REG_GET_SSWZ(src) << 9; + GLint i; + GLuint newswz = 0; + GLuint offset; + for(i=0; i < 4; ++i){ + offset = GET_SWZ(arbswz, i); + + newswz |= (offset <= 3)?GET_SWZ(vsrcswz, offset) << i*3:offset << i*3; + } + + arbswz = newswz & (SWZ_X_MASK|SWZ_Y_MASK|SWZ_Z_MASK); + REG_SET_SSWZ(src, GET_SWZ(newswz, 3)); + } + else + { + /* set scalar swizzling */ + REG_SET_SSWZ(src, GET_SWZ(arbswz, 3)); + + } do { vswz = REG_GET_VSWZ(src); do { @@ -1234,62 +1257,87 @@ static GLboolean parse_program(struct r300_fragment_program *rp) break; case OPCODE_COS: /* - * cos using taylor serie: - * cos(x) = 1 - x^2/2! + x^4/4! - x^6/6! + * cos using a parabola (see SIN): + * cos(x): + * x += PI/2 + * x = (x < PI)?x : x-2*PI + * result = sin(x) */ temp = get_temp_reg(rp); - cnstv[0] = 0.5; - cnstv[1] = 0.041666667; - cnstv[2] = 0.001388889; - cnstv[4] = 0.0; - cnst = emit_const4fv(rp, cnstv); + if(rp->const_sin == -1){ + cnstv[0] = 1.273239545; + cnstv[1] =-0.405284735; + cnstv[2] = 3.141592654; + cnstv[3] = 0.225; + rp->const_sin = emit_const4fv(rp, cnstv); + } + cnst = rp->const_sin; src[0] = t_scalar_src(rp, fpi->SrcReg[0]); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_XYZ, - src[0], - src[0], - pfs_zero, - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_Y | WRITEMASK_Z, - temp, temp, - pfs_zero, - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_Z, - temp, - swizzle(temp, X, X, X, W), - pfs_zero, - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_XYZ, - temp, cnst, - pfs_zero, - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_X, - pfs_one, - pfs_one, - negate(temp), - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_X, - temp, - pfs_one, - swizzle(temp, Y, Y, Y, W), - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_X, - temp, - pfs_one, - negate(swizzle(temp, Z, Z, Z, W)), - flags); - emit_arith(rp, PFS_OP_MAD, dest, mask, + emit_arith(rp, PFS_OP_LG2, temp, WRITEMASK_W, + pfs_half, + undef, + undef, + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, + swizzle(cnst, Z, Z, Z, Z), //PI + pfs_half, + swizzle(keep(src[0]), X, X, X, X), + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_W, + negate(swizzle(temp, W, W, W, W)), //-2 + swizzle(cnst, Z, Z, Z, Z), //PI swizzle(temp, X, X, X, X), - pfs_one, + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Y, + swizzle(cnst, Z, Z, Z, Z), //PI + negate(pfs_half), + swizzle(src[0], X, X, X, X), + 0); + + emit_arith(rp, PFS_OP_CMP, temp, WRITEMASK_Z, + swizzle(temp, W, W, W, W), + swizzle(temp, X, X, X, X), + swizzle(temp, Y, Y, Y, Y), + 0); + + /* SIN */ + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X | WRITEMASK_Y, + swizzle(temp, Z, Z, Z, Z), + cnst, pfs_zero, - flags); + 0); + + if(rp->optimization == DRI_CONF_FP_OPTIMIZATION_SPEED){ + emit_arith(rp, PFS_OP_MAD, dest, mask, + swizzle(temp, Y, Y, Y, Y), + absolute(swizzle(temp, Z, Z, Z, Z)), + swizzle(temp, X, X, X, X), + flags); + }else{ + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, + swizzle(temp, Y, Y, Y, Y), + absolute(swizzle(temp, Z, Z, Z, Z)), + swizzle(temp, X, X, X, X), + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Y, + swizzle(temp, X, X, X, X), + absolute(swizzle(temp, X, X, X, X)), + negate(swizzle(temp, X, X, X, X)), + 0); + + + emit_arith(rp, PFS_OP_MAD, dest, mask, + swizzle(temp, Y, Y, Y, Y), + swizzle(cnst, W, W, W, W), + swizzle(temp, X, X, X, X), + flags); + } free_temp(rp, temp); break; case OPCODE_DP3: @@ -1398,7 +1446,7 @@ static GLboolean parse_program(struct r300_fragment_program *rp) * change the compare to (t.x + 0.5) > 0.5 we may * save one instruction by doing CMP -t.x */ - cnstv[0] = cnstv[1] = cnstv[2] = cnstv[4] = 0.50001; + cnstv[0] = cnstv[1] = cnstv[2] = cnstv[3] = 0.50001; src[0] = t_src(rp, fpi->SrcReg[0]); temp = get_temp_reg(rp); cnst = emit_const4fv(rp, cnstv); @@ -1548,68 +1596,55 @@ static GLboolean parse_program(struct r300_fragment_program *rp) break; case OPCODE_SIN: /* - * sin using taylor serie: - * sin(x) = x - x^3/3! + x^5/5! - x^7/7! + * using a parabola: + * sin(x) = 4/pi * x + -4/(pi*pi) * x * abs(x) + * extra precision is obtained by weighting against + * itself squared. */ + temp = get_temp_reg(rp); - cnstv[0] = 0.333333333; - cnstv[1] = 0.008333333; - cnstv[2] = 0.000198413; - cnstv[4] = 0.0; - cnst = emit_const4fv(rp, cnstv); + if(rp->const_sin == -1){ + cnstv[0] = 1.273239545; + cnstv[1] =-0.405284735; + cnstv[2] = 3.141592654; + cnstv[3] = 0.225; + rp->const_sin = emit_const4fv(rp, cnstv); + } + cnst = rp->const_sin; src[0] = t_scalar_src(rp, fpi->SrcReg[0]); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_XYZ, - src[0], - src[0], - pfs_zero, - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_Y | WRITEMASK_Z, - temp, temp, - pfs_zero, - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_Z, - temp, - swizzle(temp, X, X, X, W), + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X | WRITEMASK_Y, + swizzle(keep(src[0]), X, X, X, X), + cnst, pfs_zero, - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_XYZ, - src[0], - temp, - pfs_zero, - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_XYZ, - temp, cnst, - pfs_zero, - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_X, - src[0], - pfs_one, - negate(temp), - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_X, - temp, - pfs_one, - swizzle(temp, Y, Y, Y, W), - flags); - emit_arith(rp, PFS_OP_MAD, temp, - WRITEMASK_X, - temp, - pfs_one, - negate(swizzle(temp, Z, Z, Z, W)), - flags); - emit_arith(rp, PFS_OP_MAD, dest, mask, - swizzle(temp, X, X, X, X), - pfs_one, - pfs_zero, - flags); + 0); + + if(rp->optimization == DRI_CONF_FP_OPTIMIZATION_SPEED){ + emit_arith(rp, PFS_OP_MAD, dest, mask, + swizzle(temp, Y, Y, Y, Y), + absolute(swizzle(src[0], X, X, X, X)), + swizzle(temp, X, X, X, X), + flags); + }else{ + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, + swizzle(temp, Y, Y, Y, Y), + absolute(swizzle(src[0], X, X, X, X)), + swizzle(temp, X, X, X, X), + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Y, + swizzle(temp, X, X, X, X), + absolute(swizzle(temp, X, X, X, X)), + negate(swizzle(temp, X, X, X, X)), + 0); + + + emit_arith(rp, PFS_OP_MAD, dest, mask, + swizzle(temp, Y, Y, Y, Y), + swizzle(cnst, W, W, W, W), + swizzle(temp, X, X, X, X), + flags); + } free_temp(rp, temp); break; case OPCODE_SLT: @@ -1681,7 +1716,7 @@ static GLboolean parse_program(struct r300_fragment_program *rp) /* - Init structures * - Determine what hwregs each input corresponds to */ -static void init_program(struct r300_fragment_program *rp) +static void init_program(r300ContextPtr r300, struct r300_fragment_program *rp) { struct r300_pfs_compile_state *cs = NULL; struct gl_fragment_program *mp = &rp->mesa_program; @@ -1691,6 +1726,7 @@ static void init_program(struct r300_fragment_program *rp) int i,j; /* New compile, reset tracking data */ + rp->optimization = driQueryOptioni(&r300->radeon.optionCache, "fp_optimization"); rp->translated = GL_FALSE; rp->error = GL_FALSE; rp->cs = cs = &(R300_CONTEXT(rp->ctx)->state.pfs_compile); @@ -1703,6 +1739,7 @@ static void init_program(struct r300_fragment_program *rp) rp->max_temp_idx = 0; rp->node[0].alu_end = -1; rp->node[0].tex_end = -1; + rp->const_sin = -1; _mesa_memset(cs, 0, sizeof(*rp->cs)); for (i=0;iparams_uptodate = GL_TRUE; } -void r300_translate_fragment_shader(struct r300_fragment_program *rp) +void r300_translate_fragment_shader(r300ContextPtr r300, struct r300_fragment_program *rp) { struct r300_pfs_compile_state *cs = NULL; if (!rp->translated) { - init_program(rp); + init_program(r300, rp); cs = rp->cs; if (parse_program(rp) == GL_FALSE) { diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.h b/src/mesa/drivers/dri/r300/r300_fragprog.h index b0cebe60bb..73986abc3c 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.h +++ b/src/mesa/drivers/dri/r300/r300_fragprog.h @@ -112,8 +112,11 @@ typedef struct r300_fragment_program_swizzle { ((0 | SRC_CONST) << R300_FPI3_SRC1A_SHIFT) | \ ((0 | SRC_CONST) << R300_FPI3_SRC2A_SHIFT)) +#define DRI_CONF_FP_OPTIMIZATION_SPEED 0 +#define DRI_CONF_FP_OPTIMIZATION_QUALITY 1 + struct r300_fragment_program; -extern void r300_translate_fragment_shader(struct r300_fragment_program *rp); +extern void r300_translate_fragment_shader(r300ContextPtr r300, struct r300_fragment_program *rp); #endif diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index e29df87696..211c451f66 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -392,7 +392,7 @@ int r300Fallback(GLcontext *ctx) if (rp) { if (!rp->translated) - r300_translate_fragment_shader(rp); + r300_translate_fragment_shader(r300, rp); FALLBACK_IF(!rp->translated); } diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index a12f3bb531..906dfceb48 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -1820,7 +1820,7 @@ void r300SetupPixelShader(r300ContextPtr rmesa) if (!rp) /* should only happenen once, just after context is created */ return; - r300_translate_fragment_shader(rp); + r300_translate_fragment_shader(rmesa, rp); if (!rp->translated) { fprintf(stderr, "%s: No valid fragment shader, exiting\n", __func__); return; diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index cee1f7e2f9..fc5aa11462 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -55,6 +55,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r200_span.h" #elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) #include "r300_context.h" +#include "r300_fragprog.h" #include "radeon_span.h" #endif @@ -168,6 +169,13 @@ DRI_CONF_OPT_BEGIN(disable_stencil_two_side,bool,def) \ DRI_CONF_DESC(en,"Disable GL_EXT_stencil_two_side") \ DRI_CONF_OPT_END +#define DRI_CONF_FP_OPTIMIZATION(def) \ +DRI_CONF_OPT_BEGIN_V(fp_optimization,enum,def,"0:1") \ + DRI_CONF_DESC_BEGIN(en,"Fragment Program optimization") \ + DRI_CONF_ENUM(0,"Optimize for Speed") \ + DRI_CONF_ENUM(1,"Optimize for Quality") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END const char __driConfigOptions[] = DRI_CONF_BEGIN @@ -190,12 +198,13 @@ DRI_CONF_BEGIN DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER) DRI_CONF_ROUND_MODE(DRI_CONF_ROUND_TRUNC) DRI_CONF_DITHER_MODE(DRI_CONF_DITHER_XERRORDIFF) + DRI_CONF_FP_OPTIMIZATION(DRI_CONF_FP_OPTIMIZATION_SPEED) DRI_CONF_SECTION_END DRI_CONF_SECTION_DEBUG DRI_CONF_NO_RAST(false) DRI_CONF_SECTION_END DRI_CONF_END; -static const GLuint __driNConfigOptions = 17; +static const GLuint __driNConfigOptions = 18; #ifndef RADEON_DEBUG int RADEON_DEBUG = 0; -- cgit v1.2.3 From 1e6688742e6a6e11d002c1fce5dca3da3d58594f Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Mon, 12 Feb 2007 16:38:50 +0800 Subject: I965: fix a failure on waiting irq. Wait until getting the right fence if drm/i915 resets the counter. --- src/mesa/drivers/dri/i965/intel_ioctl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i965/intel_ioctl.c b/src/mesa/drivers/dri/i965/intel_ioctl.c index 4da31277ea..0a8e976f70 100644 --- a/src/mesa/drivers/dri/i965/intel_ioctl.c +++ b/src/mesa/drivers/dri/i965/intel_ioctl.c @@ -108,7 +108,8 @@ void intelWaitIrq( struct intel_context *intel, int seq ) /* This seems quite often to return before it should!?! */ - } while (ret == -EAGAIN || ret == -EINTR || (ret == -EBUSY && lastdispatch != intel->sarea->last_dispatch) || (ret == 0 && seq > intel->sarea->last_dispatch)); + } while (ret == -EAGAIN || ret == -EINTR || (ret == -EBUSY && lastdispatch != intel->sarea->last_dispatch) || (ret == 0 && seq > intel->sarea->last_dispatch) + || (ret == 0 && intel->sarea->last_dispatch - seq >= (1 << 24))); if ( ret ) { -- cgit v1.2.3 From bc82b44db9dbb6ea0f02c2a9a430e8d402c85bd3 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 14 Feb 2007 11:11:23 +0100 Subject: i915tex: Take into account various mapping states when dropping the batch buffer after a resolution / rotation switch. --- src/mesa/drivers/dri/i915tex/intel_context.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c index aa76875a4a..a5ce08b170 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.c +++ b/src/mesa/drivers/dri/i915tex/intel_context.c @@ -643,7 +643,9 @@ intelContendedLock(struct intel_context *intel, GLuint flags) if (sarea->width != intel->width || sarea->height != intel->height || sarea->rotation != intel->current_rotation) { - + + void *batchMap = intel->batch->map; + /* * FIXME: Really only need to do this when drawing to a * common back- or front buffer. @@ -653,9 +655,18 @@ intelContendedLock(struct intel_context *intel, GLuint flags) * This will drop the outstanding batchbuffer on the floor */ - driBOUnmap(intel->batch->buffer); + if (batchMap != NULL) { + driBOUnmap(intel->batch->buffer); + intel->batch->map = NULL; + } + intel_batchbuffer_reset(intel->batch); + if (batchMap == NULL) { + driBOUnmap(intel->batch->buffer); + intel->batch->map = NULL; + } + /* lose all primitives */ intel->prim.primitive = ~0; intel->prim.start_ptr = 0; -- cgit v1.2.3 From 83cf4ce6e40ed1841b94f528dc89838e875c720d Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Wed, 14 Feb 2007 20:28:31 +0100 Subject: nouveau: nv10: there are 8 clipping regions --- src/mesa/drivers/dri/nouveau/nv10_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 8fbc76c308..d69c6824ed 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -619,7 +619,7 @@ static void nv10WindowMoved(nouveauContextPtr nmesa) NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 2); OUT_RING_CACHE(((w+x-1) << 16) | x | 0x08000800); OUT_RING_CACHE(((h+y-1) << 16) | y | 0x08000800); - for (i=1; i<7; i++) { + for (i=1; i<8; i++) { BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 1); OUT_RING_CACHE(0); -- cgit v1.2.3 From e4c772bead57c0190f74f1fa43dd129e170567f7 Mon Sep 17 00:00:00 2001 From: Rune Peterson Date: Wed, 14 Feb 2007 23:10:52 +0100 Subject: r300: Fix cos & add scs to fragment program. So this do : - Fixes COS. - Does range reductions for SIN & COS. - Adds SCS. - removes the optimized version of SIN & COS. - tweaked weight (should help on precision). - fixed a copy paste typo in emit_arith(). --- src/mesa/drivers/dri/r300/r300_context.h | 2 +- src/mesa/drivers/dri/r300/r300_fragprog.c | 270 ++++++++++++++++++++---------- 2 files changed, 184 insertions(+), 88 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index b140235159..48b50bca65 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -731,7 +731,7 @@ struct r300_fragment_program { int max_temp_idx; /* the index of the sin constant is stored here */ - GLint const_sin; + GLint const_sin[2]; GLuint optimization; }; diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c index b00cf9ed33..8e45bd5403 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog.c @@ -33,7 +33,6 @@ /*TODO'S * - * - SCS instructions * - Depth write, WPOS/FOGC inputs * - FogOption * - Verify results of opcodes for accuracy, I've only checked them @@ -1081,7 +1080,7 @@ static void emit_arith(struct r300_fragment_program *rp, break; } if (emit_sop && - (s_swiz[REG_GET_VSWZ(src[i])].flags & SLOT_VECTOR)) { + (s_swiz[REG_GET_SSWZ(src[i])].flags & SLOT_VECTOR)) { vpos = spos = MAX2(vpos, spos); break; } @@ -1204,6 +1203,25 @@ static GLuint get_attrib(struct r300_fragment_program *rp, GLuint attr) } #endif +static void make_sin_const(struct r300_fragment_program *rp) +{ + if(rp->const_sin[0] == -1){ + GLfloat cnstv[4]; + + cnstv[0] = 1.273239545; // 4/PI + cnstv[1] =-0.405284735; // -4/(PI*PI) + cnstv[2] = 3.141592654; // PI + cnstv[3] = 0.2225; // weight + rp->const_sin[0] = emit_const4fv(rp, cnstv); + + cnstv[0] = 0.5; + cnstv[1] = -1.5; + cnstv[2] = 0.159154943; // 1/(2*PI) + cnstv[3] = 6.283185307; // 2*PI + rp->const_sin[1] = emit_const4fv(rp, cnstv); + } +} + static GLboolean parse_program(struct r300_fragment_program *rp) { struct gl_fragment_program *mp = &rp->mesa_program; @@ -1260,84 +1278,68 @@ static GLboolean parse_program(struct r300_fragment_program *rp) * cos using a parabola (see SIN): * cos(x): * x += PI/2 - * x = (x < PI)?x : x-2*PI + * x = (x/(2*PI))+0.5 + * x = frac(x) + * x = (x*2*PI)-PI * result = sin(x) */ temp = get_temp_reg(rp); - if(rp->const_sin == -1){ - cnstv[0] = 1.273239545; - cnstv[1] =-0.405284735; - cnstv[2] = 3.141592654; - cnstv[3] = 0.225; - rp->const_sin = emit_const4fv(rp, cnstv); - } - cnst = rp->const_sin; + make_sin_const(rp); src[0] = t_scalar_src(rp, fpi->SrcReg[0]); - emit_arith(rp, PFS_OP_LG2, temp, WRITEMASK_W, - pfs_half, - undef, - undef, - 0); + /* add 0.5*PI and do range reduction */ emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, - swizzle(cnst, Z, Z, Z, Z), //PI + swizzle(rp->const_sin[0], Z, Z, Z, Z), //PI pfs_half, swizzle(keep(src[0]), X, X, X, X), 0); - emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_W, - negate(swizzle(temp, W, W, W, W)), //-2 - swizzle(cnst, Z, Z, Z, Z), //PI + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, swizzle(temp, X, X, X, X), + swizzle(rp->const_sin[1], Z, Z, Z, Z), + pfs_half, 0); - emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Y, - swizzle(cnst, Z, Z, Z, Z), //PI - negate(pfs_half), - swizzle(src[0], X, X, X, X), + emit_arith(rp, PFS_OP_FRC, temp, WRITEMASK_X, + swizzle(temp, X, X, X, X), + undef, + undef, 0); - - emit_arith(rp, PFS_OP_CMP, temp, WRITEMASK_Z, - swizzle(temp, W, W, W, W), + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Z, swizzle(temp, X, X, X, X), - swizzle(temp, Y, Y, Y, Y), + swizzle(rp->const_sin[1], W, W, W, W), //2*PI + negate(swizzle(rp->const_sin[0], Z, Z, Z, Z)), //-PI 0); /* SIN */ emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X | WRITEMASK_Y, swizzle(temp, Z, Z, Z, Z), - cnst, + rp->const_sin[0], pfs_zero, 0); - if(rp->optimization == DRI_CONF_FP_OPTIMIZATION_SPEED){ - emit_arith(rp, PFS_OP_MAD, dest, mask, - swizzle(temp, Y, Y, Y, Y), - absolute(swizzle(temp, Z, Z, Z, Z)), - swizzle(temp, X, X, X, X), - flags); - }else{ - emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, - swizzle(temp, Y, Y, Y, Y), - absolute(swizzle(temp, Z, Z, Z, Z)), - swizzle(temp, X, X, X, X), - 0); + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, + swizzle(temp, Y, Y, Y, Y), + absolute(swizzle(temp, Z, Z, Z, Z)), + swizzle(temp, X, X, X, X), + 0); - emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Y, - swizzle(temp, X, X, X, X), - absolute(swizzle(temp, X, X, X, X)), - negate(swizzle(temp, X, X, X, X)), - 0); + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Y, + swizzle(temp, X, X, X, X), + absolute(swizzle(temp, X, X, X, X)), + negate(swizzle(temp, X, X, X, X)), + 0); - emit_arith(rp, PFS_OP_MAD, dest, mask, - swizzle(temp, Y, Y, Y, Y), - swizzle(cnst, W, W, W, W), - swizzle(temp, X, X, X, X), - flags); - } + emit_arith(rp, PFS_OP_MAD, dest, mask, + swizzle(temp, Y, Y, Y, Y), + swizzle(rp->const_sin[0], W, W, W, W), + swizzle(temp, X, X, X, X), + flags); + free_temp(rp, temp); break; case OPCODE_DP3: @@ -1577,7 +1579,93 @@ static GLboolean parse_program(struct r300_fragment_program *rp) flags); break; case OPCODE_SCS: - ERROR("SCS not implemented\n"); + /* + * cos using a parabola (see SIN): + * cos(x): + * x += PI/2 + * x = (x/(2*PI))+0.5 + * x = frac(x) + * x = (x*2*PI)-PI + * result = sin(x) + */ + temp = get_temp_reg(rp); + make_sin_const(rp); + src[0] = t_scalar_src(rp, fpi->SrcReg[0]); + + /* add 0.5*PI and do range reduction */ + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X|WRITEMASK_Y, + swizzle(rp->const_sin[0], Z, Z, Z, Z), + rp->const_sin[1], + swizzle(keep(src[0]), X, X, X, X), + 0); + + emit_arith(rp, PFS_OP_CMP, temp, WRITEMASK_W, + swizzle(rp->const_sin[0], Z, Z, Z, Z), + negate(pfs_half), + swizzle(keep(src[0]), X, X, X, X), + 0); + + emit_arith(rp, PFS_OP_CMP, temp, WRITEMASK_Z, + swizzle(temp, X, X, X, X), + swizzle(temp, Y, Y, Y, Y), + swizzle(temp, W, W, W, W), + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X | WRITEMASK_Y, + swizzle(temp, Z, Z, Z, Z), + rp->const_sin[0], + pfs_zero, + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_W, + swizzle(temp, Y, Y, Y, Y), + absolute(swizzle(temp, Z, Z, Z, Z)), + swizzle(temp, X, X, X, X), + 0); + + if(mask & WRITEMASK_Y) + { + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X | WRITEMASK_Y, + swizzle(keep(src[0]), X, X, X, X), + rp->const_sin[0], + pfs_zero, + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, + swizzle(temp, Y, Y, Y, Y), + absolute(swizzle(keep(src[0]), X, X, X, X)), + swizzle(temp, X, X, X, X), + 0); + } + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Z, + swizzle(temp, W, W, W, W), + absolute(swizzle(temp, W, W, W, W)), + negate(swizzle(temp, W, W, W, W)), + 0); + + emit_arith(rp, PFS_OP_MAD, dest, WRITEMASK_X, + swizzle(temp, Z, Z, Z, Z), + swizzle(rp->const_sin[0], W, W, W, W), + swizzle(temp, W, W, W, W), + flags); + + if(mask & WRITEMASK_Y) + { + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_W, + swizzle(temp, X, X, X, X), + absolute(swizzle(temp, X, X, X, X)), + negate(swizzle(temp, X, X, X, X)), + 0); + + emit_arith(rp, PFS_OP_MAD, dest, WRITEMASK_Y, + swizzle(temp, W, W, W, W), + swizzle(rp->const_sin[0], W, W, W, W), + swizzle(temp, X, X, X, X), + flags); + } + free_temp(rp, temp); break; case OPCODE_SGE: src[0] = t_src(rp, fpi->SrcReg[0]); @@ -1603,48 +1691,56 @@ static GLboolean parse_program(struct r300_fragment_program *rp) */ temp = get_temp_reg(rp); - if(rp->const_sin == -1){ - cnstv[0] = 1.273239545; - cnstv[1] =-0.405284735; - cnstv[2] = 3.141592654; - cnstv[3] = 0.225; - rp->const_sin = emit_const4fv(rp, cnstv); - } - cnst = rp->const_sin; + make_sin_const(rp); src[0] = t_scalar_src(rp, fpi->SrcReg[0]); - emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X | WRITEMASK_Y, + /* do range reduction */ + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, swizzle(keep(src[0]), X, X, X, X), - cnst, + swizzle(rp->const_sin[1], Z, Z, Z, Z), + pfs_half, + 0); + + emit_arith(rp, PFS_OP_FRC, temp, WRITEMASK_X, + swizzle(temp, X, X, X, X), + undef, + undef, + 0); + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Z, + swizzle(temp, X, X, X, X), + swizzle(rp->const_sin[1], W, W, W, W), //2*PI + negate(swizzle(rp->const_sin[0], Z, Z, Z, Z)), //PI + 0); + + /* SIN */ + + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X | WRITEMASK_Y, + swizzle(temp, Z, Z, Z, Z), + rp->const_sin[0], pfs_zero, 0); - if(rp->optimization == DRI_CONF_FP_OPTIMIZATION_SPEED){ - emit_arith(rp, PFS_OP_MAD, dest, mask, - swizzle(temp, Y, Y, Y, Y), - absolute(swizzle(src[0], X, X, X, X)), - swizzle(temp, X, X, X, X), - flags); - }else{ - emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, - swizzle(temp, Y, Y, Y, Y), - absolute(swizzle(src[0], X, X, X, X)), - swizzle(temp, X, X, X, X), - 0); + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_X, + swizzle(temp, Y, Y, Y, Y), + absolute(swizzle(temp, Z, Z, Z, Z)), + swizzle(temp, X, X, X, X), + 0); - emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Y, - swizzle(temp, X, X, X, X), - absolute(swizzle(temp, X, X, X, X)), - negate(swizzle(temp, X, X, X, X)), - 0); + emit_arith(rp, PFS_OP_MAD, temp, WRITEMASK_Y, + swizzle(temp, X, X, X, X), + absolute(swizzle(temp, X, X, X, X)), + negate(swizzle(temp, X, X, X, X)), + 0); - emit_arith(rp, PFS_OP_MAD, dest, mask, - swizzle(temp, Y, Y, Y, Y), - swizzle(cnst, W, W, W, W), - swizzle(temp, X, X, X, X), - flags); - } + emit_arith(rp, PFS_OP_MAD, dest, mask, + swizzle(temp, Y, Y, Y, Y), + swizzle(rp->const_sin[0], W, W, W, W), + swizzle(temp, X, X, X, X), + flags); + free_temp(rp, temp); break; case OPCODE_SLT: @@ -1739,7 +1835,7 @@ static void init_program(r300ContextPtr r300, struct r300_fragment_program *rp) rp->max_temp_idx = 0; rp->node[0].alu_end = -1; rp->node[0].tex_end = -1; - rp->const_sin = -1; + rp->const_sin[0] = -1; _mesa_memset(cs, 0, sizeof(*rp->cs)); for (i=0;i Date: Fri, 16 Feb 2007 19:46:54 +0100 Subject: nouveau: nv10: fix viewport scale and origin --- src/mesa/drivers/dri/nouveau/nv10_state.c | 45 ++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 12 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index d69c6824ed..e64fcb12f5 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -34,6 +34,29 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "mtypes.h" #include "colormac.h" +static void nv10ViewportScale(nouveauContextPtr nmesa) +{ + GLcontext *ctx = nmesa->glCtx; + GLuint w = ctx->Viewport.Width; + GLuint h = ctx->Viewport.Height; + + GLfloat max_depth = (ctx->Viewport.Near + ctx->Viewport.Far) * 0.5; + switch (ctx->DrawBuffer->_DepthBuffer->DepthBits) { + case 16: + max_depth *= 32767.0; + break; + case 24: + max_depth *= 16777215.0; + break; + } + + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X, 4); + OUT_RING_CACHEf ((((GLfloat) w) * 0.5) - 2048.0); + OUT_RING_CACHEf ((((GLfloat) h) * 0.5) - 2048.0); + OUT_RING_CACHEf (max_depth); + OUT_RING_CACHEf (0.0); +} + static void nv10AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); @@ -167,6 +190,8 @@ static void nv10DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval) BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2); OUT_RING_CACHEf(nearval); OUT_RING_CACHEf(farval); + + nv10ViewportScale(nmesa); } /** Specify the current buffer for writing */ @@ -628,18 +653,7 @@ static void nv10WindowMoved(nouveauContextPtr nmesa) OUT_RING_CACHE(0); } - /* viewport transform */ - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X, 4); - OUT_RING_CACHEf ((GLfloat) x); - OUT_RING_CACHEf ((GLfloat) (y+h)); - OUT_RING_CACHEf (0.0); - OUT_RING_CACHEf (0.0); - - BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X, 4); - OUT_RING_CACHEf ((((GLfloat) w) * 0.5) - 2048.0); - OUT_RING_CACHEf ((((GLfloat) h) * 0.5) - 2048.0); - OUT_RING_CACHEf (16777215.0 * 0.5); - OUT_RING_CACHEf (0.0); + nv10ViewportScale(nmesa); } /* Initialise any card-specific non-GL related state */ @@ -700,6 +714,13 @@ static GLboolean nv10BindBuffers(nouveauContextPtr nmesa, int num_color, OUT_RING_CACHE(color[0]->offset); OUT_RING_CACHE(depth ? depth->offset : color[0]->offset); + /* Always set to bottom left of buffer */ + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X, 4); + OUT_RING_CACHEf (0.0); + OUT_RING_CACHEf ((GLfloat) h); + OUT_RING_CACHEf (0.0); + OUT_RING_CACHEf (0.0); + return GL_TRUE; } -- cgit v1.2.3 From 9131536f00cca586be7dfc1cfbc47188c78e4920 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 16 Feb 2007 19:54:55 +0100 Subject: nouveau: nv10: rescale depth near and far --- src/mesa/drivers/dri/nouveau/nv10_state.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index e64fcb12f5..803dd962b5 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -187,9 +187,15 @@ static void nv10DepthMask(GLcontext *ctx, GLboolean flag) static void nv10DepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + GLfloat depth_scale = 16777216.0; + if (ctx->DrawBuffer->_DepthBuffer->DepthBits == 16) { + depth_scale = 32768.0; + } + BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_DEPTH_RANGE_NEAR, 2); - OUT_RING_CACHEf(nearval); - OUT_RING_CACHEf(farval); + OUT_RING_CACHEf(nearval * depth_scale); + OUT_RING_CACHEf(farval * depth_scale); nv10ViewportScale(nmesa); } -- cgit v1.2.3 From f942dc5522682b70fb05df5b2d5d732bb65e6fe2 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 16 Feb 2007 20:26:57 +0100 Subject: nouveau: nv10: set clear value for 16 and 24 bits depth --- src/mesa/drivers/dri/nouveau/nv10_state.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 803dd962b5..cc0f5a7220 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -121,16 +121,27 @@ static void nv10ClearColor(GLcontext *ctx, const GLfloat color[4]) static void nv10ClearDepth(GLcontext *ctx, GLclampd d) { - /* FIXME: check if 16 or 24/32 bits depth buffer */ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - nmesa->clear_value=((nmesa->clear_value&0x000000FF)|(((uint32_t)(d*0xFFFFFF))<<8)); + + switch (ctx->DrawBuffer->_DepthBuffer->DepthBits) { + case 16: + nmesa->clear_value = (uint32_t)(d*0x7FFF); + break; + case 24: + nmesa->clear_value = ((nmesa->clear_value&0x000000FF) | + (((uint32_t)(d*0xFFFFFF))<<8)); + break; + } } static void nv10ClearStencil(GLcontext *ctx, GLint s) { - /* FIXME: not valid for 16 bits depth buffer (0 stencil bits) */ nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - nmesa->clear_value=((nmesa->clear_value&0xFFFFFF00)|(s&0x000000FF)); + + if (ctx->DrawBuffer->_DepthBuffer->DepthBits == 24) { + nmesa->clear_value = ((nmesa->clear_value&0xFFFFFF00)| + (s&0x000000FF)); + } } static void nv10ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) -- cgit v1.2.3 From 66d8e55184ff8ebfdfef174336dbb5560c45e735 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 16 Feb 2007 22:03:31 +0100 Subject: nouveau: nv20: update --- src/mesa/drivers/dri/nouveau/nv20_state.c | 208 +++++++++++++++++++++++++----- 1 file changed, 176 insertions(+), 32 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv20_state.c b/src/mesa/drivers/dri/nouveau/nv20_state.c index 8e38d6eba0..bcca69daf0 100644 --- a/src/mesa/drivers/dri/nouveau/nv20_state.c +++ b/src/mesa/drivers/dri/nouveau/nv20_state.c @@ -41,8 +41,8 @@ static void nv20AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) CLAMPED_FLOAT_TO_UBYTE(ubRef, ref); BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC, 2); - OUT_RING_CACHE(func); /* NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_FUNC */ - OUT_RING_CACHE(ubRef); /* NV20_TCL_PRIMITIVE_3D_ALPHA_FUNC_REF */ + OUT_RING_CACHE(func); + OUT_RING_CACHE(ubRef); } static void nv20BlendColor(GLcontext *ctx, const GLfloat color[4]) @@ -76,6 +76,11 @@ static void nv20BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, GLenum dfac OUT_RING_CACHE((dfactorA<<16) | dfactorRGB); } +static void nv20Clear(GLcontext *ctx, GLbitfield mask) +{ + /* TODO */ +} + static void nv20ClearColor(GLcontext *ctx, const GLfloat color[4]) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); @@ -297,7 +302,11 @@ static void nv20Enable(GLcontext *ctx, GLenum cap, GLboolean state) // case GL_POST_COLOR_MATRIX_COLOR_TABLE: // case GL_POST_CONVOLUTION_COLOR_TABLE: // case GL_RESCALE_NORMAL: -// case GL_SCISSOR_TEST: + case GL_SCISSOR_TEST: + /* No enable bit, nv20Scissor will adjust to max range */ + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); + break; // case GL_SEPARABLE_2D: case GL_STENCIL_TEST: // TODO BACK and FRONT ? @@ -511,9 +520,22 @@ static void nv20PolygonMode(GLcontext *ctx, GLenum face, GLenum mode) } /** Set the scale and units used to calculate depth values */ -void (*PolygonOffset)(GLcontext *ctx, GLfloat factor, GLfloat units); +static void nv20PolygonOffset(GLcontext *ctx, GLfloat factor, GLfloat units) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR, 2); + OUT_RING_CACHEf(factor); + OUT_RING_CACHEf(units); +} + /** Set the polygon stippling pattern */ -void (*PolygonStipple)(GLcontext *ctx, const GLubyte *mask ); +static void nv20PolygonStipple(GLcontext *ctx, const GLubyte *mask ) +{ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(0), 32); + OUT_RING_CACHEp(mask, 32); +} + /* Specifies the current buffer for reading */ void (*ReadBuffer)( GLcontext *ctx, GLenum buffer ); /** Set rasterization mode */ @@ -522,6 +544,22 @@ void (*RenderMode)(GLcontext *ctx, GLenum mode ); /** Define the scissor box */ static void nv20Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) { + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + /* There's no scissor enable bit, so adjust the scissor to cover the + * maximum draw buffer bounds + */ + if (!ctx->Scissor.Enabled) { + x = y = 0; + w = h = 4095; + } else { + x += nmesa->drawX; + y += nmesa->drawY; + } + + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SCISSOR_X2_X1, 2); + OUT_RING_CACHE(((x+w-1) << 16) | x); + OUT_RING_CACHE(((y+h-1) << 16) | y); } /** Select flat or smooth shading */ @@ -576,22 +614,98 @@ void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname, void (*TexParameter)(GLcontext *ctx, GLenum target, struct gl_texture_object *texObj, GLenum pname, const GLfloat *params); -void (*TextureMatrix)(GLcontext *ctx, GLuint unit, const GLmatrix *mat); -/** Set the viewport */ -static void nv20Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +static void nv20TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) { - /* TODO: Where do the VIEWPORT_XFRM_* regs come in? */ - nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2); - OUT_RING_CACHE((w << 16) | x); - OUT_RING_CACHE((h << 16) | y); + /* TODO */ +} + +/* Update anything that depends on the window position/size */ +static void nv20WindowMoved(nouveauContextPtr nmesa) +{ + GLcontext *ctx = nmesa->glCtx; + GLfloat *v = nmesa->viewport.m; + GLuint w = ctx->Viewport.Width; + GLuint h = ctx->Viewport.Height; + GLuint x = ctx->Viewport.X + nmesa->drawX; + GLuint y = ctx->Viewport.Y + nmesa->drawY; + int i; + + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 2); + OUT_RING_CACHE((w << 16) | x); + OUT_RING_CACHE((h << 16) | y); + + BEGIN_RING_SIZE(NvSub3D, 0x02b4, 1); + OUT_RING(0); + + BEGIN_RING_CACHE(NvSub3D, + NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 2); + OUT_RING_CACHE((4095 << 16) | 0); + OUT_RING_CACHE((4095 << 16) | 0); + for (i=1; i<8; i++) { + BEGIN_RING_CACHE(NvSub3D, + NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 1); + OUT_RING_CACHE(0); + BEGIN_RING_CACHE(NvSub3D, + NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(i), 1); + OUT_RING_CACHE(0); + } + + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); + + /* TODO: recalc viewport scale coefs */ } /* Initialise any card-specific non-GL related state */ static GLboolean nv20InitCard(nouveauContextPtr nmesa) { - return GL_TRUE; + nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); + + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SET_OBJECT1, 2); + OUT_RING(NvDmaFB); /* 184 dma_object1 */ + OUT_RING(NvDmaFB); /* 188 dma_object2 */ + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SET_OBJECT3, 2); + OUT_RING(NvDmaFB); /* 194 dma_object3 */ + OUT_RING(NvDmaFB); /* 198 dma_object4 */ + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SET_OBJECT8, 1); + OUT_RING(NvDmaFB); /* 1a8 dma_object8 */ + + BEGIN_RING_SIZE(NvSub3D, 0x17e0, 3); + OUT_RINGf(0.0); + OUT_RINGf(0.0); + OUT_RINGf(1.0); + + BEGIN_RING_SIZE(NvSub3D, 0x1e6c, 1); + OUT_RING(0x0db6); + BEGIN_RING_SIZE(NvSub3D, 0x0290, 1); + OUT_RING(0x00100001); + BEGIN_RING_SIZE(NvSub3D, 0x09fc, 1); + OUT_RING(0); + BEGIN_RING_SIZE(NvSub3D, 0x1d80, 1); + OUT_RING(1); + BEGIN_RING_SIZE(NvSub3D, 0x09f8, 1); + OUT_RING(4); + + BEGIN_RING_SIZE(NvSub3D, 0x17ec, 3); + OUT_RINGf(0.0); + OUT_RINGf(1.0); + OUT_RINGf(0.0); + + BEGIN_RING_SIZE(NvSub3D, 0x1d88, 1); + OUT_RING(3); + + /* FIXME: More dma objects to setup ? */ + + BEGIN_RING_SIZE(NvSub3D, 0x1e98, 1); + OUT_RING(0); + + BEGIN_RING_SIZE(NvSub3D, 0x120, 3); + OUT_RING(0); + OUT_RING(1); + OUT_RING(2); + + return GL_TRUE; } /* Update buffer offset/pitch/format */ @@ -599,26 +713,57 @@ static GLboolean nv20BindBuffers(nouveauContextPtr nmesa, int num_color, nouveau_renderbuffer **color, nouveau_renderbuffer *depth) { - return GL_TRUE; -} + GLuint x, y, w, h; + GLuint pitch, format, depth_pitch; + + w = color[0]->mesa.Width; + h = color[0]->mesa.Height; + x = nmesa->drawX; + y = nmesa->drawY; + + if (num_color != 1) + return GL_FALSE; + + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VIEWPORT_HORIZ, 6); + OUT_RING_CACHE((w << 16) | x); + OUT_RING_CACHE((h << 16) | y); + depth_pitch = (depth ? depth->pitch : color[0]->pitch); + pitch = (depth_pitch<<16) | color[0]->pitch; + format = 0x128; + if (color[0]->mesa._ActualFormat != GL_RGBA8) { + format = 0x123; /* R5G6B5 color buffer */ + } + OUT_RING_CACHE(format); + OUT_RING_CACHE(pitch); + OUT_RING_CACHE(color[0]->offset); + OUT_RING_CACHE(depth ? depth->offset : color[0]->offset); + + if (depth) { + BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_LMA_DEPTH_BUFFER_PITCH, 2); + /* TODO: use a different buffer */ + OUT_RING(depth->pitch); + OUT_RING(depth->offset); + } -/* Update anything that depends on the window position/size */ -static void nv20WindowMoved(nouveauContextPtr nmesa) -{ + /* Always set to bottom left of buffer */ + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VIEWPORT_ORIGIN_X, 4); + OUT_RING_CACHEf (0.0); + OUT_RING_CACHEf ((GLfloat) h); + OUT_RING_CACHEf (0.0); + OUT_RING_CACHEf (0.0); + + return GL_TRUE; } void nv20InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - nmesa->hw_func.InitCard = nv20InitCard; - nmesa->hw_func.BindBuffers = nv20BindBuffers; - nmesa->hw_func.WindowMoved = nv20WindowMoved; - func->AlphaFunc = nv20AlphaFunc; func->BlendColor = nv20BlendColor; func->BlendEquationSeparate = nv20BlendEquationSeparate; func->BlendFuncSeparate = nv20BlendFuncSeparate; + func->Clear = nv20Clear; func->ClearColor = nv20ClearColor; func->ClearDepth = nv20ClearDepth; func->ClearStencil = nv20ClearStencil; @@ -641,22 +786,21 @@ void nv20InitStateFuncs(GLcontext *ctx, struct dd_function_table *func) func->PointParameterfv = nv20PointParameterfv; func->PointSize = nv20PointSize; func->PolygonMode = nv20PolygonMode; -#if 0 func->PolygonOffset = nv20PolygonOffset; func->PolygonStipple = nv20PolygonStipple; - func->ReadBuffer = nv20ReadBuffer; - func->RenderMode = nv20RenderMode; -#endif +/* func->ReadBuffer = nv20ReadBuffer;*/ +/* func->RenderMode = nv20RenderMode;*/ func->Scissor = nv20Scissor; func->ShadeModel = nv20ShadeModel; func->StencilFuncSeparate = nv20StencilFuncSeparate; func->StencilMaskSeparate = nv20StencilMaskSeparate; func->StencilOpSeparate = nv20StencilOpSeparate; -#if 0 - func->TexGen = nv20TexGen; - func->TexParameter = nv20TexParameter; +/* func->TexGen = nv20TexGen;*/ +/* func->TexParameter = nv20TexParameter;*/ func->TextureMatrix = nv20TextureMatrix; -#endif - func->Viewport = nv20Viewport; + + nmesa->hw_func.InitCard = nv20InitCard; + nmesa->hw_func.BindBuffers = nv20BindBuffers; + nmesa->hw_func.WindowMoved = nv20WindowMoved; } -- cgit v1.2.3 From 0fccb646e0c83f6bb4c8b453cc2e915e8cee21f1 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 16 Feb 2007 22:09:42 +0100 Subject: nouveau: nv20: texture matrix --- src/mesa/drivers/dri/nouveau/nv20_state.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv20_state.c b/src/mesa/drivers/dri/nouveau/nv20_state.c index bcca69daf0..417590d729 100644 --- a/src/mesa/drivers/dri/nouveau/nv20_state.c +++ b/src/mesa/drivers/dri/nouveau/nv20_state.c @@ -617,7 +617,10 @@ void (*TexParameter)(GLcontext *ctx, GLenum target, static void nv20TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) { - /* TODO */ + nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_TX_MATRIX(unit, 0), 16); + /*XXX: This SHOULD work.*/ + OUT_RING_CACHEp(mat->m, 16); } /* Update anything that depends on the window position/size */ -- cgit v1.2.3 From 4cc4a753fa3c41e5ef1890a9a03c97d3c39b6535 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 16 Feb 2007 22:39:12 +0100 Subject: nouveau: nv10,20: wrong viewport clip setup --- src/mesa/drivers/dri/nouveau/nv10_state.c | 4 +++- src/mesa/drivers/dri/nouveau/nv20_state.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index cc0f5a7220..e0475bb3da 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -658,8 +658,10 @@ static void nv10WindowMoved(nouveauContextPtr nmesa) OUT_RING(0); BEGIN_RING_CACHE(NvSub3D, - NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 2); + NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 1); OUT_RING_CACHE(((w+x-1) << 16) | x | 0x08000800); + BEGIN_RING_CACHE(NvSub3D, + NV10_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(0), 1); OUT_RING_CACHE(((h+y-1) << 16) | y | 0x08000800); for (i=1; i<8; i++) { BEGIN_RING_CACHE(NvSub3D, diff --git a/src/mesa/drivers/dri/nouveau/nv20_state.c b/src/mesa/drivers/dri/nouveau/nv20_state.c index 417590d729..030713c0db 100644 --- a/src/mesa/drivers/dri/nouveau/nv20_state.c +++ b/src/mesa/drivers/dri/nouveau/nv20_state.c @@ -642,8 +642,10 @@ static void nv20WindowMoved(nouveauContextPtr nmesa) OUT_RING(0); BEGIN_RING_CACHE(NvSub3D, - NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 2); + NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 1); OUT_RING_CACHE((4095 << 16) | 0); + BEGIN_RING_CACHE(NvSub3D, + NV20_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_VERT(0), 1); OUT_RING_CACHE((4095 << 16) | 0); for (i=1; i<8; i++) { BEGIN_RING_CACHE(NvSub3D, -- cgit v1.2.3 From 21f2f7f26b5b9ab9f219f2bd22c68bcaa8cbdfe3 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 16 Feb 2007 22:39:28 +0100 Subject: nouveau: nv50: update --- src/mesa/drivers/dri/nouveau/nv50_state.c | 76 ++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv50_state.c b/src/mesa/drivers/dri/nouveau/nv50_state.c index d03c6bf6f2..818e268615 100644 --- a/src/mesa/drivers/dri/nouveau/nv50_state.c +++ b/src/mesa/drivers/dri/nouveau/nv50_state.c @@ -293,7 +293,11 @@ static void nv50Enable(GLcontext *ctx, GLenum cap, GLboolean state) // case GL_POST_COLOR_MATRIX_COLOR_TABLE: // case GL_POST_CONVOLUTION_COLOR_TABLE: // case GL_RESCALE_NORMAL: -// case GL_SCISSOR_TEST: + case GL_SCISSOR_TEST: + /* No enable bit, nv50Scissor will adjust to max range */ + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); + break; // case GL_SEPARABLE_2D: case GL_STENCIL_TEST: // TODO BACK and FRONT ? @@ -416,6 +420,21 @@ void (*RenderMode)(GLcontext *ctx, GLenum mode ); static void nv50Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); + + /* There's no scissor enable bit, so adjust the scissor to cover the + * maximum draw buffer bounds + */ + if (!ctx->Scissor.Enabled) { + x = y = 0; + w = h = 8191; + } else { + x += nmesa->drawX; + y += nmesa->drawY; + } + + BEGIN_RING_CACHE(NvSub3D, NV50_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS, 2); + OUT_RING_CACHE(((w) << 16) | x); + OUT_RING_CACHE(((h) << 16) | y); } /** Select flat or smooth shading */ @@ -503,10 +522,65 @@ static void nv50TextureMatrix(GLcontext *ctx, GLuint unit, const GLmatrix *mat) static void nv50WindowMoved(nouveauContextPtr nmesa) { + GLcontext *ctx = nmesa->glCtx; + GLfloat *v = nmesa->viewport.m; + GLuint w = ctx->Viewport.Width; + GLuint h = ctx->Viewport.Height; + GLuint x = ctx->Viewport.X + nmesa->drawX; + GLuint y = ctx->Viewport.Y + nmesa->drawY; + int i; + + BEGIN_RING_CACHE(NvSub3D, + NV50_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(0), 2); + OUT_RING_CACHE((8191 << 16) | 0); + OUT_RING_CACHE((8191 << 16) | 0); + for (i=1; i<8; i++) { + BEGIN_RING_CACHE(NvSub3D, + NV50_TCL_PRIMITIVE_3D_VIEWPORT_CLIP_HORIZ(i), 2); + OUT_RING_CACHE(0); + OUT_RING_CACHE(0); + } + + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); } static GLboolean nv50InitCard(nouveauContextPtr nmesa) { + int i,j; + + nouveauObjectOnSubchannel(nmesa, NvSub3D, Nv3D); + + BEGIN_RING_SIZE(NvSub3D, 0x1558, 1); + OUT_RING(1); + + BEGIN_RING_SIZE(NvSub3D, NV50_TCL_PRIMITIVE_3D_SET_OBJECT_1(0), 8); + for (i=0; i<8; i++) { + OUT_RING(NvDmaFB); + } + + BEGIN_RING_SIZE(NvSub3D, NV50_TCL_PRIMITIVE_3D_SET_OBJECT_0(0), 12); + for (i=0; i<12; i++) { + OUT_RING(NvDmaFB); + } + + BEGIN_RING_SIZE(NvSub3D, 0x121c, 1); + OUT_RING(1); + + for (i=0; i<8; i++) { + BEGIN_RING_SIZE(NvSub3D, 0x0200 + (i*0x20), 5); + for (j=0; j<5; j++) { + OUT_RING(0); + } + } + + BEGIN_RING_SIZE(NvSub3D, 0x0fe0, 5); + OUT_RING(0); + OUT_RING(0); + OUT_RING(0x16); + OUT_RING(0); + OUT_RING(0); + return GL_FALSE; } -- cgit v1.2.3 From d2b06403c6f06ee37f46c2a504983884382c8abc Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 19 Feb 2007 19:57:30 +0100 Subject: i915tex: Fix performance regression with new vbo code and latest drm. With current memory preferences, vbos ended up in AGP space where reading from them got a bit slow. Make sure buffer objects are initially created in system memory. --- src/mesa/drivers/dri/i915tex/intel_buffer_objects.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c index 31c41d8685..ba3c7f0c1f 100644 --- a/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c +++ b/src/mesa/drivers/dri/i915tex/intel_buffer_objects.c @@ -50,7 +50,10 @@ intel_bufferobj_alloc(GLcontext * ctx, GLuint name, GLenum target) _mesa_initialize_buffer_object(&obj->Base, name, target); driGenBuffers(intel->intelScreen->regionPool, - "bufferobj", 1, &obj->buffer, 64, 0, 0); + "bufferobj", 1, &obj->buffer, 64, + DRM_BO_FLAG_MEM_LOCAL | + DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, + 0); return &obj->Base; } -- cgit v1.2.3 From d44027dbbd8837b2a32466b0617283649e770907 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 20 Feb 2007 12:48:50 -0500 Subject: Fix parallel make in r300 driver. --- src/mesa/drivers/dri/r300/Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile index 5abb91d987..2ee2328934 100644 --- a/src/mesa/drivers/dri/r300/Makefile +++ b/src/mesa/drivers/dri/r300/Makefile @@ -90,9 +90,11 @@ COMMON_SYMLINKS = \ include ../Makefile.template -$(SYMLINKS): +server: mkdir -p server - for i in $(SYMLINKS) ; do rm -f $$i && test -f ../radeon/$$i && ln -s ../../radeon/$$i $$i ; done + +$(SYMLINKS): server + @[ -e $@ ] || ln -sf ../../radeon/$@ server/ $(COMMON_SYMLINKS): @[ -e $@ ] || ln -sf ../radeon/$@ ./ -- cgit v1.2.3 From 102ad2e066b7a6fcd893db58c64ca685e49a3dfd Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 20 Feb 2007 23:04:21 +0100 Subject: nouveau: nv10: keep 24/8 depth/stencil value, don't check for depth bits --- src/mesa/drivers/dri/nouveau/nv10_state.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index e0475bb3da..09fc07556d 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -123,25 +123,25 @@ static void nv10ClearDepth(GLcontext *ctx, GLclampd d) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - switch (ctx->DrawBuffer->_DepthBuffer->DepthBits) { +/* switch (ctx->DrawBuffer->_DepthBuffer->DepthBits) { case 16: nmesa->clear_value = (uint32_t)(d*0x7FFF); break; - case 24: + case 24:*/ nmesa->clear_value = ((nmesa->clear_value&0x000000FF) | (((uint32_t)(d*0xFFFFFF))<<8)); - break; - } +/* break; + }*/ } static void nv10ClearStencil(GLcontext *ctx, GLint s) { nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); - if (ctx->DrawBuffer->_DepthBuffer->DepthBits == 24) { +/* if (ctx->DrawBuffer->_DepthBuffer->DepthBits == 24) {*/ nmesa->clear_value = ((nmesa->clear_value&0xFFFFFF00)| (s&0x000000FF)); - } +/* }*/ } static void nv10ClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation) -- cgit v1.2.3 From 79870d100f90555b520af342cf59496236ff8f20 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 20 Feb 2007 23:13:48 +0100 Subject: nouveau: nv10: also check ctx->DrawBuffer in nv10ViewportScale --- src/mesa/drivers/dri/nouveau/nv10_state.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index 09fc07556d..e204eba6ba 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -41,13 +41,18 @@ static void nv10ViewportScale(nouveauContextPtr nmesa) GLuint h = ctx->Viewport.Height; GLfloat max_depth = (ctx->Viewport.Near + ctx->Viewport.Far) * 0.5; - switch (ctx->DrawBuffer->_DepthBuffer->DepthBits) { - case 16: - max_depth *= 32767.0; - break; - case 24: - max_depth *= 16777215.0; - break; + if (ctx->DrawBuffer) { + switch (ctx->DrawBuffer->_DepthBuffer->DepthBits) { + case 16: + max_depth *= 32767.0; + break; + case 24: + max_depth *= 16777215.0; + break; + } + } else { + /* Default to 24 bits range */ + max_depth *= 16777215.0; } BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X, 4); -- cgit v1.2.3 From 440759c2cdfdd9a7fbc6500fca2afa519126c1a7 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 20 Feb 2007 23:17:09 +0100 Subject: nouveau: nv10: grr, ctx->DrawBuffer invalid? --- src/mesa/drivers/dri/nouveau/nv10_state.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/nouveau/nv10_state.c b/src/mesa/drivers/dri/nouveau/nv10_state.c index e204eba6ba..5f304ccab9 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state.c @@ -41,7 +41,7 @@ static void nv10ViewportScale(nouveauContextPtr nmesa) GLuint h = ctx->Viewport.Height; GLfloat max_depth = (ctx->Viewport.Near + ctx->Viewport.Far) * 0.5; - if (ctx->DrawBuffer) { +/* if (ctx->DrawBuffer) { switch (ctx->DrawBuffer->_DepthBuffer->DepthBits) { case 16: max_depth *= 32767.0; @@ -50,10 +50,10 @@ static void nv10ViewportScale(nouveauContextPtr nmesa) max_depth *= 16777215.0; break; } - } else { + } else {*/ /* Default to 24 bits range */ max_depth *= 16777215.0; - } +/* }*/ BEGIN_RING_CACHE(NvSub3D, NV10_TCL_PRIMITIVE_3D_VIEWPORT_SCALE_X, 4); OUT_RING_CACHEf ((((GLfloat) w) * 0.5) - 2048.0); -- cgit v1.2.3