diff options
author | marha <marha@users.sourceforge.net> | 2011-09-12 08:58:44 +0200 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2011-09-12 08:58:44 +0200 |
commit | 24a692ce832161d3b794110dd82b1508d38a0887 (patch) | |
tree | 388d2fd8dc707763d6ffea7edfa2a6a1410c7c5e /mesalib/src/mesa | |
parent | f9cf11136d65f20aab4fb6d5fc3ec3c59185a0b4 (diff) | |
download | vcxsrv-24a692ce832161d3b794110dd82b1508d38a0887.tar.gz vcxsrv-24a692ce832161d3b794110dd82b1508d38a0887.tar.bz2 vcxsrv-24a692ce832161d3b794110dd82b1508d38a0887.zip |
git update 12 sep 2011
Diffstat (limited to 'mesalib/src/mesa')
-rw-r--r-- | mesalib/src/mesa/drivers/dri/common/depthtmp.h | 548 | ||||
-rw-r--r-- | mesalib/src/mesa/drivers/dri/common/dri_util.c | 12 | ||||
-rw-r--r-- | mesalib/src/mesa/drivers/dri/common/spantmp2.h | 20 | ||||
-rw-r--r-- | mesalib/src/mesa/drivers/dri/common/utils.c | 1532 | ||||
-rw-r--r-- | mesalib/src/mesa/drivers/dri/common/utils.h | 221 | ||||
-rw-r--r-- | mesalib/src/mesa/drivers/dri/swrast/swrast.c | 19 | ||||
-rw-r--r-- | mesalib/src/mesa/main/extensions.c | 8 | ||||
-rw-r--r-- | mesalib/src/mesa/main/nvprogram.c | 2 | ||||
-rw-r--r-- | mesalib/src/mesa/main/nvprogram.h | 238 | ||||
-rw-r--r-- | mesalib/src/mesa/main/teximage.h | 571 | ||||
-rw-r--r-- | mesalib/src/mesa/program/ir_to_mesa.cpp | 17 | ||||
-rw-r--r-- | mesalib/src/mesa/program/nvvertparse.c | 2918 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_extensions.c | 11 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 33 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c | 2 | ||||
-rw-r--r-- | mesalib/src/mesa/swrast/s_spantemp.h | 449 |
16 files changed, 3274 insertions, 3327 deletions
diff --git a/mesalib/src/mesa/drivers/dri/common/depthtmp.h b/mesalib/src/mesa/drivers/dri/common/depthtmp.h index 8e751d7b2..c6e2bb75c 100644 --- a/mesalib/src/mesa/drivers/dri/common/depthtmp.h +++ b/mesalib/src/mesa/drivers/dri/common/depthtmp.h @@ -1,270 +1,278 @@ -
-/*
- * Notes:
- * 1. These functions plug into the gl_renderbuffer structure.
- * 2. The 'values' parameter always points to GLuint values, regardless of
- * the actual Z buffer depth.
- */
-
-
-#include "spantmp_common.h"
-
-#ifndef DBG
-#define DBG 0
-#endif
-
-#ifndef HAVE_HW_DEPTH_SPANS
-#define HAVE_HW_DEPTH_SPANS 0
-#endif
-
-#ifndef HAVE_HW_DEPTH_PIXELS
-#define HAVE_HW_DEPTH_PIXELS 0
-#endif
-
-static void TAG(WriteDepthSpan)( struct gl_context *ctx,
- struct gl_renderbuffer *rb,
- GLuint n, GLint x, GLint y,
- const void *values,
- const GLubyte mask[] )
-{
- HW_WRITE_LOCK()
- {
- const VALUE_TYPE *depth = (const VALUE_TYPE *) values;
- GLint x1;
- GLint n1;
- LOCAL_DEPTH_VARS;
-
- y = Y_FLIP( y );
-
-#if HAVE_HW_DEPTH_SPANS
- (void) x1; (void) n1;
-
- if ( DBG ) fprintf( stderr, "WriteDepthSpan 0..%d (x1 %d)\n",
- (int)n, (int)x );
-
- WRITE_DEPTH_SPAN();
-#else
- HW_CLIPLOOP()
- {
- GLint i = 0;
- CLIPSPAN( x, y, n, x1, n1, i );
-
- if ( DBG ) fprintf( stderr, "WriteDepthSpan %d..%d (x1 %d) (mask %p)\n",
- (int)i, (int)n1, (int)x1, mask );
-
- if ( mask ) {
- for ( ; n1>0 ; i++, x1++, n1-- ) {
- if ( mask[i] ) WRITE_DEPTH( x1, y, depth[i] );
- }
- } else {
- for ( ; n1>0 ; i++, x1++, n1-- ) {
- WRITE_DEPTH( x1, y, depth[i] );
- }
- }
- }
- HW_ENDCLIPLOOP();
-#endif
- }
- HW_WRITE_UNLOCK();
-}
-
-
-#if HAVE_HW_DEPTH_SPANS
-/* implement MonoWriteDepthSpan() in terms of WriteDepthSpan() */
-static void
-TAG(WriteMonoDepthSpan)( struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLuint n, GLint x, GLint y,
- const void *value, const GLubyte mask[] )
-{
- const GLuint depthVal = *((GLuint *) value);
- GLuint depths[MAX_WIDTH];
- GLuint i;
- for (i = 0; i < n; i++)
- depths[i] = depthVal;
- TAG(WriteDepthSpan)(ctx, rb, n, x, y, depths, mask);
-}
-#else
-static void TAG(WriteMonoDepthSpan)( struct gl_context *ctx,
- struct gl_renderbuffer *rb,
- GLuint n, GLint x, GLint y,
- const void *value,
- const GLubyte mask[] )
-{
- HW_WRITE_LOCK()
- {
- const GLuint depth = *((GLuint *) value);
- GLint x1;
- GLint n1;
- LOCAL_DEPTH_VARS;
-
- y = Y_FLIP( y );
-
- HW_CLIPLOOP()
- {
- GLint i = 0;
- CLIPSPAN( x, y, n, x1, n1, i );
-
- if ( DBG ) fprintf( stderr, "%s %d..%d (x1 %d) = %u\n",
- __FUNCTION__, (int)i, (int)n1, (int)x1, (GLuint)depth );
-
- if ( mask ) {
- for ( ; n1>0 ; i++, x1++, n1-- ) {
- if ( mask[i] ) WRITE_DEPTH( x1, y, depth );
- }
- } else {
- for ( ; n1>0 ; x1++, n1-- ) {
- WRITE_DEPTH( x1, y, depth );
- }
- }
- }
- HW_ENDCLIPLOOP();
- }
- HW_WRITE_UNLOCK();
-}
-#endif
-
-
-static void TAG(WriteDepthPixels)( struct gl_context *ctx,
- struct gl_renderbuffer *rb,
- GLuint n,
- const GLint x[],
- const GLint y[],
- const void *values,
- const GLubyte mask[] )
-{
- HW_WRITE_LOCK()
- {
- const VALUE_TYPE *depth = (const VALUE_TYPE *) values;
- GLuint i;
- LOCAL_DEPTH_VARS;
-
- if ( DBG ) fprintf( stderr, "WriteDepthPixels\n" );
-
-#if HAVE_HW_DEPTH_PIXELS
- (void) i;
-
- WRITE_DEPTH_PIXELS();
-#else
- HW_CLIPLOOP()
- {
- if ( mask ) {
- for ( i = 0 ; i < n ; i++ ) {
- if ( mask[i] ) {
- const int fy = Y_FLIP( y[i] );
- if ( CLIPPIXEL( x[i], fy ) )
- WRITE_DEPTH( x[i], fy, depth[i] );
- }
- }
- }
- else {
- for ( i = 0 ; i < n ; i++ ) {
- const int fy = Y_FLIP( y[i] );
- if ( CLIPPIXEL( x[i], fy ) )
- WRITE_DEPTH( x[i], fy, depth[i] );
- }
- }
- }
- HW_ENDCLIPLOOP();
-#endif
- }
- HW_WRITE_UNLOCK();
-}
-
-
-/* Read depth spans and pixels
- */
-static void TAG(ReadDepthSpan)( struct gl_context *ctx,
- struct gl_renderbuffer *rb,
- GLuint n, GLint x, GLint y,
- void *values )
-{
- HW_READ_LOCK()
- {
- VALUE_TYPE *depth = (VALUE_TYPE *) values;
- GLint x1, n1;
- LOCAL_DEPTH_VARS;
-
- y = Y_FLIP( y );
-
- if ( DBG ) fprintf( stderr, "ReadDepthSpan\n" );
-
-#if HAVE_HW_DEPTH_SPANS
- (void) x1; (void) n1;
-
- READ_DEPTH_SPAN();
-#else
- HW_CLIPLOOP()
- {
- GLint i = 0;
- CLIPSPAN( x, y, n, x1, n1, i );
- for ( ; n1>0 ; i++, n1-- ) {
- READ_DEPTH( depth[i], x+i, y );
- }
- }
- HW_ENDCLIPLOOP();
-#endif
- }
- HW_READ_UNLOCK();
-}
-
-static void TAG(ReadDepthPixels)( struct gl_context *ctx,
- struct gl_renderbuffer *rb,
- GLuint n,
- const GLint x[], const GLint y[],
- void *values )
-{
- HW_READ_LOCK()
- {
- VALUE_TYPE *depth = (VALUE_TYPE *) values;
- GLuint i;
- LOCAL_DEPTH_VARS;
-
- if ( DBG ) fprintf( stderr, "ReadDepthPixels\n" );
-
-#if HAVE_HW_DEPTH_PIXELS
- (void) i;
-
- READ_DEPTH_PIXELS();
-#else
- HW_CLIPLOOP()
- {
- for ( i = 0 ; i < n ;i++ ) {
- int fy = Y_FLIP( y[i] );
- if ( CLIPPIXEL( x[i], fy ) )
- READ_DEPTH( depth[i], x[i], fy );
- }
- }
- HW_ENDCLIPLOOP();
-#endif
- }
- HW_READ_UNLOCK();
-}
-
-
-/**
- * Initialize the given renderbuffer's span routines to point to
- * the depth/z functions we generated above.
- */
-static void TAG(InitDepthPointers)(struct gl_renderbuffer *rb)
-{
- rb->GetRow = TAG(ReadDepthSpan);
- rb->GetValues = TAG(ReadDepthPixels);
- rb->PutRow = TAG(WriteDepthSpan);
- rb->PutRowRGB = NULL;
- rb->PutMonoRow = TAG(WriteMonoDepthSpan);
- rb->PutValues = TAG(WriteDepthPixels);
- rb->PutMonoValues = NULL;
-}
-
-
-#if HAVE_HW_DEPTH_SPANS
-#undef WRITE_DEPTH_SPAN
-#undef WRITE_DEPTH_PIXELS
-#undef READ_DEPTH_SPAN
-#undef READ_DEPTH_PIXELS
-#else
-#undef WRITE_DEPTH
-#undef READ_DEPTH
-#endif
-#undef TAG
-#undef VALUE_TYPE
+ +/* + * Notes: + * 1. These functions plug into the gl_renderbuffer structure. + * 2. The 'values' parameter always points to GLuint values, regardless of + * the actual Z buffer depth. + */ + + +#include "spantmp_common.h" + +#ifndef DBG +#define DBG 0 +#endif + +#ifndef HAVE_HW_DEPTH_SPANS +#define HAVE_HW_DEPTH_SPANS 0 +#endif + +#ifndef HAVE_HW_DEPTH_PIXELS +#define HAVE_HW_DEPTH_PIXELS 0 +#endif + +static void TAG(WriteDepthSpan)( struct gl_context *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const void *values, + const GLubyte mask[] ) +{ + HW_WRITE_LOCK() + { + const VALUE_TYPE *depth = (const VALUE_TYPE *) values; + GLint x1; + GLint n1; + LOCAL_DEPTH_VARS; + + y = Y_FLIP( y ); + +#if HAVE_HW_DEPTH_SPANS + (void) x1; (void) n1; + + if ( DBG ) fprintf( stderr, "WriteDepthSpan 0..%d (x1 %d)\n", + (int)n, (int)x ); + + WRITE_DEPTH_SPAN(); +#else + HW_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN( x, y, n, x1, n1, i ); + + if ( DBG ) fprintf( stderr, "WriteDepthSpan %d..%d (x1 %d) (mask %p)\n", + (int)i, (int)n1, (int)x1, mask ); + + if ( mask ) { + for ( ; n1>0 ; i++, x1++, n1-- ) { + if ( mask[i] ) WRITE_DEPTH( x1, y, depth[i] ); + } + } else { + for ( ; n1>0 ; i++, x1++, n1-- ) { + WRITE_DEPTH( x1, y, depth[i] ); + } + } + } + HW_ENDCLIPLOOP(); +#endif + } + HW_WRITE_UNLOCK(); + + (void) ctx; +} + + +#if HAVE_HW_DEPTH_SPANS +/* implement MonoWriteDepthSpan() in terms of WriteDepthSpan() */ +static void +TAG(WriteMonoDepthSpan)( struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const void *value, const GLubyte mask[] ) +{ + const GLuint depthVal = *((GLuint *) value); + GLuint depths[MAX_WIDTH]; + GLuint i; + for (i = 0; i < n; i++) + depths[i] = depthVal; + TAG(WriteDepthSpan)(ctx, rb, n, x, y, depths, mask); +} +#else +static void TAG(WriteMonoDepthSpan)( struct gl_context *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const void *value, + const GLubyte mask[] ) +{ + HW_WRITE_LOCK() + { + const GLuint depth = *((GLuint *) value); + GLint x1; + GLint n1; + LOCAL_DEPTH_VARS; + + y = Y_FLIP( y ); + + HW_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN( x, y, n, x1, n1, i ); + + if ( DBG ) fprintf( stderr, "%s %d..%d (x1 %d) = %u\n", + __FUNCTION__, (int)i, (int)n1, (int)x1, (GLuint)depth ); + + if ( mask ) { + for ( ; n1>0 ; i++, x1++, n1-- ) { + if ( mask[i] ) WRITE_DEPTH( x1, y, depth ); + } + } else { + for ( ; n1>0 ; x1++, n1-- ) { + WRITE_DEPTH( x1, y, depth ); + } + } + } + HW_ENDCLIPLOOP(); + } + HW_WRITE_UNLOCK(); + + (void) ctx; +} +#endif + + +static void TAG(WriteDepthPixels)( struct gl_context *ctx, + struct gl_renderbuffer *rb, + GLuint n, + const GLint x[], + const GLint y[], + const void *values, + const GLubyte mask[] ) +{ + HW_WRITE_LOCK() + { + const VALUE_TYPE *depth = (const VALUE_TYPE *) values; + GLuint i; + LOCAL_DEPTH_VARS; + + if ( DBG ) fprintf( stderr, "WriteDepthPixels\n" ); + +#if HAVE_HW_DEPTH_PIXELS + (void) i; + + WRITE_DEPTH_PIXELS(); +#else + HW_CLIPLOOP() + { + if ( mask ) { + for ( i = 0 ; i < n ; i++ ) { + if ( mask[i] ) { + const int fy = Y_FLIP( y[i] ); + if ( CLIPPIXEL( x[i], fy ) ) + WRITE_DEPTH( x[i], fy, depth[i] ); + } + } + } + else { + for ( i = 0 ; i < n ; i++ ) { + const int fy = Y_FLIP( y[i] ); + if ( CLIPPIXEL( x[i], fy ) ) + WRITE_DEPTH( x[i], fy, depth[i] ); + } + } + } + HW_ENDCLIPLOOP(); +#endif + } + HW_WRITE_UNLOCK(); + + (void) ctx; +} + + +/* Read depth spans and pixels + */ +static void TAG(ReadDepthSpan)( struct gl_context *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + void *values ) +{ + HW_READ_LOCK() + { + VALUE_TYPE *depth = (VALUE_TYPE *) values; + GLint x1, n1; + LOCAL_DEPTH_VARS; + + y = Y_FLIP( y ); + + if ( DBG ) fprintf( stderr, "ReadDepthSpan\n" ); + +#if HAVE_HW_DEPTH_SPANS + (void) x1; (void) n1; + + READ_DEPTH_SPAN(); +#else + HW_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN( x, y, n, x1, n1, i ); + for ( ; n1>0 ; i++, n1-- ) { + READ_DEPTH( depth[i], x+i, y ); + } + } + HW_ENDCLIPLOOP(); +#endif + } + HW_READ_UNLOCK(); +} + +static void TAG(ReadDepthPixels)( struct gl_context *ctx, + struct gl_renderbuffer *rb, + GLuint n, + const GLint x[], const GLint y[], + void *values ) +{ + HW_READ_LOCK() + { + VALUE_TYPE *depth = (VALUE_TYPE *) values; + GLuint i; + LOCAL_DEPTH_VARS; + + if ( DBG ) fprintf( stderr, "ReadDepthPixels\n" ); + +#if HAVE_HW_DEPTH_PIXELS + (void) i; + + READ_DEPTH_PIXELS(); +#else + HW_CLIPLOOP() + { + for ( i = 0 ; i < n ;i++ ) { + int fy = Y_FLIP( y[i] ); + if ( CLIPPIXEL( x[i], fy ) ) + READ_DEPTH( depth[i], x[i], fy ); + } + } + HW_ENDCLIPLOOP(); +#endif + } + HW_READ_UNLOCK(); + + (void) ctx; +} + + +/** + * Initialize the given renderbuffer's span routines to point to + * the depth/z functions we generated above. + */ +static void TAG(InitDepthPointers)(struct gl_renderbuffer *rb) +{ + rb->GetRow = TAG(ReadDepthSpan); + rb->GetValues = TAG(ReadDepthPixels); + rb->PutRow = TAG(WriteDepthSpan); + rb->PutRowRGB = NULL; + rb->PutMonoRow = TAG(WriteMonoDepthSpan); + rb->PutValues = TAG(WriteDepthPixels); + rb->PutMonoValues = NULL; +} + + +#if HAVE_HW_DEPTH_SPANS +#undef WRITE_DEPTH_SPAN +#undef WRITE_DEPTH_PIXELS +#undef READ_DEPTH_SPAN +#undef READ_DEPTH_PIXELS +#else +#undef WRITE_DEPTH +#undef READ_DEPTH +#endif +#undef TAG +#undef VALUE_TYPE diff --git a/mesalib/src/mesa/drivers/dri/common/dri_util.c b/mesalib/src/mesa/drivers/dri/common/dri_util.c index 82638fa72..6d6401934 100644 --- a/mesalib/src/mesa/drivers/dri/common/dri_util.c +++ b/mesalib/src/mesa/drivers/dri/common/dri_util.c @@ -418,6 +418,7 @@ driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config, * supported either. */ (void) attrs; + (void) renderType; pdp = malloc(sizeof *pdp); if (!pdp) { @@ -594,8 +595,10 @@ driDestroyContext(__DRIcontext *pcp) /** * Create the per-drawable private driver information. * - * \param render_type Type of rendering target. \c GLX_RGBA is the only + * \param render_type Type of rendering target. \c GLX_RGBA_TYPE is the only * type likely to ever be supported for direct-rendering. + * However, \c GLX_RGBA_FLOAT_TYPE_ARB may eventually be + * supported by some drivers. * \param shared Context with which to share textures, etc. or NULL * * \returns An opaque pointer to the per-context private information on @@ -616,6 +619,8 @@ driCreateNewContext(__DRIscreen *psp, const __DRIconfig *config, __DRIcontext *pcp; void * const shareCtx = (shared != NULL) ? shared->driverPrivate : NULL; + (void) render_type; + pcp = malloc(sizeof *pcp); if (!pcp) return NULL; @@ -700,6 +705,9 @@ dri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config, static int driCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask) { + (void) dest; + (void) src; + (void) mask; return GL_FALSE; } @@ -806,6 +814,8 @@ driCreateNewScreen(int scrn, static const __DRIextension *emptyExtensionList[] = { NULL }; __DRIscreen *psp; + (void) loaderPrivate; + if (driDriverAPI.InitScreen == NULL) return NULL; diff --git a/mesalib/src/mesa/drivers/dri/common/spantmp2.h b/mesalib/src/mesa/drivers/dri/common/spantmp2.h index abd79562f..83cfbb164 100644 --- a/mesalib/src/mesa/drivers/dri/common/spantmp2.h +++ b/mesalib/src/mesa/drivers/dri/common/spantmp2.h @@ -465,6 +465,8 @@ static void TAG(WriteRGBASpan)( struct gl_context *ctx, GLuint n, GLint x, GLint y, const void *values, const GLubyte mask[] ) { + (void) ctx; + HW_WRITE_LOCK() { const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; @@ -508,6 +510,8 @@ static void TAG(WriteRGBSpan)( struct gl_context *ctx, GLuint n, GLint x, GLint y, const void *values, const GLubyte mask[] ) { + (void) ctx; + HW_WRITE_LOCK() { const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; @@ -547,6 +551,8 @@ static void TAG(WriteRGBAPixels)( struct gl_context *ctx, GLuint n, const GLint x[], const GLint y[], const void *values, const GLubyte mask[] ) { + (void) ctx; + HW_WRITE_LOCK() { const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; @@ -593,6 +599,8 @@ static void TAG(WriteMonoRGBASpan)( struct gl_context *ctx, GLuint n, GLint x, GLint y, const void *value, const GLubyte mask[] ) { + (void) ctx; + HW_WRITE_LOCK() { const GLubyte *color = (const GLubyte *) value; @@ -634,6 +642,8 @@ static void TAG(WriteMonoRGBAPixels)( struct gl_context *ctx, const void *value, const GLubyte mask[] ) { + (void) ctx; + HW_WRITE_LOCK() { const GLubyte *color = (const GLubyte *) value; @@ -673,6 +683,8 @@ static void TAG(ReadRGBASpan)( struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint n, GLint x, GLint y, void *values) { + (void) ctx; + HW_READ_LOCK() { GLubyte (*rgba)[4] = (GLubyte (*)[4]) values; @@ -713,6 +725,8 @@ static void TAG2(ReadRGBASpan,_MMX)( struct gl_context *ctx, __asm__ __volatile__( "emms" ); #endif + (void) ctx; + HW_READ_LOCK() { GLubyte (*rgba)[4] = (GLubyte (*)[4]) values; @@ -757,6 +771,8 @@ static void TAG2(ReadRGBASpan,_SSE2)( struct gl_context *ctx, GLuint n, GLint x, GLint y, void *values) { + (void) ctx; + HW_READ_LOCK() { GLubyte (*rgba)[4] = (GLubyte (*)[4]) values; @@ -799,6 +815,8 @@ static void TAG2(ReadRGBASpan,_SSE)( struct gl_context *ctx, __asm__ __volatile__( "emms" ); #endif + (void) ctx; + HW_READ_LOCK() { GLubyte (*rgba)[4] = (GLubyte (*)[4]) values; @@ -834,6 +852,8 @@ static void TAG(ReadRGBAPixels)( struct gl_context *ctx, GLuint n, const GLint x[], const GLint y[], void *values ) { + (void) ctx; + HW_READ_LOCK() { GLubyte (*rgba)[4] = (GLubyte (*)[4]) values; diff --git a/mesalib/src/mesa/drivers/dri/common/utils.c b/mesalib/src/mesa/drivers/dri/common/utils.c index 539296d1a..54156d34a 100644 --- a/mesalib/src/mesa/drivers/dri/common/utils.c +++ b/mesalib/src/mesa/drivers/dri/common/utils.c @@ -1,823 +1,709 @@ -/*
- * (C) Copyright IBM Corporation 2002, 2004
- * 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
- * VA LINUX SYSTEM, IBM 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.
- */
-
-/**
- * \file utils.c
- * Utility functions for DRI drivers.
- *
- * \author Ian Romanick <idr@us.ibm.com>
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include "main/mtypes.h"
-#include "main/cpuinfo.h"
-#include "main/extensions.h"
-#include "utils.h"
-
-
-/**
- * Print message to \c stderr if the \c LIBGL_DEBUG environment variable
- * is set.
- *
- * Is called from the drivers.
- *
- * \param f \c printf like format string.
- */
-void
-__driUtilMessage(const char *f, ...)
-{
- va_list args;
-
- if (getenv("LIBGL_DEBUG")) {
- fprintf(stderr, "libGL: ");
- va_start(args, f);
- vfprintf(stderr, f, args);
- va_end(args);
- fprintf(stderr, "\n");
- }
-}
-
-
-unsigned
-driParseDebugString( const char * debug,
- const struct dri_debug_control * control )
-{
- unsigned flag;
-
-
- flag = 0;
- if ( debug != NULL ) {
- while( control->string != NULL ) {
- if ( !strcmp( debug, "all" ) ||
- strstr( debug, control->string ) != NULL ) {
- flag |= control->flag;
- }
-
- control++;
- }
- }
-
- return flag;
-}
-
-
-
-/**
- * Create the \c GL_RENDERER string for DRI drivers.
- *
- * Almost all DRI drivers use a \c GL_RENDERER string of the form:
- *
- * "Mesa DRI <chip> <driver date> <AGP speed) <CPU information>"
- *
- * Using the supplied chip name, driver data, and AGP speed, this function
- * creates the string.
- *
- * \param buffer Buffer to hold the \c GL_RENDERER string.
- * \param hardware_name Name of the hardware.
- * \param agp_mode AGP mode (speed).
- *
- * \returns
- * The length of the string stored in \c buffer. This does \b not include
- * the terminating \c NUL character.
- */
-unsigned
-driGetRendererString( char * buffer, const char * hardware_name,
- GLuint agp_mode )
-{
- unsigned offset;
- char *cpu;
-
- offset = sprintf( buffer, "Mesa DRI %s", hardware_name );
-
- /* Append any AGP-specific information.
- */
- switch ( agp_mode ) {
- case 1:
- case 2:
- case 4:
- case 8:
- offset += sprintf( & buffer[ offset ], " AGP %ux", agp_mode );
- break;
-
- default:
- break;
- }
-
- /* Append any CPU-specific information.
- */
- cpu = _mesa_get_cpu_string();
- if (cpu) {
- offset += sprintf(buffer + offset, " %s", cpu);
- free(cpu);
- }
-
- return offset;
-}
-
-
-
-
-#define need_GL_ARB_copy_buffer
-#define need_GL_ARB_draw_buffers
-#define need_GL_ARB_multisample
-#define need_GL_ARB_texture_compression
-#define need_GL_ARB_transpose_matrix
-#define need_GL_ARB_vertex_buffer_object
-#define need_GL_ARB_window_pos
-#define need_GL_EXT_compiled_vertex_array
-#define need_GL_EXT_multi_draw_arrays
-#define need_GL_EXT_polygon_offset
-#define need_GL_EXT_texture_object
-#define need_GL_EXT_vertex_array
-#define need_GL_IBM_multimode_draw_arrays
-#define need_GL_MESA_window_pos
-
-/* These are needed in *all* drivers because Mesa internally implements
- * certain functionality in terms of functions provided by these extensions.
- * For example, glBlendFunc is implemented by calling glBlendFuncSeparateEXT.
- */
-#define need_GL_EXT_blend_func_separate
-#define need_GL_NV_vertex_program
-
-#include "main/remap_helper.h"
-
-static const struct dri_extension all_mesa_extensions[] = {
- { "GL_ARB_copy_buffer", GL_ARB_copy_buffer_functions },
- { "GL_ARB_draw_buffers", GL_ARB_draw_buffers_functions },
- { "GL_ARB_multisample", GL_ARB_multisample_functions },
- { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions },
- { "GL_ARB_transpose_matrix", GL_ARB_transpose_matrix_functions },
- { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions},
- { "GL_ARB_window_pos", GL_ARB_window_pos_functions },
- { "GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions },
- { "GL_EXT_compiled_vertex_array", GL_EXT_compiled_vertex_array_functions },
- { "GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions },
- { "GL_EXT_polygon_offset", GL_EXT_polygon_offset_functions },
- { "GL_EXT_texture_object", GL_EXT_texture_object_functions },
- { "GL_EXT_vertex_array", GL_EXT_vertex_array_functions },
- { "GL_IBM_multimode_draw_arrays", GL_IBM_multimode_draw_arrays_functions },
- { "GL_MESA_window_pos", GL_MESA_window_pos_functions },
- { "GL_NV_vertex_program", GL_NV_vertex_program_functions },
- { NULL, NULL }
-};
-
-
-/**
- * Enable and map extensions supported by the driver.
- *
- * When ctx is NULL, extensions are not enabled, but their functions
- * are still mapped. When extensions_to_enable is NULL, all static
- * functions known to mesa core are mapped.
- *
- * \bug
- * ARB_imaging isn't handled properly. In Mesa, enabling ARB_imaging also
- * enables all the sub-extensions that are folded into it. This means that
- * we need to add entry-points (via \c driInitSingleExtension) for those
- * new functions here.
- */
-void driInitExtensions( struct gl_context * ctx,
- const struct dri_extension * extensions_to_enable,
- GLboolean enable_imaging )
-{
- static int first_time = 1;
- unsigned i;
-
- if ( first_time ) {
- first_time = 0;
- driInitExtensions( NULL, all_mesa_extensions, GL_FALSE );
- }
-
- if ( (ctx != NULL) && enable_imaging ) {
- _mesa_enable_imaging_extensions( ctx );
- }
-
- /* The caller is too lazy to list any extension */
- if ( extensions_to_enable == NULL ) {
- /* Map the static functions. Together with those mapped by remap
- * table, this should cover everything mesa core knows.
- */
- _mesa_map_static_functions();
- return;
- }
-
- for ( i = 0 ; extensions_to_enable[i].name != NULL ; i++ ) {
- driInitSingleExtension( ctx, & extensions_to_enable[i] );
- }
-}
-
-
-
-
-/**
- * Enable and map functions for a single extension
- *
- * \param ctx Context where extension is to be enabled.
- * \param ext Extension that is to be enabled.
- *
- * \sa driInitExtensions, _mesa_enable_extension, _mesa_map_function_array
- */
-void driInitSingleExtension( struct gl_context * ctx,
- const struct dri_extension * ext )
-{
- if ( ext->functions != NULL ) {
- _mesa_map_function_array(ext->functions);
- }
-
- if ( ctx != NULL ) {
- _mesa_enable_extension( ctx, ext->name );
- }
-}
-
-
-/**
- * Utility function used by drivers to test the verions of other components.
- *
- * \param driver_name Name of the driver. Used in error messages.
- * \param driActual Actual DRI version supplied __driCreateNewScreen.
- * \param driExpected Minimum DRI version required by the driver.
- * \param ddxActual Actual DDX version supplied __driCreateNewScreen.
- * \param ddxExpected Minimum DDX minor and range of DDX major version required by the driver.
- * \param drmActual Actual DRM version supplied __driCreateNewScreen.
- * \param drmExpected Minimum DRM version required by the driver.
- *
- * \returns \c GL_TRUE if all version requirements are met. Otherwise,
- * \c GL_FALSE is returned.
- *
- * \sa __driCreateNewScreen, driCheckDriDdxDrmVersions2
- *
- * \todo
- * Now that the old \c driCheckDriDdxDrmVersions function is gone, this
- * function and \c driCheckDriDdxDrmVersions2 should be renamed.
- */
-GLboolean
-driCheckDriDdxDrmVersions3(const char * driver_name,
- const __DRIversion * driActual,
- const __DRIversion * driExpected,
- const __DRIversion * ddxActual,
- const __DRIutilversion2 * ddxExpected,
- const __DRIversion * drmActual,
- const __DRIversion * drmExpected)
-{
- static const char format[] = "%s DRI driver expected %s version %d.%d.x "
- "but got version %d.%d.%d\n";
- static const char format2[] = "%s DRI driver expected %s version %d-%d.%d.x "
- "but got version %d.%d.%d\n";
-
-
- /* Check the DRI version */
- if ( (driActual->major != driExpected->major)
- || (driActual->minor < driExpected->minor) ) {
- fprintf(stderr, format, driver_name, "DRI",
- driExpected->major, driExpected->minor,
- driActual->major, driActual->minor, driActual->patch);
- return GL_FALSE;
- }
-
- /* Check that the DDX driver version is compatible */
- if ( (ddxActual->major < ddxExpected->major_min)
- || (ddxActual->major > ddxExpected->major_max)
- || (ddxActual->minor < ddxExpected->minor) ) {
- fprintf(stderr, format2, driver_name, "DDX",
- ddxExpected->major_min, ddxExpected->major_max, ddxExpected->minor,
- ddxActual->major, ddxActual->minor, ddxActual->patch);
- return GL_FALSE;
- }
-
- /* Check that the DRM driver version is compatible */
- if ( (drmActual->major != drmExpected->major)
- || (drmActual->minor < drmExpected->minor) ) {
- fprintf(stderr, format, driver_name, "DRM",
- drmExpected->major, drmExpected->minor,
- drmActual->major, drmActual->minor, drmActual->patch);
- return GL_FALSE;
- }
-
- return GL_TRUE;
-}
-
-GLboolean
-driCheckDriDdxDrmVersions2(const char * driver_name,
- const __DRIversion * driActual,
- const __DRIversion * driExpected,
- const __DRIversion * ddxActual,
- const __DRIversion * ddxExpected,
- const __DRIversion * drmActual,
- const __DRIversion * drmExpected)
-{
- __DRIutilversion2 ddx_expected;
- ddx_expected.major_min = ddxExpected->major;
- ddx_expected.major_max = ddxExpected->major;
- ddx_expected.minor = ddxExpected->minor;
- ddx_expected.patch = ddxExpected->patch;
- return driCheckDriDdxDrmVersions3(driver_name, driActual,
- driExpected, ddxActual, & ddx_expected,
- drmActual, drmExpected);
-}
-
-GLboolean driClipRectToFramebuffer( const struct gl_framebuffer *buffer,
- GLint *x, GLint *y,
- GLsizei *width, GLsizei *height )
-{
- /* left clipping */
- if (*x < buffer->_Xmin) {
- *width -= (buffer->_Xmin - *x);
- *x = buffer->_Xmin;
- }
-
- /* right clipping */
- if (*x + *width > buffer->_Xmax)
- *width -= (*x + *width - buffer->_Xmax - 1);
-
- if (*width <= 0)
- return GL_FALSE;
-
- /* bottom clipping */
- if (*y < buffer->_Ymin) {
- *height -= (buffer->_Ymin - *y);
- *y = buffer->_Ymin;
- }
-
- /* top clipping */
- if (*y + *height > buffer->_Ymax)
- *height -= (*y + *height - buffer->_Ymax - 1);
-
- if (*height <= 0)
- return GL_FALSE;
-
- return GL_TRUE;
-}
-
-/**
- * Creates a set of \c struct gl_config that a driver will expose.
- *
- * A set of \c struct gl_config will be created based on the supplied
- * parameters. The number of modes processed will be 2 *
- * \c num_depth_stencil_bits * \c num_db_modes.
- *
- * For the most part, data is just copied from \c depth_bits, \c stencil_bits,
- * \c db_modes, and \c visType into each \c struct gl_config element.
- * However, the meanings of \c fb_format and \c fb_type require further
- * explanation. The \c fb_format specifies which color components are in
- * each pixel and what the default order is. For example, \c GL_RGB specifies
- * that red, green, blue are available and red is in the "most significant"
- * position and blue is in the "least significant". The \c fb_type specifies
- * the bit sizes of each component and the actual ordering. For example, if
- * \c GL_UNSIGNED_SHORT_5_6_5_REV is specified with \c GL_RGB, bits [15:11]
- * are the blue value, bits [10:5] are the green value, and bits [4:0] are
- * the red value.
- *
- * One sublte issue is the combination of \c GL_RGB or \c GL_BGR and either
- * of the \c GL_UNSIGNED_INT_8_8_8_8 modes. The resulting mask values in the
- * \c struct gl_config structure is \b identical to the \c GL_RGBA or
- * \c GL_BGRA case, except the \c alphaMask is zero. This means that, as
- * far as this routine is concerned, \c GL_RGB with \c GL_UNSIGNED_INT_8_8_8_8
- * still uses 32-bits.
- *
- * If in doubt, look at the tables used in the function.
- *
- * \param ptr_to_modes Pointer to a pointer to a linked list of
- * \c struct gl_config. Upon completion, a pointer to
- * the next element to be process will be stored here.
- * If the function fails and returns \c GL_FALSE, this
- * value will be unmodified, but some elements in the
- * linked list may be modified.
- * \param fb_format Format of the framebuffer. Currently only \c GL_RGB,
- * \c GL_RGBA, \c GL_BGR, and \c GL_BGRA are supported.
- * \param fb_type Type of the pixels in the framebuffer. Currently only
- * \c GL_UNSIGNED_SHORT_5_6_5,
- * \c GL_UNSIGNED_SHORT_5_6_5_REV,
- * \c GL_UNSIGNED_INT_8_8_8_8, and
- * \c GL_UNSIGNED_INT_8_8_8_8_REV are supported.
- * \param depth_bits Array of depth buffer sizes to be exposed.
- * \param stencil_bits Array of stencil buffer sizes to be exposed.
- * \param num_depth_stencil_bits Number of entries in both \c depth_bits and
- * \c stencil_bits.
- * \param db_modes Array of buffer swap modes. If an element has a
- * value of \c GLX_NONE, then it represents a
- * single-buffered mode. Other valid values are
- * \c GLX_SWAP_EXCHANGE_OML, \c GLX_SWAP_COPY_OML, and
- * \c GLX_SWAP_UNDEFINED_OML. See the
- * GLX_OML_swap_method extension spec for more details.
- * \param num_db_modes Number of entries in \c db_modes.
- * \param msaa_samples Array of msaa sample count. 0 represents a visual
- * without a multisample buffer.
- * \param num_msaa_modes Number of entries in \c msaa_samples.
- * \param visType GLX visual type. Usually either \c GLX_TRUE_COLOR or
- * \c GLX_DIRECT_COLOR.
- *
- * \returns
- * \c GL_TRUE on success or \c GL_FALSE on failure. Currently the only
- * cause of failure is a bad parameter (i.e., unsupported \c fb_format or
- * \c fb_type).
- *
- * \todo
- * There is currently no way to support packed RGB modes (i.e., modes with
- * exactly 3 bytes per pixel) or floating-point modes. This could probably
- * be done by creating some new, private enums with clever names likes
- * \c GL_UNSIGNED_3BYTE_8_8_8, \c GL_4FLOAT_32_32_32_32,
- * \c GL_4HALF_16_16_16_16, etc. We can cross that bridge when we come to it.
- */
-__DRIconfig **
-driCreateConfigs(GLenum fb_format, GLenum fb_type,
- const uint8_t * depth_bits, const uint8_t * stencil_bits,
- unsigned num_depth_stencil_bits,
- const GLenum * db_modes, unsigned num_db_modes,
- const uint8_t * msaa_samples, unsigned num_msaa_modes,
- GLboolean enable_accum)
-{
- static const uint8_t bits_table[4][4] = {
- /* R G B A */
- { 3, 3, 2, 0 }, /* Any GL_UNSIGNED_BYTE_3_3_2 */
- { 5, 6, 5, 0 }, /* Any GL_UNSIGNED_SHORT_5_6_5 */
- { 8, 8, 8, 0 }, /* Any RGB with any GL_UNSIGNED_INT_8_8_8_8 */
- { 8, 8, 8, 8 } /* Any RGBA with any GL_UNSIGNED_INT_8_8_8_8 */
- };
-
- static const uint32_t masks_table_rgb[6][4] = {
- { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2 */
- { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV */
- { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5 */
- { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV */
- { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000 }, /* 8_8_8_8 */
- { 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 } /* 8_8_8_8_REV */
- };
-
- static const uint32_t masks_table_rgba[6][4] = {
- { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2 */
- { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV */
- { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5 */
- { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV */
- { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF }, /* 8_8_8_8 */
- { 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 }, /* 8_8_8_8_REV */
- };
-
- static const uint32_t masks_table_bgr[6][4] = {
- { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */
- { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */
- { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5 */
- { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV */
- { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000 }, /* 8_8_8_8 */
- { 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }, /* 8_8_8_8_REV */
- };
-
- static const uint32_t masks_table_bgra[6][4] = {
- { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */
- { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */
- { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5 */
- { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV */
- { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF }, /* 8_8_8_8 */
- { 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }, /* 8_8_8_8_REV */
- };
-
- static const uint8_t bytes_per_pixel[6] = {
- 1, /* 3_3_2 */
- 1, /* 2_3_3_REV */
- 2, /* 5_6_5 */
- 2, /* 5_6_5_REV */
- 4, /* 8_8_8_8 */
- 4 /* 8_8_8_8_REV */
- };
-
- const uint8_t * bits;
- const uint32_t * masks;
- int index;
- __DRIconfig **configs, **c;
- struct gl_config *modes;
- unsigned i, j, k, h;
- unsigned num_modes;
- unsigned num_accum_bits = (enable_accum) ? 2 : 1;
-
- switch ( fb_type ) {
- case GL_UNSIGNED_BYTE_3_3_2:
- index = 0;
- break;
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- index = 1;
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- index = 2;
- break;
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- index = 3;
- break;
- case GL_UNSIGNED_INT_8_8_8_8:
- index = 4;
- break;
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- index = 5;
- break;
- default:
- fprintf( stderr, "[%s:%u] Unknown framebuffer type 0x%04x.\n",
- __FUNCTION__, __LINE__, fb_type );
- return NULL;
- }
-
-
- /* Valid types are GL_UNSIGNED_SHORT_5_6_5 and GL_UNSIGNED_INT_8_8_8_8 and
- * the _REV versions.
- *
- * Valid formats are GL_RGBA, GL_RGB, and GL_BGRA.
- */
-
- switch ( fb_format ) {
- case GL_RGB:
- masks = masks_table_rgb[ index ];
- break;
-
- case GL_RGBA:
- masks = masks_table_rgba[ index ];
- break;
-
- case GL_BGR:
- masks = masks_table_bgr[ index ];
- break;
-
- case GL_BGRA:
- masks = masks_table_bgra[ index ];
- break;
-
- default:
- fprintf( stderr, "[%s:%u] Unknown framebuffer format 0x%04x.\n",
- __FUNCTION__, __LINE__, fb_format );
- return NULL;
- }
-
- switch ( bytes_per_pixel[ index ] ) {
- case 1:
- bits = bits_table[0];
- break;
- case 2:
- bits = bits_table[1];
- break;
- default:
- bits = ((fb_format == GL_RGB) || (fb_format == GL_BGR))
- ? bits_table[2]
- : bits_table[3];
- break;
- }
-
- num_modes = num_depth_stencil_bits * num_db_modes * num_accum_bits * num_msaa_modes;
- configs = calloc(1, (num_modes + 1) * sizeof *configs);
- if (configs == NULL)
- return NULL;
-
- c = configs;
- for ( k = 0 ; k < num_depth_stencil_bits ; k++ ) {
- for ( i = 0 ; i < num_db_modes ; i++ ) {
- for ( h = 0 ; h < num_msaa_modes; h++ ) {
- for ( j = 0 ; j < num_accum_bits ; j++ ) {
- *c = malloc (sizeof **c);
- modes = &(*c)->modes;
- c++;
-
- memset(modes, 0, sizeof *modes);
- modes->redBits = bits[0];
- modes->greenBits = bits[1];
- modes->blueBits = bits[2];
- modes->alphaBits = bits[3];
- modes->redMask = masks[0];
- modes->greenMask = masks[1];
- modes->blueMask = masks[2];
- modes->alphaMask = masks[3];
- modes->rgbBits = modes->redBits + modes->greenBits
- + modes->blueBits + modes->alphaBits;
-
- modes->accumRedBits = 16 * j;
- modes->accumGreenBits = 16 * j;
- modes->accumBlueBits = 16 * j;
- modes->accumAlphaBits = (masks[3] != 0) ? 16 * j : 0;
- modes->visualRating = (j == 0) ? GLX_NONE : GLX_SLOW_CONFIG;
-
- modes->stencilBits = stencil_bits[k];
- modes->depthBits = depth_bits[k];
-
- modes->transparentPixel = GLX_NONE;
- modes->transparentRed = GLX_DONT_CARE;
- modes->transparentGreen = GLX_DONT_CARE;
- modes->transparentBlue = GLX_DONT_CARE;
- modes->transparentAlpha = GLX_DONT_CARE;
- modes->transparentIndex = GLX_DONT_CARE;
- modes->rgbMode = GL_TRUE;
-
- if ( db_modes[i] == GLX_NONE ) {
- modes->doubleBufferMode = GL_FALSE;
- }
- else {
- modes->doubleBufferMode = GL_TRUE;
- modes->swapMethod = db_modes[i];
- }
-
- modes->samples = msaa_samples[h];
- modes->sampleBuffers = modes->samples ? 1 : 0;
-
-
- modes->haveAccumBuffer = ((modes->accumRedBits +
- modes->accumGreenBits +
- modes->accumBlueBits +
- modes->accumAlphaBits) > 0);
- modes->haveDepthBuffer = (modes->depthBits > 0);
- modes->haveStencilBuffer = (modes->stencilBits > 0);
-
- modes->bindToTextureRgb = GL_TRUE;
- modes->bindToTextureRgba = GL_TRUE;
- modes->bindToMipmapTexture = GL_FALSE;
- modes->bindToTextureTargets =
- __DRI_ATTRIB_TEXTURE_1D_BIT |
- __DRI_ATTRIB_TEXTURE_2D_BIT |
- __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT;
-
- modes->sRGBCapable = GL_FALSE;
- }
- }
- }
- }
- *c = NULL;
-
- return configs;
-}
-
-__DRIconfig **driConcatConfigs(__DRIconfig **a,
- __DRIconfig **b)
-{
- __DRIconfig **all;
- int i, j, index;
-
- i = 0;
- while (a[i] != NULL)
- i++;
- j = 0;
- while (b[j] != NULL)
- j++;
-
- all = malloc((i + j + 1) * sizeof *all);
- index = 0;
- for (i = 0; a[i] != NULL; i++)
- all[index++] = a[i];
- for (j = 0; b[j] != NULL; j++)
- all[index++] = b[j];
- all[index++] = NULL;
-
- free(a);
- free(b);
-
- return all;
-}
-
-#define __ATTRIB(attrib, field) \
- { attrib, offsetof(struct gl_config, field) }
-
-static const struct { unsigned int attrib, offset; } attribMap[] = {
- __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits),
- __ATTRIB(__DRI_ATTRIB_LEVEL, level),
- __ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits),
- __ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits),
- __ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits),
- __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits),
- __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits),
- __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits),
- __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits),
- __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits),
- __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits),
- __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits),
- __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers),
- __ATTRIB(__DRI_ATTRIB_SAMPLES, samples),
- __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode),
- __ATTRIB(__DRI_ATTRIB_STEREO, stereoMode),
- __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentPixel),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha),
- __ATTRIB(__DRI_ATTRIB_FLOAT_MODE, floatMode),
- __ATTRIB(__DRI_ATTRIB_RED_MASK, redMask),
- __ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask),
- __ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask),
- __ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask),
- __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth),
- __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight),
- __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels),
- __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth),
- __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight),
- __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod),
- __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb),
- __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba),
- __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture),
- __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS, bindToTextureTargets),
- __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted),
- __ATTRIB(__DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE, sRGBCapable),
-
- /* The struct field doesn't matter here, these are handled by the
- * switch in driGetConfigAttribIndex. We need them in the array
- * so the iterator includes them though.*/
- __ATTRIB(__DRI_ATTRIB_RENDER_TYPE, level),
- __ATTRIB(__DRI_ATTRIB_CONFIG_CAVEAT, level),
- __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, level)
-};
-
-#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
-
-
-/**
- * Return the value of a configuration attribute. The attribute is
- * indicated by the index.
- */
-static int
-driGetConfigAttribIndex(const __DRIconfig *config,
- unsigned int index, unsigned int *value)
-{
- switch (attribMap[index].attrib) {
- case __DRI_ATTRIB_RENDER_TYPE:
- /* no support for color index mode */
- *value = __DRI_ATTRIB_RGBA_BIT;
- break;
- case __DRI_ATTRIB_CONFIG_CAVEAT:
- if (config->modes.visualRating == GLX_NON_CONFORMANT_CONFIG)
- *value = __DRI_ATTRIB_NON_CONFORMANT_CONFIG;
- else if (config->modes.visualRating == GLX_SLOW_CONFIG)
- *value = __DRI_ATTRIB_SLOW_BIT;
- else
- *value = 0;
- break;
- case __DRI_ATTRIB_SWAP_METHOD:
- /* XXX no return value??? */
- break;
-
- case __DRI_ATTRIB_FLOAT_MODE:
- /* this field is not int-sized */
- *value = config->modes.floatMode;
- break;
-
- default:
- /* any other int-sized field */
- *value = *(unsigned int *)
- ((char *) &config->modes + attribMap[index].offset);
-
- break;
- }
-
- return GL_TRUE;
-}
-
-
-/**
- * Get the value of a configuration attribute.
- * \param attrib the attribute (one of the _DRI_ATTRIB_x tokens)
- * \param value returns the attribute's value
- * \return 1 for success, 0 for failure
- */
-int
-driGetConfigAttrib(const __DRIconfig *config,
- unsigned int attrib, unsigned int *value)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(attribMap); i++)
- if (attribMap[i].attrib == attrib)
- return driGetConfigAttribIndex(config, i, value);
-
- return GL_FALSE;
-}
-
-
-/**
- * Get a configuration attribute name and value, given an index.
- * \param index which field of the __DRIconfig to query
- * \param attrib returns the attribute name (one of the _DRI_ATTRIB_x tokens)
- * \param value returns the attribute's value
- * \return 1 for success, 0 for failure
- */
-int
-driIndexConfigAttrib(const __DRIconfig *config, int index,
- unsigned int *attrib, unsigned int *value)
-{
- if (index >= 0 && index < ARRAY_SIZE(attribMap)) {
- *attrib = attribMap[index].attrib;
- return driGetConfigAttribIndex(config, index, value);
- }
-
- return GL_FALSE;
-}
+/* + * (C) Copyright IBM Corporation 2002, 2004 + * 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 + * VA LINUX SYSTEM, IBM 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. + */ + +/** + * \file utils.c + * Utility functions for DRI drivers. + * + * \author Ian Romanick <idr@us.ibm.com> + */ + +#include <string.h> +#include <stdlib.h> +#include "main/mtypes.h" +#include "main/cpuinfo.h" +#include "main/extensions.h" +#include "utils.h" + + +/** + * Print message to \c stderr if the \c LIBGL_DEBUG environment variable + * is set. + * + * Is called from the drivers. + * + * \param f \c printf like format string. + */ +void +__driUtilMessage(const char *f, ...) +{ + va_list args; + + if (getenv("LIBGL_DEBUG")) { + fprintf(stderr, "libGL: "); + va_start(args, f); + vfprintf(stderr, f, args); + va_end(args); + fprintf(stderr, "\n"); + } +} + + +unsigned +driParseDebugString( const char * debug, + const struct dri_debug_control * control ) +{ + unsigned flag; + + + flag = 0; + if ( debug != NULL ) { + while( control->string != NULL ) { + if ( !strcmp( debug, "all" ) || + strstr( debug, control->string ) != NULL ) { + flag |= control->flag; + } + + control++; + } + } + + return flag; +} + + + +/** + * Create the \c GL_RENDERER string for DRI drivers. + * + * Almost all DRI drivers use a \c GL_RENDERER string of the form: + * + * "Mesa DRI <chip> <driver date> <AGP speed) <CPU information>" + * + * Using the supplied chip name, driver data, and AGP speed, this function + * creates the string. + * + * \param buffer Buffer to hold the \c GL_RENDERER string. + * \param hardware_name Name of the hardware. + * \param agp_mode AGP mode (speed). + * + * \returns + * The length of the string stored in \c buffer. This does \b not include + * the terminating \c NUL character. + */ +unsigned +driGetRendererString( char * buffer, const char * hardware_name, + GLuint agp_mode ) +{ + unsigned offset; + char *cpu; + + offset = sprintf( buffer, "Mesa DRI %s", hardware_name ); + + /* Append any AGP-specific information. + */ + switch ( agp_mode ) { + case 1: + case 2: + case 4: + case 8: + offset += sprintf( & buffer[ offset ], " AGP %ux", agp_mode ); + break; + + default: + break; + } + + /* Append any CPU-specific information. + */ + cpu = _mesa_get_cpu_string(); + if (cpu) { + offset += sprintf(buffer + offset, " %s", cpu); + free(cpu); + } + + return offset; +} + + +/** + * Utility function used by drivers to test the verions of other components. + * + * \param driver_name Name of the driver. Used in error messages. + * \param driActual Actual DRI version supplied __driCreateNewScreen. + * \param driExpected Minimum DRI version required by the driver. + * \param ddxActual Actual DDX version supplied __driCreateNewScreen. + * \param ddxExpected Minimum DDX minor and range of DDX major version required by the driver. + * \param drmActual Actual DRM version supplied __driCreateNewScreen. + * \param drmExpected Minimum DRM version required by the driver. + * + * \returns \c GL_TRUE if all version requirements are met. Otherwise, + * \c GL_FALSE is returned. + * + * \sa __driCreateNewScreen, driCheckDriDdxDrmVersions2 + * + * \todo + * Now that the old \c driCheckDriDdxDrmVersions function is gone, this + * function and \c driCheckDriDdxDrmVersions2 should be renamed. + */ +GLboolean +driCheckDriDdxDrmVersions3(const char * driver_name, + const __DRIversion * driActual, + const __DRIversion * driExpected, + const __DRIversion * ddxActual, + const __DRIutilversion2 * ddxExpected, + const __DRIversion * drmActual, + const __DRIversion * drmExpected) +{ + static const char format[] = "%s DRI driver expected %s version %d.%d.x " + "but got version %d.%d.%d\n"; + static const char format2[] = "%s DRI driver expected %s version %d-%d.%d.x " + "but got version %d.%d.%d\n"; + + + /* Check the DRI version */ + if ( (driActual->major != driExpected->major) + || (driActual->minor < driExpected->minor) ) { + fprintf(stderr, format, driver_name, "DRI", + driExpected->major, driExpected->minor, + driActual->major, driActual->minor, driActual->patch); + return GL_FALSE; + } + + /* Check that the DDX driver version is compatible */ + if ( (ddxActual->major < ddxExpected->major_min) + || (ddxActual->major > ddxExpected->major_max) + || (ddxActual->minor < ddxExpected->minor) ) { + fprintf(stderr, format2, driver_name, "DDX", + ddxExpected->major_min, ddxExpected->major_max, ddxExpected->minor, + ddxActual->major, ddxActual->minor, ddxActual->patch); + return GL_FALSE; + } + + /* Check that the DRM driver version is compatible */ + if ( (drmActual->major != drmExpected->major) + || (drmActual->minor < drmExpected->minor) ) { + fprintf(stderr, format, driver_name, "DRM", + drmExpected->major, drmExpected->minor, + drmActual->major, drmActual->minor, drmActual->patch); + return GL_FALSE; + } + + return GL_TRUE; +} + +GLboolean +driCheckDriDdxDrmVersions2(const char * driver_name, + const __DRIversion * driActual, + const __DRIversion * driExpected, + const __DRIversion * ddxActual, + const __DRIversion * ddxExpected, + const __DRIversion * drmActual, + const __DRIversion * drmExpected) +{ + __DRIutilversion2 ddx_expected; + ddx_expected.major_min = ddxExpected->major; + ddx_expected.major_max = ddxExpected->major; + ddx_expected.minor = ddxExpected->minor; + ddx_expected.patch = ddxExpected->patch; + return driCheckDriDdxDrmVersions3(driver_name, driActual, + driExpected, ddxActual, & ddx_expected, + drmActual, drmExpected); +} + +GLboolean driClipRectToFramebuffer( const struct gl_framebuffer *buffer, + GLint *x, GLint *y, + GLsizei *width, GLsizei *height ) +{ + /* left clipping */ + if (*x < buffer->_Xmin) { + *width -= (buffer->_Xmin - *x); + *x = buffer->_Xmin; + } + + /* right clipping */ + if (*x + *width > buffer->_Xmax) + *width -= (*x + *width - buffer->_Xmax - 1); + + if (*width <= 0) + return GL_FALSE; + + /* bottom clipping */ + if (*y < buffer->_Ymin) { + *height -= (buffer->_Ymin - *y); + *y = buffer->_Ymin; + } + + /* top clipping */ + if (*y + *height > buffer->_Ymax) + *height -= (*y + *height - buffer->_Ymax - 1); + + if (*height <= 0) + return GL_FALSE; + + return GL_TRUE; +} + +/** + * Creates a set of \c struct gl_config that a driver will expose. + * + * A set of \c struct gl_config will be created based on the supplied + * parameters. The number of modes processed will be 2 * + * \c num_depth_stencil_bits * \c num_db_modes. + * + * For the most part, data is just copied from \c depth_bits, \c stencil_bits, + * \c db_modes, and \c visType into each \c struct gl_config element. + * However, the meanings of \c fb_format and \c fb_type require further + * explanation. The \c fb_format specifies which color components are in + * each pixel and what the default order is. For example, \c GL_RGB specifies + * that red, green, blue are available and red is in the "most significant" + * position and blue is in the "least significant". The \c fb_type specifies + * the bit sizes of each component and the actual ordering. For example, if + * \c GL_UNSIGNED_SHORT_5_6_5_REV is specified with \c GL_RGB, bits [15:11] + * are the blue value, bits [10:5] are the green value, and bits [4:0] are + * the red value. + * + * One sublte issue is the combination of \c GL_RGB or \c GL_BGR and either + * of the \c GL_UNSIGNED_INT_8_8_8_8 modes. The resulting mask values in the + * \c struct gl_config structure is \b identical to the \c GL_RGBA or + * \c GL_BGRA case, except the \c alphaMask is zero. This means that, as + * far as this routine is concerned, \c GL_RGB with \c GL_UNSIGNED_INT_8_8_8_8 + * still uses 32-bits. + * + * If in doubt, look at the tables used in the function. + * + * \param ptr_to_modes Pointer to a pointer to a linked list of + * \c struct gl_config. Upon completion, a pointer to + * the next element to be process will be stored here. + * If the function fails and returns \c GL_FALSE, this + * value will be unmodified, but some elements in the + * linked list may be modified. + * \param fb_format Format of the framebuffer. Currently only \c GL_RGB, + * \c GL_RGBA, \c GL_BGR, and \c GL_BGRA are supported. + * \param fb_type Type of the pixels in the framebuffer. Currently only + * \c GL_UNSIGNED_SHORT_5_6_5, + * \c GL_UNSIGNED_SHORT_5_6_5_REV, + * \c GL_UNSIGNED_INT_8_8_8_8, and + * \c GL_UNSIGNED_INT_8_8_8_8_REV are supported. + * \param depth_bits Array of depth buffer sizes to be exposed. + * \param stencil_bits Array of stencil buffer sizes to be exposed. + * \param num_depth_stencil_bits Number of entries in both \c depth_bits and + * \c stencil_bits. + * \param db_modes Array of buffer swap modes. If an element has a + * value of \c GLX_NONE, then it represents a + * single-buffered mode. Other valid values are + * \c GLX_SWAP_EXCHANGE_OML, \c GLX_SWAP_COPY_OML, and + * \c GLX_SWAP_UNDEFINED_OML. See the + * GLX_OML_swap_method extension spec for more details. + * \param num_db_modes Number of entries in \c db_modes. + * \param msaa_samples Array of msaa sample count. 0 represents a visual + * without a multisample buffer. + * \param num_msaa_modes Number of entries in \c msaa_samples. + * \param visType GLX visual type. Usually either \c GLX_TRUE_COLOR or + * \c GLX_DIRECT_COLOR. + * + * \returns + * \c GL_TRUE on success or \c GL_FALSE on failure. Currently the only + * cause of failure is a bad parameter (i.e., unsupported \c fb_format or + * \c fb_type). + * + * \todo + * There is currently no way to support packed RGB modes (i.e., modes with + * exactly 3 bytes per pixel) or floating-point modes. This could probably + * be done by creating some new, private enums with clever names likes + * \c GL_UNSIGNED_3BYTE_8_8_8, \c GL_4FLOAT_32_32_32_32, + * \c GL_4HALF_16_16_16_16, etc. We can cross that bridge when we come to it. + */ +__DRIconfig ** +driCreateConfigs(GLenum fb_format, GLenum fb_type, + const uint8_t * depth_bits, const uint8_t * stencil_bits, + unsigned num_depth_stencil_bits, + const GLenum * db_modes, unsigned num_db_modes, + const uint8_t * msaa_samples, unsigned num_msaa_modes, + GLboolean enable_accum) +{ + static const uint8_t bits_table[4][4] = { + /* R G B A */ + { 3, 3, 2, 0 }, /* Any GL_UNSIGNED_BYTE_3_3_2 */ + { 5, 6, 5, 0 }, /* Any GL_UNSIGNED_SHORT_5_6_5 */ + { 8, 8, 8, 0 }, /* Any RGB with any GL_UNSIGNED_INT_8_8_8_8 */ + { 8, 8, 8, 8 } /* Any RGBA with any GL_UNSIGNED_INT_8_8_8_8 */ + }; + + static const uint32_t masks_table_rgb[6][4] = { + { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2 */ + { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV */ + { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5 */ + { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV */ + { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000 }, /* 8_8_8_8 */ + { 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 } /* 8_8_8_8_REV */ + }; + + static const uint32_t masks_table_rgba[6][4] = { + { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2 */ + { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV */ + { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5 */ + { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV */ + { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF }, /* 8_8_8_8 */ + { 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 }, /* 8_8_8_8_REV */ + }; + + static const uint32_t masks_table_bgr[6][4] = { + { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */ + { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */ + { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5 */ + { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV */ + { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000 }, /* 8_8_8_8 */ + { 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }, /* 8_8_8_8_REV */ + }; + + static const uint32_t masks_table_bgra[6][4] = { + { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */ + { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */ + { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5 */ + { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV */ + { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF }, /* 8_8_8_8 */ + { 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }, /* 8_8_8_8_REV */ + }; + + static const uint8_t bytes_per_pixel[6] = { + 1, /* 3_3_2 */ + 1, /* 2_3_3_REV */ + 2, /* 5_6_5 */ + 2, /* 5_6_5_REV */ + 4, /* 8_8_8_8 */ + 4 /* 8_8_8_8_REV */ + }; + + const uint8_t * bits; + const uint32_t * masks; + int index; + __DRIconfig **configs, **c; + struct gl_config *modes; + unsigned i, j, k, h; + unsigned num_modes; + unsigned num_accum_bits = (enable_accum) ? 2 : 1; + + switch ( fb_type ) { + case GL_UNSIGNED_BYTE_3_3_2: + index = 0; + break; + case GL_UNSIGNED_BYTE_2_3_3_REV: + index = 1; + break; + case GL_UNSIGNED_SHORT_5_6_5: + index = 2; + break; + case GL_UNSIGNED_SHORT_5_6_5_REV: + index = 3; + break; + case GL_UNSIGNED_INT_8_8_8_8: + index = 4; + break; + case GL_UNSIGNED_INT_8_8_8_8_REV: + index = 5; + break; + default: + fprintf( stderr, "[%s:%u] Unknown framebuffer type 0x%04x.\n", + __FUNCTION__, __LINE__, fb_type ); + return NULL; + } + + + /* Valid types are GL_UNSIGNED_SHORT_5_6_5 and GL_UNSIGNED_INT_8_8_8_8 and + * the _REV versions. + * + * Valid formats are GL_RGBA, GL_RGB, and GL_BGRA. + */ + + switch ( fb_format ) { + case GL_RGB: + masks = masks_table_rgb[ index ]; + break; + + case GL_RGBA: + masks = masks_table_rgba[ index ]; + break; + + case GL_BGR: + masks = masks_table_bgr[ index ]; + break; + + case GL_BGRA: + masks = masks_table_bgra[ index ]; + break; + + default: + fprintf( stderr, "[%s:%u] Unknown framebuffer format 0x%04x.\n", + __FUNCTION__, __LINE__, fb_format ); + return NULL; + } + + switch ( bytes_per_pixel[ index ] ) { + case 1: + bits = bits_table[0]; + break; + case 2: + bits = bits_table[1]; + break; + default: + bits = ((fb_format == GL_RGB) || (fb_format == GL_BGR)) + ? bits_table[2] + : bits_table[3]; + break; + } + + num_modes = num_depth_stencil_bits * num_db_modes * num_accum_bits * num_msaa_modes; + configs = calloc(1, (num_modes + 1) * sizeof *configs); + if (configs == NULL) + return NULL; + + c = configs; + for ( k = 0 ; k < num_depth_stencil_bits ; k++ ) { + for ( i = 0 ; i < num_db_modes ; i++ ) { + for ( h = 0 ; h < num_msaa_modes; h++ ) { + for ( j = 0 ; j < num_accum_bits ; j++ ) { + *c = malloc (sizeof **c); + modes = &(*c)->modes; + c++; + + memset(modes, 0, sizeof *modes); + modes->redBits = bits[0]; + modes->greenBits = bits[1]; + modes->blueBits = bits[2]; + modes->alphaBits = bits[3]; + modes->redMask = masks[0]; + modes->greenMask = masks[1]; + modes->blueMask = masks[2]; + modes->alphaMask = masks[3]; + modes->rgbBits = modes->redBits + modes->greenBits + + modes->blueBits + modes->alphaBits; + + modes->accumRedBits = 16 * j; + modes->accumGreenBits = 16 * j; + modes->accumBlueBits = 16 * j; + modes->accumAlphaBits = (masks[3] != 0) ? 16 * j : 0; + modes->visualRating = (j == 0) ? GLX_NONE : GLX_SLOW_CONFIG; + + modes->stencilBits = stencil_bits[k]; + modes->depthBits = depth_bits[k]; + + modes->transparentPixel = GLX_NONE; + modes->transparentRed = GLX_DONT_CARE; + modes->transparentGreen = GLX_DONT_CARE; + modes->transparentBlue = GLX_DONT_CARE; + modes->transparentAlpha = GLX_DONT_CARE; + modes->transparentIndex = GLX_DONT_CARE; + modes->rgbMode = GL_TRUE; + + if ( db_modes[i] == GLX_NONE ) { + modes->doubleBufferMode = GL_FALSE; + } + else { + modes->doubleBufferMode = GL_TRUE; + modes->swapMethod = db_modes[i]; + } + + modes->samples = msaa_samples[h]; + modes->sampleBuffers = modes->samples ? 1 : 0; + + + modes->haveAccumBuffer = ((modes->accumRedBits + + modes->accumGreenBits + + modes->accumBlueBits + + modes->accumAlphaBits) > 0); + modes->haveDepthBuffer = (modes->depthBits > 0); + modes->haveStencilBuffer = (modes->stencilBits > 0); + + modes->bindToTextureRgb = GL_TRUE; + modes->bindToTextureRgba = GL_TRUE; + modes->bindToMipmapTexture = GL_FALSE; + modes->bindToTextureTargets = + __DRI_ATTRIB_TEXTURE_1D_BIT | + __DRI_ATTRIB_TEXTURE_2D_BIT | + __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT; + + modes->sRGBCapable = GL_FALSE; + } + } + } + } + *c = NULL; + + return configs; +} + +__DRIconfig **driConcatConfigs(__DRIconfig **a, + __DRIconfig **b) +{ + __DRIconfig **all; + int i, j, index; + + i = 0; + while (a[i] != NULL) + i++; + j = 0; + while (b[j] != NULL) + j++; + + all = malloc((i + j + 1) * sizeof *all); + index = 0; + for (i = 0; a[i] != NULL; i++) + all[index++] = a[i]; + for (j = 0; b[j] != NULL; j++) + all[index++] = b[j]; + all[index++] = NULL; + + free(a); + free(b); + + return all; +} + +#define __ATTRIB(attrib, field) \ + { attrib, offsetof(struct gl_config, field) } + +static const struct { unsigned int attrib, offset; } attribMap[] = { + __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits), + __ATTRIB(__DRI_ATTRIB_LEVEL, level), + __ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits), + __ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits), + __ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits), + __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits), + __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits), + __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits), + __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits), + __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits), + __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits), + __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits), + __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers), + __ATTRIB(__DRI_ATTRIB_SAMPLES, samples), + __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode), + __ATTRIB(__DRI_ATTRIB_STEREO, stereoMode), + __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentPixel), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha), + __ATTRIB(__DRI_ATTRIB_FLOAT_MODE, floatMode), + __ATTRIB(__DRI_ATTRIB_RED_MASK, redMask), + __ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask), + __ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask), + __ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask), + __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth), + __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight), + __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels), + __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth), + __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight), + __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod), + __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb), + __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba), + __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture), + __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS, bindToTextureTargets), + __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted), + __ATTRIB(__DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE, sRGBCapable), + + /* The struct field doesn't matter here, these are handled by the + * switch in driGetConfigAttribIndex. We need them in the array + * so the iterator includes them though.*/ + __ATTRIB(__DRI_ATTRIB_RENDER_TYPE, level), + __ATTRIB(__DRI_ATTRIB_CONFIG_CAVEAT, level), + __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, level) +}; + +#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) + + +/** + * Return the value of a configuration attribute. The attribute is + * indicated by the index. + */ +static int +driGetConfigAttribIndex(const __DRIconfig *config, + unsigned int index, unsigned int *value) +{ + switch (attribMap[index].attrib) { + case __DRI_ATTRIB_RENDER_TYPE: + /* no support for color index mode */ + *value = __DRI_ATTRIB_RGBA_BIT; + break; + case __DRI_ATTRIB_CONFIG_CAVEAT: + if (config->modes.visualRating == GLX_NON_CONFORMANT_CONFIG) + *value = __DRI_ATTRIB_NON_CONFORMANT_CONFIG; + else if (config->modes.visualRating == GLX_SLOW_CONFIG) + *value = __DRI_ATTRIB_SLOW_BIT; + else + *value = 0; + break; + case __DRI_ATTRIB_SWAP_METHOD: + /* XXX no return value??? */ + break; + + case __DRI_ATTRIB_FLOAT_MODE: + /* this field is not int-sized */ + *value = config->modes.floatMode; + break; + + default: + /* any other int-sized field */ + *value = *(unsigned int *) + ((char *) &config->modes + attribMap[index].offset); + + break; + } + + return GL_TRUE; +} + + +/** + * Get the value of a configuration attribute. + * \param attrib the attribute (one of the _DRI_ATTRIB_x tokens) + * \param value returns the attribute's value + * \return 1 for success, 0 for failure + */ +int +driGetConfigAttrib(const __DRIconfig *config, + unsigned int attrib, unsigned int *value) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(attribMap); i++) + if (attribMap[i].attrib == attrib) + return driGetConfigAttribIndex(config, i, value); + + return GL_FALSE; +} + + +/** + * Get a configuration attribute name and value, given an index. + * \param index which field of the __DRIconfig to query + * \param attrib returns the attribute name (one of the _DRI_ATTRIB_x tokens) + * \param value returns the attribute's value + * \return 1 for success, 0 for failure + */ +int +driIndexConfigAttrib(const __DRIconfig *config, int index, + unsigned int *attrib, unsigned int *value) +{ + if (index >= 0 && index < ARRAY_SIZE(attribMap)) { + *attrib = attribMap[index].attrib; + return driGetConfigAttribIndex(config, index, value); + } + + return GL_FALSE; +} diff --git a/mesalib/src/mesa/drivers/dri/common/utils.h b/mesalib/src/mesa/drivers/dri/common/utils.h index 10fb23de9..100d0dd51 100644 --- a/mesalib/src/mesa/drivers/dri/common/utils.h +++ b/mesalib/src/mesa/drivers/dri/common/utils.h @@ -1,123 +1,98 @@ -/*
- * (C) Copyright IBM Corporation 2002, 2004
- * 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
- * VA LINUX SYSTEM, IBM 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:
- * Ian Romanick <idr@us.ibm.com>
- */
-
-#ifndef DRI_DEBUG_H
-#define DRI_DEBUG_H
-
-#include <GL/gl.h>
-#include <GL/internal/dri_interface.h>
-#include "main/context.h"
-#include "main/remap.h"
-
-typedef struct __DRIutilversionRec2 __DRIutilversion2;
-
-struct dri_debug_control {
- const char * string;
- unsigned flag;
-};
-
-/**
- * Description of the API for an extension to OpenGL.
- */
-struct dri_extension {
- /**
- * Name of the extension.
- */
- const char * name;
-
-
- /**
- * Pointer to a list of \c dri_extension_function structures. The list
- * is terminated by a structure with a \c NULL
- * \c dri_extension_function::strings pointer.
- */
- const struct gl_function_remap * functions;
-};
-
-/**
- * Used to store a version which includes a major range instead of a single
- * major version number.
- */
-struct __DRIutilversionRec2 {
- int major_min; /** min allowed Major version number. */
- int major_max; /** max allowed Major version number. */
- int minor; /**< Minor version number. */
- int patch; /**< Patch-level. */
-};
-
-extern void
-__driUtilMessage(const char *f, ...);
-
-extern unsigned driParseDebugString( const char * debug,
- const struct dri_debug_control * control );
-
-extern unsigned driGetRendererString( char * buffer,
- const char * hardware_name, GLuint agp_mode );
-
-extern void driInitExtensions( struct gl_context * ctx,
- const struct dri_extension * card_extensions, GLboolean enable_imaging );
-
-extern void driInitSingleExtension( struct gl_context * ctx,
- const struct dri_extension * ext );
-
-extern GLboolean driCheckDriDdxDrmVersions2(const char * driver_name,
- const __DRIversion * driActual, const __DRIversion * driExpected,
- const __DRIversion * ddxActual, const __DRIversion * ddxExpected,
- const __DRIversion * drmActual, const __DRIversion * drmExpected);
-
-extern GLboolean driCheckDriDdxDrmVersions3(const char * driver_name,
- const __DRIversion * driActual, const __DRIversion * driExpected,
- const __DRIversion * ddxActual, const __DRIutilversion2 * ddxExpected,
- const __DRIversion * drmActual, const __DRIversion * drmExpected);
-
-extern GLboolean driClipRectToFramebuffer( const struct gl_framebuffer *buffer,
- GLint *x, GLint *y,
- GLsizei *width, GLsizei *height );
-
-struct __DRIconfigRec {
- struct gl_config modes;
-};
-
-extern __DRIconfig **
-driCreateConfigs(GLenum fb_format, GLenum fb_type,
- const uint8_t * depth_bits, const uint8_t * stencil_bits,
- unsigned num_depth_stencil_bits,
- const GLenum * db_modes, unsigned num_db_modes,
- const uint8_t * msaa_samples, unsigned num_msaa_modes,
- GLboolean enable_accum);
-
-__DRIconfig **driConcatConfigs(__DRIconfig **a,
- __DRIconfig **b);
-
-int
-driGetConfigAttrib(const __DRIconfig *config,
- unsigned int attrib, unsigned int *value);
-int
-driIndexConfigAttrib(const __DRIconfig *config, int index,
- unsigned int *attrib, unsigned int *value);
-
-#endif /* DRI_DEBUG_H */
+/* + * (C) Copyright IBM Corporation 2002, 2004 + * 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 + * VA LINUX SYSTEM, IBM 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: + * Ian Romanick <idr@us.ibm.com> + */ + +#ifndef DRI_DEBUG_H +#define DRI_DEBUG_H + +#include <GL/gl.h> +#include <GL/internal/dri_interface.h> +#include "main/context.h" + +typedef struct __DRIutilversionRec2 __DRIutilversion2; + +struct dri_debug_control { + const char * string; + unsigned flag; +}; + +/** + * Used to store a version which includes a major range instead of a single + * major version number. + */ +struct __DRIutilversionRec2 { + int major_min; /** min allowed Major version number. */ + int major_max; /** max allowed Major version number. */ + int minor; /**< Minor version number. */ + int patch; /**< Patch-level. */ +}; + +extern void +__driUtilMessage(const char *f, ...); + +extern unsigned driParseDebugString( const char * debug, + const struct dri_debug_control * control ); + +extern unsigned driGetRendererString( char * buffer, + const char * hardware_name, GLuint agp_mode ); + +extern GLboolean driCheckDriDdxDrmVersions2(const char * driver_name, + const __DRIversion * driActual, const __DRIversion * driExpected, + const __DRIversion * ddxActual, const __DRIversion * ddxExpected, + const __DRIversion * drmActual, const __DRIversion * drmExpected); + +extern GLboolean driCheckDriDdxDrmVersions3(const char * driver_name, + const __DRIversion * driActual, const __DRIversion * driExpected, + const __DRIversion * ddxActual, const __DRIutilversion2 * ddxExpected, + const __DRIversion * drmActual, const __DRIversion * drmExpected); + +extern GLboolean driClipRectToFramebuffer( const struct gl_framebuffer *buffer, + GLint *x, GLint *y, + GLsizei *width, GLsizei *height ); + +struct __DRIconfigRec { + struct gl_config modes; +}; + +extern __DRIconfig ** +driCreateConfigs(GLenum fb_format, GLenum fb_type, + const uint8_t * depth_bits, const uint8_t * stencil_bits, + unsigned num_depth_stencil_bits, + const GLenum * db_modes, unsigned num_db_modes, + const uint8_t * msaa_samples, unsigned num_msaa_modes, + GLboolean enable_accum); + +__DRIconfig **driConcatConfigs(__DRIconfig **a, + __DRIconfig **b); + +int +driGetConfigAttrib(const __DRIconfig *config, + unsigned int attrib, unsigned int *value); +int +driIndexConfigAttrib(const __DRIconfig *config, int index, + unsigned int *attrib, unsigned int *value); + +#endif /* DRI_DEBUG_H */ diff --git a/mesalib/src/mesa/drivers/dri/swrast/swrast.c b/mesalib/src/mesa/drivers/dri/swrast/swrast.c index 719b406ec..6c94947a0 100644 --- a/mesalib/src/mesa/drivers/dri/swrast/swrast.c +++ b/mesalib/src/mesa/drivers/dri/swrast/swrast.c @@ -135,6 +135,9 @@ swrastFillInModes(__DRIscreen *psp, uint8_t stencil_bits_array[4]; uint8_t msaa_samples_array[1]; + (void) psp; + (void) have_back_buffer; + depth_bits_array[0] = 0; depth_bits_array[1] = 0; depth_bits_array[2] = depth_bits; @@ -215,6 +218,7 @@ static void dri_destroy_screen(__DRIscreen * sPriv) { TRACE; + (void) sPriv; } @@ -278,6 +282,9 @@ swrast_alloc_front_storage(struct gl_context *ctx, struct gl_renderbuffer *rb, TRACE; + (void) ctx; + (void) internalFormat; + rb->Data = NULL; rb->Width = width; rb->Height = height; @@ -376,6 +383,9 @@ dri_create_buffer(__DRIscreen * sPriv, TRACE; + (void) sPriv; + (void) isPixmap; + drawable = CALLOC_STRUCT(dri_drawable); if (drawable == NULL) goto drawable_fail; @@ -537,6 +547,10 @@ viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h) struct gl_framebuffer *draw = ctx->WinSysDrawBuffer; struct gl_framebuffer *read = ctx->WinSysReadBuffer; + (void) x; + (void) y; + (void) w; + (void) h; swrast_check_and_update_window_size(ctx, draw); swrast_check_and_update_window_size(ctx, read); } @@ -609,9 +623,6 @@ InitExtensionsES2(struct gl_context *ctx) { int i; - /* Can't use driInitExtensions() since it uses extensions from - * main/remap_helper.h when called the first time. */ - for (i = 0; es2_extensions[i]; i++) _mesa_enable_extension(ctx, es2_extensions[i]); } @@ -681,8 +692,6 @@ dri_create_context(gl_api api, _mesa_enable_1_5_extensions(mesaCtx); _mesa_enable_2_0_extensions(mesaCtx); _mesa_enable_2_1_extensions(mesaCtx); - - driInitExtensions( mesaCtx, NULL, GL_FALSE ); break; case API_OPENGLES: _mesa_enable_1_3_extensions(mesaCtx); diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c index 1903a503c..9cec15b58 100644 --- a/mesalib/src/mesa/main/extensions.c +++ b/mesalib/src/mesa/main/extensions.c @@ -37,6 +37,8 @@ #include "mfeatures.h" #include "mtypes.h" +#define ALIGN(value, alignment) (((value) + alignment - 1) & ~(alignment - 1)) + enum { DISABLE = 0, GL = 1 << API_OPENGL, @@ -769,11 +771,11 @@ get_extension_override( struct gl_context *ctx ) if (env_const == NULL) { /* Return the empty string rather than NULL. This simplifies the logic * of client functions. */ - return calloc(1, sizeof(char)); + return calloc(4, sizeof(char)); } /* extra_exts: List of unrecognized extensions. */ - extra_exts = calloc(strlen(env_const), sizeof(char)); + extra_exts = calloc(ALIGN(strlen(env_const) + 2, 4), sizeof(char)); /* Copy env_const because strtok() is destructive. */ env = strdup(env_const); @@ -907,7 +909,7 @@ _mesa_make_extension_string(struct gl_context *ctx) if (extra_extensions != NULL) length += 1 + strlen(extra_extensions); /* +1 for space */ - exts = (char *) calloc(length + 1, sizeof(char)); + exts = (char *) calloc(ALIGN(length + 1, 4), sizeof(char)); if (exts == NULL) { free(extra_extensions); return NULL; diff --git a/mesalib/src/mesa/main/nvprogram.c b/mesalib/src/mesa/main/nvprogram.c index 7ff7645b7..a0e89b10f 100644 --- a/mesalib/src/mesa/main/nvprogram.c +++ b/mesalib/src/mesa/main/nvprogram.c @@ -560,7 +560,7 @@ _mesa_emit_nv_temp_initialization(struct gl_context *ctx, } void -_mesa_setup_nv_temporary_count(struct gl_context *ctx, struct gl_program *program) +_mesa_setup_nv_temporary_count(struct gl_program *program) { GLuint i; diff --git a/mesalib/src/mesa/main/nvprogram.h b/mesalib/src/mesa/main/nvprogram.h index 3d12b4e33..fc579a9fe 100644 --- a/mesalib/src/mesa/main/nvprogram.h +++ b/mesalib/src/mesa/main/nvprogram.h @@ -1,119 +1,119 @@ -/*
- * 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:
- * Brian Paul
- */
-
-
-#ifndef NVPROGRAM_H
-#define NVPROGRAM_H
-
-#include "glheader.h"
-
-struct gl_context;
-struct gl_program;
-
-extern void GLAPIENTRY
-_mesa_ExecuteProgramNV(GLenum target, GLuint id, const GLfloat *params);
-
-extern GLboolean GLAPIENTRY
-_mesa_AreProgramsResidentNV(GLsizei n, const GLuint *ids, GLboolean *residences);
-
-extern void GLAPIENTRY
-_mesa_RequestResidentProgramsNV(GLsizei n, const GLuint *ids);
-
-extern void GLAPIENTRY
-_mesa_GetProgramParameterfvNV(GLenum target, GLuint index, GLenum pname, GLfloat *params);
-
-extern void GLAPIENTRY
-_mesa_GetProgramParameterdvNV(GLenum target, GLuint index, GLenum pname, GLdouble *params);
-
-extern void GLAPIENTRY
-_mesa_GetProgramivNV(GLuint id, GLenum pname, GLint *params);
-
-extern void GLAPIENTRY
-_mesa_GetProgramStringNV(GLuint id, GLenum pname, GLubyte *program);
-
-extern void GLAPIENTRY
-_mesa_GetTrackMatrixivNV(GLenum target, GLuint address, GLenum pname, GLint *params);
-
-extern void GLAPIENTRY
-_mesa_GetVertexAttribdvNV(GLuint index, GLenum pname, GLdouble *params);
-
-extern void GLAPIENTRY
-_mesa_GetVertexAttribfvNV(GLuint index, GLenum pname, GLfloat *params);
-
-extern void GLAPIENTRY
-_mesa_GetVertexAttribivNV(GLuint index, GLenum pname, GLint *params);
-
-extern void GLAPIENTRY
-_mesa_GetVertexAttribPointervNV(GLuint index, GLenum pname, GLvoid **pointer);
-
-extern void GLAPIENTRY
-_mesa_LoadProgramNV(GLenum target, GLuint id, GLsizei len, const GLubyte *program);
-
-extern void GLAPIENTRY
-_mesa_ProgramParameters4dvNV(GLenum target, GLuint index, GLsizei num,
- const GLdouble *params);
-
-extern void GLAPIENTRY
-_mesa_ProgramParameters4fvNV(GLenum target, GLuint index, GLsizei num,
- const GLfloat *params);
-
-extern void GLAPIENTRY
-_mesa_TrackMatrixNV(GLenum target, GLuint address, GLenum matrix, GLenum transform);
-
-
-extern void GLAPIENTRY
-_mesa_ProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte *name,
- GLfloat x, GLfloat y, GLfloat z, GLfloat w);
-
-extern void GLAPIENTRY
-_mesa_ProgramNamedParameter4fvNV(GLuint id, GLsizei len, const GLubyte *name,
- const float v[]);
-
-extern void GLAPIENTRY
-_mesa_ProgramNamedParameter4dNV(GLuint id, GLsizei len, const GLubyte *name,
- GLdouble x, GLdouble y, GLdouble z, GLdouble w);
-
-extern void GLAPIENTRY
-_mesa_ProgramNamedParameter4dvNV(GLuint id, GLsizei len, const GLubyte *name,
- const double v[]);
-
-extern void GLAPIENTRY
-_mesa_GetProgramNamedParameterfvNV(GLuint id, GLsizei len, const GLubyte *name,
- GLfloat *params);
-
-extern void GLAPIENTRY
-_mesa_GetProgramNamedParameterdvNV(GLuint id, GLsizei len, const GLubyte *name,
- GLdouble *params);
-
-extern void
-_mesa_setup_nv_temporary_count(struct gl_context *ctx, struct gl_program *program);
-
-extern void
-_mesa_emit_nv_temp_initialization(struct gl_context *ctx,
- struct gl_program *program);
-
-#endif
+/* + * 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: + * Brian Paul + */ + + +#ifndef NVPROGRAM_H +#define NVPROGRAM_H + +#include "glheader.h" + +struct gl_context; +struct gl_program; + +extern void GLAPIENTRY +_mesa_ExecuteProgramNV(GLenum target, GLuint id, const GLfloat *params); + +extern GLboolean GLAPIENTRY +_mesa_AreProgramsResidentNV(GLsizei n, const GLuint *ids, GLboolean *residences); + +extern void GLAPIENTRY +_mesa_RequestResidentProgramsNV(GLsizei n, const GLuint *ids); + +extern void GLAPIENTRY +_mesa_GetProgramParameterfvNV(GLenum target, GLuint index, GLenum pname, GLfloat *params); + +extern void GLAPIENTRY +_mesa_GetProgramParameterdvNV(GLenum target, GLuint index, GLenum pname, GLdouble *params); + +extern void GLAPIENTRY +_mesa_GetProgramivNV(GLuint id, GLenum pname, GLint *params); + +extern void GLAPIENTRY +_mesa_GetProgramStringNV(GLuint id, GLenum pname, GLubyte *program); + +extern void GLAPIENTRY +_mesa_GetTrackMatrixivNV(GLenum target, GLuint address, GLenum pname, GLint *params); + +extern void GLAPIENTRY +_mesa_GetVertexAttribdvNV(GLuint index, GLenum pname, GLdouble *params); + +extern void GLAPIENTRY +_mesa_GetVertexAttribfvNV(GLuint index, GLenum pname, GLfloat *params); + +extern void GLAPIENTRY +_mesa_GetVertexAttribivNV(GLuint index, GLenum pname, GLint *params); + +extern void GLAPIENTRY +_mesa_GetVertexAttribPointervNV(GLuint index, GLenum pname, GLvoid **pointer); + +extern void GLAPIENTRY +_mesa_LoadProgramNV(GLenum target, GLuint id, GLsizei len, const GLubyte *program); + +extern void GLAPIENTRY +_mesa_ProgramParameters4dvNV(GLenum target, GLuint index, GLsizei num, + const GLdouble *params); + +extern void GLAPIENTRY +_mesa_ProgramParameters4fvNV(GLenum target, GLuint index, GLsizei num, + const GLfloat *params); + +extern void GLAPIENTRY +_mesa_TrackMatrixNV(GLenum target, GLuint address, GLenum matrix, GLenum transform); + + +extern void GLAPIENTRY +_mesa_ProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte *name, + GLfloat x, GLfloat y, GLfloat z, GLfloat w); + +extern void GLAPIENTRY +_mesa_ProgramNamedParameter4fvNV(GLuint id, GLsizei len, const GLubyte *name, + const float v[]); + +extern void GLAPIENTRY +_mesa_ProgramNamedParameter4dNV(GLuint id, GLsizei len, const GLubyte *name, + GLdouble x, GLdouble y, GLdouble z, GLdouble w); + +extern void GLAPIENTRY +_mesa_ProgramNamedParameter4dvNV(GLuint id, GLsizei len, const GLubyte *name, + const double v[]); + +extern void GLAPIENTRY +_mesa_GetProgramNamedParameterfvNV(GLuint id, GLsizei len, const GLubyte *name, + GLfloat *params); + +extern void GLAPIENTRY +_mesa_GetProgramNamedParameterdvNV(GLuint id, GLsizei len, const GLubyte *name, + GLdouble *params); + +extern void +_mesa_setup_nv_temporary_count(struct gl_program *program); + +extern void +_mesa_emit_nv_temp_initialization(struct gl_context *ctx, + struct gl_program *program); + +#endif diff --git a/mesalib/src/mesa/main/teximage.h b/mesalib/src/mesa/main/teximage.h index b59961eaf..8ef1d4560 100644 --- a/mesalib/src/mesa/main/teximage.h +++ b/mesalib/src/mesa/main/teximage.h @@ -1,285 +1,286 @@ -/**
- * \file teximage.h
- * Texture images manipulation functions.
- */
-
-/*
- * Mesa 3-D graphics library
- * Version: 6.5
- *
- * 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.
- */
-
-
-#ifndef TEXIMAGE_H
-#define TEXIMAGE_H
-
-
-#include "mtypes.h"
-#include "formats.h"
-
-
-extern void *
-_mesa_alloc_texmemory(GLsizei bytes);
-
-extern void
-_mesa_free_texmemory(void *m);
-
-
-/** \name Internal functions */
-/*@{*/
-
-extern GLint
-_mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat );
-
-
-extern GLboolean
-_mesa_is_proxy_texture(GLenum target);
-
-
-extern struct gl_texture_image *
-_mesa_new_texture_image( struct gl_context *ctx );
-
-
-extern void
-_mesa_delete_texture_image( struct gl_context *ctx,
- struct gl_texture_image *teximage );
-
-extern void
-_mesa_free_texture_image_data( struct gl_context *ctx,
- struct gl_texture_image *texImage );
-
-
-extern void
-_mesa_init_teximage_fields(struct gl_context *ctx, GLenum target,
- struct gl_texture_image *img,
- GLsizei width, GLsizei height, GLsizei depth,
- GLint border, GLenum internalFormat,
- gl_format format);
-
-
-extern gl_format
-_mesa_choose_texture_format(struct gl_context *ctx,
- struct gl_texture_object *texObj,
- GLenum target, GLint level,
- GLenum internalFormat, GLenum format, GLenum type);
-
-
-extern void
-_mesa_clear_texture_image(struct gl_context *ctx,
- struct gl_texture_image *texImage);
-
-
-extern void
-_mesa_set_tex_image(struct gl_texture_object *tObj,
- GLenum target, GLint level,
- struct gl_texture_image *texImage);
-
-
-extern struct gl_texture_object *
-_mesa_select_tex_object(struct gl_context *ctx,
- const struct gl_texture_unit *texUnit,
- GLenum target);
-
-extern struct gl_texture_object *
-_mesa_get_current_tex_object(struct gl_context *ctx, GLenum target);
-
-
-extern struct gl_texture_image *
-_mesa_select_tex_image(struct gl_context *ctx,
- const struct gl_texture_object *texObj,
- GLenum target, GLint level);
-
-
-extern struct gl_texture_image *
-_mesa_get_tex_image(struct gl_context *ctx, struct gl_texture_object *texObj,
- GLenum target, GLint level);
-
-
-extern struct gl_texture_image *
-_mesa_get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level);
-
-
-extern GLint
-_mesa_max_texture_levels(struct gl_context *ctx, GLenum target);
-
-
-extern GLboolean
-_mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
- GLint internalFormat, GLenum format, GLenum type,
- GLint width, GLint height, GLint depth, GLint border);
-
-
-extern GLuint
-_mesa_tex_target_to_face(GLenum target);
-
-extern GLint
-_mesa_get_texture_dimensions(GLenum target);
-
-/**
- * Lock a texture for updating. See also _mesa_lock_context_textures().
- */
-static INLINE void
-_mesa_lock_texture(struct gl_context *ctx, struct gl_texture_object *texObj)
-{
- _glthread_LOCK_MUTEX(ctx->Shared->TexMutex);
- ctx->Shared->TextureStateStamp++;
- (void) texObj;
-}
-
-static INLINE void
-_mesa_unlock_texture(struct gl_context *ctx, struct gl_texture_object *texObj)
-{
- _glthread_UNLOCK_MUTEX(ctx->Shared->TexMutex);
-}
-
-/*@}*/
-
-
-/** \name API entry point functions */
-/*@{*/
-
-extern void GLAPIENTRY
-_mesa_TexImage1D( GLenum target, GLint level, GLint internalformat,
- GLsizei width, GLint border,
- GLenum format, GLenum type, const GLvoid *pixels );
-
-
-extern void GLAPIENTRY
-_mesa_TexImage2D( GLenum target, GLint level, GLint internalformat,
- GLsizei width, GLsizei height, GLint border,
- GLenum format, GLenum type, const GLvoid *pixels );
-
-
-extern void GLAPIENTRY
-_mesa_TexImage3D( GLenum target, GLint level, GLint internalformat,
- GLsizei width, GLsizei height, GLsizei depth, GLint border,
- GLenum format, GLenum type, const GLvoid *pixels );
-
-
-extern void GLAPIENTRY
-_mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalformat,
- GLsizei width, GLsizei height, GLsizei depth,
- GLint border, GLenum format, GLenum type,
- const GLvoid *pixels );
-
-extern void GLAPIENTRY
-_mesa_EGLImageTargetTexture2DOES( GLenum target, GLeglImageOES image );
-
-extern void GLAPIENTRY
-_mesa_TexSubImage1D( GLenum target, GLint level, GLint xoffset,
- GLsizei width,
- GLenum format, GLenum type,
- const GLvoid *pixels );
-
-
-extern void GLAPIENTRY
-_mesa_TexSubImage2D( GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- const GLvoid *pixels );
-
-
-extern void GLAPIENTRY
-_mesa_TexSubImage3D( GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLenum type,
- const GLvoid *pixels );
-
-
-extern void GLAPIENTRY
-_mesa_CopyTexImage1D( GLenum target, GLint level, GLenum internalformat,
- GLint x, GLint y, GLsizei width, GLint border );
-
-
-extern void GLAPIENTRY
-_mesa_CopyTexImage2D( GLenum target, GLint level,
- GLenum internalformat, GLint x, GLint y,
- GLsizei width, GLsizei height, GLint border );
-
-
-extern void GLAPIENTRY
-_mesa_CopyTexSubImage1D( GLenum target, GLint level, GLint xoffset,
- GLint x, GLint y, GLsizei width );
-
-
-extern void GLAPIENTRY
-_mesa_CopyTexSubImage2D( GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLint x, GLint y, GLsizei width, GLsizei height );
-
-
-extern void GLAPIENTRY
-_mesa_CopyTexSubImage3D( GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLint x, GLint y, GLsizei width, GLsizei height );
-
-
-
-extern void GLAPIENTRY
-_mesa_CompressedTexImage1DARB(GLenum target, GLint level,
- GLenum internalformat, GLsizei width,
- GLint border, GLsizei imageSize,
- const GLvoid *data);
-
-extern void GLAPIENTRY
-_mesa_CompressedTexImage2DARB(GLenum target, GLint level,
- GLenum internalformat, GLsizei width,
- GLsizei height, GLint border, GLsizei imageSize,
- const GLvoid *data);
-
-extern void GLAPIENTRY
-_mesa_CompressedTexImage3DARB(GLenum target, GLint level,
- GLenum internalformat, GLsizei width,
- GLsizei height, GLsizei depth, GLint border,
- GLsizei imageSize, const GLvoid *data);
-
-#ifdef VMS
-#define _mesa_CompressedTexSubImage1DARB _mesa_CompressedTexSubImage1DAR
-#define _mesa_CompressedTexSubImage2DARB _mesa_CompressedTexSubImage2DAR
-#define _mesa_CompressedTexSubImage3DARB _mesa_CompressedTexSubImage3DAR
-#endif
-extern void GLAPIENTRY
-_mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
- GLsizei width, GLenum format,
- GLsizei imageSize, const GLvoid *data);
-
-extern void GLAPIENTRY
-_mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
- GLint yoffset, GLsizei width, GLsizei height,
- GLenum format, GLsizei imageSize,
- const GLvoid *data);
-
-extern void GLAPIENTRY
-_mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
- GLint yoffset, GLint zoffset, GLsizei width,
- GLsizei height, GLsizei depth, GLenum format,
- GLsizei imageSize, const GLvoid *data);
-
-
-extern void GLAPIENTRY
-_mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer);
-
-
-/*@}*/
-
-#endif
+/** + * \file teximage.h + * Texture images manipulation functions. + */ + +/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * 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. + */ + + +#ifndef TEXIMAGE_H +#define TEXIMAGE_H + + +#include "mtypes.h" +#include "formats.h" + + +extern void * +_mesa_alloc_texmemory(GLsizei bytes); + +extern void +_mesa_free_texmemory(void *m); + + +/** \name Internal functions */ +/*@{*/ + +extern GLint +_mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat ); + + +extern GLboolean +_mesa_is_proxy_texture(GLenum target); + + +extern struct gl_texture_image * +_mesa_new_texture_image( struct gl_context *ctx ); + + +extern void +_mesa_delete_texture_image( struct gl_context *ctx, + struct gl_texture_image *teximage ); + +extern void +_mesa_free_texture_image_data( struct gl_context *ctx, + struct gl_texture_image *texImage ); + + +extern void +_mesa_init_teximage_fields(struct gl_context *ctx, GLenum target, + struct gl_texture_image *img, + GLsizei width, GLsizei height, GLsizei depth, + GLint border, GLenum internalFormat, + gl_format format); + + +extern gl_format +_mesa_choose_texture_format(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum target, GLint level, + GLenum internalFormat, GLenum format, GLenum type); + + +extern void +_mesa_clear_texture_image(struct gl_context *ctx, + struct gl_texture_image *texImage); + + +extern void +_mesa_set_tex_image(struct gl_texture_object *tObj, + GLenum target, GLint level, + struct gl_texture_image *texImage); + + +extern struct gl_texture_object * +_mesa_select_tex_object(struct gl_context *ctx, + const struct gl_texture_unit *texUnit, + GLenum target); + +extern struct gl_texture_object * +_mesa_get_current_tex_object(struct gl_context *ctx, GLenum target); + + +extern struct gl_texture_image * +_mesa_select_tex_image(struct gl_context *ctx, + const struct gl_texture_object *texObj, + GLenum target, GLint level); + + +extern struct gl_texture_image * +_mesa_get_tex_image(struct gl_context *ctx, struct gl_texture_object *texObj, + GLenum target, GLint level); + + +extern struct gl_texture_image * +_mesa_get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level); + + +extern GLint +_mesa_max_texture_levels(struct gl_context *ctx, GLenum target); + + +extern GLboolean +_mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level, + GLint internalFormat, GLenum format, GLenum type, + GLint width, GLint height, GLint depth, GLint border); + + +extern GLuint +_mesa_tex_target_to_face(GLenum target); + +extern GLint +_mesa_get_texture_dimensions(GLenum target); + +/** + * Lock a texture for updating. See also _mesa_lock_context_textures(). + */ +static INLINE void +_mesa_lock_texture(struct gl_context *ctx, struct gl_texture_object *texObj) +{ + _glthread_LOCK_MUTEX(ctx->Shared->TexMutex); + ctx->Shared->TextureStateStamp++; + (void) texObj; +} + +static INLINE void +_mesa_unlock_texture(struct gl_context *ctx, struct gl_texture_object *texObj) +{ + (void) texObj; + _glthread_UNLOCK_MUTEX(ctx->Shared->TexMutex); +} + +/*@}*/ + + +/** \name API entry point functions */ +/*@{*/ + +extern void GLAPIENTRY +_mesa_TexImage1D( GLenum target, GLint level, GLint internalformat, + GLsizei width, GLint border, + GLenum format, GLenum type, const GLvoid *pixels ); + + +extern void GLAPIENTRY +_mesa_TexImage2D( GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLint border, + GLenum format, GLenum type, const GLvoid *pixels ); + + +extern void GLAPIENTRY +_mesa_TexImage3D( GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLsizei depth, GLint border, + GLenum format, GLenum type, const GLvoid *pixels ); + + +extern void GLAPIENTRY +_mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth, + GLint border, GLenum format, GLenum type, + const GLvoid *pixels ); + +extern void GLAPIENTRY +_mesa_EGLImageTargetTexture2DOES( GLenum target, GLeglImageOES image ); + +extern void GLAPIENTRY +_mesa_TexSubImage1D( GLenum target, GLint level, GLint xoffset, + GLsizei width, + GLenum format, GLenum type, + const GLvoid *pixels ); + + +extern void GLAPIENTRY +_mesa_TexSubImage2D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels ); + + +extern void GLAPIENTRY +_mesa_TexSubImage3D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, + const GLvoid *pixels ); + + +extern void GLAPIENTRY +_mesa_CopyTexImage1D( GLenum target, GLint level, GLenum internalformat, + GLint x, GLint y, GLsizei width, GLint border ); + + +extern void GLAPIENTRY +_mesa_CopyTexImage2D( GLenum target, GLint level, + GLenum internalformat, GLint x, GLint y, + GLsizei width, GLsizei height, GLint border ); + + +extern void GLAPIENTRY +_mesa_CopyTexSubImage1D( GLenum target, GLint level, GLint xoffset, + GLint x, GLint y, GLsizei width ); + + +extern void GLAPIENTRY +_mesa_CopyTexSubImage2D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, GLsizei width, GLsizei height ); + + +extern void GLAPIENTRY +_mesa_CopyTexSubImage3D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, GLsizei width, GLsizei height ); + + + +extern void GLAPIENTRY +_mesa_CompressedTexImage1DARB(GLenum target, GLint level, + GLenum internalformat, GLsizei width, + GLint border, GLsizei imageSize, + const GLvoid *data); + +extern void GLAPIENTRY +_mesa_CompressedTexImage2DARB(GLenum target, GLint level, + GLenum internalformat, GLsizei width, + GLsizei height, GLint border, GLsizei imageSize, + const GLvoid *data); + +extern void GLAPIENTRY +_mesa_CompressedTexImage3DARB(GLenum target, GLint level, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, GLint border, + GLsizei imageSize, const GLvoid *data); + +#ifdef VMS +#define _mesa_CompressedTexSubImage1DARB _mesa_CompressedTexSubImage1DAR +#define _mesa_CompressedTexSubImage2DARB _mesa_CompressedTexSubImage2DAR +#define _mesa_CompressedTexSubImage3DARB _mesa_CompressedTexSubImage3DAR +#endif +extern void GLAPIENTRY +_mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, + GLsizei width, GLenum format, + GLsizei imageSize, const GLvoid *data); + +extern void GLAPIENTRY +_mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLsizei imageSize, + const GLvoid *data); + +extern void GLAPIENTRY +_mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, GLenum format, + GLsizei imageSize, const GLvoid *data); + + +extern void GLAPIENTRY +_mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer); + + +/*@}*/ + +#endif diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp index 9813c4ae8..69a84de39 100644 --- a/mesalib/src/mesa/program/ir_to_mesa.cpp +++ b/mesalib/src/mesa/program/ir_to_mesa.cpp @@ -2156,6 +2156,8 @@ ir_to_mesa_visitor::visit(ir_texture *ir) break; } + const glsl_type *sampler_type = ir->sampler->type; + if (ir->projector) { if (opcode == OPCODE_TEX) { /* Slot the projector in as the last component of the coord. */ @@ -2187,6 +2189,9 @@ ir_to_mesa_visitor::visit(ir_texture *ir) tmp_src = get_temp(glsl_type::vec4_type); dst_reg tmp_dst = dst_reg(tmp_src); + /* Projective division not allowed for array samplers. */ + assert(!sampler_type->sampler_array); + tmp_dst.writemask = WRITEMASK_Z; emit(ir, OPCODE_MOV, tmp_dst, this->result); @@ -2211,7 +2216,15 @@ ir_to_mesa_visitor::visit(ir_texture *ir) * coord. */ ir->shadow_comparitor->accept(this); - coord_dst.writemask = WRITEMASK_Z; + + /* XXX This will need to be updated for cubemap array samplers. */ + if (sampler_type->sampler_dimensionality == GLSL_SAMPLER_DIM_2D && + sampler_type->sampler_array) { + coord_dst.writemask = WRITEMASK_W; + } else { + coord_dst.writemask = WRITEMASK_Z; + } + emit(ir, OPCODE_MOV, coord_dst, this->result); coord_dst.writemask = WRITEMASK_XYZW; } @@ -2235,8 +2248,6 @@ ir_to_mesa_visitor::visit(ir_texture *ir) this->shader_program, this->prog); - const glsl_type *sampler_type = ir->sampler->type; - switch (sampler_type->sampler_dimensionality) { case GLSL_SAMPLER_DIM_1D: inst->tex_target = (sampler_type->sampler_array) diff --git a/mesalib/src/mesa/program/nvvertparse.c b/mesalib/src/mesa/program/nvvertparse.c index 8f7199a99..91fe2c48b 100644 --- a/mesalib/src/mesa/program/nvvertparse.c +++ b/mesalib/src/mesa/program/nvvertparse.c @@ -1,1459 +1,1459 @@ -/*
- * Mesa 3-D graphics library
- * Version: 6.5.2
- *
- * 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 nvvertparse.c
- * NVIDIA vertex program parser.
- * \author Brian Paul
- */
-
-/*
- * Regarding GL_NV_vertex_program, GL_NV_vertex_program1_1:
- *
- * Portions of this software may use or implement intellectual
- * property owned and licensed by NVIDIA Corporation. NVIDIA disclaims
- * any and all warranties with respect to such intellectual property,
- * including any use thereof or modifications thereto.
- */
-
-#include "main/glheader.h"
-#include "main/context.h"
-#include "main/imports.h"
-#include "main/nvprogram.h"
-#include "nvvertparse.h"
-#include "prog_instruction.h"
-#include "prog_parameter.h"
-#include "prog_print.h"
-#include "program.h"
-
-
-/**
- * Current parsing state. This structure is passed among the parsing
- * functions and keeps track of the current parser position and various
- * program attributes.
- */
-struct parse_state {
- struct gl_context *ctx;
- const GLubyte *start;
- const GLubyte *pos;
- const GLubyte *curLine;
- GLboolean isStateProgram;
- GLboolean isPositionInvariant;
- GLboolean isVersion1_1;
- GLbitfield inputsRead;
- GLbitfield outputsWritten;
- GLboolean anyProgRegsWritten;
- GLboolean indirectRegisterFiles;
- GLuint numInst; /* number of instructions parsed */
-};
-
-
-/*
- * Called whenever we find an error during parsing.
- */
-static void
-record_error(struct parse_state *parseState, const char *msg, int lineNo)
-{
-#ifdef DEBUG
- GLint line, column;
- const GLubyte *lineStr;
- lineStr = _mesa_find_line_column(parseState->start,
- parseState->pos, &line, &column);
- _mesa_debug(parseState->ctx,
- "nvfragparse.c(%d): line %d, column %d:%s (%s)\n",
- lineNo, line, column, (char *) lineStr, msg);
- free((void *) lineStr);
-#else
- (void) lineNo;
-#endif
-
- /* Check that no error was already recorded. Only record the first one. */
- if (parseState->ctx->Program.ErrorString[0] == 0) {
- _mesa_set_program_error(parseState->ctx,
- parseState->pos - parseState->start,
- msg);
- }
-}
-
-
-#define RETURN_ERROR \
-do { \
- record_error(parseState, "Unexpected end of input.", __LINE__); \
- return GL_FALSE; \
-} while(0)
-
-#define RETURN_ERROR1(msg) \
-do { \
- record_error(parseState, msg, __LINE__); \
- return GL_FALSE; \
-} while(0)
-
-#define RETURN_ERROR2(msg1, msg2) \
-do { \
- char err[1000]; \
- sprintf(err, "%s %s", msg1, msg2); \
- record_error(parseState, err, __LINE__); \
- return GL_FALSE; \
-} while(0)
-
-
-
-
-
-static GLboolean IsLetter(GLubyte b)
-{
- return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z');
-}
-
-
-static GLboolean IsDigit(GLubyte b)
-{
- return b >= '0' && b <= '9';
-}
-
-
-static GLboolean IsWhitespace(GLubyte b)
-{
- return b == ' ' || b == '\t' || b == '\n' || b == '\r';
-}
-
-
-/**
- * Starting at 'str' find the next token. A token can be an integer,
- * an identifier or punctuation symbol.
- * \return <= 0 we found an error, else, return number of characters parsed.
- */
-static GLint
-GetToken(struct parse_state *parseState, GLubyte *token)
-{
- const GLubyte *str = parseState->pos;
- GLint i = 0, j = 0;
-
- token[0] = 0;
-
- /* skip whitespace and comments */
- while (str[i] && (IsWhitespace(str[i]) || str[i] == '#')) {
- if (str[i] == '#') {
- /* skip comment */
- while (str[i] && (str[i] != '\n' && str[i] != '\r')) {
- i++;
- }
- if (str[i] == '\n' || str[i] == '\r')
- parseState->curLine = str + i + 1;
- }
- else {
- /* skip whitespace */
- if (str[i] == '\n' || str[i] == '\r')
- parseState->curLine = str + i + 1;
- i++;
- }
- }
-
- if (str[i] == 0)
- return -i;
-
- /* try matching an integer */
- while (str[i] && IsDigit(str[i])) {
- token[j++] = str[i++];
- }
- if (j > 0 || !str[i]) {
- token[j] = 0;
- return i;
- }
-
- /* try matching an identifier */
- if (IsLetter(str[i])) {
- while (str[i] && (IsLetter(str[i]) || IsDigit(str[i]))) {
- token[j++] = str[i++];
- }
- token[j] = 0;
- return i;
- }
-
- /* punctuation character */
- if (str[i]) {
- token[0] = str[i++];
- token[1] = 0;
- return i;
- }
-
- /* end of input */
- token[0] = 0;
- return i;
-}
-
-
-/**
- * Get next token from input stream and increment stream pointer past token.
- */
-static GLboolean
-Parse_Token(struct parse_state *parseState, GLubyte *token)
-{
- GLint i;
- i = GetToken(parseState, token);
- if (i <= 0) {
- parseState->pos += (-i);
- return GL_FALSE;
- }
- parseState->pos += i;
- return GL_TRUE;
-}
-
-
-/**
- * Get next token from input stream but don't increment stream pointer.
- */
-static GLboolean
-Peek_Token(struct parse_state *parseState, GLubyte *token)
-{
- GLint i, len;
- i = GetToken(parseState, token);
- if (i <= 0) {
- parseState->pos += (-i);
- return GL_FALSE;
- }
- len = (GLint) strlen((const char *) token);
- parseState->pos += (i - len);
- return GL_TRUE;
-}
-
-
-/**
- * Try to match 'pattern' as the next token after any whitespace/comments.
- * Advance the current parsing position only if we match the pattern.
- * \return GL_TRUE if pattern is matched, GL_FALSE otherwise.
- */
-static GLboolean
-Parse_String(struct parse_state *parseState, const char *pattern)
-{
- const GLubyte *m;
- GLint i;
-
- /* skip whitespace and comments */
- while (IsWhitespace(*parseState->pos) || *parseState->pos == '#') {
- if (*parseState->pos == '#') {
- while (*parseState->pos && (*parseState->pos != '\n' && *parseState->pos != '\r')) {
- parseState->pos += 1;
- }
- if (*parseState->pos == '\n' || *parseState->pos == '\r')
- parseState->curLine = parseState->pos + 1;
- }
- else {
- /* skip whitespace */
- if (*parseState->pos == '\n' || *parseState->pos == '\r')
- parseState->curLine = parseState->pos + 1;
- parseState->pos += 1;
- }
- }
-
- /* Try to match the pattern */
- m = parseState->pos;
- for (i = 0; pattern[i]; i++) {
- if (*m != (GLubyte) pattern[i])
- return GL_FALSE;
- m += 1;
- }
- parseState->pos = m;
-
- return GL_TRUE; /* success */
-}
-
-
-/**********************************************************************/
-
-static const char *InputRegisters[MAX_NV_VERTEX_PROGRAM_INPUTS + 1] = {
- "OPOS", "WGHT", "NRML", "COL0", "COL1", "FOGC", "6", "7",
- "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", NULL
-};
-
-static const char *OutputRegisters[MAX_NV_VERTEX_PROGRAM_OUTPUTS + 1] = {
- "HPOS", "COL0", "COL1", "FOGC",
- "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7",
- "PSIZ", "BFC0", "BFC1", NULL
-};
-
-
-
-/**
- * Parse a temporary register: Rnn
- */
-static GLboolean
-Parse_TempReg(struct parse_state *parseState, GLint *tempRegNum)
-{
- GLubyte token[100];
-
- /* Should be 'R##' */
- if (!Parse_Token(parseState, token))
- RETURN_ERROR;
- if (token[0] != 'R')
- RETURN_ERROR1("Expected R##");
-
- if (IsDigit(token[1])) {
- GLint reg = atoi((char *) (token + 1));
- if (reg >= MAX_NV_VERTEX_PROGRAM_TEMPS)
- RETURN_ERROR1("Bad temporary register name");
- *tempRegNum = reg;
- }
- else {
- RETURN_ERROR1("Bad temporary register name");
- }
-
- return GL_TRUE;
-}
-
-
-/**
- * Parse address register "A0.x"
- */
-static GLboolean
-Parse_AddrReg(struct parse_state *parseState)
-{
- /* match 'A0' */
- if (!Parse_String(parseState, "A0"))
- RETURN_ERROR;
-
- /* match '.' */
- if (!Parse_String(parseState, "."))
- RETURN_ERROR;
-
- /* match 'x' */
- if (!Parse_String(parseState, "x"))
- RETURN_ERROR;
-
- return GL_TRUE;
-}
-
-
-/**
- * Parse absolute program parameter register "c[##]"
- */
-static GLboolean
-Parse_AbsParamReg(struct parse_state *parseState, GLint *regNum)
-{
- GLubyte token[100];
-
- if (!Parse_String(parseState, "c"))
- RETURN_ERROR;
-
- if (!Parse_String(parseState, "["))
- RETURN_ERROR;
-
- if (!Parse_Token(parseState, token))
- RETURN_ERROR;
-
- if (IsDigit(token[0])) {
- /* a numbered program parameter register */
- GLint reg = atoi((char *) token);
- if (reg >= MAX_NV_VERTEX_PROGRAM_PARAMS)
- RETURN_ERROR1("Bad program parameter number");
- *regNum = reg;
- }
- else {
- RETURN_ERROR;
- }
-
- if (!Parse_String(parseState, "]"))
- RETURN_ERROR;
-
- return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_ParamReg(struct parse_state *parseState, struct prog_src_register *srcReg)
-{
- GLubyte token[100];
-
- if (!Parse_String(parseState, "c"))
- RETURN_ERROR;
-
- if (!Parse_String(parseState, "["))
- RETURN_ERROR;
-
- if (!Peek_Token(parseState, token))
- RETURN_ERROR;
-
- if (IsDigit(token[0])) {
- /* a numbered program parameter register */
- GLint reg;
- (void) Parse_Token(parseState, token);
- reg = atoi((char *) token);
- if (reg >= MAX_NV_VERTEX_PROGRAM_PARAMS)
- RETURN_ERROR1("Bad program parameter number");
- srcReg->File = PROGRAM_ENV_PARAM;
- srcReg->Index = reg;
- }
- else if (strcmp((const char *) token, "A0") == 0) {
- /* address register "A0.x" */
- if (!Parse_AddrReg(parseState))
- RETURN_ERROR;
-
- srcReg->RelAddr = GL_TRUE;
- srcReg->File = PROGRAM_ENV_PARAM;
- parseState->indirectRegisterFiles |= (1 << srcReg->File);
- /* Look for +/-N offset */
- if (!Peek_Token(parseState, token))
- RETURN_ERROR;
-
- if (token[0] == '-' || token[0] == '+') {
- const GLubyte sign = token[0];
- (void) Parse_Token(parseState, token); /* consume +/- */
-
- /* an integer should be next */
- if (!Parse_Token(parseState, token))
- RETURN_ERROR;
-
- if (IsDigit(token[0])) {
- const GLint k = atoi((char *) token);
- if (sign == '-') {
- if (k > 64)
- RETURN_ERROR1("Bad address offset");
- srcReg->Index = -k;
- }
- else {
- if (k > 63)
- RETURN_ERROR1("Bad address offset");
- srcReg->Index = k;
- }
- }
- else {
- RETURN_ERROR;
- }
- }
- else {
- /* probably got a ']', catch it below */
- }
- }
- else {
- RETURN_ERROR;
- }
-
- /* Match closing ']' */
- if (!Parse_String(parseState, "]"))
- RETURN_ERROR;
-
- return GL_TRUE;
-}
-
-
-/**
- * Parse v[#] or v[<name>]
- */
-static GLboolean
-Parse_AttribReg(struct parse_state *parseState, GLint *tempRegNum)
-{
- GLubyte token[100];
- GLint j;
-
- /* Match 'v' */
- if (!Parse_String(parseState, "v"))
- RETURN_ERROR;
-
- /* Match '[' */
- if (!Parse_String(parseState, "["))
- RETURN_ERROR;
-
- /* match number or named register */
- if (!Parse_Token(parseState, token))
- RETURN_ERROR;
-
- if (parseState->isStateProgram && token[0] != '0')
- RETURN_ERROR1("Only v[0] accessible in vertex state programs");
-
- if (IsDigit(token[0])) {
- GLint reg = atoi((char *) token);
- if (reg >= MAX_NV_VERTEX_PROGRAM_INPUTS)
- RETURN_ERROR1("Bad vertex attribute register name");
- *tempRegNum = reg;
- }
- else {
- for (j = 0; InputRegisters[j]; j++) {
- if (strcmp((const char *) token, InputRegisters[j]) == 0) {
- *tempRegNum = j;
- break;
- }
- }
- if (!InputRegisters[j]) {
- /* unknown input register label */
- RETURN_ERROR2("Bad register name", token);
- }
- }
-
- /* Match '[' */
- if (!Parse_String(parseState, "]"))
- RETURN_ERROR;
-
- return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_OutputReg(struct parse_state *parseState, GLint *outputRegNum)
-{
- GLubyte token[100];
- GLint start, j;
-
- /* Match 'o' */
- if (!Parse_String(parseState, "o"))
- RETURN_ERROR;
-
- /* Match '[' */
- if (!Parse_String(parseState, "["))
- RETURN_ERROR;
-
- /* Get output reg name */
- if (!Parse_Token(parseState, token))
- RETURN_ERROR;
-
- if (parseState->isPositionInvariant)
- start = 1; /* skip HPOS register name */
- else
- start = 0;
-
- /* try to match an output register name */
- for (j = start; OutputRegisters[j]; j++) {
- if (strcmp((const char *) token, OutputRegisters[j]) == 0) {
- *outputRegNum = j;
- break;
- }
- }
- if (!OutputRegisters[j])
- RETURN_ERROR1("Unrecognized output register name");
-
- /* Match ']' */
- if (!Parse_String(parseState, "]"))
- RETURN_ERROR1("Expected ]");
-
- return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_MaskedDstReg(struct parse_state *parseState, struct prog_dst_register *dstReg)
-{
- GLubyte token[100];
- GLint idx;
-
- /* Dst reg can be R<n> or o[n] */
- if (!Peek_Token(parseState, token))
- RETURN_ERROR;
-
- if (token[0] == 'R') {
- /* a temporary register */
- dstReg->File = PROGRAM_TEMPORARY;
- if (!Parse_TempReg(parseState, &idx))
- RETURN_ERROR;
- dstReg->Index = idx;
- }
- else if (!parseState->isStateProgram && token[0] == 'o') {
- /* an output register */
- dstReg->File = PROGRAM_OUTPUT;
- if (!Parse_OutputReg(parseState, &idx))
- RETURN_ERROR;
- dstReg->Index = idx;
- }
- else if (parseState->isStateProgram && token[0] == 'c' &&
- parseState->isStateProgram) {
- /* absolute program parameter register */
- /* Only valid for vertex state programs */
- dstReg->File = PROGRAM_ENV_PARAM;
- if (!Parse_AbsParamReg(parseState, &idx))
- RETURN_ERROR;
- dstReg->Index = idx;
- }
- else {
- RETURN_ERROR1("Bad destination register name");
- }
-
- /* Parse optional write mask */
- if (!Peek_Token(parseState, token))
- RETURN_ERROR;
-
- if (token[0] == '.') {
- /* got a mask */
- GLint k = 0;
-
- if (!Parse_String(parseState, "."))
- RETURN_ERROR;
-
- if (!Parse_Token(parseState, token))
- RETURN_ERROR;
-
- dstReg->WriteMask = 0;
-
- if (token[k] == 'x') {
- dstReg->WriteMask |= WRITEMASK_X;
- k++;
- }
- if (token[k] == 'y') {
- dstReg->WriteMask |= WRITEMASK_Y;
- k++;
- }
- if (token[k] == 'z') {
- dstReg->WriteMask |= WRITEMASK_Z;
- k++;
- }
- if (token[k] == 'w') {
- dstReg->WriteMask |= WRITEMASK_W;
- k++;
- }
- if (k == 0) {
- RETURN_ERROR1("Bad writemask character");
- }
- return GL_TRUE;
- }
- else {
- dstReg->WriteMask = WRITEMASK_XYZW;
- return GL_TRUE;
- }
-}
-
-
-static GLboolean
-Parse_SwizzleSrcReg(struct parse_state *parseState, struct prog_src_register *srcReg)
-{
- GLubyte token[100];
- GLint idx;
-
- srcReg->RelAddr = GL_FALSE;
-
- /* check for '-' */
- if (!Peek_Token(parseState, token))
- RETURN_ERROR;
- if (token[0] == '-') {
- (void) Parse_String(parseState, "-");
- srcReg->Negate = NEGATE_XYZW;
- if (!Peek_Token(parseState, token))
- RETURN_ERROR;
- }
- else {
- srcReg->Negate = NEGATE_NONE;
- }
-
- /* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */
- if (token[0] == 'R') {
- srcReg->File = PROGRAM_TEMPORARY;
- if (!Parse_TempReg(parseState, &idx))
- RETURN_ERROR;
- srcReg->Index = idx;
- }
- else if (token[0] == 'c') {
- if (!Parse_ParamReg(parseState, srcReg))
- RETURN_ERROR;
- }
- else if (token[0] == 'v') {
- srcReg->File = PROGRAM_INPUT;
- if (!Parse_AttribReg(parseState, &idx))
- RETURN_ERROR;
- srcReg->Index = idx;
- }
- else {
- RETURN_ERROR2("Bad source register name", token);
- }
-
- /* init swizzle fields */
- srcReg->Swizzle = SWIZZLE_NOOP;
-
- /* Look for optional swizzle suffix */
- if (!Peek_Token(parseState, token))
- RETURN_ERROR;
- if (token[0] == '.') {
- (void) Parse_String(parseState, "."); /* consume . */
-
- if (!Parse_Token(parseState, token))
- RETURN_ERROR;
-
- if (token[1] == 0) {
- /* single letter swizzle */
- if (token[0] == 'x')
- srcReg->Swizzle = SWIZZLE_XXXX;
- else if (token[0] == 'y')
- srcReg->Swizzle = SWIZZLE_YYYY;
- else if (token[0] == 'z')
- srcReg->Swizzle = SWIZZLE_ZZZZ;
- else if (token[0] == 'w')
- srcReg->Swizzle = SWIZZLE_WWWW;
- else
- RETURN_ERROR1("Expected x, y, z, or w");
- }
- else {
- /* 2, 3 or 4-component swizzle */
- GLint k;
-
- srcReg->Swizzle = 0;
-
- for (k = 0; token[k] && k < 5; k++) {
- if (token[k] == 'x')
- srcReg->Swizzle |= 0 << (k*3);
- else if (token[k] == 'y')
- srcReg->Swizzle |= 1 << (k*3);
- else if (token[k] == 'z')
- srcReg->Swizzle |= 2 << (k*3);
- else if (token[k] == 'w')
- srcReg->Swizzle |= 3 << (k*3);
- else
- RETURN_ERROR;
- }
- if (k >= 5)
- RETURN_ERROR;
- }
- }
-
- return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_ScalarSrcReg(struct parse_state *parseState, struct prog_src_register *srcReg)
-{
- GLubyte token[100];
- GLint idx;
-
- srcReg->RelAddr = GL_FALSE;
-
- /* check for '-' */
- if (!Peek_Token(parseState, token))
- RETURN_ERROR;
- if (token[0] == '-') {
- srcReg->Negate = NEGATE_XYZW;
- (void) Parse_String(parseState, "-"); /* consume '-' */
- if (!Peek_Token(parseState, token))
- RETURN_ERROR;
- }
- else {
- srcReg->Negate = NEGATE_NONE;
- }
-
- /* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */
- if (token[0] == 'R') {
- srcReg->File = PROGRAM_TEMPORARY;
- if (!Parse_TempReg(parseState, &idx))
- RETURN_ERROR;
- srcReg->Index = idx;
- }
- else if (token[0] == 'c') {
- if (!Parse_ParamReg(parseState, srcReg))
- RETURN_ERROR;
- }
- else if (token[0] == 'v') {
- srcReg->File = PROGRAM_INPUT;
- if (!Parse_AttribReg(parseState, &idx))
- RETURN_ERROR;
- srcReg->Index = idx;
- }
- else {
- RETURN_ERROR2("Bad source register name", token);
- }
-
- /* Look for .[xyzw] suffix */
- if (!Parse_String(parseState, "."))
- RETURN_ERROR;
-
- if (!Parse_Token(parseState, token))
- RETURN_ERROR;
-
- if (token[0] == 'x' && token[1] == 0) {
- srcReg->Swizzle = 0;
- }
- else if (token[0] == 'y' && token[1] == 0) {
- srcReg->Swizzle = 1;
- }
- else if (token[0] == 'z' && token[1] == 0) {
- srcReg->Swizzle = 2;
- }
- else if (token[0] == 'w' && token[1] == 0) {
- srcReg->Swizzle = 3;
- }
- else {
- RETURN_ERROR1("Bad scalar source suffix");
- }
-
- return GL_TRUE;
-}
-
-
-static GLint
-Parse_UnaryOpInstruction(struct parse_state *parseState,
- struct prog_instruction *inst,
- enum prog_opcode opcode)
-{
- if (opcode == OPCODE_ABS && !parseState->isVersion1_1)
- RETURN_ERROR1("ABS illegal for vertex program 1.0");
-
- inst->Opcode = opcode;
-
- /* dest reg */
- if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
- RETURN_ERROR;
-
- /* comma */
- if (!Parse_String(parseState, ","))
- RETURN_ERROR;
-
- /* src arg */
- if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0]))
- RETURN_ERROR;
-
- /* semicolon */
- if (!Parse_String(parseState, ";"))
- RETURN_ERROR;
-
- return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_BiOpInstruction(struct parse_state *parseState,
- struct prog_instruction *inst,
- enum prog_opcode opcode)
-{
- if (opcode == OPCODE_DPH && !parseState->isVersion1_1)
- RETURN_ERROR1("DPH illegal for vertex program 1.0");
- if (opcode == OPCODE_SUB && !parseState->isVersion1_1)
- RETURN_ERROR1("SUB illegal for vertex program 1.0");
-
- inst->Opcode = opcode;
-
- /* dest reg */
- if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
- RETURN_ERROR;
-
- /* comma */
- if (!Parse_String(parseState, ","))
- RETURN_ERROR;
-
- /* first src arg */
- if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0]))
- RETURN_ERROR;
-
- /* comma */
- if (!Parse_String(parseState, ","))
- RETURN_ERROR;
-
- /* second src arg */
- if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[1]))
- RETURN_ERROR;
-
- /* semicolon */
- if (!Parse_String(parseState, ";"))
- RETURN_ERROR;
-
- /* make sure we don't reference more than one program parameter register */
- if (inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
- inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
- inst->SrcReg[0].Index != inst->SrcReg[1].Index)
- RETURN_ERROR1("Can't reference two program parameter registers");
-
- /* make sure we don't reference more than one vertex attribute register */
- if (inst->SrcReg[0].File == PROGRAM_INPUT &&
- inst->SrcReg[1].File == PROGRAM_INPUT &&
- inst->SrcReg[0].Index != inst->SrcReg[1].Index)
- RETURN_ERROR1("Can't reference two vertex attribute registers");
-
- return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_TriOpInstruction(struct parse_state *parseState,
- struct prog_instruction *inst,
- enum prog_opcode opcode)
-{
- inst->Opcode = opcode;
-
- /* dest reg */
- if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
- RETURN_ERROR;
-
- /* comma */
- if (!Parse_String(parseState, ","))
- RETURN_ERROR;
-
- /* first src arg */
- if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0]))
- RETURN_ERROR;
-
- /* comma */
- if (!Parse_String(parseState, ","))
- RETURN_ERROR;
-
- /* second src arg */
- if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[1]))
- RETURN_ERROR;
-
- /* comma */
- if (!Parse_String(parseState, ","))
- RETURN_ERROR;
-
- /* third src arg */
- if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[2]))
- RETURN_ERROR;
-
- /* semicolon */
- if (!Parse_String(parseState, ";"))
- RETURN_ERROR;
-
- /* make sure we don't reference more than one program parameter register */
- if ((inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
- inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
- inst->SrcReg[0].Index != inst->SrcReg[1].Index) ||
- (inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
- inst->SrcReg[2].File == PROGRAM_ENV_PARAM &&
- inst->SrcReg[0].Index != inst->SrcReg[2].Index) ||
- (inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
- inst->SrcReg[2].File == PROGRAM_ENV_PARAM &&
- inst->SrcReg[1].Index != inst->SrcReg[2].Index))
- RETURN_ERROR1("Can only reference one program register");
-
- /* make sure we don't reference more than one vertex attribute register */
- if ((inst->SrcReg[0].File == PROGRAM_INPUT &&
- inst->SrcReg[1].File == PROGRAM_INPUT &&
- inst->SrcReg[0].Index != inst->SrcReg[1].Index) ||
- (inst->SrcReg[0].File == PROGRAM_INPUT &&
- inst->SrcReg[2].File == PROGRAM_INPUT &&
- inst->SrcReg[0].Index != inst->SrcReg[2].Index) ||
- (inst->SrcReg[1].File == PROGRAM_INPUT &&
- inst->SrcReg[2].File == PROGRAM_INPUT &&
- inst->SrcReg[1].Index != inst->SrcReg[2].Index))
- RETURN_ERROR1("Can only reference one input register");
-
- return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_ScalarInstruction(struct parse_state *parseState,
- struct prog_instruction *inst,
- enum prog_opcode opcode)
-{
- if (opcode == OPCODE_RCC && !parseState->isVersion1_1)
- RETURN_ERROR1("RCC illegal for vertex program 1.0");
-
- inst->Opcode = opcode;
-
- /* dest reg */
- if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
- RETURN_ERROR;
-
- /* comma */
- if (!Parse_String(parseState, ","))
- RETURN_ERROR;
-
- /* first src arg */
- if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
- RETURN_ERROR;
-
- /* semicolon */
- if (!Parse_String(parseState, ";"))
- RETURN_ERROR;
-
- return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_AddressInstruction(struct parse_state *parseState, struct prog_instruction *inst)
-{
- inst->Opcode = OPCODE_ARL;
-
- /* Make ARB_vp backends happy */
- inst->DstReg.File = PROGRAM_ADDRESS;
- inst->DstReg.WriteMask = WRITEMASK_X;
- inst->DstReg.Index = 0;
-
- /* dest A0 reg */
- if (!Parse_AddrReg(parseState))
- RETURN_ERROR;
-
- /* comma */
- if (!Parse_String(parseState, ","))
- RETURN_ERROR;
-
- /* parse src reg */
- if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
- RETURN_ERROR;
-
- /* semicolon */
- if (!Parse_String(parseState, ";"))
- RETURN_ERROR;
-
- return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_EndInstruction(struct parse_state *parseState, struct prog_instruction *inst)
-{
- GLubyte token[100];
-
- inst->Opcode = OPCODE_END;
-
- /* this should fail! */
- if (Parse_Token(parseState, token))
- RETURN_ERROR2("Unexpected token after END:", token);
- else
- return GL_TRUE;
-}
-
-
-/**
- * The PRINT instruction is Mesa-specific and is meant as a debugging aid for
- * the vertex program developer.
- * The NV_vertex_program extension grammar is modified as follows:
- *
- * <instruction> ::= <ARL-instruction>
- * | ...
- * | <PRINT-instruction>
- *
- * <PRINT-instruction> ::= "PRINT" <string literal>
- * | "PRINT" <string literal> "," <srcReg>
- * | "PRINT" <string literal> "," <dstReg>
- */
-static GLboolean
-Parse_PrintInstruction(struct parse_state *parseState, struct prog_instruction *inst)
-{
- const GLubyte *str;
- GLubyte *msg;
- GLuint len;
- GLubyte token[100];
- struct prog_src_register *srcReg = &inst->SrcReg[0];
- GLint idx;
-
- inst->Opcode = OPCODE_PRINT;
-
- /* The first argument is a literal string 'just like this' */
- if (!Parse_String(parseState, "'"))
- RETURN_ERROR;
-
- str = parseState->pos;
- for (len = 0; str[len] != '\''; len++) /* find closing quote */
- ;
- parseState->pos += len + 1;
- msg = (GLubyte*) malloc(len + 1);
-
- memcpy(msg, str, len);
- msg[len] = 0;
- inst->Data = msg;
-
- /* comma */
- if (Parse_String(parseState, ",")) {
-
- /* The second argument is a register name */
- if (!Peek_Token(parseState, token))
- RETURN_ERROR;
-
- srcReg->RelAddr = GL_FALSE;
- srcReg->Negate = NEGATE_NONE;
- srcReg->Swizzle = SWIZZLE_NOOP;
-
- /* Register can be R<n>, c[n], c[n +/- offset], a named vertex attrib,
- * or an o[n] output register.
- */
- if (token[0] == 'R') {
- srcReg->File = PROGRAM_TEMPORARY;
- if (!Parse_TempReg(parseState, &idx))
- RETURN_ERROR;
- srcReg->Index = idx;
- }
- else if (token[0] == 'c') {
- srcReg->File = PROGRAM_ENV_PARAM;
- if (!Parse_ParamReg(parseState, srcReg))
- RETURN_ERROR;
- }
- else if (token[0] == 'v') {
- srcReg->File = PROGRAM_INPUT;
- if (!Parse_AttribReg(parseState, &idx))
- RETURN_ERROR;
- srcReg->Index = idx;
- }
- else if (token[0] == 'o') {
- srcReg->File = PROGRAM_OUTPUT;
- if (!Parse_OutputReg(parseState, &idx))
- RETURN_ERROR;
- srcReg->Index = idx;
- }
- else {
- RETURN_ERROR2("Bad source register name", token);
- }
- }
- else {
- srcReg->File = PROGRAM_UNDEFINED;
- }
-
- /* semicolon */
- if (!Parse_String(parseState, ";"))
- RETURN_ERROR;
-
- return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_OptionSequence(struct parse_state *parseState,
- struct prog_instruction program[])
-{
- (void) program;
- while (1) {
- if (!Parse_String(parseState, "OPTION"))
- return GL_TRUE; /* ok, not an OPTION statement */
- if (Parse_String(parseState, "NV_position_invariant")) {
- parseState->isPositionInvariant = GL_TRUE;
- }
- else {
- RETURN_ERROR1("unexpected OPTION statement");
- }
- if (!Parse_String(parseState, ";"))
- return GL_FALSE;
- }
-}
-
-
-static GLboolean
-Parse_InstructionSequence(struct parse_state *parseState,
- struct prog_instruction program[])
-{
- while (1) {
- struct prog_instruction *inst = program + parseState->numInst;
-
- /* Initialize the instruction */
- _mesa_init_instructions(inst, 1);
-
- if (Parse_String(parseState, "MOV")) {
- if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_MOV))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "LIT")) {
- if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_LIT))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "ABS")) {
- if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_ABS))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "MUL")) {
- if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MUL))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "ADD")) {
- if (!Parse_BiOpInstruction(parseState, inst, OPCODE_ADD))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "DP3")) {
- if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DP3))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "DP4")) {
- if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DP4))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "DST")) {
- if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DST))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "MIN")) {
- if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MIN))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "MAX")) {
- if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MAX))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "SLT")) {
- if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SLT))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "SGE")) {
- if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SGE))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "DPH")) {
- if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DPH))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "SUB")) {
- if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SUB))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "MAD")) {
- if (!Parse_TriOpInstruction(parseState, inst, OPCODE_MAD))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "RCP")) {
- if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RCP))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "RSQ")) {
- if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RSQ))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "EXP")) {
- if (!Parse_ScalarInstruction(parseState, inst, OPCODE_EXP))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "LOG")) {
- if (!Parse_ScalarInstruction(parseState, inst, OPCODE_LOG))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "RCC")) {
- if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RCC))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "ARL")) {
- if (!Parse_AddressInstruction(parseState, inst))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "PRINT")) {
- if (!Parse_PrintInstruction(parseState, inst))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "END")) {
- if (!Parse_EndInstruction(parseState, inst))
- RETURN_ERROR;
- else {
- parseState->numInst++;
- return GL_TRUE; /* all done */
- }
- }
- else {
- /* bad instruction name */
- RETURN_ERROR1("Unexpected token");
- }
-
- /* examine input/output registers */
- if (inst->DstReg.File == PROGRAM_OUTPUT)
- parseState->outputsWritten |= (1 << inst->DstReg.Index);
- else if (inst->DstReg.File == PROGRAM_ENV_PARAM)
- parseState->anyProgRegsWritten = GL_TRUE;
-
- if (inst->SrcReg[0].File == PROGRAM_INPUT)
- parseState->inputsRead |= (1 << inst->SrcReg[0].Index);
- if (inst->SrcReg[1].File == PROGRAM_INPUT)
- parseState->inputsRead |= (1 << inst->SrcReg[1].Index);
- if (inst->SrcReg[2].File == PROGRAM_INPUT)
- parseState->inputsRead |= (1 << inst->SrcReg[2].Index);
-
- parseState->numInst++;
-
- if (parseState->numInst >= MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS)
- RETURN_ERROR1("Program too long");
- }
-
- RETURN_ERROR;
-}
-
-
-static GLboolean
-Parse_Program(struct parse_state *parseState,
- struct prog_instruction instBuffer[])
-{
- if (parseState->isVersion1_1) {
- if (!Parse_OptionSequence(parseState, instBuffer)) {
- return GL_FALSE;
- }
- }
- return Parse_InstructionSequence(parseState, instBuffer);
-}
-
-
-/**
- * Parse/compile the 'str' returning the compiled 'program'.
- * ctx->Program.ErrorPos will be -1 if successful. Otherwise, ErrorPos
- * indicates the position of the error in 'str'.
- */
-void
-_mesa_parse_nv_vertex_program(struct gl_context *ctx, GLenum dstTarget,
- const GLubyte *str, GLsizei len,
- struct gl_vertex_program *program)
-{
- struct parse_state parseState;
- struct prog_instruction instBuffer[MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS];
- struct prog_instruction *newInst;
- GLenum target;
- GLubyte *programString;
-
- /* Make a null-terminated copy of the program string */
- programString = (GLubyte *) MALLOC(len + 1);
- if (!programString) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
- return;
- }
- memcpy(programString, str, len);
- programString[len] = 0;
-
- /* Get ready to parse */
- parseState.ctx = ctx;
- parseState.start = programString;
- parseState.isPositionInvariant = GL_FALSE;
- parseState.isVersion1_1 = GL_FALSE;
- parseState.numInst = 0;
- parseState.inputsRead = 0;
- parseState.outputsWritten = 0;
- parseState.anyProgRegsWritten = GL_FALSE;
- parseState.indirectRegisterFiles = 0x0;
-
- /* Reset error state */
- _mesa_set_program_error(ctx, -1, NULL);
-
- /* check the program header */
- if (strncmp((const char *) programString, "!!VP1.0", 7) == 0) {
- target = GL_VERTEX_PROGRAM_NV;
- parseState.pos = programString + 7;
- parseState.isStateProgram = GL_FALSE;
- }
- else if (strncmp((const char *) programString, "!!VP1.1", 7) == 0) {
- target = GL_VERTEX_PROGRAM_NV;
- parseState.pos = programString + 7;
- parseState.isStateProgram = GL_FALSE;
- parseState.isVersion1_1 = GL_TRUE;
- }
- else if (strncmp((const char *) programString, "!!VSP1.0", 8) == 0) {
- target = GL_VERTEX_STATE_PROGRAM_NV;
- parseState.pos = programString + 8;
- parseState.isStateProgram = GL_TRUE;
- }
- else {
- /* invalid header */
- ctx->Program.ErrorPos = 0;
- _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)");
- return;
- }
-
- /* make sure target and header match */
- if (target != dstTarget) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glLoadProgramNV(target mismatch)");
- return;
- }
-
-
- if (Parse_Program(&parseState, instBuffer)) {
- gl_state_index state_tokens[STATE_LENGTH] = {0, 0, 0, 0, 0};
- int i;
-
- /* successful parse! */
-
- if (parseState.isStateProgram) {
- if (!parseState.anyProgRegsWritten) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glLoadProgramNV(c[#] not written)");
- return;
- }
- }
- else {
- if (!parseState.isPositionInvariant &&
- !(parseState.outputsWritten & (1 << VERT_RESULT_HPOS))) {
- /* bit 1 = HPOS register */
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glLoadProgramNV(HPOS not written)");
- return;
- }
- }
-
- /* copy the compiled instructions */
- assert(parseState.numInst <= MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS);
- newInst = _mesa_alloc_instructions(parseState.numInst);
- if (!newInst) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
- free(programString);
- return; /* out of memory */
- }
- _mesa_copy_instructions(newInst, instBuffer, parseState.numInst);
-
- /* install the program */
- program->Base.Target = target;
- if (program->Base.String) {
- free(program->Base.String);
- }
- program->Base.String = programString;
- program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB;
- if (program->Base.Instructions) {
- free(program->Base.Instructions);
- }
- program->Base.Instructions = newInst;
- program->Base.InputsRead = parseState.inputsRead;
- if (parseState.isPositionInvariant)
- program->Base.InputsRead |= VERT_BIT_POS;
- program->Base.NumInstructions = parseState.numInst;
- program->Base.OutputsWritten = parseState.outputsWritten;
- program->IsPositionInvariant = parseState.isPositionInvariant;
- program->IsNVProgram = GL_TRUE;
-
-#ifdef DEBUG_foo
- printf("--- glLoadProgramNV result ---\n");
- _mesa_fprint_program_opt(stdout, &program->Base, PROG_PRINT_NV, 0);
- printf("------------------------------\n");
-#endif
-
- if (program->Base.Parameters)
- _mesa_free_parameter_list(program->Base.Parameters);
-
- program->Base.Parameters = _mesa_new_parameter_list ();
- program->Base.NumParameters = 0;
-
- program->Base.IndirectRegisterFiles = parseState.indirectRegisterFiles;
-
- state_tokens[0] = STATE_VERTEX_PROGRAM;
- state_tokens[1] = STATE_ENV;
- /* Add refs to all of the potential params, in order. If we want to not
- * upload everything, _mesa_layout_parameters is the answer.
- */
- for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS; i++) {
- GLint index;
- state_tokens[2] = i;
- index = _mesa_add_state_reference(program->Base.Parameters,
- state_tokens);
- assert(index == i);
- }
- program->Base.NumParameters = program->Base.Parameters->NumParameters;
-
- _mesa_setup_nv_temporary_count(ctx, &program->Base);
- _mesa_emit_nv_temp_initialization(ctx, &program->Base);
- }
- else {
- /* Error! */
- _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV");
- /* NOTE: _mesa_set_program_error would have been called already */
- /* GL_NV_vertex_program isn't supposed to set the error string
- * so we reset it here.
- */
- _mesa_set_program_error(ctx, ctx->Program.ErrorPos, NULL);
- }
-}
-
-
-const char *
-_mesa_nv_vertex_input_register_name(GLuint i)
-{
- ASSERT(i < MAX_NV_VERTEX_PROGRAM_INPUTS);
- return InputRegisters[i];
-}
-
-
-const char *
-_mesa_nv_vertex_output_register_name(GLuint i)
-{
- ASSERT(i < MAX_NV_VERTEX_PROGRAM_OUTPUTS);
- return OutputRegisters[i];
-}
-
+/* + * Mesa 3-D graphics library + * Version: 6.5.2 + * + * 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 nvvertparse.c + * NVIDIA vertex program parser. + * \author Brian Paul + */ + +/* + * Regarding GL_NV_vertex_program, GL_NV_vertex_program1_1: + * + * Portions of this software may use or implement intellectual + * property owned and licensed by NVIDIA Corporation. NVIDIA disclaims + * any and all warranties with respect to such intellectual property, + * including any use thereof or modifications thereto. + */ + +#include "main/glheader.h" +#include "main/context.h" +#include "main/imports.h" +#include "main/nvprogram.h" +#include "nvvertparse.h" +#include "prog_instruction.h" +#include "prog_parameter.h" +#include "prog_print.h" +#include "program.h" + + +/** + * Current parsing state. This structure is passed among the parsing + * functions and keeps track of the current parser position and various + * program attributes. + */ +struct parse_state { + struct gl_context *ctx; + const GLubyte *start; + const GLubyte *pos; + const GLubyte *curLine; + GLboolean isStateProgram; + GLboolean isPositionInvariant; + GLboolean isVersion1_1; + GLbitfield inputsRead; + GLbitfield outputsWritten; + GLboolean anyProgRegsWritten; + GLboolean indirectRegisterFiles; + GLuint numInst; /* number of instructions parsed */ +}; + + +/* + * Called whenever we find an error during parsing. + */ +static void +record_error(struct parse_state *parseState, const char *msg, int lineNo) +{ +#ifdef DEBUG + GLint line, column; + const GLubyte *lineStr; + lineStr = _mesa_find_line_column(parseState->start, + parseState->pos, &line, &column); + _mesa_debug(parseState->ctx, + "nvfragparse.c(%d): line %d, column %d:%s (%s)\n", + lineNo, line, column, (char *) lineStr, msg); + free((void *) lineStr); +#else + (void) lineNo; +#endif + + /* Check that no error was already recorded. Only record the first one. */ + if (parseState->ctx->Program.ErrorString[0] == 0) { + _mesa_set_program_error(parseState->ctx, + parseState->pos - parseState->start, + msg); + } +} + + +#define RETURN_ERROR \ +do { \ + record_error(parseState, "Unexpected end of input.", __LINE__); \ + return GL_FALSE; \ +} while(0) + +#define RETURN_ERROR1(msg) \ +do { \ + record_error(parseState, msg, __LINE__); \ + return GL_FALSE; \ +} while(0) + +#define RETURN_ERROR2(msg1, msg2) \ +do { \ + char err[1000]; \ + sprintf(err, "%s %s", msg1, msg2); \ + record_error(parseState, err, __LINE__); \ + return GL_FALSE; \ +} while(0) + + + + + +static GLboolean IsLetter(GLubyte b) +{ + return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z'); +} + + +static GLboolean IsDigit(GLubyte b) +{ + return b >= '0' && b <= '9'; +} + + +static GLboolean IsWhitespace(GLubyte b) +{ + return b == ' ' || b == '\t' || b == '\n' || b == '\r'; +} + + +/** + * Starting at 'str' find the next token. A token can be an integer, + * an identifier or punctuation symbol. + * \return <= 0 we found an error, else, return number of characters parsed. + */ +static GLint +GetToken(struct parse_state *parseState, GLubyte *token) +{ + const GLubyte *str = parseState->pos; + GLint i = 0, j = 0; + + token[0] = 0; + + /* skip whitespace and comments */ + while (str[i] && (IsWhitespace(str[i]) || str[i] == '#')) { + if (str[i] == '#') { + /* skip comment */ + while (str[i] && (str[i] != '\n' && str[i] != '\r')) { + i++; + } + if (str[i] == '\n' || str[i] == '\r') + parseState->curLine = str + i + 1; + } + else { + /* skip whitespace */ + if (str[i] == '\n' || str[i] == '\r') + parseState->curLine = str + i + 1; + i++; + } + } + + if (str[i] == 0) + return -i; + + /* try matching an integer */ + while (str[i] && IsDigit(str[i])) { + token[j++] = str[i++]; + } + if (j > 0 || !str[i]) { + token[j] = 0; + return i; + } + + /* try matching an identifier */ + if (IsLetter(str[i])) { + while (str[i] && (IsLetter(str[i]) || IsDigit(str[i]))) { + token[j++] = str[i++]; + } + token[j] = 0; + return i; + } + + /* punctuation character */ + if (str[i]) { + token[0] = str[i++]; + token[1] = 0; + return i; + } + + /* end of input */ + token[0] = 0; + return i; +} + + +/** + * Get next token from input stream and increment stream pointer past token. + */ +static GLboolean +Parse_Token(struct parse_state *parseState, GLubyte *token) +{ + GLint i; + i = GetToken(parseState, token); + if (i <= 0) { + parseState->pos += (-i); + return GL_FALSE; + } + parseState->pos += i; + return GL_TRUE; +} + + +/** + * Get next token from input stream but don't increment stream pointer. + */ +static GLboolean +Peek_Token(struct parse_state *parseState, GLubyte *token) +{ + GLint i, len; + i = GetToken(parseState, token); + if (i <= 0) { + parseState->pos += (-i); + return GL_FALSE; + } + len = (GLint) strlen((const char *) token); + parseState->pos += (i - len); + return GL_TRUE; +} + + +/** + * Try to match 'pattern' as the next token after any whitespace/comments. + * Advance the current parsing position only if we match the pattern. + * \return GL_TRUE if pattern is matched, GL_FALSE otherwise. + */ +static GLboolean +Parse_String(struct parse_state *parseState, const char *pattern) +{ + const GLubyte *m; + GLint i; + + /* skip whitespace and comments */ + while (IsWhitespace(*parseState->pos) || *parseState->pos == '#') { + if (*parseState->pos == '#') { + while (*parseState->pos && (*parseState->pos != '\n' && *parseState->pos != '\r')) { + parseState->pos += 1; + } + if (*parseState->pos == '\n' || *parseState->pos == '\r') + parseState->curLine = parseState->pos + 1; + } + else { + /* skip whitespace */ + if (*parseState->pos == '\n' || *parseState->pos == '\r') + parseState->curLine = parseState->pos + 1; + parseState->pos += 1; + } + } + + /* Try to match the pattern */ + m = parseState->pos; + for (i = 0; pattern[i]; i++) { + if (*m != (GLubyte) pattern[i]) + return GL_FALSE; + m += 1; + } + parseState->pos = m; + + return GL_TRUE; /* success */ +} + + +/**********************************************************************/ + +static const char *InputRegisters[MAX_NV_VERTEX_PROGRAM_INPUTS + 1] = { + "OPOS", "WGHT", "NRML", "COL0", "COL1", "FOGC", "6", "7", + "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", NULL +}; + +static const char *OutputRegisters[MAX_NV_VERTEX_PROGRAM_OUTPUTS + 1] = { + "HPOS", "COL0", "COL1", "FOGC", + "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", + "PSIZ", "BFC0", "BFC1", NULL +}; + + + +/** + * Parse a temporary register: Rnn + */ +static GLboolean +Parse_TempReg(struct parse_state *parseState, GLint *tempRegNum) +{ + GLubyte token[100]; + + /* Should be 'R##' */ + if (!Parse_Token(parseState, token)) + RETURN_ERROR; + if (token[0] != 'R') + RETURN_ERROR1("Expected R##"); + + if (IsDigit(token[1])) { + GLint reg = atoi((char *) (token + 1)); + if (reg >= MAX_NV_VERTEX_PROGRAM_TEMPS) + RETURN_ERROR1("Bad temporary register name"); + *tempRegNum = reg; + } + else { + RETURN_ERROR1("Bad temporary register name"); + } + + return GL_TRUE; +} + + +/** + * Parse address register "A0.x" + */ +static GLboolean +Parse_AddrReg(struct parse_state *parseState) +{ + /* match 'A0' */ + if (!Parse_String(parseState, "A0")) + RETURN_ERROR; + + /* match '.' */ + if (!Parse_String(parseState, ".")) + RETURN_ERROR; + + /* match 'x' */ + if (!Parse_String(parseState, "x")) + RETURN_ERROR; + + return GL_TRUE; +} + + +/** + * Parse absolute program parameter register "c[##]" + */ +static GLboolean +Parse_AbsParamReg(struct parse_state *parseState, GLint *regNum) +{ + GLubyte token[100]; + + if (!Parse_String(parseState, "c")) + RETURN_ERROR; + + if (!Parse_String(parseState, "[")) + RETURN_ERROR; + + if (!Parse_Token(parseState, token)) + RETURN_ERROR; + + if (IsDigit(token[0])) { + /* a numbered program parameter register */ + GLint reg = atoi((char *) token); + if (reg >= MAX_NV_VERTEX_PROGRAM_PARAMS) + RETURN_ERROR1("Bad program parameter number"); + *regNum = reg; + } + else { + RETURN_ERROR; + } + + if (!Parse_String(parseState, "]")) + RETURN_ERROR; + + return GL_TRUE; +} + + +static GLboolean +Parse_ParamReg(struct parse_state *parseState, struct prog_src_register *srcReg) +{ + GLubyte token[100]; + + if (!Parse_String(parseState, "c")) + RETURN_ERROR; + + if (!Parse_String(parseState, "[")) + RETURN_ERROR; + + if (!Peek_Token(parseState, token)) + RETURN_ERROR; + + if (IsDigit(token[0])) { + /* a numbered program parameter register */ + GLint reg; + (void) Parse_Token(parseState, token); + reg = atoi((char *) token); + if (reg >= MAX_NV_VERTEX_PROGRAM_PARAMS) + RETURN_ERROR1("Bad program parameter number"); + srcReg->File = PROGRAM_ENV_PARAM; + srcReg->Index = reg; + } + else if (strcmp((const char *) token, "A0") == 0) { + /* address register "A0.x" */ + if (!Parse_AddrReg(parseState)) + RETURN_ERROR; + + srcReg->RelAddr = GL_TRUE; + srcReg->File = PROGRAM_ENV_PARAM; + parseState->indirectRegisterFiles |= (1 << srcReg->File); + /* Look for +/-N offset */ + if (!Peek_Token(parseState, token)) + RETURN_ERROR; + + if (token[0] == '-' || token[0] == '+') { + const GLubyte sign = token[0]; + (void) Parse_Token(parseState, token); /* consume +/- */ + + /* an integer should be next */ + if (!Parse_Token(parseState, token)) + RETURN_ERROR; + + if (IsDigit(token[0])) { + const GLint k = atoi((char *) token); + if (sign == '-') { + if (k > 64) + RETURN_ERROR1("Bad address offset"); + srcReg->Index = -k; + } + else { + if (k > 63) + RETURN_ERROR1("Bad address offset"); + srcReg->Index = k; + } + } + else { + RETURN_ERROR; + } + } + else { + /* probably got a ']', catch it below */ + } + } + else { + RETURN_ERROR; + } + + /* Match closing ']' */ + if (!Parse_String(parseState, "]")) + RETURN_ERROR; + + return GL_TRUE; +} + + +/** + * Parse v[#] or v[<name>] + */ +static GLboolean +Parse_AttribReg(struct parse_state *parseState, GLint *tempRegNum) +{ + GLubyte token[100]; + GLint j; + + /* Match 'v' */ + if (!Parse_String(parseState, "v")) + RETURN_ERROR; + + /* Match '[' */ + if (!Parse_String(parseState, "[")) + RETURN_ERROR; + + /* match number or named register */ + if (!Parse_Token(parseState, token)) + RETURN_ERROR; + + if (parseState->isStateProgram && token[0] != '0') + RETURN_ERROR1("Only v[0] accessible in vertex state programs"); + + if (IsDigit(token[0])) { + GLint reg = atoi((char *) token); + if (reg >= MAX_NV_VERTEX_PROGRAM_INPUTS) + RETURN_ERROR1("Bad vertex attribute register name"); + *tempRegNum = reg; + } + else { + for (j = 0; InputRegisters[j]; j++) { + if (strcmp((const char *) token, InputRegisters[j]) == 0) { + *tempRegNum = j; + break; + } + } + if (!InputRegisters[j]) { + /* unknown input register label */ + RETURN_ERROR2("Bad register name", token); + } + } + + /* Match '[' */ + if (!Parse_String(parseState, "]")) + RETURN_ERROR; + + return GL_TRUE; +} + + +static GLboolean +Parse_OutputReg(struct parse_state *parseState, GLint *outputRegNum) +{ + GLubyte token[100]; + GLint start, j; + + /* Match 'o' */ + if (!Parse_String(parseState, "o")) + RETURN_ERROR; + + /* Match '[' */ + if (!Parse_String(parseState, "[")) + RETURN_ERROR; + + /* Get output reg name */ + if (!Parse_Token(parseState, token)) + RETURN_ERROR; + + if (parseState->isPositionInvariant) + start = 1; /* skip HPOS register name */ + else + start = 0; + + /* try to match an output register name */ + for (j = start; OutputRegisters[j]; j++) { + if (strcmp((const char *) token, OutputRegisters[j]) == 0) { + *outputRegNum = j; + break; + } + } + if (!OutputRegisters[j]) + RETURN_ERROR1("Unrecognized output register name"); + + /* Match ']' */ + if (!Parse_String(parseState, "]")) + RETURN_ERROR1("Expected ]"); + + return GL_TRUE; +} + + +static GLboolean +Parse_MaskedDstReg(struct parse_state *parseState, struct prog_dst_register *dstReg) +{ + GLubyte token[100]; + GLint idx; + + /* Dst reg can be R<n> or o[n] */ + if (!Peek_Token(parseState, token)) + RETURN_ERROR; + + if (token[0] == 'R') { + /* a temporary register */ + dstReg->File = PROGRAM_TEMPORARY; + if (!Parse_TempReg(parseState, &idx)) + RETURN_ERROR; + dstReg->Index = idx; + } + else if (!parseState->isStateProgram && token[0] == 'o') { + /* an output register */ + dstReg->File = PROGRAM_OUTPUT; + if (!Parse_OutputReg(parseState, &idx)) + RETURN_ERROR; + dstReg->Index = idx; + } + else if (parseState->isStateProgram && token[0] == 'c' && + parseState->isStateProgram) { + /* absolute program parameter register */ + /* Only valid for vertex state programs */ + dstReg->File = PROGRAM_ENV_PARAM; + if (!Parse_AbsParamReg(parseState, &idx)) + RETURN_ERROR; + dstReg->Index = idx; + } + else { + RETURN_ERROR1("Bad destination register name"); + } + + /* Parse optional write mask */ + if (!Peek_Token(parseState, token)) + RETURN_ERROR; + + if (token[0] == '.') { + /* got a mask */ + GLint k = 0; + + if (!Parse_String(parseState, ".")) + RETURN_ERROR; + + if (!Parse_Token(parseState, token)) + RETURN_ERROR; + + dstReg->WriteMask = 0; + + if (token[k] == 'x') { + dstReg->WriteMask |= WRITEMASK_X; + k++; + } + if (token[k] == 'y') { + dstReg->WriteMask |= WRITEMASK_Y; + k++; + } + if (token[k] == 'z') { + dstReg->WriteMask |= WRITEMASK_Z; + k++; + } + if (token[k] == 'w') { + dstReg->WriteMask |= WRITEMASK_W; + k++; + } + if (k == 0) { + RETURN_ERROR1("Bad writemask character"); + } + return GL_TRUE; + } + else { + dstReg->WriteMask = WRITEMASK_XYZW; + return GL_TRUE; + } +} + + +static GLboolean +Parse_SwizzleSrcReg(struct parse_state *parseState, struct prog_src_register *srcReg) +{ + GLubyte token[100]; + GLint idx; + + srcReg->RelAddr = GL_FALSE; + + /* check for '-' */ + if (!Peek_Token(parseState, token)) + RETURN_ERROR; + if (token[0] == '-') { + (void) Parse_String(parseState, "-"); + srcReg->Negate = NEGATE_XYZW; + if (!Peek_Token(parseState, token)) + RETURN_ERROR; + } + else { + srcReg->Negate = NEGATE_NONE; + } + + /* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */ + if (token[0] == 'R') { + srcReg->File = PROGRAM_TEMPORARY; + if (!Parse_TempReg(parseState, &idx)) + RETURN_ERROR; + srcReg->Index = idx; + } + else if (token[0] == 'c') { + if (!Parse_ParamReg(parseState, srcReg)) + RETURN_ERROR; + } + else if (token[0] == 'v') { + srcReg->File = PROGRAM_INPUT; + if (!Parse_AttribReg(parseState, &idx)) + RETURN_ERROR; + srcReg->Index = idx; + } + else { + RETURN_ERROR2("Bad source register name", token); + } + + /* init swizzle fields */ + srcReg->Swizzle = SWIZZLE_NOOP; + + /* Look for optional swizzle suffix */ + if (!Peek_Token(parseState, token)) + RETURN_ERROR; + if (token[0] == '.') { + (void) Parse_String(parseState, "."); /* consume . */ + + if (!Parse_Token(parseState, token)) + RETURN_ERROR; + + if (token[1] == 0) { + /* single letter swizzle */ + if (token[0] == 'x') + srcReg->Swizzle = SWIZZLE_XXXX; + else if (token[0] == 'y') + srcReg->Swizzle = SWIZZLE_YYYY; + else if (token[0] == 'z') + srcReg->Swizzle = SWIZZLE_ZZZZ; + else if (token[0] == 'w') + srcReg->Swizzle = SWIZZLE_WWWW; + else + RETURN_ERROR1("Expected x, y, z, or w"); + } + else { + /* 2, 3 or 4-component swizzle */ + GLint k; + + srcReg->Swizzle = 0; + + for (k = 0; token[k] && k < 5; k++) { + if (token[k] == 'x') + srcReg->Swizzle |= 0 << (k*3); + else if (token[k] == 'y') + srcReg->Swizzle |= 1 << (k*3); + else if (token[k] == 'z') + srcReg->Swizzle |= 2 << (k*3); + else if (token[k] == 'w') + srcReg->Swizzle |= 3 << (k*3); + else + RETURN_ERROR; + } + if (k >= 5) + RETURN_ERROR; + } + } + + return GL_TRUE; +} + + +static GLboolean +Parse_ScalarSrcReg(struct parse_state *parseState, struct prog_src_register *srcReg) +{ + GLubyte token[100]; + GLint idx; + + srcReg->RelAddr = GL_FALSE; + + /* check for '-' */ + if (!Peek_Token(parseState, token)) + RETURN_ERROR; + if (token[0] == '-') { + srcReg->Negate = NEGATE_XYZW; + (void) Parse_String(parseState, "-"); /* consume '-' */ + if (!Peek_Token(parseState, token)) + RETURN_ERROR; + } + else { + srcReg->Negate = NEGATE_NONE; + } + + /* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */ + if (token[0] == 'R') { + srcReg->File = PROGRAM_TEMPORARY; + if (!Parse_TempReg(parseState, &idx)) + RETURN_ERROR; + srcReg->Index = idx; + } + else if (token[0] == 'c') { + if (!Parse_ParamReg(parseState, srcReg)) + RETURN_ERROR; + } + else if (token[0] == 'v') { + srcReg->File = PROGRAM_INPUT; + if (!Parse_AttribReg(parseState, &idx)) + RETURN_ERROR; + srcReg->Index = idx; + } + else { + RETURN_ERROR2("Bad source register name", token); + } + + /* Look for .[xyzw] suffix */ + if (!Parse_String(parseState, ".")) + RETURN_ERROR; + + if (!Parse_Token(parseState, token)) + RETURN_ERROR; + + if (token[0] == 'x' && token[1] == 0) { + srcReg->Swizzle = 0; + } + else if (token[0] == 'y' && token[1] == 0) { + srcReg->Swizzle = 1; + } + else if (token[0] == 'z' && token[1] == 0) { + srcReg->Swizzle = 2; + } + else if (token[0] == 'w' && token[1] == 0) { + srcReg->Swizzle = 3; + } + else { + RETURN_ERROR1("Bad scalar source suffix"); + } + + return GL_TRUE; +} + + +static GLint +Parse_UnaryOpInstruction(struct parse_state *parseState, + struct prog_instruction *inst, + enum prog_opcode opcode) +{ + if (opcode == OPCODE_ABS && !parseState->isVersion1_1) + RETURN_ERROR1("ABS illegal for vertex program 1.0"); + + inst->Opcode = opcode; + + /* dest reg */ + if (!Parse_MaskedDstReg(parseState, &inst->DstReg)) + RETURN_ERROR; + + /* comma */ + if (!Parse_String(parseState, ",")) + RETURN_ERROR; + + /* src arg */ + if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0])) + RETURN_ERROR; + + /* semicolon */ + if (!Parse_String(parseState, ";")) + RETURN_ERROR; + + return GL_TRUE; +} + + +static GLboolean +Parse_BiOpInstruction(struct parse_state *parseState, + struct prog_instruction *inst, + enum prog_opcode opcode) +{ + if (opcode == OPCODE_DPH && !parseState->isVersion1_1) + RETURN_ERROR1("DPH illegal for vertex program 1.0"); + if (opcode == OPCODE_SUB && !parseState->isVersion1_1) + RETURN_ERROR1("SUB illegal for vertex program 1.0"); + + inst->Opcode = opcode; + + /* dest reg */ + if (!Parse_MaskedDstReg(parseState, &inst->DstReg)) + RETURN_ERROR; + + /* comma */ + if (!Parse_String(parseState, ",")) + RETURN_ERROR; + + /* first src arg */ + if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0])) + RETURN_ERROR; + + /* comma */ + if (!Parse_String(parseState, ",")) + RETURN_ERROR; + + /* second src arg */ + if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[1])) + RETURN_ERROR; + + /* semicolon */ + if (!Parse_String(parseState, ";")) + RETURN_ERROR; + + /* make sure we don't reference more than one program parameter register */ + if (inst->SrcReg[0].File == PROGRAM_ENV_PARAM && + inst->SrcReg[1].File == PROGRAM_ENV_PARAM && + inst->SrcReg[0].Index != inst->SrcReg[1].Index) + RETURN_ERROR1("Can't reference two program parameter registers"); + + /* make sure we don't reference more than one vertex attribute register */ + if (inst->SrcReg[0].File == PROGRAM_INPUT && + inst->SrcReg[1].File == PROGRAM_INPUT && + inst->SrcReg[0].Index != inst->SrcReg[1].Index) + RETURN_ERROR1("Can't reference two vertex attribute registers"); + + return GL_TRUE; +} + + +static GLboolean +Parse_TriOpInstruction(struct parse_state *parseState, + struct prog_instruction *inst, + enum prog_opcode opcode) +{ + inst->Opcode = opcode; + + /* dest reg */ + if (!Parse_MaskedDstReg(parseState, &inst->DstReg)) + RETURN_ERROR; + + /* comma */ + if (!Parse_String(parseState, ",")) + RETURN_ERROR; + + /* first src arg */ + if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0])) + RETURN_ERROR; + + /* comma */ + if (!Parse_String(parseState, ",")) + RETURN_ERROR; + + /* second src arg */ + if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[1])) + RETURN_ERROR; + + /* comma */ + if (!Parse_String(parseState, ",")) + RETURN_ERROR; + + /* third src arg */ + if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[2])) + RETURN_ERROR; + + /* semicolon */ + if (!Parse_String(parseState, ";")) + RETURN_ERROR; + + /* make sure we don't reference more than one program parameter register */ + if ((inst->SrcReg[0].File == PROGRAM_ENV_PARAM && + inst->SrcReg[1].File == PROGRAM_ENV_PARAM && + inst->SrcReg[0].Index != inst->SrcReg[1].Index) || + (inst->SrcReg[0].File == PROGRAM_ENV_PARAM && + inst->SrcReg[2].File == PROGRAM_ENV_PARAM && + inst->SrcReg[0].Index != inst->SrcReg[2].Index) || + (inst->SrcReg[1].File == PROGRAM_ENV_PARAM && + inst->SrcReg[2].File == PROGRAM_ENV_PARAM && + inst->SrcReg[1].Index != inst->SrcReg[2].Index)) + RETURN_ERROR1("Can only reference one program register"); + + /* make sure we don't reference more than one vertex attribute register */ + if ((inst->SrcReg[0].File == PROGRAM_INPUT && + inst->SrcReg[1].File == PROGRAM_INPUT && + inst->SrcReg[0].Index != inst->SrcReg[1].Index) || + (inst->SrcReg[0].File == PROGRAM_INPUT && + inst->SrcReg[2].File == PROGRAM_INPUT && + inst->SrcReg[0].Index != inst->SrcReg[2].Index) || + (inst->SrcReg[1].File == PROGRAM_INPUT && + inst->SrcReg[2].File == PROGRAM_INPUT && + inst->SrcReg[1].Index != inst->SrcReg[2].Index)) + RETURN_ERROR1("Can only reference one input register"); + + return GL_TRUE; +} + + +static GLboolean +Parse_ScalarInstruction(struct parse_state *parseState, + struct prog_instruction *inst, + enum prog_opcode opcode) +{ + if (opcode == OPCODE_RCC && !parseState->isVersion1_1) + RETURN_ERROR1("RCC illegal for vertex program 1.0"); + + inst->Opcode = opcode; + + /* dest reg */ + if (!Parse_MaskedDstReg(parseState, &inst->DstReg)) + RETURN_ERROR; + + /* comma */ + if (!Parse_String(parseState, ",")) + RETURN_ERROR; + + /* first src arg */ + if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0])) + RETURN_ERROR; + + /* semicolon */ + if (!Parse_String(parseState, ";")) + RETURN_ERROR; + + return GL_TRUE; +} + + +static GLboolean +Parse_AddressInstruction(struct parse_state *parseState, struct prog_instruction *inst) +{ + inst->Opcode = OPCODE_ARL; + + /* Make ARB_vp backends happy */ + inst->DstReg.File = PROGRAM_ADDRESS; + inst->DstReg.WriteMask = WRITEMASK_X; + inst->DstReg.Index = 0; + + /* dest A0 reg */ + if (!Parse_AddrReg(parseState)) + RETURN_ERROR; + + /* comma */ + if (!Parse_String(parseState, ",")) + RETURN_ERROR; + + /* parse src reg */ + if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0])) + RETURN_ERROR; + + /* semicolon */ + if (!Parse_String(parseState, ";")) + RETURN_ERROR; + + return GL_TRUE; +} + + +static GLboolean +Parse_EndInstruction(struct parse_state *parseState, struct prog_instruction *inst) +{ + GLubyte token[100]; + + inst->Opcode = OPCODE_END; + + /* this should fail! */ + if (Parse_Token(parseState, token)) + RETURN_ERROR2("Unexpected token after END:", token); + else + return GL_TRUE; +} + + +/** + * The PRINT instruction is Mesa-specific and is meant as a debugging aid for + * the vertex program developer. + * The NV_vertex_program extension grammar is modified as follows: + * + * <instruction> ::= <ARL-instruction> + * | ... + * | <PRINT-instruction> + * + * <PRINT-instruction> ::= "PRINT" <string literal> + * | "PRINT" <string literal> "," <srcReg> + * | "PRINT" <string literal> "," <dstReg> + */ +static GLboolean +Parse_PrintInstruction(struct parse_state *parseState, struct prog_instruction *inst) +{ + const GLubyte *str; + GLubyte *msg; + GLuint len; + GLubyte token[100]; + struct prog_src_register *srcReg = &inst->SrcReg[0]; + GLint idx; + + inst->Opcode = OPCODE_PRINT; + + /* The first argument is a literal string 'just like this' */ + if (!Parse_String(parseState, "'")) + RETURN_ERROR; + + str = parseState->pos; + for (len = 0; str[len] != '\''; len++) /* find closing quote */ + ; + parseState->pos += len + 1; + msg = (GLubyte*) malloc(len + 1); + + memcpy(msg, str, len); + msg[len] = 0; + inst->Data = msg; + + /* comma */ + if (Parse_String(parseState, ",")) { + + /* The second argument is a register name */ + if (!Peek_Token(parseState, token)) + RETURN_ERROR; + + srcReg->RelAddr = GL_FALSE; + srcReg->Negate = NEGATE_NONE; + srcReg->Swizzle = SWIZZLE_NOOP; + + /* Register can be R<n>, c[n], c[n +/- offset], a named vertex attrib, + * or an o[n] output register. + */ + if (token[0] == 'R') { + srcReg->File = PROGRAM_TEMPORARY; + if (!Parse_TempReg(parseState, &idx)) + RETURN_ERROR; + srcReg->Index = idx; + } + else if (token[0] == 'c') { + srcReg->File = PROGRAM_ENV_PARAM; + if (!Parse_ParamReg(parseState, srcReg)) + RETURN_ERROR; + } + else if (token[0] == 'v') { + srcReg->File = PROGRAM_INPUT; + if (!Parse_AttribReg(parseState, &idx)) + RETURN_ERROR; + srcReg->Index = idx; + } + else if (token[0] == 'o') { + srcReg->File = PROGRAM_OUTPUT; + if (!Parse_OutputReg(parseState, &idx)) + RETURN_ERROR; + srcReg->Index = idx; + } + else { + RETURN_ERROR2("Bad source register name", token); + } + } + else { + srcReg->File = PROGRAM_UNDEFINED; + } + + /* semicolon */ + if (!Parse_String(parseState, ";")) + RETURN_ERROR; + + return GL_TRUE; +} + + +static GLboolean +Parse_OptionSequence(struct parse_state *parseState, + struct prog_instruction program[]) +{ + (void) program; + while (1) { + if (!Parse_String(parseState, "OPTION")) + return GL_TRUE; /* ok, not an OPTION statement */ + if (Parse_String(parseState, "NV_position_invariant")) { + parseState->isPositionInvariant = GL_TRUE; + } + else { + RETURN_ERROR1("unexpected OPTION statement"); + } + if (!Parse_String(parseState, ";")) + return GL_FALSE; + } +} + + +static GLboolean +Parse_InstructionSequence(struct parse_state *parseState, + struct prog_instruction program[]) +{ + while (1) { + struct prog_instruction *inst = program + parseState->numInst; + + /* Initialize the instruction */ + _mesa_init_instructions(inst, 1); + + if (Parse_String(parseState, "MOV")) { + if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_MOV)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "LIT")) { + if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_LIT)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "ABS")) { + if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_ABS)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "MUL")) { + if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MUL)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "ADD")) { + if (!Parse_BiOpInstruction(parseState, inst, OPCODE_ADD)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "DP3")) { + if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DP3)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "DP4")) { + if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DP4)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "DST")) { + if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DST)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "MIN")) { + if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MIN)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "MAX")) { + if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MAX)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "SLT")) { + if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SLT)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "SGE")) { + if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SGE)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "DPH")) { + if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DPH)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "SUB")) { + if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SUB)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "MAD")) { + if (!Parse_TriOpInstruction(parseState, inst, OPCODE_MAD)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "RCP")) { + if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RCP)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "RSQ")) { + if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RSQ)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "EXP")) { + if (!Parse_ScalarInstruction(parseState, inst, OPCODE_EXP)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "LOG")) { + if (!Parse_ScalarInstruction(parseState, inst, OPCODE_LOG)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "RCC")) { + if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RCC)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "ARL")) { + if (!Parse_AddressInstruction(parseState, inst)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "PRINT")) { + if (!Parse_PrintInstruction(parseState, inst)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "END")) { + if (!Parse_EndInstruction(parseState, inst)) + RETURN_ERROR; + else { + parseState->numInst++; + return GL_TRUE; /* all done */ + } + } + else { + /* bad instruction name */ + RETURN_ERROR1("Unexpected token"); + } + + /* examine input/output registers */ + if (inst->DstReg.File == PROGRAM_OUTPUT) + parseState->outputsWritten |= (1 << inst->DstReg.Index); + else if (inst->DstReg.File == PROGRAM_ENV_PARAM) + parseState->anyProgRegsWritten = GL_TRUE; + + if (inst->SrcReg[0].File == PROGRAM_INPUT) + parseState->inputsRead |= (1 << inst->SrcReg[0].Index); + if (inst->SrcReg[1].File == PROGRAM_INPUT) + parseState->inputsRead |= (1 << inst->SrcReg[1].Index); + if (inst->SrcReg[2].File == PROGRAM_INPUT) + parseState->inputsRead |= (1 << inst->SrcReg[2].Index); + + parseState->numInst++; + + if (parseState->numInst >= MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS) + RETURN_ERROR1("Program too long"); + } + + RETURN_ERROR; +} + + +static GLboolean +Parse_Program(struct parse_state *parseState, + struct prog_instruction instBuffer[]) +{ + if (parseState->isVersion1_1) { + if (!Parse_OptionSequence(parseState, instBuffer)) { + return GL_FALSE; + } + } + return Parse_InstructionSequence(parseState, instBuffer); +} + + +/** + * Parse/compile the 'str' returning the compiled 'program'. + * ctx->Program.ErrorPos will be -1 if successful. Otherwise, ErrorPos + * indicates the position of the error in 'str'. + */ +void +_mesa_parse_nv_vertex_program(struct gl_context *ctx, GLenum dstTarget, + const GLubyte *str, GLsizei len, + struct gl_vertex_program *program) +{ + struct parse_state parseState; + struct prog_instruction instBuffer[MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS]; + struct prog_instruction *newInst; + GLenum target; + GLubyte *programString; + + /* Make a null-terminated copy of the program string */ + programString = (GLubyte *) MALLOC(len + 1); + if (!programString) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV"); + return; + } + memcpy(programString, str, len); + programString[len] = 0; + + /* Get ready to parse */ + parseState.ctx = ctx; + parseState.start = programString; + parseState.isPositionInvariant = GL_FALSE; + parseState.isVersion1_1 = GL_FALSE; + parseState.numInst = 0; + parseState.inputsRead = 0; + parseState.outputsWritten = 0; + parseState.anyProgRegsWritten = GL_FALSE; + parseState.indirectRegisterFiles = 0x0; + + /* Reset error state */ + _mesa_set_program_error(ctx, -1, NULL); + + /* check the program header */ + if (strncmp((const char *) programString, "!!VP1.0", 7) == 0) { + target = GL_VERTEX_PROGRAM_NV; + parseState.pos = programString + 7; + parseState.isStateProgram = GL_FALSE; + } + else if (strncmp((const char *) programString, "!!VP1.1", 7) == 0) { + target = GL_VERTEX_PROGRAM_NV; + parseState.pos = programString + 7; + parseState.isStateProgram = GL_FALSE; + parseState.isVersion1_1 = GL_TRUE; + } + else if (strncmp((const char *) programString, "!!VSP1.0", 8) == 0) { + target = GL_VERTEX_STATE_PROGRAM_NV; + parseState.pos = programString + 8; + parseState.isStateProgram = GL_TRUE; + } + else { + /* invalid header */ + ctx->Program.ErrorPos = 0; + _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)"); + return; + } + + /* make sure target and header match */ + if (target != dstTarget) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glLoadProgramNV(target mismatch)"); + return; + } + + + if (Parse_Program(&parseState, instBuffer)) { + gl_state_index state_tokens[STATE_LENGTH] = {0, 0, 0, 0, 0}; + int i; + + /* successful parse! */ + + if (parseState.isStateProgram) { + if (!parseState.anyProgRegsWritten) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glLoadProgramNV(c[#] not written)"); + return; + } + } + else { + if (!parseState.isPositionInvariant && + !(parseState.outputsWritten & (1 << VERT_RESULT_HPOS))) { + /* bit 1 = HPOS register */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glLoadProgramNV(HPOS not written)"); + return; + } + } + + /* copy the compiled instructions */ + assert(parseState.numInst <= MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS); + newInst = _mesa_alloc_instructions(parseState.numInst); + if (!newInst) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV"); + free(programString); + return; /* out of memory */ + } + _mesa_copy_instructions(newInst, instBuffer, parseState.numInst); + + /* install the program */ + program->Base.Target = target; + if (program->Base.String) { + free(program->Base.String); + } + program->Base.String = programString; + program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB; + if (program->Base.Instructions) { + free(program->Base.Instructions); + } + program->Base.Instructions = newInst; + program->Base.InputsRead = parseState.inputsRead; + if (parseState.isPositionInvariant) + program->Base.InputsRead |= VERT_BIT_POS; + program->Base.NumInstructions = parseState.numInst; + program->Base.OutputsWritten = parseState.outputsWritten; + program->IsPositionInvariant = parseState.isPositionInvariant; + program->IsNVProgram = GL_TRUE; + +#ifdef DEBUG_foo + printf("--- glLoadProgramNV result ---\n"); + _mesa_fprint_program_opt(stdout, &program->Base, PROG_PRINT_NV, 0); + printf("------------------------------\n"); +#endif + + if (program->Base.Parameters) + _mesa_free_parameter_list(program->Base.Parameters); + + program->Base.Parameters = _mesa_new_parameter_list (); + program->Base.NumParameters = 0; + + program->Base.IndirectRegisterFiles = parseState.indirectRegisterFiles; + + state_tokens[0] = STATE_VERTEX_PROGRAM; + state_tokens[1] = STATE_ENV; + /* Add refs to all of the potential params, in order. If we want to not + * upload everything, _mesa_layout_parameters is the answer. + */ + for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS; i++) { + GLint index; + state_tokens[2] = i; + index = _mesa_add_state_reference(program->Base.Parameters, + state_tokens); + assert(index == i); + } + program->Base.NumParameters = program->Base.Parameters->NumParameters; + + _mesa_setup_nv_temporary_count(&program->Base); + _mesa_emit_nv_temp_initialization(ctx, &program->Base); + } + else { + /* Error! */ + _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV"); + /* NOTE: _mesa_set_program_error would have been called already */ + /* GL_NV_vertex_program isn't supposed to set the error string + * so we reset it here. + */ + _mesa_set_program_error(ctx, ctx->Program.ErrorPos, NULL); + } +} + + +const char * +_mesa_nv_vertex_input_register_name(GLuint i) +{ + ASSERT(i < MAX_NV_VERTEX_PROGRAM_INPUTS); + return InputRegisters[i]; +} + + +const char * +_mesa_nv_vertex_output_register_name(GLuint i) +{ + ASSERT(i < MAX_NV_VERTEX_PROGRAM_OUTPUTS); + return OutputRegisters[i]; +} + diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c index a41e9e872..0ad9e1286 100644 --- a/mesalib/src/mesa/state_tracker/st_extensions.c +++ b/mesalib/src/mesa/state_tracker/st_extensions.c @@ -85,6 +85,9 @@ void st_init_limits(struct st_context *st) c->MaxTextureRectSize = _min(1 << (c->MaxTextureLevels - 1), MAX_TEXTURE_RECT_SIZE); + c->MaxArrayTextureLayers + = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS); + c->MaxTextureImageUnits = _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS), MAX_TEXTURE_IMAGE_UNITS); @@ -170,6 +173,12 @@ void st_init_limits(struct st_context *st) /* raise MaxParameters if native support is higher */ pc->MaxParameters = MAX2(pc->MaxParameters, pc->MaxNativeParameters); + /* Gallium doesn't really care about local vs. env parameters so use the + * same limits. + */ + pc->MaxLocalParams = pc->MaxParameters; + pc->MaxEnvParams = pc->MaxParameters; + options->EmitNoNoise = TRUE; /* TODO: make these more fine-grained if anyone needs it */ @@ -499,7 +508,7 @@ void st_init_extensions(struct st_context *st) } /* GL_EXT_texture_array */ - if (screen->get_param(screen, PIPE_CAP_ARRAY_TEXTURES)) { + if (screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS) > 1) { ctx->Extensions.EXT_texture_array = GL_TRUE; ctx->Extensions.MESA_texture_array = GL_TRUE; } diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 9394bea00..892169822 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -519,7 +519,7 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, inst->function = NULL; - if (op == TGSI_OPCODE_ARL) + if (op == TGSI_OPCODE_ARL || op == TGSI_OPCODE_UARL) this->num_address_regs = 1; /* Update indirect addressing status used by TGSI */ @@ -746,16 +746,12 @@ void glsl_to_tgsi_visitor::emit_arl(ir_instruction *ir, st_dst_reg dst, st_src_reg src0) { - st_src_reg tmp = get_temp(glsl_type::float_type); + int op = TGSI_OPCODE_ARL; - if (src0.type == GLSL_TYPE_INT) - emit(NULL, TGSI_OPCODE_I2F, st_dst_reg(tmp), src0); - else if (src0.type == GLSL_TYPE_UINT) - emit(NULL, TGSI_OPCODE_U2F, st_dst_reg(tmp), src0); - else - tmp = src0; - - emit(NULL, TGSI_OPCODE_ARL, dst, tmp); + if (src0.type == GLSL_TYPE_INT || src0.type == GLSL_TYPE_UINT) + op = TGSI_OPCODE_UARL; + + emit(NULL, op, dst, src0); } /** @@ -2558,6 +2554,8 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) break; } + const glsl_type *sampler_type = ir->sampler->type; + if (ir->projector) { if (opcode == TGSI_OPCODE_TEX) { /* Slot the projector in as the last component of the coord. */ @@ -2589,6 +2587,9 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) tmp_src = get_temp(glsl_type::vec4_type); st_dst_reg tmp_dst = st_dst_reg(tmp_src); + /* Projective division not allowed for array samplers. */ + assert(!sampler_type->sampler_array); + tmp_dst.writemask = WRITEMASK_Z; emit(ir, TGSI_OPCODE_MOV, tmp_dst, this->result); @@ -2613,7 +2614,15 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) * coord. */ ir->shadow_comparitor->accept(this); - coord_dst.writemask = WRITEMASK_Z; + + /* XXX This will need to be updated for cubemap array samplers. */ + if (sampler_type->sampler_dimensionality == GLSL_SAMPLER_DIM_2D && + sampler_type->sampler_array) { + coord_dst.writemask = WRITEMASK_W; + } else { + coord_dst.writemask = WRITEMASK_Z; + } + emit(ir, TGSI_OPCODE_MOV, coord_dst, this->result); coord_dst.writemask = WRITEMASK_XYZW; } @@ -2651,8 +2660,6 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) inst->tex_offsets[0].SwizzleZ = GET_SWZ(offset.swizzle, 2); } - const glsl_type *sampler_type = ir->sampler->type; - switch (sampler_type->sampler_dimensionality) { case GLSL_SAMPLER_DIM_1D: inst->tex_target = (sampler_type->sampler_array) diff --git a/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c b/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c index f4263c64c..b4111b00d 100644 --- a/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c +++ b/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c @@ -276,6 +276,8 @@ translate_texture_target( GLuint textarget, case TEXTURE_1D_INDEX: return TGSI_TEXTURE_SHADOW1D; case TEXTURE_2D_INDEX: return TGSI_TEXTURE_SHADOW2D; case TEXTURE_RECT_INDEX: return TGSI_TEXTURE_SHADOWRECT; + case TEXTURE_1D_ARRAY_INDEX: return TGSI_TEXTURE_SHADOW1D_ARRAY; + case TEXTURE_2D_ARRAY_INDEX: return TGSI_TEXTURE_SHADOW2D_ARRAY; default: break; } } diff --git a/mesalib/src/mesa/swrast/s_spantemp.h b/mesalib/src/mesa/swrast/s_spantemp.h index 125d19638..517c2eb3f 100644 --- a/mesalib/src/mesa/swrast/s_spantemp.h +++ b/mesalib/src/mesa/swrast/s_spantemp.h @@ -1,221 +1,228 @@ -/*
- * Mesa 3-D graphics library
- * Version: 6.5.1
- *
- * 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.
- */
-
-
-/*
- * Templates for the span/pixel-array write/read functions called via
- * the gl_renderbuffer's GetRow, GetValues, PutRow, PutMonoRow, PutValues
- * and PutMonoValues functions.
- *
- * Define the following macros before including this file:
- * NAME(BASE) to generate the function name (i.e. add prefix or suffix)
- * RB_TYPE the renderbuffer DataType
- * SPAN_VARS to declare any local variables
- * INIT_PIXEL_PTR(P, X, Y) to initialize a pointer to a pixel
- * INC_PIXEL_PTR(P) to increment a pixel pointer by one pixel
- * STORE_PIXEL(DST, X, Y, VALUE) to store pixel values in buffer
- * FETCH_PIXEL(DST, SRC) to fetch pixel values from buffer
- *
- * Note that in the STORE_PIXEL macros, we also pass in the (X,Y) coordinates
- * for the pixels to be stored. This is useful when dithering and probably
- * ignored otherwise.
- */
-
-#include "main/macros.h"
-
-
-#if !defined(RB_COMPONENTS)
-#define RB_COMPONENTS 4
-#endif
-
-
-static void
-NAME(get_row)( struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLuint count, GLint x, GLint y, void *values )
-{
-#ifdef SPAN_VARS
- SPAN_VARS
-#endif
- RB_TYPE (*dest)[RB_COMPONENTS] = (RB_TYPE (*)[RB_COMPONENTS]) values;
- GLuint i;
- INIT_PIXEL_PTR(pixel, x, y);
- for (i = 0; i < count; i++) {
- FETCH_PIXEL(dest[i], pixel);
- INC_PIXEL_PTR(pixel);
- }
- (void) rb;
-}
-
-
-static void
-NAME(get_values)( struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLuint count, const GLint x[], const GLint y[], void *values )
-{
-#ifdef SPAN_VARS
- SPAN_VARS
-#endif
- RB_TYPE (*dest)[RB_COMPONENTS] = (RB_TYPE (*)[RB_COMPONENTS]) values;
- GLuint i;
- for (i = 0; i < count; i++) {
- INIT_PIXEL_PTR(pixel, x[i], y[i]);
- FETCH_PIXEL(dest[i], pixel);
- }
- (void) rb;
-}
-
-
-static void
-NAME(put_row)( struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLuint count, GLint x, GLint y,
- const void *values, const GLubyte mask[] )
-{
-#ifdef SPAN_VARS
- SPAN_VARS
-#endif
- const RB_TYPE (*src)[RB_COMPONENTS] = (const RB_TYPE (*)[RB_COMPONENTS]) values;
- GLuint i;
- INIT_PIXEL_PTR(pixel, x, y);
- if (mask) {
- for (i = 0; i < count; i++) {
- if (mask[i]) {
- STORE_PIXEL(pixel, x + i, y, src[i]);
- }
- INC_PIXEL_PTR(pixel);
- }
- }
- else {
- for (i = 0; i < count; i++) {
- STORE_PIXEL(pixel, x + i, y, src[i]);
- INC_PIXEL_PTR(pixel);
- }
- }
- (void) rb;
-}
-
-
-static void
-NAME(put_row_rgb)( struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLuint count, GLint x, GLint y,
- const void *values, const GLubyte mask[] )
-{
-#ifdef SPAN_VARS
- SPAN_VARS
-#endif
- const RB_TYPE (*src)[3] = (const RB_TYPE (*)[3]) values;
- GLuint i;
- INIT_PIXEL_PTR(pixel, x, y);
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
-#ifdef STORE_PIXEL_RGB
- STORE_PIXEL_RGB(pixel, x + i, y, src[i]);
-#else
- STORE_PIXEL(pixel, x + i, y, src[i]);
-#endif
- }
- INC_PIXEL_PTR(pixel);
- }
- (void) rb;
-}
-
-
-static void
-NAME(put_mono_row)( struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLuint count, GLint x, GLint y,
- const void *value, const GLubyte mask[] )
-{
-#ifdef SPAN_VARS
- SPAN_VARS
-#endif
- const RB_TYPE *src = (const RB_TYPE *) value;
- GLuint i;
- INIT_PIXEL_PTR(pixel, x, y);
- if (mask) {
- for (i = 0; i < count; i++) {
- if (mask[i]) {
- STORE_PIXEL(pixel, x + i, y, src);
- }
- INC_PIXEL_PTR(pixel);
- }
- }
- else {
- for (i = 0; i < count; i++) {
- STORE_PIXEL(pixel, x + i, y, src);
- INC_PIXEL_PTR(pixel);
- }
- }
- (void) rb;
-}
-
-
-static void
-NAME(put_values)( struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLuint count, const GLint x[], const GLint y[],
- const void *values, const GLubyte mask[] )
-{
-#ifdef SPAN_VARS
- SPAN_VARS
-#endif
- const RB_TYPE (*src)[RB_COMPONENTS] = (const RB_TYPE (*)[RB_COMPONENTS]) values;
- GLuint i;
- ASSERT(mask);
- for (i = 0; i < count; i++) {
- if (mask[i]) {
- INIT_PIXEL_PTR(pixel, x[i], y[i]);
- STORE_PIXEL(pixel, x[i], y[i], src[i]);
- }
- }
- (void) rb;
-}
-
-
-static void
-NAME(put_mono_values)( struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLuint count, const GLint x[], const GLint y[],
- const void *value, const GLubyte mask[] )
-{
-#ifdef SPAN_VARS
- SPAN_VARS
-#endif
- const RB_TYPE *src = (const RB_TYPE *) value;
- GLuint i;
- ASSERT(mask);
- for (i = 0; i < count; i++) {
- if (mask[i]) {
- INIT_PIXEL_PTR(pixel, x[i], y[i]);
- STORE_PIXEL(pixel, x[i], y[i], src);
- }
- }
- (void) rb;
-}
-
-
-#undef NAME
-#undef RB_TYPE
-#undef RB_COMPONENTS
-#undef SPAN_VARS
-#undef INIT_PIXEL_PTR
-#undef INC_PIXEL_PTR
-#undef STORE_PIXEL
-#undef STORE_PIXEL_RGB
-#undef FETCH_PIXEL
+/* + * Mesa 3-D graphics library + * Version: 6.5.1 + * + * 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. + */ + + +/* + * Templates for the span/pixel-array write/read functions called via + * the gl_renderbuffer's GetRow, GetValues, PutRow, PutMonoRow, PutValues + * and PutMonoValues functions. + * + * Define the following macros before including this file: + * NAME(BASE) to generate the function name (i.e. add prefix or suffix) + * RB_TYPE the renderbuffer DataType + * SPAN_VARS to declare any local variables + * INIT_PIXEL_PTR(P, X, Y) to initialize a pointer to a pixel + * INC_PIXEL_PTR(P) to increment a pixel pointer by one pixel + * STORE_PIXEL(DST, X, Y, VALUE) to store pixel values in buffer + * FETCH_PIXEL(DST, SRC) to fetch pixel values from buffer + * + * Note that in the STORE_PIXEL macros, we also pass in the (X,Y) coordinates + * for the pixels to be stored. This is useful when dithering and probably + * ignored otherwise. + */ + +#include "main/macros.h" + + +#if !defined(RB_COMPONENTS) +#define RB_COMPONENTS 4 +#endif + + +static void +NAME(get_row)( struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, GLint x, GLint y, void *values ) +{ +#ifdef SPAN_VARS + SPAN_VARS +#endif + RB_TYPE (*dest)[RB_COMPONENTS] = (RB_TYPE (*)[RB_COMPONENTS]) values; + GLuint i; + INIT_PIXEL_PTR(pixel, x, y); + for (i = 0; i < count; i++) { + FETCH_PIXEL(dest[i], pixel); + INC_PIXEL_PTR(pixel); + } + (void) rb; + (void) ctx; +} + + +static void +NAME(get_values)( struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], void *values ) +{ +#ifdef SPAN_VARS + SPAN_VARS +#endif + RB_TYPE (*dest)[RB_COMPONENTS] = (RB_TYPE (*)[RB_COMPONENTS]) values; + GLuint i; + for (i = 0; i < count; i++) { + INIT_PIXEL_PTR(pixel, x[i], y[i]); + FETCH_PIXEL(dest[i], pixel); + } + (void) rb; + (void) ctx; +} + + +static void +NAME(put_row)( struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, GLint x, GLint y, + const void *values, const GLubyte mask[] ) +{ +#ifdef SPAN_VARS + SPAN_VARS +#endif + const RB_TYPE (*src)[RB_COMPONENTS] = (const RB_TYPE (*)[RB_COMPONENTS]) values; + GLuint i; + INIT_PIXEL_PTR(pixel, x, y); + if (mask) { + for (i = 0; i < count; i++) { + if (mask[i]) { + STORE_PIXEL(pixel, x + i, y, src[i]); + } + INC_PIXEL_PTR(pixel); + } + } + else { + for (i = 0; i < count; i++) { + STORE_PIXEL(pixel, x + i, y, src[i]); + INC_PIXEL_PTR(pixel); + } + } + (void) rb; + (void) ctx; +} + + +static void +NAME(put_row_rgb)( struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, GLint x, GLint y, + const void *values, const GLubyte mask[] ) +{ +#ifdef SPAN_VARS + SPAN_VARS +#endif + const RB_TYPE (*src)[3] = (const RB_TYPE (*)[3]) values; + GLuint i; + INIT_PIXEL_PTR(pixel, x, y); + for (i = 0; i < count; i++) { + if (!mask || mask[i]) { +#ifdef STORE_PIXEL_RGB + STORE_PIXEL_RGB(pixel, x + i, y, src[i]); +#else + STORE_PIXEL(pixel, x + i, y, src[i]); +#endif + } + INC_PIXEL_PTR(pixel); + } + (void) rb; + (void) ctx; +} + + +static void +NAME(put_mono_row)( struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, GLint x, GLint y, + const void *value, const GLubyte mask[] ) +{ +#ifdef SPAN_VARS + SPAN_VARS +#endif + const RB_TYPE *src = (const RB_TYPE *) value; + GLuint i; + INIT_PIXEL_PTR(pixel, x, y); + if (mask) { + for (i = 0; i < count; i++) { + if (mask[i]) { + STORE_PIXEL(pixel, x + i, y, src); + } + INC_PIXEL_PTR(pixel); + } + } + else { + for (i = 0; i < count; i++) { + STORE_PIXEL(pixel, x + i, y, src); + INC_PIXEL_PTR(pixel); + } + } + (void) rb; + (void) ctx; +} + + +static void +NAME(put_values)( struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], + const void *values, const GLubyte mask[] ) +{ +#ifdef SPAN_VARS + SPAN_VARS +#endif + const RB_TYPE (*src)[RB_COMPONENTS] = (const RB_TYPE (*)[RB_COMPONENTS]) values; + GLuint i; + ASSERT(mask); + for (i = 0; i < count; i++) { + if (mask[i]) { + INIT_PIXEL_PTR(pixel, x[i], y[i]); + STORE_PIXEL(pixel, x[i], y[i], src[i]); + } + } + (void) rb; + (void) ctx; +} + + +static void +NAME(put_mono_values)( struct gl_context *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], + const void *value, const GLubyte mask[] ) +{ +#ifdef SPAN_VARS + SPAN_VARS +#endif + const RB_TYPE *src = (const RB_TYPE *) value; + GLuint i; + ASSERT(mask); + for (i = 0; i < count; i++) { + if (mask[i]) { + INIT_PIXEL_PTR(pixel, x[i], y[i]); + STORE_PIXEL(pixel, x[i], y[i], src); + } + } + (void) rb; + (void) ctx; +} + + +#undef NAME +#undef RB_TYPE +#undef RB_COMPONENTS +#undef SPAN_VARS +#undef INIT_PIXEL_PTR +#undef INC_PIXEL_PTR +#undef STORE_PIXEL +#undef STORE_PIXEL_RGB +#undef FETCH_PIXEL |