From 8ee6ab6acb8f89fbc87865751573fcbffb4695ef Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 15:02:01 -0600 Subject: mesa: fix _mesa_dump_textures(), add null ptr check Calling _mesa_dump_textures() deleted the textures... oops!!! --- src/mesa/main/debug.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/debug.c b/src/mesa/main/debug.c index fdd10dd307..2eabcdaf49 100644 --- a/src/mesa/main/debug.c +++ b/src/mesa/main/debug.c @@ -3,6 +3,7 @@ * Version: 6.5 * * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * Copyright (C) 2009 VMware, Inc. 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"), @@ -262,7 +263,7 @@ static void write_texture_image(struct gl_texture_object *texObj) { const struct gl_texture_image *img = texObj->Image[0][0]; - if (img) { + if (img && img->Data) { char s[100]; /* make filename */ @@ -338,5 +339,5 @@ _mesa_dump_textures(GLboolean dumpImages) { GET_CURRENT_CONTEXT(ctx); DumpImages = dumpImages; - _mesa_HashDeleteAll(ctx->Shared->TexObjects, dump_texture_cb, ctx); + _mesa_HashWalk(ctx->Shared->TexObjects, dump_texture_cb, ctx); } -- cgit v1.2.3 From 725d50601c2c010ce427a23a6e023f79df8a3a22 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 16:38:04 -0600 Subject: mesa: fix comment typo --- src/mesa/main/pixel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/pixel.c b/src/mesa/main/pixel.c index 52781e048e..57ae9c721a 100644 --- a/src/mesa/main/pixel.c +++ b/src/mesa/main/pixel.c @@ -819,7 +819,7 @@ update_image_transfer_state(GLcontext *ctx) /** - * Update meas pixel transfer derived state. + * Update mesa pixel transfer derived state. */ void _mesa_update_pixel( GLcontext *ctx, GLuint new_state ) { -- cgit v1.2.3 From 6b0c9366a3f13d74c00666cb7c26b65732f6b1aa Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 22 Apr 2009 16:41:05 -0600 Subject: mesa: minor state-update changes in histogram code Call FLUSH_VERTICES() in _mesa_Histogram(). No need to signal _NEW_PIXEL in ResetHistogram(), ResetMinmax(). --- src/mesa/main/histogram.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/histogram.c b/src/mesa/main/histogram.c index 905c1ad830..5fee4fd0e3 100644 --- a/src/mesa/main/histogram.c +++ b/src/mesa/main/histogram.c @@ -975,6 +975,8 @@ _mesa_Histogram(GLenum target, GLsizei width, GLenum internalFormat, GLboolean s } } + FLUSH_VERTICES(ctx, _NEW_PIXEL); + /* reset histograms */ for (i = 0; i < HISTOGRAM_TABLE_SIZE; i++) { ctx->Histogram.Count[i][0] = 0; @@ -1002,8 +1004,6 @@ _mesa_Histogram(GLenum target, GLsizei width, GLenum internalFormat, GLboolean s ctx->Histogram.AlphaSize = 8 * sizeof(GLuint); ctx->Histogram.LuminanceSize = 8 * sizeof(GLuint); } - - ctx->NewState |= _NEW_PIXEL; } @@ -1058,8 +1058,6 @@ _mesa_ResetHistogram(GLenum target) ctx->Histogram.Count[i][2] = 0; ctx->Histogram.Count[i][3] = 0; } - - ctx->NewState |= _NEW_PIXEL; } @@ -1083,7 +1081,6 @@ _mesa_ResetMinmax(GLenum target) ctx->MinMax.Min[GCOMP] = 1000; ctx->MinMax.Max[GCOMP] = -1000; ctx->MinMax.Min[BCOMP] = 1000; ctx->MinMax.Max[BCOMP] = -1000; ctx->MinMax.Min[ACOMP] = 1000; ctx->MinMax.Max[ACOMP] = -1000; - ctx->NewState |= _NEW_PIXEL; } -- cgit v1.2.3 From 1d0039959302fddd560dc7f9642f312e588cce0e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 23 Apr 2009 17:54:34 -0600 Subject: mesa: more informative error messages --- src/mesa/main/texparam.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c index 515a35cdfc..e60ab6aa12 100644 --- a/src/mesa/main/texparam.c +++ b/src/mesa/main/texparam.c @@ -69,7 +69,7 @@ validate_texture_wrap_mode(GLcontext * ctx, GLenum target, GLenum wrap) return GL_TRUE; } - _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); + _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param=0x%x)", wrap ); return GL_FALSE; } @@ -209,7 +209,8 @@ set_tex_parameteri(GLcontext *ctx, } /* fall-through */ default: - _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); + _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param=0x%x)", + params[0] ); } return GL_FALSE; @@ -223,7 +224,8 @@ set_tex_parameteri(GLcontext *ctx, texObj->MagFilter = params[0]; return GL_TRUE; default: - _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); + _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param=0x%x)", + params[0]); } return GL_FALSE; @@ -262,7 +264,8 @@ set_tex_parameteri(GLcontext *ctx, return GL_FALSE; if (params[0] < 0 || (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0)) { - _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)"); + _mesa_error(ctx, GL_INVALID_VALUE, + "glTexParameter(param=%d)", params[0]); return GL_FALSE; } flush(ctx, texObj); @@ -273,7 +276,8 @@ set_tex_parameteri(GLcontext *ctx, if (texObj->MaxLevel == params[0]) return GL_FALSE; if (params[0] < 0 || texObj->Target == GL_TEXTURE_RECTANGLE_ARB) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(param)"); + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTexParameter(param=%d)", params[0]); return GL_FALSE; } flush(ctx, texObj); @@ -340,7 +344,7 @@ set_tex_parameteri(GLcontext *ctx, } } else { - _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname); } return GL_FALSE; -- cgit v1.2.3 From 1c9786894cc3ce66665ca507a6daf6a829e5af89 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 24 Apr 2009 10:46:40 -0600 Subject: mesa: fix up error/warning/debug output newlines As of commit 23ad86cfb91c294ce85a3116d4b825aaa3988a6e all messages go through output_if_debug(). Add new parameter to output_if_debug() to indicate whether to emit a newline. _mesa_warning() and _mesa_error() calls should not end their strings with \n. _mesa_debug() calls should end their text with \n. --- src/mesa/main/context.c | 2 +- src/mesa/main/imports.c | 35 ++++++++++++++++++++++++++--------- 2 files changed, 27 insertions(+), 10 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 5726dbd983..4469c8e1fa 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -434,7 +434,7 @@ one_time_init( GLcontext *ctx ) } #if defined(DEBUG) && defined(__DATE__) && defined(__TIME__) - _mesa_debug(ctx, "Mesa %s DEBUG build %s %s", + _mesa_debug(ctx, "Mesa %s DEBUG build %s %s\n", MESA_VERSION_STRING, __DATE__, __TIME__); #endif diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c index 2ac93a5237..8797f36695 100644 --- a/src/mesa/main/imports.c +++ b/src/mesa/main/imports.c @@ -980,7 +980,8 @@ _mesa_vsprintf( char *str, const char *fmt, va_list args ) /*@{*/ static void -output_if_debug(const char *prefixString, const char *outputString) +output_if_debug(const char *prefixString, const char *outputString, + GLboolean newline) { static int debug = -1; @@ -1004,16 +1005,19 @@ output_if_debug(const char *prefixString, const char *outputString) /* Now only print the string if we're required to do so. */ if (debug) { - fprintf(stderr, "%s: %s\n", prefixString, outputString); + fprintf(stderr, "%s: %s", prefixString, outputString); + if (newline) + fprintf(stderr, "\n"); } } + /** * Report a warning (a recoverable error condition) to stderr if * either DEBUG is defined or the MESA_DEBUG env var is set. * * \param ctx GL context. - * \param fmtString printf() alike format string. + * \param fmtString printf()-like format string. */ void _mesa_warning( GLcontext *ctx, const char *fmtString, ... ) @@ -1025,11 +1029,12 @@ _mesa_warning( GLcontext *ctx, const char *fmtString, ... ) (void) vsnprintf( str, MAXSTRING, fmtString, args ); va_end( args ); - output_if_debug("Mesa warning", str); + output_if_debug("Mesa warning", str, GL_TRUE); } + /** - * Report an internla implementation problem. + * Report an internal implementation problem. * Prints the message to stderr via fprintf(). * * \param ctx GL context. @@ -1050,8 +1055,9 @@ _mesa_problem( const GLcontext *ctx, const char *fmtString, ... ) fprintf(stderr, "Please report at bugzilla.freedesktop.org\n"); } + /** - * Record an OpenGL state error. These usually occur when the users + * Record an OpenGL state error. These usually occur when the user * passes invalid parameters to a GL function. * * If debugging is enabled (either at compile-time via the DEBUG macro, or @@ -1123,11 +1129,22 @@ _mesa_error( GLcontext *ctx, GLenum error, const char *fmtString, ... ) errstr = "unknown"; break; } - _mesa_debug(ctx, "User error: %s in %s\n", errstr, where); + + { + char s[MAXSTRING], s2[MAXSTRING]; + va_list args; + va_start(args, fmtString); + vsnprintf(s, MAXSTRING, fmtString, args); + va_end(args); + + snprintf(s2, MAXSTRING, "%s in %s", errstr, s); + output_if_debug("Mesa: User error", s2, GL_TRUE); + } } _mesa_record_error(ctx, error); -} +} + /** * Report debug information. Print error message to stderr via fprintf(). @@ -1145,7 +1162,7 @@ _mesa_debug( const GLcontext *ctx, const char *fmtString, ... ) va_start(args, fmtString); vsnprintf(s, MAXSTRING, fmtString, args); va_end(args); - output_if_debug("Mesa", s); + output_if_debug("Mesa", s, GL_FALSE); #endif /* DEBUG */ (void) ctx; (void) fmtString; -- cgit v1.2.3 From 99b77d05d2e8c4af5f7d752d6827c21fd6c4d5ee Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 27 Apr 2009 13:09:58 +0100 Subject: mesa: Call _mesa_snprintf instead of snprintf. snprintf not directly available on Windows. --- src/mesa/main/imports.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c index 8797f36695..615f7c9a6d 100644 --- a/src/mesa/main/imports.c +++ b/src/mesa/main/imports.c @@ -1137,7 +1137,7 @@ _mesa_error( GLcontext *ctx, GLenum error, const char *fmtString, ... ) vsnprintf(s, MAXSTRING, fmtString, args); va_end(args); - snprintf(s2, MAXSTRING, "%s in %s", errstr, s); + _mesa_snprintf(s2, MAXSTRING, "%s in %s", errstr, s); output_if_debug("Mesa: User error", s2, GL_TRUE); } } -- cgit v1.2.3 From c0bff53334194f9d1aada23510123f1591d5512e Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 28 Apr 2009 17:49:50 +0100 Subject: mesa/main: protect driver.finish with FLUSH_CURRENT Already doing this for driver.flush() --- src/mesa/main/context.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/mesa/main') diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 4469c8e1fa..016284de9a 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1497,6 +1497,7 @@ _mesa_Finish(void) { GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + FLUSH_CURRENT( ctx, 0 ); if (ctx->Driver.Finish) { ctx->Driver.Finish(ctx); } -- cgit v1.2.3 From 8a488b1be720247339f5c86fea5d2bff3d0fe084 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 09:19:59 -0600 Subject: mesa: remove -devel suffix from version --- src/mesa/main/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/version.h b/src/mesa/main/version.h index f5bf6e2c85..ba027465d4 100644 --- a/src/mesa/main/version.h +++ b/src/mesa/main/version.h @@ -31,7 +31,7 @@ #define MESA_MAJOR 7 #define MESA_MINOR 5 #define MESA_PATCH 0 -#define MESA_VERSION_STRING "7.5-devel" +#define MESA_VERSION_STRING "7.5" /* To make version comparison easy */ #define MESA_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) -- cgit v1.2.3 From 666e5bf4a6728484b4bc0c7e2583f141f1f2b2b7 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 09:22:20 -0600 Subject: mesa: bump version to 7.6 (devel) --- Makefile | 2 +- configs/default | 2 +- src/mesa/main/version.h | 7 ++++--- 3 files changed, 6 insertions(+), 5 deletions(-) (limited to 'src/mesa/main') diff --git a/Makefile b/Makefile index a77825e8f9..ab41116795 100644 --- a/Makefile +++ b/Makefile @@ -181,7 +181,7 @@ ultrix-gcc: # Rules for making release tarballs -VERSION=7.5-devel +VERSION=7.6-devel DIRECTORY = Mesa-$(VERSION) LIB_NAME = MesaLib-$(VERSION) DEMO_NAME = MesaDemos-$(VERSION) diff --git a/configs/default b/configs/default index b5ef80afb3..9c479fccdf 100644 --- a/configs/default +++ b/configs/default @@ -9,7 +9,7 @@ CONFIG_NAME = default # Version info MESA_MAJOR=7 -MESA_MINOR=5 +MESA_MINOR=6 MESA_TINY=0 MESA_VERSION = $(MESA_MAJOR).$(MESA_MINOR).$(MESA_TINY) diff --git a/src/mesa/main/version.h b/src/mesa/main/version.h index f5bf6e2c85..d4d3dd1a94 100644 --- a/src/mesa/main/version.h +++ b/src/mesa/main/version.h @@ -1,8 +1,9 @@ /* * Mesa 3-D graphics library - * Version: 7.5 + * Version: 7.6 * * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * Copyright (C) 2009 VMware, Inc. 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"), @@ -29,9 +30,9 @@ /* Mesa version */ #define MESA_MAJOR 7 -#define MESA_MINOR 5 +#define MESA_MINOR 6 #define MESA_PATCH 0 -#define MESA_VERSION_STRING "7.5-devel" +#define MESA_VERSION_STRING "7.6-devel" /* To make version comparison easy */ #define MESA_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) -- cgit v1.2.3 From 3f25219c7bf0f090502489928f0f018e62c4f6cf Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 09:30:32 -0600 Subject: mesa: create/use a fallback texture when bound texture is incomplete When a GLSL sampler reads from an incomplete texture it should return (0,0,0,1). Instead of jumping through hoops in all the drivers to make this happen, just create/install a fallback texture with those texel values. Fixes piglit/fp-incomplete-tex on i965 and more importantly, fixes some GPU lockups when trying to sample from missing surfaces. If a binding table entry is NULL, it seems that sampling sometimes works, but not always (lockup). Todo: create a fallback texture for each type of texture target? --- src/mesa/main/mtypes.h | 3 +++ src/mesa/main/texobj.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ src/mesa/main/texobj.h | 3 +++ src/mesa/main/texstate.c | 9 ++++++-- 4 files changed, 66 insertions(+), 2 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 30c7cca3b5..38c3b1bb40 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2050,6 +2050,9 @@ struct gl_shared_state /** Default texture objects (shared by all texture units) */ struct gl_texture_object *DefaultTex[NUM_TEXTURE_TARGETS]; + /** Fallback texture used when a bound texture is incomplete */ + struct gl_texture_object *FallbackTex; + /** * \name Thread safety and statechange notification for texture * objects. diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c index b63f747fe8..0024efc0e6 100644 --- a/src/mesa/main/texobj.c +++ b/src/mesa/main/texobj.c @@ -662,6 +662,59 @@ _mesa_test_texobj_completeness( const GLcontext *ctx, } } + +/** + * Return pointer to a default/fallback texture. + * The texture is a 2D 8x8 RGBA texture with all texels = (0,0,0,1). + * That's the value a sampler should get when sampling from an + * incomplete texture. + */ +struct gl_texture_object * +_mesa_get_fallback_texture(GLcontext *ctx) +{ + if (!ctx->Shared->FallbackTex) { + /* create fallback texture now */ + static GLubyte texels[8 * 8][4]; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + GLuint i; + + for (i = 0; i < 8 * 8; i++) { + texels[i][0] = + texels[i][1] = + texels[i][2] = 0x0; + texels[i][3] = 0xff; + } + + /* create texture object */ + texObj = ctx->Driver.NewTextureObject(ctx, 0, GL_TEXTURE_2D); + assert(texObj->RefCount == 1); + texObj->MinFilter = GL_NEAREST; + texObj->MagFilter = GL_NEAREST; + + /* create level[0] texture image */ + texImage = _mesa_get_tex_image(ctx, texObj, GL_TEXTURE_2D, 0); + + /* init the image fields */ + _mesa_init_teximage_fields(ctx, GL_TEXTURE_2D, texImage, + 8, 8, 1, 0, GL_RGBA); + + /* set image data */ + ctx->Driver.TexImage2D(ctx, GL_TEXTURE_2D, 0, GL_RGBA, + 8, 8, 0, + GL_RGBA, GL_UNSIGNED_BYTE, texels, + &ctx->DefaultPacking, texObj, texImage); + + _mesa_test_texobj_completeness(ctx, texObj); + assert(texObj->_Complete); + + ctx->Shared->FallbackTex = texObj; + } + return ctx->Shared->FallbackTex; +} + + + /*@}*/ diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h index d5374c5d6c..2599c0816a 100644 --- a/src/mesa/main/texobj.h +++ b/src/mesa/main/texobj.h @@ -65,6 +65,9 @@ extern void _mesa_test_texobj_completeness( const GLcontext *ctx, struct gl_texture_object *obj ); +extern struct gl_texture_object * +_mesa_get_fallback_texture(GLcontext *ctx); + extern void _mesa_unlock_context_textures( GLcontext *ctx ); diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 73f8a5339e..32d55ba8d5 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -561,8 +561,13 @@ update_texture_state( GLcontext *ctx ) } if (!texUnit->_ReallyEnabled) { - _mesa_reference_texobj(&texUnit->_Current, NULL); - continue; + /* If we get here it means the shader (or fixed-function state) + * is expecting a texture object, but there isn't one (or it's + * incomplete). Use the fallback texture. + */ + struct gl_texture_object *texObj = _mesa_get_fallback_texture(ctx); + texUnit->_ReallyEnabled = 1 << TEXTURE_2D_INDEX; + _mesa_reference_texobj(&texUnit->_Current, texObj); } /* if we get here, we know this texture unit is enabled */ -- cgit v1.2.3 From 30b3d800917cc5b41ec508fd38a0ae1da8624a36 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 12:12:43 -0600 Subject: mesa: fix comment --- src/mesa/main/mtypes.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 38c3b1bb40..cf71077728 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1028,7 +1028,7 @@ struct gl_stencil_attrib /** * An index for each type of texture object. These correspond to the GL - * target target enums, such as GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP, etc. + * texture target enums, such as GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP, etc. * Note: the order is from highest priority to lowest priority. */ typedef enum -- cgit v1.2.3 From 63f01309801c5a900d8d7f5ccd63413e33ff9bff Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 18:04:07 -0600 Subject: mesa: fix state validation bug for glCopyTex[Sub]Image() We need to make sure the framebuffer state is up to date to make sure we read pixels from the right buffer when doing a texture image copy. --- src/mesa/main/teximage.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 8c03c36c75..76b46d700b 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -51,6 +51,17 @@ #include "mtypes.h" +/** + * State changes which we care about for glCopyTex[Sub]Image() calls. + * In particular, we care about pixel transfer state and buffer state + * (such as glReadBuffer to make sure we read from the right renderbuffer). + */ +#define NEW_COPY_TEX_STATE (_MESA_NEW_TRANSFER_STATE | \ + _NEW_BUFFERS | \ + _NEW_PIXEL) + + + /** * We allocate texture memory on 512-byte boundaries so we can use MMX/SSE * elsewhere. @@ -3008,7 +3019,7 @@ _mesa_CopyTexImage1D( GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) + if (ctx->NewState & NEW_COPY_TEX_STATE) _mesa_update_state(ctx); #if FEATURE_convolve @@ -3073,7 +3084,7 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) + if (ctx->NewState & NEW_COPY_TEX_STATE) _mesa_update_state(ctx); #if FEATURE_convolve @@ -3141,7 +3152,7 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) + if (ctx->NewState & NEW_COPY_TEX_STATE) _mesa_update_state(ctx); if (copytexsubimage_error_check1(ctx, 1, target, level)) @@ -3196,7 +3207,7 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) + if (ctx->NewState & NEW_COPY_TEX_STATE) _mesa_update_state(ctx); if (copytexsubimage_error_check1(ctx, 2, target, level)) @@ -3251,7 +3262,7 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) + if (ctx->NewState & NEW_COPY_TEX_STATE) _mesa_update_state(ctx); if (copytexsubimage_error_check1(ctx, 3, target, level)) -- cgit v1.2.3 From 62043b27575c378c027251316421e4699f461108 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 1 May 2009 18:31:04 -0600 Subject: mesa: in glReadBufer() set _NEW_BUFFERS, not _NEW_PIXEL Since GL_READ_BUFFER is historically part of the gl_pixel_attrib group it made sense to signal changes with _NEW_PIXEL. But now with FBOs it's also part of the framebuffer state. Now _NEW_PIXEL strictly indicates pixels transfer state changes. This change avoids framebuffer state validation when any random bit of pixel-transfer state is set. DRI drivers updated too: don't check _NEW_COLOR when updating framebuffer state. I think that was just copied from the Xlib driver because we care about dither enable/disable state there. --- src/mesa/drivers/dri/intel/intel_buffers.c | 2 +- src/mesa/drivers/dri/r200/r200_state.c | 2 +- src/mesa/drivers/dri/r300/r300_state.c | 2 +- src/mesa/drivers/dri/radeon/radeon_state.c | 2 +- src/mesa/drivers/x11/xm_dd.c | 3 ++- src/mesa/main/buffers.c | 2 +- 6 files changed, 7 insertions(+), 6 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c index b86cafea24..4f4ea45b74 100644 --- a/src/mesa/drivers/dri/intel/intel_buffers.c +++ b/src/mesa/drivers/dri/intel/intel_buffers.c @@ -157,7 +157,7 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb) /* Do this here, not core Mesa, since this function is called from * many places within the driver. */ - if (ctx->NewState & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { + if (ctx->NewState & _NEW_BUFFERS) { /* this updates the DrawBuffer->_NumColorDrawBuffers fields, etc */ _mesa_update_framebuffer(ctx); /* this updates the DrawBuffer's Width/Height if it's a FBO */ diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c index 28ba5f49bc..81ee1ed022 100644 --- a/src/mesa/drivers/dri/r200/r200_state.c +++ b/src/mesa/drivers/dri/r200/r200_state.c @@ -2480,7 +2480,7 @@ void r200ValidateState( GLcontext *ctx ) r200ContextPtr rmesa = R200_CONTEXT(ctx); GLuint new_state = rmesa->NewGLState; - if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { + if (new_state & _NEW_BUFFERS) { r200UpdateDrawBuffer(ctx); } diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index b96ba4ed94..07299f3b36 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -2589,7 +2589,7 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state) _tnl_InvalidateState(ctx, new_state); _ae_invalidate_state(ctx, new_state); - if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { + if (new_state & _NEW_BUFFERS) { r300UpdateDrawBuffer(ctx); } diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c index b6561001e7..4432f85691 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.c +++ b/src/mesa/drivers/dri/radeon/radeon_state.c @@ -2255,7 +2255,7 @@ void radeonValidateState( GLcontext *ctx ) radeonContextPtr rmesa = RADEON_CONTEXT(ctx); GLuint new_state = rmesa->NewGLState; - if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { + if (new_state & _NEW_BUFFERS) { radeonUpdateDrawBuffer(ctx); } diff --git a/src/mesa/drivers/x11/xm_dd.c b/src/mesa/drivers/x11/xm_dd.c index 305df548fa..9a01465bdf 100644 --- a/src/mesa/drivers/x11/xm_dd.c +++ b/src/mesa/drivers/x11/xm_dd.c @@ -912,8 +912,9 @@ xmesa_update_state( GLcontext *ctx, GLbitfield new_state ) /* * GL_DITHER, GL_READ/DRAW_BUFFER, buffer binding state, etc. effect * renderbuffer span/clear funcs. + * Check _NEW_COLOR to detect dither enable/disable. */ - if (new_state & (_NEW_COLOR | _NEW_PIXEL | _NEW_BUFFERS)) { + if (new_state & (_NEW_COLOR | _NEW_BUFFERS)) { XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); struct xmesa_renderbuffer *front_xrb, *back_xrb; diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c index c5f13345f0..d8b5f3b1f4 100644 --- a/src/mesa/main/buffers.c +++ b/src/mesa/main/buffers.c @@ -443,7 +443,7 @@ _mesa_readbuffer(GLcontext *ctx, GLenum buffer, GLint bufferIndex) fb->ColorReadBuffer = buffer; fb->_ColorReadBufferIndex = bufferIndex; - ctx->NewState |= _NEW_PIXEL; + ctx->NewState |= _NEW_BUFFERS; } -- cgit v1.2.3 From 22b417b75ce0e6658a5d1e0e80cb6c3fdf631774 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Fri, 1 May 2009 18:20:42 +0100 Subject: mesa/main: set PREFER_DP4 to match position_invarient code This is a quick fix for z fighting in quake4 caused by the mismatch between vertex transformation here and in the position_invarient code. Full fix would be to make this driver-tunable and adjust both position_invarient and ffvertex_prog.c code to respect driver preferences. --- src/mesa/main/ffvertex_prog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c index 1ce5685af4..82e1c4af66 100644 --- a/src/mesa/main/ffvertex_prog.c +++ b/src/mesa/main/ffvertex_prog.c @@ -319,7 +319,7 @@ static void make_state_key( GLcontext *ctx, struct state_key *key ) * multiplications with DP4's or with MUL/MAD's? SSE works better * with the latter, drivers may differ. */ -#define PREFER_DP4 0 +#define PREFER_DP4 1 /* Use uregs to represent registers internally, translate to Mesa's -- cgit v1.2.3 From 113403ef51e2ec764db061aabf569d6f1a1a3ef0 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Tue, 5 May 2009 12:12:28 +0100 Subject: mesa: more complete fix for transform_invarient glitches Add a new flag mvp_with_dp4 in the context, and use that to switch both ffvertex.c and programopt.c vertex transformation code to either DP4 or MUL/MAD implementations. --- src/mesa/main/context.c | 13 ++++ src/mesa/main/context.h | 4 ++ src/mesa/main/ffvertex_prog.c | 16 +++-- src/mesa/main/mtypes.h | 6 ++ src/mesa/shader/programopt.c | 119 +++++++++++++++++++++++++++++++++++- src/mesa/state_tracker/st_context.c | 6 ++ 6 files changed, 153 insertions(+), 11 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 016284de9a..d780f91f04 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1522,4 +1522,17 @@ _mesa_Flush(void) } +/** + * Set mvp_with_dp4 flag. If a driver has a preference for DP4 over + * MUL/MAD, or vice versa, call this function to register that. + * Otherwise we default to MUL/MAD. + */ +void +_mesa_set_mvp_with_dp4( GLcontext *ctx, + GLboolean flag ) +{ + ctx->mvp_with_dp4 = flag; +} + + /*@}*/ diff --git a/src/mesa/main/context.h b/src/mesa/main/context.h index ecc1cec779..5b57d88029 100644 --- a/src/mesa/main/context.h +++ b/src/mesa/main/context.h @@ -151,6 +151,10 @@ extern struct _glapi_table * _mesa_get_dispatch(GLcontext *ctx); +void +_mesa_set_mvp_with_dp4( GLcontext *ctx, + GLboolean flag ); + /** \name Miscellaneous */ /*@{*/ diff --git a/src/mesa/main/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c index 82e1c4af66..43325b1352 100644 --- a/src/mesa/main/ffvertex_prog.c +++ b/src/mesa/main/ffvertex_prog.c @@ -315,12 +315,6 @@ static void make_state_key( GLcontext *ctx, struct state_key *key ) */ #define DISASSEM 0 -/* Should be tunable by the driver - do we want to do matrix - * multiplications with DP4's or with MUL/MAD's? SSE works better - * with the latter, drivers may differ. - */ -#define PREFER_DP4 1 - /* Use uregs to represent registers internally, translate to Mesa's * expected formats on emit. @@ -348,6 +342,7 @@ struct tnl_program { const struct state_key *state; struct gl_vertex_program *program; GLint max_inst; /** number of instructions allocated for program */ + GLboolean mvp_with_dp4; GLuint temp_in_use; GLuint temp_reserved; @@ -775,7 +770,7 @@ static struct ureg get_eye_position( struct tnl_program *p ) p->eye_position = reserve_temp(p); - if (PREFER_DP4) { + if (p->mvp_with_dp4) { register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3, 0, modelview ); @@ -881,7 +876,7 @@ static void build_hpos( struct tnl_program *p ) struct ureg hpos = register_output( p, VERT_RESULT_HPOS ); struct ureg mvp[4]; - if (PREFER_DP4) { + if (p->mvp_with_dp4) { register_matrix_param5( p, STATE_MVP_MATRIX, 0, 0, 3, 0, mvp ); emit_matrix_transform_vec4( p, hpos, mvp, pos ); @@ -1574,7 +1569,7 @@ static void build_texture_transform( struct tnl_program *p ) struct ureg in = (!is_undef(out_texgen) ? out_texgen : register_input(p, VERT_ATTRIB_TEX0+i)); - if (PREFER_DP4) { + if (p->mvp_with_dp4) { register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3, 0, texmat ); emit_matrix_transform_vec4( p, out, texmat, in ); @@ -1708,6 +1703,7 @@ static void build_tnl_program( struct tnl_program *p ) static void create_new_program( const struct state_key *key, struct gl_vertex_program *program, + GLboolean mvp_with_dp4, GLuint max_temps) { struct tnl_program p; @@ -1721,6 +1717,7 @@ create_new_program( const struct state_key *key, p.transformed_normal = undef; p.identity = undef; p.temp_in_use = 0; + p.mvp_with_dp4 = mvp_with_dp4; if (max_temps >= sizeof(int) * 8) p.temp_reserved = 0; @@ -1776,6 +1773,7 @@ _mesa_get_fixed_func_vertex_program(GLcontext *ctx) return NULL; create_new_program( &key, prog, + ctx->mvp_with_dp4, ctx->Const.VertexProgram.MaxTemps ); #if 0 diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index cf71077728..587dc80146 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2980,6 +2980,12 @@ struct __GLcontextRec /** software compression/decompression supported or not */ GLboolean Mesa_DXTn; + /** + * Use dp4 (rather than mul/mad) instructions for position + * transformation? + */ + GLboolean mvp_with_dp4; + /** Core tnl module support */ struct gl_tnl_module TnlModule; diff --git a/src/mesa/shader/programopt.c b/src/mesa/shader/programopt.c index ecd98dc85c..f70c75cec8 100644 --- a/src/mesa/shader/programopt.c +++ b/src/mesa/shader/programopt.c @@ -45,8 +45,8 @@ * into a vertex program. * May be used to implement the position_invariant option. */ -void -_mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog) +static void +_mesa_insert_mvp_dp4_code(GLcontext *ctx, struct gl_vertex_program *vprog) { struct prog_instruction *newInst; const GLuint origLen = vprog->Base.NumInstructions; @@ -113,6 +113,121 @@ _mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog) } +static void +_mesa_insert_mvp_mad_code(GLcontext *ctx, struct gl_vertex_program *vprog) +{ + struct prog_instruction *newInst; + const GLuint origLen = vprog->Base.NumInstructions; + const GLuint newLen = origLen + 4; + GLuint hposTemp; + GLuint i; + + /* + * Setup state references for the modelview/projection matrix. + * XXX we should check if these state vars are already declared. + */ + static const gl_state_index mvpState[4][STATE_LENGTH] = { + { STATE_MVP_MATRIX, 0, 0, 0, STATE_MATRIX_TRANSPOSE }, + { STATE_MVP_MATRIX, 0, 1, 1, STATE_MATRIX_TRANSPOSE }, + { STATE_MVP_MATRIX, 0, 2, 2, STATE_MATRIX_TRANSPOSE }, + { STATE_MVP_MATRIX, 0, 3, 3, STATE_MATRIX_TRANSPOSE }, + }; + GLint mvpRef[4]; + + for (i = 0; i < 4; i++) { + mvpRef[i] = _mesa_add_state_reference(vprog->Base.Parameters, + mvpState[i]); + } + + /* Alloc storage for new instructions */ + newInst = _mesa_alloc_instructions(newLen); + if (!newInst) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, + "glProgramString(inserting position_invariant code)"); + return; + } + + /* TEMP hposTemp; */ + hposTemp = vprog->Base.NumTemporaries++; + + /* + * Generated instructions: + * emit_op2(p, OPCODE_MUL, tmp, 0, swizzle1(src,X), mat[0]); + * emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Y), mat[1], tmp); + * emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Z), mat[2], tmp); + * emit_op3(p, OPCODE_MAD, dest, 0, swizzle1(src,W), mat[3], tmp); + */ + _mesa_init_instructions(newInst, 4); + + newInst[0].Opcode = OPCODE_MUL; + newInst[0].DstReg.File = PROGRAM_TEMPORARY; + newInst[0].DstReg.Index = hposTemp; + newInst[0].DstReg.WriteMask = WRITEMASK_XYZW; + newInst[0].SrcReg[0].File = PROGRAM_INPUT; + newInst[0].SrcReg[0].Index = VERT_ATTRIB_POS; + newInst[0].SrcReg[0].Swizzle = SWIZZLE_XXXX; + newInst[0].SrcReg[1].File = PROGRAM_STATE_VAR; + newInst[0].SrcReg[1].Index = mvpRef[0]; + newInst[0].SrcReg[1].Swizzle = SWIZZLE_NOOP; + + for (i = 1; i <= 2; i++) { + newInst[i].Opcode = OPCODE_MAD; + newInst[i].DstReg.File = PROGRAM_TEMPORARY; + newInst[i].DstReg.Index = hposTemp; + newInst[i].DstReg.WriteMask = WRITEMASK_XYZW; + newInst[i].SrcReg[0].File = PROGRAM_INPUT; + newInst[i].SrcReg[0].Index = VERT_ATTRIB_POS; + newInst[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(i,i,i,i); + newInst[i].SrcReg[1].File = PROGRAM_STATE_VAR; + newInst[i].SrcReg[1].Index = mvpRef[i]; + newInst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP; + newInst[i].SrcReg[2].File = PROGRAM_TEMPORARY; + newInst[i].SrcReg[2].Index = hposTemp; + newInst[1].SrcReg[2].Swizzle = SWIZZLE_NOOP; + } + + newInst[3].Opcode = OPCODE_MAD; + newInst[3].DstReg.File = PROGRAM_OUTPUT; + newInst[3].DstReg.Index = VERT_RESULT_HPOS; + newInst[3].DstReg.WriteMask = WRITEMASK_XYZW; + newInst[3].SrcReg[0].File = PROGRAM_INPUT; + newInst[3].SrcReg[0].Index = VERT_ATTRIB_POS; + newInst[3].SrcReg[0].Swizzle = SWIZZLE_WWWW; + newInst[3].SrcReg[1].File = PROGRAM_STATE_VAR; + newInst[3].SrcReg[1].Index = mvpRef[3]; + newInst[3].SrcReg[1].Swizzle = SWIZZLE_NOOP; + newInst[3].SrcReg[2].File = PROGRAM_TEMPORARY; + newInst[3].SrcReg[2].Index = hposTemp; + newInst[3].SrcReg[2].Swizzle = SWIZZLE_NOOP; + + + /* Append original instructions after new instructions */ + _mesa_copy_instructions (newInst + 4, vprog->Base.Instructions, origLen); + + /* free old instructions */ + _mesa_free_instructions(vprog->Base.Instructions, origLen); + + /* install new instructions */ + vprog->Base.Instructions = newInst; + vprog->Base.NumInstructions = newLen; + vprog->Base.InputsRead |= VERT_BIT_POS; + vprog->Base.OutputsWritten |= (1 << VERT_RESULT_HPOS); +} + + +void +_mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog) +{ + if (ctx->mvp_with_dp4) + _mesa_insert_mvp_dp4_code( ctx, vprog ); + else + _mesa_insert_mvp_mad_code( ctx, vprog ); +} + + + + + /** * Append extra instructions onto the given fragment program to implement diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 92a630eff9..2a1f21c51c 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -177,6 +177,12 @@ struct st_context *st_create_context(struct pipe_context *pipe, ctx = _mesa_create_context(visual, shareCtx, &funcs, NULL); + /* XXX: need a capability bit in gallium to query if the pipe + * driver prefers DP4 or MUL/MAD for vertex transformation. + */ + if (debug_get_bool_option("MESA_MVP_DP4", FALSE)) + _mesa_set_mvp_with_dp4( ctx, GL_TRUE ); + return st_create_context_priv(ctx, pipe); } -- cgit v1.2.3 From c0d3761c167c2d952e92c46cf3a0e26461985ada Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 5 May 2009 16:17:55 -0600 Subject: mesa: minor simplification in enable_texture(), updated comments --- src/mesa/main/enable.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c index f432be183c..2e7baa48ff 100644 --- a/src/mesa/main/enable.c +++ b/src/mesa/main/enable.c @@ -222,14 +222,16 @@ get_texcoord_unit(GLcontext *ctx) /** * Helper function to enable or disable a texture target. + * \param bit one of the TEXTURE_x_BIT values + * \return GL_TRUE if state is changing or GL_FALSE if no change */ static GLboolean -enable_texture(GLcontext *ctx, GLboolean state, GLbitfield bit) +enable_texture(GLcontext *ctx, GLboolean state, GLbitfield texBit) { const GLuint curr = ctx->Texture.CurrentUnit; struct gl_texture_unit *texUnit = &ctx->Texture.Unit[curr]; - const GLuint newenabled = (!state) - ? (texUnit->Enabled & ~bit) : (texUnit->Enabled | bit); + const GLbitfield newenabled = state + ? (texUnit->Enabled | texBit) : (texUnit->Enabled & ~texBit); if (!ctx->DrawBuffer->Visual.rgbMode || texUnit->Enabled == newenabled) return GL_FALSE; -- cgit v1.2.3 From 01e16befd4809e3e93ee7855a4a5d7df9fe010d9 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 5 May 2009 16:21:20 -0600 Subject: mesa: only use fallback texture when using shaders, not fixed-function The semantics are a little different for shaders vs. fixed-function when trying to use an incomplete texture. The fallback texture returning (0,0,0,1) should only be used with shaders. Fixes glean fbo test regression. --- src/mesa/main/texstate.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 32d55ba8d5..9664bd58bc 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -560,10 +560,10 @@ update_texture_state( GLcontext *ctx ) } } - if (!texUnit->_ReallyEnabled) { - /* If we get here it means the shader (or fixed-function state) - * is expecting a texture object, but there isn't one (or it's - * incomplete). Use the fallback texture. + if (fprog && !texUnit->_ReallyEnabled) { + /* If we get here it means the shader is expecting a texture + * object, but there isn't one (or it's incomplete). Use the + * fallback texture. */ struct gl_texture_object *texObj = _mesa_get_fallback_texture(ctx); texUnit->_ReallyEnabled = 1 << TEXTURE_2D_INDEX; -- cgit v1.2.3 From a0edbfb28fb2e670c657d52190a7e8b1ccf4f46e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 5 May 2009 16:29:04 -0600 Subject: mesa: only use fallback texture when using shaders, not fixed-function The semantics are a little different for shaders vs. fixed-function when trying to use an incomplete texture. The fallback texture returning (0,0,0,1) should only be used with shaders. Fixes glean fbo test regression. --- src/mesa/main/texstate.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 9664bd58bc..5453331c67 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -560,14 +560,20 @@ update_texture_state( GLcontext *ctx ) } } - if (fprog && !texUnit->_ReallyEnabled) { - /* If we get here it means the shader is expecting a texture - * object, but there isn't one (or it's incomplete). Use the - * fallback texture. - */ - struct gl_texture_object *texObj = _mesa_get_fallback_texture(ctx); - texUnit->_ReallyEnabled = 1 << TEXTURE_2D_INDEX; - _mesa_reference_texobj(&texUnit->_Current, texObj); + if (!texUnit->_ReallyEnabled) { + if (fprog) { + /* If we get here it means the shader is expecting a texture + * object, but there isn't one (or it's incomplete). Use the + * fallback texture. + */ + struct gl_texture_object *texObj = _mesa_get_fallback_texture(ctx); + texUnit->_ReallyEnabled = 1 << TEXTURE_2D_INDEX; + _mesa_reference_texobj(&texUnit->_Current, texObj); + } + else { + /* fixed-function: texture unit is really disabled */ + continue; + } } /* if we get here, we know this texture unit is enabled */ -- cgit v1.2.3 From 823815a48556940cc27867717658afda93733ce8 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 5 May 2009 16:30:30 -0600 Subject: Revert "mesa: only use fallback texture when using shaders, not fixed-function" This reverts commit a0edbfb28fb2e670c657d52190a7e8b1ccf4f46e. This patch didn't completely fix the problem. The next patch will. --- src/mesa/main/texstate.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 5453331c67..9664bd58bc 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -560,20 +560,14 @@ update_texture_state( GLcontext *ctx ) } } - if (!texUnit->_ReallyEnabled) { - if (fprog) { - /* If we get here it means the shader is expecting a texture - * object, but there isn't one (or it's incomplete). Use the - * fallback texture. - */ - struct gl_texture_object *texObj = _mesa_get_fallback_texture(ctx); - texUnit->_ReallyEnabled = 1 << TEXTURE_2D_INDEX; - _mesa_reference_texobj(&texUnit->_Current, texObj); - } - else { - /* fixed-function: texture unit is really disabled */ - continue; - } + if (fprog && !texUnit->_ReallyEnabled) { + /* If we get here it means the shader is expecting a texture + * object, but there isn't one (or it's incomplete). Use the + * fallback texture. + */ + struct gl_texture_object *texObj = _mesa_get_fallback_texture(ctx); + texUnit->_ReallyEnabled = 1 << TEXTURE_2D_INDEX; + _mesa_reference_texobj(&texUnit->_Current, texObj); } /* if we get here, we know this texture unit is enabled */ -- cgit v1.2.3 From 51325f44d1e7e62b47795a79f8038d10dc5bc30b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 5 May 2009 16:29:04 -0600 Subject: mesa: only use fallback texture when using shaders, not fixed-function (take two) The semantics are a little different for shaders vs. fixed-function when trying to use an incomplete texture. The fallback texture returning (0,0,0,1) should only be used with shaders. For fixed function, the texture unit is truly disabled/ignored. Fixes glean fbo test regression. --- src/mesa/main/texstate.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 9664bd58bc..5453331c67 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -560,14 +560,20 @@ update_texture_state( GLcontext *ctx ) } } - if (fprog && !texUnit->_ReallyEnabled) { - /* If we get here it means the shader is expecting a texture - * object, but there isn't one (or it's incomplete). Use the - * fallback texture. - */ - struct gl_texture_object *texObj = _mesa_get_fallback_texture(ctx); - texUnit->_ReallyEnabled = 1 << TEXTURE_2D_INDEX; - _mesa_reference_texobj(&texUnit->_Current, texObj); + if (!texUnit->_ReallyEnabled) { + if (fprog) { + /* If we get here it means the shader is expecting a texture + * object, but there isn't one (or it's incomplete). Use the + * fallback texture. + */ + struct gl_texture_object *texObj = _mesa_get_fallback_texture(ctx); + texUnit->_ReallyEnabled = 1 << TEXTURE_2D_INDEX; + _mesa_reference_texobj(&texUnit->_Current, texObj); + } + else { + /* fixed-function: texture unit is really disabled */ + continue; + } } /* if we get here, we know this texture unit is enabled */ -- cgit v1.2.3 From a13df193c23f9202ade6f16643e3ef529cff772b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 12:23:28 -0600 Subject: mesa: use elementBuf local var instead of ctx->Array.ElementArrayBufferObj Makes no real difference, but more consistant. --- src/mesa/main/api_validate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index 42d1e579e0..1986cbecbb 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -72,7 +72,7 @@ max_buffer_index(GLcontext *ctx, GLuint count, GLenum type, if (map) { ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, - ctx->Array.ElementArrayBufferObj); + elementBuf); } return max; -- cgit v1.2.3 From 88af3f8783452dcf50a9e2e82076f52b2044f643 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 12:27:38 -0600 Subject: mesa: new comments, minor reformatting --- src/mesa/main/api_validate.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index 1986cbecbb..dfe754dee5 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -44,10 +44,8 @@ max_buffer_index(GLcontext *ctx, GLuint count, GLenum type, if (elementBuf->Name) { /* elements are in a user-defined buffer object. need to map it */ - map = ctx->Driver.MapBuffer(ctx, - GL_ELEMENT_ARRAY_BUFFER_ARB, - GL_READ_ONLY, - elementBuf); + map = ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, + GL_READ_ONLY, elementBuf); /* Actual address is the sum of pointers */ indices = (const GLvoid *) ADD_POINTERS(map, (const GLubyte *) indices); } @@ -70,14 +68,16 @@ max_buffer_index(GLcontext *ctx, GLuint count, GLenum type, } if (map) { - ctx->Driver.UnmapBuffer(ctx, - GL_ELEMENT_ARRAY_BUFFER_ARB, - elementBuf); + ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, elementBuf); } return max; } + +/** + * Check if OK to render by examining framebuffer status and vertex arrays. + */ static GLboolean check_valid_to_render(GLcontext *ctx, char *function) { @@ -105,6 +105,12 @@ check_valid_to_render(GLcontext *ctx, char *function) return GL_TRUE; } + +/** + * Error checking for glDrawElements(). Includes parameter checking + * and VBO bounds checking. + * \return GL_TRUE if OK to render, GL_FALSE if error found + */ GLboolean _mesa_validate_DrawElements(GLcontext *ctx, GLenum mode, GLsizei count, GLenum type, @@ -184,6 +190,12 @@ _mesa_validate_DrawElements(GLcontext *ctx, return GL_TRUE; } + +/** + * Error checking for glDrawRangeElements(). Includes parameter checking + * and VBO bounds checking. + * \return GL_TRUE if OK to render, GL_FALSE if error found + */ GLboolean _mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode, GLuint start, GLuint end, @@ -265,6 +277,7 @@ _mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode, /** * Called from the tnl module to error check the function parameters and * verify that we really can draw something. + * \return GL_TRUE if OK to render, GL_FALSE if error found */ GLboolean _mesa_validate_DrawArrays(GLcontext *ctx, -- cgit v1.2.3 From bb1fb2a5444c6b7d83ccb47949f60ed9fb4f0f93 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 12:37:10 -0600 Subject: mesa: code consolidation in glDraw[Range]Elements() validation --- src/mesa/main/api_validate.c | 48 ++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 26 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index dfe754dee5..ad150eea80 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -30,6 +30,26 @@ #include "state.h" + +/** + * \return number of bytes in array [count] of type. + */ +static GLsizei +index_bytes(GLenum type, GLsizei count) +{ + if (type == GL_UNSIGNED_INT) { + return count * sizeof(GLuint); + } + else if (type == GL_UNSIGNED_BYTE) { + return count * sizeof(GLubyte); + } + else { + ASSERT(type == GL_UNSIGNED_SHORT); + return count * sizeof(GLushort); + } +} + + /** * Find the max index in the given element/index buffer */ @@ -146,7 +166,6 @@ _mesa_validate_DrawElements(GLcontext *ctx, /* Vertex buffer object tests */ if (ctx->Array.ElementArrayBufferObj->Name) { /* use indices in the buffer object */ - GLuint indexBytes; if (!ctx->Array.ElementArrayBufferObj->Size) { _mesa_warning(ctx, @@ -154,19 +173,8 @@ _mesa_validate_DrawElements(GLcontext *ctx, return GL_FALSE; } - if (type == GL_UNSIGNED_INT) { - indexBytes = count * sizeof(GLuint); - } - else if (type == GL_UNSIGNED_BYTE) { - indexBytes = count * sizeof(GLubyte); - } - else { - ASSERT(type == GL_UNSIGNED_SHORT); - indexBytes = count * sizeof(GLushort); - } - /* make sure count doesn't go outside buffer bounds */ - if (indexBytes > (GLuint) ctx->Array.ElementArrayBufferObj->Size) { + if (index_bytes(type, count) > ctx->Array.ElementArrayBufferObj->Size) { _mesa_warning(ctx, "glDrawElements index out of buffer bounds"); return GL_FALSE; } @@ -236,21 +244,9 @@ _mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode, /* Vertex buffer object tests */ if (ctx->Array.ElementArrayBufferObj->Name) { /* use indices in the buffer object */ - GLuint indexBytes; - - if (type == GL_UNSIGNED_INT) { - indexBytes = count * sizeof(GLuint); - } - else if (type == GL_UNSIGNED_BYTE) { - indexBytes = count * sizeof(GLubyte); - } - else { - ASSERT(type == GL_UNSIGNED_SHORT); - indexBytes = count * sizeof(GLushort); - } /* make sure count doesn't go outside buffer bounds */ - if (indexBytes > ctx->Array.ElementArrayBufferObj->Size) { + if (index_bytes(type, count) > ctx->Array.ElementArrayBufferObj->Size) { _mesa_warning(ctx, "glDrawRangeElements index out of buffer bounds"); return GL_FALSE; } -- cgit v1.2.3 From 58544a28ad561d7d9e16deb048443c2d2b5c12d8 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 12:38:11 -0600 Subject: mesa: remove unnecessary buffer size check --- src/mesa/main/api_validate.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index ad150eea80..27049486ee 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -166,13 +166,6 @@ _mesa_validate_DrawElements(GLcontext *ctx, /* Vertex buffer object tests */ if (ctx->Array.ElementArrayBufferObj->Name) { /* use indices in the buffer object */ - - if (!ctx->Array.ElementArrayBufferObj->Size) { - _mesa_warning(ctx, - "glDrawElements called with empty array elements buffer"); - return GL_FALSE; - } - /* make sure count doesn't go outside buffer bounds */ if (index_bytes(type, count) > ctx->Array.ElementArrayBufferObj->Size) { _mesa_warning(ctx, "glDrawElements index out of buffer bounds"); @@ -244,7 +237,6 @@ _mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode, /* Vertex buffer object tests */ if (ctx->Array.ElementArrayBufferObj->Name) { /* use indices in the buffer object */ - /* make sure count doesn't go outside buffer bounds */ if (index_bytes(type, count) > ctx->Array.ElementArrayBufferObj->Size) { _mesa_warning(ctx, "glDrawRangeElements index out of buffer bounds"); -- cgit v1.2.3 From cc7170464493453ec8213decd21df95121b236e2 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 7 May 2009 09:36:21 -0600 Subject: mesa: unmap buffer objects during context tear-down --- src/mesa/main/shared.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/mesa/main') diff --git a/src/mesa/main/shared.c b/src/mesa/main/shared.c index 193ac8970c..ae8dd2a836 100644 --- a/src/mesa/main/shared.c +++ b/src/mesa/main/shared.c @@ -190,6 +190,10 @@ delete_bufferobj_cb(GLuint id, void *data, void *userData) { struct gl_buffer_object *bufObj = (struct gl_buffer_object *) data; GLcontext *ctx = (GLcontext *) userData; + if (bufObj->Pointer) { + ctx->Driver.UnmapBuffer(ctx, 0, bufObj); + bufObj->Pointer = NULL; + } ctx->Driver.DeleteBuffer(ctx, bufObj); } -- cgit v1.2.3 From 74bec42b45910e2ff6bf1a8cc0eeb2bc5c705767 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 09:01:47 -0600 Subject: mesa: limit number of error raised by invalid GL_TEXTURE_MAX_ANISOTROPY_EXT --- src/mesa/main/texparam.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c index e60ab6aa12..2195a334d3 100644 --- a/src/mesa/main/texparam.c +++ b/src/mesa/main/texparam.c @@ -469,8 +469,10 @@ set_tex_parameterf(GLcontext *ctx, return GL_TRUE; } else { - _mesa_error(ctx, GL_INVALID_ENUM, - "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)"); + static GLuint count = 0; + if (count++ < 10) + _mesa_error(ctx, GL_INVALID_ENUM, + "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)"); } return GL_FALSE; -- cgit v1.2.3 From 87ba2285fe11dfe068798e5f8ea8e089a5d8b28b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 09:56:26 -0600 Subject: mesa: add GL_DOUBLE case in _mesa_sizeof_type() --- src/mesa/main/image.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/mesa/main') diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c index ddae456fa1..ea76ed04e4 100644 --- a/src/mesa/main/image.c +++ b/src/mesa/main/image.c @@ -181,6 +181,8 @@ _mesa_sizeof_type( GLenum type ) return sizeof(GLint); case GL_FLOAT: return sizeof(GLfloat); + case GL_DOUBLE: + return sizeof(GLdouble); case GL_HALF_FLOAT_ARB: return sizeof(GLhalfARB); default: -- cgit v1.2.3 From b102c1d8f9ea359879e6c1c4fd8c80c00d21cad5 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 12:48:21 -0600 Subject: mesa: fix/add comments --- src/mesa/main/mtypes.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 587dc80146..bdb1081ca8 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1542,9 +1542,8 @@ struct gl_client_array GLboolean Enabled; /**< Enabled flag is a boolean */ GLboolean Normalized; /**< GL_ARB_vertex_program */ - /**< GL_ARB_vertex_buffer_object */ - struct gl_buffer_object *BufferObj; - GLuint _MaxElement; + struct gl_buffer_object *BufferObj;/**< GL_ARB_vertex_buffer_object */ + GLuint _MaxElement; /**< max element index into array buffer */ }; -- cgit v1.2.3 From a6c8e900af981e011e51268a2724e5ff4a3ff1eb Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 12:56:15 -0600 Subject: mesa: use local var to make code a bit more concise --- src/mesa/main/state.c | 73 ++++++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 36 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index f18fc8f683..47e1aaa728 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -69,17 +69,18 @@ update_separate_specular(GLcontext *ctx) static void update_arrays( GLcontext *ctx ) { + const struct gl_array_object *arrayObj = ctx->Array.ArrayObj; GLuint i, min; /* find min of _MaxElement values for all enabled arrays */ /* 0 */ if (ctx->VertexProgram._Current - && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled) { - min = ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POS]._MaxElement; + && arrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled) { + min = arrayObj->VertexAttrib[VERT_ATTRIB_POS]._MaxElement; } - else if (ctx->Array.ArrayObj->Vertex.Enabled) { - min = ctx->Array.ArrayObj->Vertex._MaxElement; + else if (arrayObj->Vertex.Enabled) { + min = arrayObj->Vertex._MaxElement; } else { /* can't draw anything without vertex positions! */ @@ -88,86 +89,86 @@ update_arrays( GLcontext *ctx ) /* 1 */ if (ctx->VertexProgram._Enabled - && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_WEIGHT].Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_WEIGHT]._MaxElement); + && arrayObj->VertexAttrib[VERT_ATTRIB_WEIGHT].Enabled) { + min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_WEIGHT]._MaxElement); } /* no conventional vertex weight array */ /* 2 */ if (ctx->VertexProgram._Enabled - && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_NORMAL]._MaxElement); + && arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled) { + min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL]._MaxElement); } - else if (ctx->Array.ArrayObj->Normal.Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->Normal._MaxElement); + else if (arrayObj->Normal.Enabled) { + min = MIN2(min, arrayObj->Normal._MaxElement); } /* 3 */ if (ctx->VertexProgram._Enabled - && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR0]._MaxElement); + && arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled) { + min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0]._MaxElement); } - else if (ctx->Array.ArrayObj->Color.Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->Color._MaxElement); + else if (arrayObj->Color.Enabled) { + min = MIN2(min, arrayObj->Color._MaxElement); } /* 4 */ if (ctx->VertexProgram._Enabled - && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR1].Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR1]._MaxElement); + && arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1].Enabled) { + min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1]._MaxElement); } - else if (ctx->Array.ArrayObj->SecondaryColor.Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->SecondaryColor._MaxElement); + else if (arrayObj->SecondaryColor.Enabled) { + min = MIN2(min, arrayObj->SecondaryColor._MaxElement); } /* 5 */ if (ctx->VertexProgram._Enabled - && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_FOG].Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_FOG]._MaxElement); + && arrayObj->VertexAttrib[VERT_ATTRIB_FOG].Enabled) { + min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_FOG]._MaxElement); } - else if (ctx->Array.ArrayObj->FogCoord.Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->FogCoord._MaxElement); + else if (arrayObj->FogCoord.Enabled) { + min = MIN2(min, arrayObj->FogCoord._MaxElement); } /* 6 */ if (ctx->VertexProgram._Enabled - && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX]._MaxElement); + && arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled) { + min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX]._MaxElement); } - else if (ctx->Array.ArrayObj->Index.Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->Index._MaxElement); + else if (arrayObj->Index.Enabled) { + min = MIN2(min, arrayObj->Index._MaxElement); } /* 7 */ if (ctx->VertexProgram._Enabled - && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG]._MaxElement); + && arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled) { + min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG]._MaxElement); } /* 8..15 */ for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX7; i++) { if (ctx->VertexProgram._Enabled - && ctx->Array.ArrayObj->VertexAttrib[i].Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[i]._MaxElement); + && arrayObj->VertexAttrib[i].Enabled) { + min = MIN2(min, arrayObj->VertexAttrib[i]._MaxElement); } else if (i - VERT_ATTRIB_TEX0 < ctx->Const.MaxTextureCoordUnits - && ctx->Array.ArrayObj->TexCoord[i - VERT_ATTRIB_TEX0].Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->TexCoord[i - VERT_ATTRIB_TEX0]._MaxElement); + && arrayObj->TexCoord[i - VERT_ATTRIB_TEX0].Enabled) { + min = MIN2(min, arrayObj->TexCoord[i - VERT_ATTRIB_TEX0]._MaxElement); } } /* 16..31 */ if (ctx->VertexProgram._Current) { for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) { - if (ctx->Array.ArrayObj->VertexAttrib[i].Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[i]._MaxElement); + if (arrayObj->VertexAttrib[i].Enabled) { + min = MIN2(min, arrayObj->VertexAttrib[i]._MaxElement); } } } - if (ctx->Array.ArrayObj->EdgeFlag.Enabled) { - min = MIN2(min, ctx->Array.ArrayObj->EdgeFlag._MaxElement); + if (arrayObj->EdgeFlag.Enabled) { + min = MIN2(min, arrayObj->EdgeFlag._MaxElement); } /* _MaxElement is one past the last legal array element */ -- cgit v1.2.3 From 0077c879b57f663c038becdde37b2f6671f59150 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 13:00:35 -0600 Subject: mesa: added _ElementSize field to gl_client_array Will be handy for bounds checking later... --- src/mesa/main/mtypes.h | 1 + src/mesa/main/varray.c | 2 ++ 2 files changed, 3 insertions(+) (limited to 'src/mesa/main') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index bdb1081ca8..716e5c655d 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1541,6 +1541,7 @@ struct gl_client_array const GLubyte *Ptr; /**< Points to array data */ GLboolean Enabled; /**< Enabled flag is a boolean */ GLboolean Normalized; /**< GL_ARB_vertex_program */ + GLuint _ElementSize; /**< size of each element in bytes */ struct gl_buffer_object *BufferObj;/**< GL_ARB_vertex_buffer_object */ GLuint _MaxElement; /**< max element index into array buffer */ diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index 106252e460..629be600d4 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -63,6 +63,8 @@ update_array(GLcontext *ctx, struct gl_client_array *array, array->StrideB = stride ? stride : elementSize; array->Normalized = normalized; array->Ptr = (const GLubyte *) ptr; + array->_ElementSize = elementSize; + #if FEATURE_ARB_vertex_buffer_object _mesa_reference_buffer_object(ctx, &array->BufferObj, ctx->Array.ArrayBufferObj); -- cgit v1.2.3 From 828aa76f360c96adea1725380c397d04690bfd04 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 13:02:38 -0600 Subject: mesa: use array->BufferObj instead of ctx->Array.ArrayBufferObj No difference, but a little more understandable. --- src/mesa/main/varray.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index 629be600d4..527555be0e 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -73,8 +73,8 @@ update_array(GLcontext *ctx, struct gl_client_array *array, * Later in glDrawArrays we'll check if start + count > _MaxElement to * be sure we won't go out of bounds. */ - if (ctx->Array.ArrayBufferObj->Name) - array->_MaxElement = ((GLsizeiptrARB) ctx->Array.ArrayBufferObj->Size + if (array->BufferObj->Name) + array->_MaxElement = ((GLsizeiptrARB) array->BufferObj->Size - (GLsizeiptrARB) array->Ptr + array->StrideB - elementSize) / array->StrideB; else -- cgit v1.2.3 From b9d0f947f2bcc47047b162e3d7c8f91b6153e02c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 15:17:25 -0600 Subject: mesa: Compute gl_client_array->_MaxElement during array validation Used to be done in the glVertex/Normal/Color/etc/Pointer() calls but if the VBO was reallocated the size could change. New _NEW_BUFFER_OBJECT state flag. --- src/mesa/main/bufferobj.c | 2 ++ src/mesa/main/mtypes.h | 1 + src/mesa/main/state.c | 88 ++++++++++++++++++++++++++++++++--------------- src/mesa/main/varray.c | 13 ------- 4 files changed, 64 insertions(+), 40 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index c8d160baa9..49f690ddd2 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -958,6 +958,8 @@ _mesa_BufferDataARB(GLenum target, GLsizeiptrARB size, bufObj->Pointer = NULL; } + FLUSH_VERTICES(ctx, _NEW_BUFFER_OBJECT); + ASSERT(ctx->Driver.BufferData); /* Give the buffer object to the driver! may be null! */ diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 716e5c655d..368acde7a1 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2619,6 +2619,7 @@ struct gl_matrix_stack #define _NEW_PROGRAM 0x8000000 /**< __GLcontextRec::VertexProgram */ #define _NEW_CURRENT_ATTRIB 0x10000000 /**< __GLcontextRec::Current */ #define _NEW_PROGRAM_CONSTANTS 0x20000000 +#define _NEW_BUFFER_OBJECT 0x40000000 #define _NEW_ALL ~0 /*@}*/ diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 47e1aaa728..a6411f7b62 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -64,97 +64,131 @@ update_separate_specular(GLcontext *ctx) /** - * Update state dependent on vertex arrays. + * Compute the index of the last array element that can be safely accessed + * in a vertex array. We can really only do this when the array lives in + * a VBO. + * The array->_MaxElement field will be updated. + * Later in glDrawArrays/Elements/etc we can do some bounds checking. + */ +static void +compute_max_element(struct gl_client_array *array) +{ + assert(array->Enabled); + if (array->BufferObj->Name) { + /* Compute the max element we can access in the VBO without going + * out of bounds. + */ + array->_MaxElement = ((GLsizeiptrARB) array->BufferObj->Size + - (GLsizeiptrARB) array->Ptr + array->StrideB + - array->_ElementSize) / array->StrideB; + } + else { + /* user-space array, no idea how big it is */ + array->_MaxElement = 2 * 1000 * 1000 * 1000; /* just a big number */ + } +} + + +/** + * Helper for update_arrays(). + * \return min(current min, array->_MaxElement). + */ +static GLuint +update_min(GLuint min, struct gl_client_array *array) +{ + compute_max_element(array); + return MIN2(min, array->_MaxElement); +} + + +/** + * Update ctx->Array._MaxElement (the max legal index into all enabled arrays). + * Need to do this upon new array state or new buffer object state. */ static void update_arrays( GLcontext *ctx ) { - const struct gl_array_object *arrayObj = ctx->Array.ArrayObj; - GLuint i, min; + struct gl_array_object *arrayObj = ctx->Array.ArrayObj; + GLuint i, min = ~0; /* find min of _MaxElement values for all enabled arrays */ /* 0 */ if (ctx->VertexProgram._Current && arrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled) { - min = arrayObj->VertexAttrib[VERT_ATTRIB_POS]._MaxElement; + min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_POS]); } else if (arrayObj->Vertex.Enabled) { - min = arrayObj->Vertex._MaxElement; - } - else { - /* can't draw anything without vertex positions! */ - min = 0; + min = update_min(min, &arrayObj->Vertex); } /* 1 */ if (ctx->VertexProgram._Enabled && arrayObj->VertexAttrib[VERT_ATTRIB_WEIGHT].Enabled) { - min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_WEIGHT]._MaxElement); + min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_WEIGHT]); } /* no conventional vertex weight array */ /* 2 */ if (ctx->VertexProgram._Enabled && arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled) { - min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL]._MaxElement); + min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL]); } else if (arrayObj->Normal.Enabled) { - min = MIN2(min, arrayObj->Normal._MaxElement); + min = update_min(min, &arrayObj->Normal); } /* 3 */ if (ctx->VertexProgram._Enabled && arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled) { - min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0]._MaxElement); + min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0]); } else if (arrayObj->Color.Enabled) { - min = MIN2(min, arrayObj->Color._MaxElement); + min = update_min(min, &arrayObj->Color); } /* 4 */ if (ctx->VertexProgram._Enabled && arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1].Enabled) { - min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1]._MaxElement); + min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1]); } else if (arrayObj->SecondaryColor.Enabled) { - min = MIN2(min, arrayObj->SecondaryColor._MaxElement); + min = update_min(min, &arrayObj->SecondaryColor); } /* 5 */ if (ctx->VertexProgram._Enabled && arrayObj->VertexAttrib[VERT_ATTRIB_FOG].Enabled) { - min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_FOG]._MaxElement); + min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_FOG]); } else if (arrayObj->FogCoord.Enabled) { - min = MIN2(min, arrayObj->FogCoord._MaxElement); + min = update_min(min, &arrayObj->FogCoord); } /* 6 */ if (ctx->VertexProgram._Enabled && arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled) { - min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX]._MaxElement); + min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX]); } else if (arrayObj->Index.Enabled) { - min = MIN2(min, arrayObj->Index._MaxElement); + min = update_min(min, &arrayObj->Index); } - /* 7 */ if (ctx->VertexProgram._Enabled && arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled) { - min = MIN2(min, arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG]._MaxElement); + min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG]); } /* 8..15 */ for (i = VERT_ATTRIB_TEX0; i <= VERT_ATTRIB_TEX7; i++) { if (ctx->VertexProgram._Enabled && arrayObj->VertexAttrib[i].Enabled) { - min = MIN2(min, arrayObj->VertexAttrib[i]._MaxElement); + min = update_min(min, &arrayObj->VertexAttrib[i]); } else if (i - VERT_ATTRIB_TEX0 < ctx->Const.MaxTextureCoordUnits && arrayObj->TexCoord[i - VERT_ATTRIB_TEX0].Enabled) { - min = MIN2(min, arrayObj->TexCoord[i - VERT_ATTRIB_TEX0]._MaxElement); + min = update_min(min, &arrayObj->TexCoord[i - VERT_ATTRIB_TEX0]); } } @@ -162,13 +196,13 @@ update_arrays( GLcontext *ctx ) if (ctx->VertexProgram._Current) { for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) { if (arrayObj->VertexAttrib[i].Enabled) { - min = MIN2(min, arrayObj->VertexAttrib[i]._MaxElement); + min = update_min(min, &arrayObj->VertexAttrib[i]); } } } if (arrayObj->EdgeFlag.Enabled) { - min = MIN2(min, arrayObj->EdgeFlag._MaxElement); + min = update_min(min, &arrayObj->EdgeFlag); } /* _MaxElement is one past the last legal array element */ @@ -548,7 +582,7 @@ _mesa_update_state_locked( GLcontext *ctx ) if (new_state & _DD_NEW_SEPARATE_SPECULAR) update_separate_specular( ctx ); - if (new_state & (_NEW_ARRAY | _NEW_PROGRAM)) + if (new_state & (_NEW_ARRAY | _NEW_PROGRAM | _NEW_BUFFER_OBJECT)) update_arrays( ctx ); if (new_state & (_NEW_BUFFERS | _NEW_VIEWPORT)) diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index 527555be0e..4d153b1c0b 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -65,22 +65,9 @@ update_array(GLcontext *ctx, struct gl_client_array *array, array->Ptr = (const GLubyte *) ptr; array->_ElementSize = elementSize; -#if FEATURE_ARB_vertex_buffer_object _mesa_reference_buffer_object(ctx, &array->BufferObj, ctx->Array.ArrayBufferObj); - /* Compute the index of the last array element that's inside the buffer. - * Later in glDrawArrays we'll check if start + count > _MaxElement to - * be sure we won't go out of bounds. - */ - if (array->BufferObj->Name) - array->_MaxElement = ((GLsizeiptrARB) array->BufferObj->Size - - (GLsizeiptrARB) array->Ptr + array->StrideB - - elementSize) / array->StrideB; - else -#endif - array->_MaxElement = 2 * 1000 * 1000 * 1000; /* just a big number */ - ctx->NewState |= _NEW_ARRAY; ctx->Array.NewState |= dirtyBit; } -- cgit v1.2.3 From dcca97a3e3c1d8f5d27e1177257964eddb9effd3 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 15:23:09 -0600 Subject: mesa: added gl_buffer_object::Written flag (for debug purposes) The flag is set when we data has been written into the buffer object. --- src/mesa/main/bufferobj.c | 6 ++++++ src/mesa/main/mtypes.h | 1 + 2 files changed, 7 insertions(+) (limited to 'src/mesa/main') diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index 49f690ddd2..43a8d2ba66 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -962,6 +962,8 @@ _mesa_BufferDataARB(GLenum target, GLsizeiptrARB size, ASSERT(ctx->Driver.BufferData); + bufObj->Written = GL_TRUE; + /* Give the buffer object to the driver! may be null! */ ctx->Driver.BufferData( ctx, target, size, data, usage, bufObj ); } @@ -982,6 +984,8 @@ _mesa_BufferSubDataARB(GLenum target, GLintptrARB offset, return; } + bufObj->Written = GL_TRUE; + ASSERT(ctx->Driver.BufferSubData); ctx->Driver.BufferSubData( ctx, target, offset, size, data, bufObj ); } @@ -1046,6 +1050,8 @@ _mesa_MapBufferARB(GLenum target, GLenum access) } bufObj->Access = access; + if (access == GL_WRITE_ONLY_ARB || access == GL_READ_WRITE_ARB) + bufObj->Written = GL_TRUE; return bufObj->Pointer; } diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 368acde7a1..276bc42eba 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1506,6 +1506,7 @@ struct gl_buffer_object GLsizeiptrARB Size; /**< Size of storage in bytes */ GLubyte *Data; /**< Location of storage either in RAM or VRAM. */ GLboolean OnCard; /**< Is buffer in VRAM? (hardware drivers) */ + GLboolean Written; /**< Ever written to? (for debugging) */ }; -- cgit v1.2.3 From 6359ecebec860963886801656ab4e01c4e9ff988 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 6 May 2009 15:39:51 -0600 Subject: mesa: remove unused gl_buffer_object::OnCard field --- src/mesa/main/bufferobj.c | 2 -- src/mesa/main/mtypes.h | 1 - 2 files changed, 3 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index 43a8d2ba66..641e5d7c3b 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -389,7 +389,6 @@ _mesa_buffer_map( GLcontext *ctx, GLenum target, GLenum access, (void) ctx; (void) target; (void) access; - ASSERT(!bufObj->OnCard); /* Just return a direct pointer to the data */ if (bufObj->Pointer) { /* already mapped! */ @@ -413,7 +412,6 @@ _mesa_buffer_unmap( GLcontext *ctx, GLenum target, { (void) ctx; (void) target; - ASSERT(!bufObj->OnCard); /* XXX we might assert here that bufObj->Pointer is non-null */ bufObj->Pointer = NULL; return GL_TRUE; diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 276bc42eba..affb000b8c 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1505,7 +1505,6 @@ struct gl_buffer_object GLsizeiptr Length; /**< mapped length */ GLsizeiptrARB Size; /**< Size of storage in bytes */ GLubyte *Data; /**< Location of storage either in RAM or VRAM. */ - GLboolean OnCard; /**< Is buffer in VRAM? (hardware drivers) */ GLboolean Written; /**< Ever written to? (for debugging) */ }; -- cgit v1.2.3 From 105c8529e78db961fee832b6248c3bcf59668bad Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 7 May 2009 13:10:48 -0600 Subject: mesa: fix comments, s/texture/buffer/ --- src/mesa/main/bufferobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index 641e5d7c3b..a983376251 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -194,7 +194,7 @@ _mesa_reference_buffer_object(GLcontext *ctx, return; if (*ptr) { - /* Unreference the old texture */ + /* Unreference the old buffer */ GLboolean deleteFlag = GL_FALSE; struct gl_buffer_object *oldObj = *ptr; @@ -227,7 +227,7 @@ _mesa_reference_buffer_object(GLcontext *ctx, ASSERT(!*ptr); if (bufObj) { - /* reference new texture */ + /* reference new buffer */ /*_glthread_LOCK_MUTEX(tex->Mutex);*/ if (bufObj->RefCount == 0) { /* this buffer's being deleted (look just above) */ -- cgit v1.2.3 From 4f6b704f9796775d8d9937c3cf75a2901b99b896 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 7 May 2009 13:30:39 -0600 Subject: mesa: move the NullBufferObj from GLcontext to gl_shared_state Since shared array objects may point to the null/default buffer object, the null/default buffer object should be part of the shared state. --- src/mesa/main/arrayobj.c | 5 +++-- src/mesa/main/bufferobj.c | 16 ++++------------ src/mesa/main/context.c | 3 --- src/mesa/main/mtypes.h | 3 ++- src/mesa/main/pixel.c | 12 ++++++------ src/mesa/main/pixelstore.c | 9 ++++++--- src/mesa/main/shared.c | 12 ++++++++++++ src/mesa/swrast/s_imaging.c | 10 +++++----- src/mesa/vbo/vbo_context.c | 9 ++++++--- src/mesa/vbo/vbo_exec_api.c | 4 ++-- src/mesa/vbo/vbo_rebase.c | 2 +- src/mesa/vbo/vbo_split_copy.c | 4 ++-- src/mesa/vbo/vbo_split_inplace.c | 2 +- 13 files changed, 50 insertions(+), 41 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c index b04095fd16..2646c12ccc 100644 --- a/src/mesa/main/arrayobj.c +++ b/src/mesa/main/arrayobj.c @@ -112,7 +112,8 @@ init_array(GLcontext *ctx, array->Normalized = GL_FALSE; #if FEATURE_ARB_vertex_buffer_object /* Vertex array buffers */ - array->BufferObj = ctx->Array.NullBufferObj; + _mesa_reference_buffer_object(ctx, &array->BufferObj, + ctx->Shared->NullBufferObj); #endif } @@ -180,7 +181,7 @@ _mesa_remove_array_object( GLcontext *ctx, struct gl_array_object *obj ) static void unbind_buffer_object( GLcontext *ctx, struct gl_buffer_object *bufObj ) { - if (bufObj != ctx->Array.NullBufferObj) { + if (bufObj != ctx->Shared->NullBufferObj) { _mesa_reference_buffer_object(ctx, &bufObj, NULL); } } diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index a983376251..1f2070ef47 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -424,16 +424,8 @@ _mesa_buffer_unmap( GLcontext *ctx, GLenum target, void _mesa_init_buffer_objects( GLcontext *ctx ) { - /* Allocate the default buffer object and set refcount so high that - * it never gets deleted. - * XXX with recent/improved refcounting this may not longer be needed. - */ - ctx->Array.NullBufferObj = _mesa_new_buffer_object(ctx, 0, 0); - if (ctx->Array.NullBufferObj) - ctx->Array.NullBufferObj->RefCount = 1000; - - ctx->Array.ArrayBufferObj = ctx->Array.NullBufferObj; - ctx->Array.ElementArrayBufferObj = ctx->Array.NullBufferObj; + ctx->Array.ArrayBufferObj = ctx->Shared->NullBufferObj; + ctx->Array.ElementArrayBufferObj = ctx->Shared->NullBufferObj; } @@ -477,7 +469,7 @@ bind_buffer_object(GLcontext *ctx, GLenum target, GLuint buffer) /* The spec says there's not a buffer object named 0, but we use * one internally because it simplifies things. */ - newBufObj = ctx->Array.NullBufferObj; + newBufObj = ctx->Shared->NullBufferObj; } else { /* non-default buffer object */ @@ -744,7 +736,7 @@ unbind(GLcontext *ctx, struct gl_buffer_object *obj) { if (*ptr == obj) { - _mesa_reference_buffer_object(ctx, ptr, ctx->Array.NullBufferObj); + _mesa_reference_buffer_object(ctx, ptr, ctx->Shared->NullBufferObj); } } diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index d780f91f04..1a290f251a 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1005,9 +1005,6 @@ _mesa_free_context_data( GLcontext *ctx ) _mesa_free_query_data(ctx); #endif -#if FEATURE_ARB_vertex_buffer_object - _mesa_delete_buffer_object(ctx, ctx->Array.NullBufferObj); -#endif _mesa_delete_array_object(ctx, ctx->Array.DefaultArrayObj); /* free dispatch tables */ diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index affb000b8c..3debbe9f2d 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1593,7 +1593,6 @@ struct gl_array_attrib GLbitfield NewState; /**< mask of _NEW_ARRAY_* values */ #if FEATURE_ARB_vertex_buffer_object - struct gl_buffer_object *NullBufferObj; struct gl_buffer_object *ArrayBufferObj; struct gl_buffer_object *ElementArrayBufferObj; #endif @@ -2064,6 +2063,8 @@ struct gl_shared_state GLuint TextureStateStamp; /**< state notification for shared tex */ /*@}*/ + /** Default buffer object for vertex arrays that aren't in VBOs */ + struct gl_buffer_object *NullBufferObj; /** * \name Vertex/fragment programs diff --git a/src/mesa/main/pixel.c b/src/mesa/main/pixel.c index 57ae9c721a..d9f3e476e8 100644 --- a/src/mesa/main/pixel.c +++ b/src/mesa/main/pixel.c @@ -170,7 +170,7 @@ _mesa_PixelMapfv( GLenum map, GLsizei mapsize, const GLfloat *values ) return; } /* restore */ - ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; + ctx->DefaultPacking.BufferObj = ctx->Shared->NullBufferObj; buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, GL_READ_ONLY_ARB, ctx->Unpack.BufferObj); @@ -229,7 +229,7 @@ _mesa_PixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values ) return; } /* restore */ - ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; + ctx->DefaultPacking.BufferObj = ctx->Shared->NullBufferObj; buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, GL_READ_ONLY_ARB, ctx->Unpack.BufferObj); @@ -303,7 +303,7 @@ _mesa_PixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values ) return; } /* restore */ - ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; + ctx->DefaultPacking.BufferObj = ctx->Shared->NullBufferObj; buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, GL_READ_ONLY_ARB, ctx->Unpack.BufferObj); @@ -371,7 +371,7 @@ _mesa_GetPixelMapfv( GLenum map, GLfloat *values ) return; } /* restore */ - ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; + ctx->DefaultPacking.BufferObj = ctx->Shared->NullBufferObj; buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, GL_WRITE_ONLY_ARB, ctx->Pack.BufferObj); @@ -432,7 +432,7 @@ _mesa_GetPixelMapuiv( GLenum map, GLuint *values ) return; } /* restore */ - ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; + ctx->DefaultPacking.BufferObj = ctx->Shared->NullBufferObj; buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, GL_WRITE_ONLY_ARB, ctx->Pack.BufferObj); @@ -494,7 +494,7 @@ _mesa_GetPixelMapusv( GLenum map, GLushort *values ) return; } /* restore */ - ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; + ctx->DefaultPacking.BufferObj = ctx->Shared->NullBufferObj; buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, GL_WRITE_ONLY_ARB, ctx->Pack.BufferObj); diff --git a/src/mesa/main/pixelstore.c b/src/mesa/main/pixelstore.c index ff1a6344cc..6a641f83f2 100644 --- a/src/mesa/main/pixelstore.c +++ b/src/mesa/main/pixelstore.c @@ -245,7 +245,8 @@ _mesa_init_pixelstore( GLcontext *ctx ) ctx->Pack.ClientStorage = GL_FALSE; ctx->Pack.Invert = GL_FALSE; #if FEATURE_EXT_pixel_buffer_object - ctx->Pack.BufferObj = ctx->Array.NullBufferObj; + _mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj, + ctx->Shared->NullBufferObj); #endif ctx->Unpack.Alignment = 4; ctx->Unpack.RowLength = 0; @@ -258,7 +259,8 @@ _mesa_init_pixelstore( GLcontext *ctx ) ctx->Unpack.ClientStorage = GL_FALSE; ctx->Unpack.Invert = GL_FALSE; #if FEATURE_EXT_pixel_buffer_object - ctx->Unpack.BufferObj = ctx->Array.NullBufferObj; + _mesa_reference_buffer_object(ctx, &ctx->Unpack.BufferObj, + ctx->Shared->NullBufferObj); #endif /* @@ -278,6 +280,7 @@ _mesa_init_pixelstore( GLcontext *ctx ) ctx->DefaultPacking.ClientStorage = GL_FALSE; ctx->DefaultPacking.Invert = GL_FALSE; #if FEATURE_EXT_pixel_buffer_object - ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj; + _mesa_reference_buffer_object(ctx, &ctx->DefaultPacking.BufferObj, + ctx->Shared->NullBufferObj); #endif } diff --git a/src/mesa/main/shared.c b/src/mesa/main/shared.c index ae8dd2a836..759883743d 100644 --- a/src/mesa/main/shared.c +++ b/src/mesa/main/shared.c @@ -33,6 +33,7 @@ #include "mtypes.h" #include "hash.h" #include "arrayobj.h" +#include "bufferobj.h" #include "shared.h" #include "shader/program.h" #include "shader/shader_api.h" @@ -92,6 +93,13 @@ _mesa_alloc_shared_state(GLcontext *ctx) shared->BufferObjects = _mesa_NewHashTable(); #endif + /* Allocate the default buffer object and set refcount so high that + * it never gets deleted. + * XXX with recent/improved refcounting this may not longer be needed. + */ + shared->NullBufferObj = _mesa_new_buffer_object(ctx, 0, 0); + shared->NullBufferObj->RefCount = 1000; + shared->ArrayObjects = _mesa_NewHashTable(); /* Create default texture objects */ @@ -341,6 +349,10 @@ _mesa_free_shared_state(GLcontext *ctx, struct gl_shared_state *shared) _mesa_DeleteHashTable(shared->RenderBuffers); #endif +#if FEATURE_ARB_vertex_buffer_object + _mesa_delete_buffer_object(ctx, shared->NullBufferObj); +#endif + /* * Free texture objects (after FBOs since some textures might have * been bound to FBOs). diff --git a/src/mesa/swrast/s_imaging.c b/src/mesa/swrast/s_imaging.c index d6be3aa022..3578b713f6 100644 --- a/src/mesa/swrast/s_imaging.c +++ b/src/mesa/swrast/s_imaging.c @@ -60,7 +60,7 @@ _swrast_CopyColorTable( GLcontext *ctx, /* save PBO binding */ bufferSave = ctx->Unpack.BufferObj; - ctx->Unpack.BufferObj = ctx->Array.NullBufferObj; + ctx->Unpack.BufferObj = ctx->Shared->NullBufferObj; _mesa_ColorTable(target, internalformat, width, GL_RGBA, CHAN_TYPE, data); @@ -94,7 +94,7 @@ _swrast_CopyColorSubTable( GLcontext *ctx,GLenum target, GLsizei start, /* save PBO binding */ bufferSave = ctx->Unpack.BufferObj; - ctx->Unpack.BufferObj = ctx->Array.NullBufferObj; + ctx->Unpack.BufferObj = ctx->Shared->NullBufferObj; _mesa_ColorSubTable(target, start, width, GL_RGBA, CHAN_TYPE, data); @@ -126,7 +126,7 @@ _swrast_CopyConvolutionFilter1D(GLcontext *ctx, GLenum target, /* save PBO binding */ bufferSave = ctx->Unpack.BufferObj; - ctx->Unpack.BufferObj = ctx->Array.NullBufferObj; + ctx->Unpack.BufferObj = ctx->Shared->NullBufferObj; /* store as convolution filter */ _mesa_ConvolutionFilter1D(target, internalFormat, width, @@ -178,12 +178,12 @@ _swrast_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target, ctx->Unpack.SkipImages = 0; ctx->Unpack.SwapBytes = GL_FALSE; ctx->Unpack.LsbFirst = GL_FALSE; - ctx->Unpack.BufferObj = ctx->Array.NullBufferObj; + ctx->Unpack.BufferObj = ctx->Shared->NullBufferObj; ctx->NewState |= _NEW_PACKUNPACK; /* save PBO binding */ bufferSave = ctx->Unpack.BufferObj; - ctx->Unpack.BufferObj = ctx->Array.NullBufferObj; + ctx->Unpack.BufferObj = ctx->Shared->NullBufferObj; _mesa_ConvolutionFilter2D(target, internalFormat, width, height, GL_RGBA, CHAN_TYPE, rgba); diff --git a/src/mesa/vbo/vbo_context.c b/src/mesa/vbo/vbo_context.c index ca8190fd05..f193a4bf1e 100644 --- a/src/mesa/vbo/vbo_context.c +++ b/src/mesa/vbo/vbo_context.c @@ -28,6 +28,7 @@ #include "main/imports.h" #include "main/mtypes.h" #include "main/api_arrayelt.h" +#include "main/bufferobj.h" #include "math/m_eval.h" #include "vbo.h" #include "vbo_context.h" @@ -81,7 +82,8 @@ static void init_legacy_currval(GLcontext *ctx) cl->Type = GL_FLOAT; cl->Format = GL_RGBA; cl->Ptr = (const void *)ctx->Current.Attrib[i]; - cl->BufferObj = ctx->Array.NullBufferObj; + _mesa_reference_buffer_object(ctx, &cl->BufferObj, + ctx->Shared->NullBufferObj); } } @@ -106,7 +108,8 @@ static void init_generic_currval(GLcontext *ctx) cl->Stride = 0; cl->StrideB = 0; cl->Enabled = 1; - cl->BufferObj = ctx->Array.NullBufferObj; + _mesa_reference_buffer_object(ctx, &cl->BufferObj, + ctx->Shared->NullBufferObj); } } @@ -150,7 +153,7 @@ static void init_mat_currval(GLcontext *ctx) cl->Stride = 0; cl->StrideB = 0; cl->Enabled = 1; - cl->BufferObj = ctx->Array.NullBufferObj; + cl->BufferObj = ctx->Shared->NullBufferObj; } } diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c index 5d35ec9c11..6871ee5cab 100644 --- a/src/mesa/vbo/vbo_exec_api.c +++ b/src/mesa/vbo/vbo_exec_api.c @@ -671,7 +671,7 @@ void vbo_use_buffer_objects(GLcontext *ctx) GLsizei size = VBO_VERT_BUFFER_SIZE; /* Make sure this func is only used once */ - assert(exec->vtx.bufferobj == ctx->Array.NullBufferObj); + assert(exec->vtx.bufferobj == ctx->Shared->NullBufferObj); if (exec->vtx.buffer_map) { _mesa_align_free(exec->vtx.buffer_map); exec->vtx.buffer_map = NULL; @@ -697,7 +697,7 @@ void vbo_exec_vtx_init( struct vbo_exec_context *exec ) */ _mesa_reference_buffer_object(ctx, &exec->vtx.bufferobj, - ctx->Array.NullBufferObj); + ctx->Shared->NullBufferObj); ASSERT(!exec->vtx.buffer_map); exec->vtx.buffer_map = (GLfloat *)ALIGN_MALLOC(VBO_VERT_BUFFER_SIZE, 64); diff --git a/src/mesa/vbo/vbo_rebase.c b/src/mesa/vbo/vbo_rebase.c index dae778e741..ea87dede64 100644 --- a/src/mesa/vbo/vbo_rebase.c +++ b/src/mesa/vbo/vbo_rebase.c @@ -161,7 +161,7 @@ void vbo_rebase_prims( GLcontext *ctx, GL_ELEMENT_ARRAY_BUFFER, ib->obj); - tmp_ib.obj = ctx->Array.NullBufferObj; + tmp_ib.obj = ctx->Shared->NullBufferObj; tmp_ib.ptr = tmp_indices; tmp_ib.count = ib->count; tmp_ib.type = ib->type; diff --git a/src/mesa/vbo/vbo_split_copy.c b/src/mesa/vbo/vbo_split_copy.c index 56a9fafac4..2f6a1998ea 100644 --- a/src/mesa/vbo/vbo_split_copy.c +++ b/src/mesa/vbo/vbo_split_copy.c @@ -459,7 +459,7 @@ replay_init( struct copy_context *copy ) dst->Ptr = copy->dstbuf + offset; dst->Enabled = GL_TRUE; dst->Normalized = src->Normalized; - dst->BufferObj = ctx->Array.NullBufferObj; + dst->BufferObj = ctx->Shared->NullBufferObj; dst->_MaxElement = copy->dstbuf_size; /* may be less! */ offset += copy->varying[i].size; @@ -479,7 +479,7 @@ replay_init( struct copy_context *copy ) */ copy->dstib.count = 0; /* duplicates dstelt_nr */ copy->dstib.type = GL_UNSIGNED_INT; - copy->dstib.obj = ctx->Array.NullBufferObj; + copy->dstib.obj = ctx->Shared->NullBufferObj; copy->dstib.ptr = copy->dstelt; } diff --git a/src/mesa/vbo/vbo_split_inplace.c b/src/mesa/vbo/vbo_split_inplace.c index fbc856e93b..3ed6b34fbf 100644 --- a/src/mesa/vbo/vbo_split_inplace.c +++ b/src/mesa/vbo/vbo_split_inplace.c @@ -221,7 +221,7 @@ static void split_prims( struct split_context *split) ib.count = count; ib.type = GL_UNSIGNED_INT; - ib.obj = split->ctx->Array.NullBufferObj; + ib.obj = split->ctx->Shared->NullBufferObj; ib.ptr = elts; tmpprim = *prim; -- cgit v1.2.3 From 9bb6684799f00fabc313ee50be671454e498d8a9 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 7 May 2009 13:36:20 -0600 Subject: mesa: array object comments --- src/mesa/main/mtypes.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/mesa/main') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 3debbe9f2d..b24366d0fe 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1557,6 +1557,8 @@ struct gl_array_object /** Name of the array object as received from glGenVertexArrayAPPLE. */ GLuint Name; + /** XXX Need a refcount here */ + /** Conventional vertex arrays */ /*@{*/ struct gl_client_array Vertex; @@ -1583,7 +1585,10 @@ struct gl_array_object */ struct gl_array_attrib { + /** Currently bound array object. See _mesa_BindVertexArrayAPPLE() */ struct gl_array_object *ArrayObj; + + /** The default vertex array object */ struct gl_array_object *DefaultArrayObj; GLint ActiveTexture; /**< Client Active Texture */ -- cgit v1.2.3 From 1030bf0ded2a88a5e27f7a4d393c11cfde3d3c5a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 7 May 2009 13:52:26 -0600 Subject: mesa: reference counting for gl_array_object Every kind of object that can be shared by multiple contexts should be refcounted. --- src/mesa/main/arrayobj.c | 67 +++++++++++++++++++++++++++++++++++++++++++++--- src/mesa/main/arrayobj.h | 23 ++++++++++++----- src/mesa/main/mtypes.h | 3 ++- src/mesa/main/varray.c | 4 +-- 4 files changed, 83 insertions(+), 14 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c index 2646c12ccc..71f4216bd3 100644 --- a/src/mesa/main/arrayobj.c +++ b/src/mesa/main/arrayobj.c @@ -94,10 +94,69 @@ void _mesa_delete_array_object( GLcontext *ctx, struct gl_array_object *obj ) { (void) ctx; + _glthread_DESTROY_MUTEX(obj->Mutex); _mesa_free(obj); } +/** + * Set ptr to arrayObj w/ reference counting. + */ +void +_mesa_reference_array_object(GLcontext *ctx, + struct gl_array_object **ptr, + struct gl_array_object *arrayObj) +{ + if (*ptr == arrayObj) + return; + + if (*ptr) { + /* Unreference the old array object */ + GLboolean deleteFlag = GL_FALSE; + struct gl_array_object *oldObj = *ptr; + + _glthread_LOCK_MUTEX(oldObj->Mutex); + ASSERT(oldObj->RefCount > 0); + oldObj->RefCount--; +#if 0 + printf("ArrayObj %p %d DECR to %d\n", + (void *) oldObj, oldObj->Name, oldObj->RefCount); +#endif + deleteFlag = (oldObj->RefCount == 0); + _glthread_UNLOCK_MUTEX(oldObj->Mutex); + + if (deleteFlag) { + ASSERT(ctx->Driver.DeleteArrayObject); + ctx->Driver.DeleteArrayObject(ctx, oldObj); + } + + *ptr = NULL; + } + ASSERT(!*ptr); + + if (arrayObj) { + /* reference new array object */ + _glthread_LOCK_MUTEX(arrayObj->Mutex); + if (arrayObj->RefCount == 0) { + /* this array's being deleted (look just above) */ + /* Not sure this can every really happen. Warn if it does. */ + _mesa_problem(NULL, "referencing deleted array object"); + *ptr = NULL; + } + else { + arrayObj->RefCount++; +#if 0 + printf("ArrayObj %p %d INCR to %d\n", + (void *) arrayObj, arrayObj->Name, arrayObj->RefCount); +#endif + *ptr = arrayObj; + } + _glthread_UNLOCK_MUTEX(arrayObj->Mutex); + } +} + + + static void init_array(GLcontext *ctx, struct gl_client_array *array, GLint size, GLint type) @@ -130,6 +189,9 @@ _mesa_initialize_array_object( GLcontext *ctx, obj->Name = name; + _glthread_INIT_MUTEX(obj->Mutex); + obj->RefCount = 1; + /* Init the individual arrays */ init_array(ctx, &obj->Vertex, 4, GL_FLOAT); init_array(ctx, &obj->Normal, 3, GL_FLOAT); @@ -227,7 +289,6 @@ _mesa_BindVertexArrayAPPLE( GLuint id ) if (!newObj) { /* If this is a new array object id, allocate an array object now. */ - newObj = (*ctx->Driver.NewArrayObject)(ctx, id); if (!newObj) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindVertexArrayAPPLE"); @@ -237,11 +298,9 @@ _mesa_BindVertexArrayAPPLE( GLuint id ) } } - ctx->NewState |= _NEW_ARRAY; ctx->Array.NewState |= _NEW_ARRAY_ALL; - ctx->Array.ArrayObj = newObj; - + _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, newObj); /* Pass BindVertexArray call to device driver */ if (ctx->Driver.BindArrayObject && newObj) diff --git a/src/mesa/main/arrayobj.h b/src/mesa/main/arrayobj.h index c7d66ec166..9c4036af5a 100644 --- a/src/mesa/main/arrayobj.h +++ b/src/mesa/main/arrayobj.h @@ -41,17 +41,26 @@ * Internal functions */ -struct gl_array_object * _mesa_new_array_object( GLcontext *ctx, - GLuint name ); +extern struct gl_array_object * +_mesa_new_array_object( GLcontext *ctx, GLuint name ); -void _mesa_delete_array_object( GLcontext *ctx, struct gl_array_object *obj ); +extern void +_mesa_delete_array_object( GLcontext *ctx, struct gl_array_object *obj ); -void _mesa_initialize_array_object( GLcontext *ctx, - struct gl_array_object *obj, GLuint name ); +extern void +_mesa_reference_array_object(GLcontext *ctx, + struct gl_array_object **ptr, + struct gl_array_object *arrayObj); -void _mesa_save_array_object( GLcontext *ctx, struct gl_array_object *obj ); +extern void +_mesa_initialize_array_object( GLcontext *ctx, + struct gl_array_object *obj, GLuint name ); -void _mesa_remove_array_object( GLcontext *ctx, struct gl_array_object *obj ); +extern void +_mesa_save_array_object( GLcontext *ctx, struct gl_array_object *obj ); + +extern void +_mesa_remove_array_object( GLcontext *ctx, struct gl_array_object *obj ); diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index b24366d0fe..d11df535f2 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1557,7 +1557,8 @@ struct gl_array_object /** Name of the array object as received from glGenVertexArrayAPPLE. */ GLuint Name; - /** XXX Need a refcount here */ + GLint RefCount; + _glthread_Mutex Mutex; /** Conventional vertex arrays */ /*@{*/ diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index 4d153b1c0b..a9c9162be1 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -1039,7 +1039,7 @@ void _mesa_init_varray(GLcontext *ctx) { ctx->Array.DefaultArrayObj = _mesa_new_array_object(ctx, 0); - ctx->Array.ArrayObj = ctx->Array.DefaultArrayObj; - + _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, + ctx->Array.DefaultArrayObj); ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */ } -- cgit v1.2.3 From 32b851c80792623195069d7a41a5808cff3b2f6f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 7 May 2009 14:26:17 -0600 Subject: mesa: clean-up vertex array object VBO unbinding and delete/refcounting Don't really delete vertex array objects until the refcount hits zero. At that time, unbind any pointers to VBOs. --- src/mesa/main/arrayobj.c | 64 +++++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 31 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c index 71f4216bd3..b4d1a77b97 100644 --- a/src/mesa/main/arrayobj.c +++ b/src/mesa/main/arrayobj.c @@ -68,6 +68,32 @@ lookup_arrayobj(GLcontext *ctx, GLuint id) } +/** + * For all the vertex arrays in the array object, unbind any pointers + * to any buffer objects (VBOs). + * This is done just prior to array object destruction. + */ +static void +unbind_array_object_vbos(GLcontext *ctx, struct gl_array_object *obj) +{ + GLuint i; + + _mesa_reference_buffer_object(ctx, &obj->Vertex.BufferObj, NULL); + _mesa_reference_buffer_object(ctx, &obj->Normal.BufferObj, NULL); + _mesa_reference_buffer_object(ctx, &obj->Color.BufferObj, NULL); + _mesa_reference_buffer_object(ctx, &obj->SecondaryColor.BufferObj, NULL); + _mesa_reference_buffer_object(ctx, &obj->FogCoord.BufferObj, NULL); + _mesa_reference_buffer_object(ctx, &obj->Index.BufferObj, NULL); + _mesa_reference_buffer_object(ctx, &obj->EdgeFlag.BufferObj, NULL); + + for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) + _mesa_reference_buffer_object(ctx, &obj->TexCoord[i].BufferObj, NULL); + + for (i = 0; i < VERT_ATTRIB_MAX; i++) + _mesa_reference_buffer_object(ctx, &obj->VertexAttrib[i].BufferObj,NULL); +} + + /** * Allocate and initialize a new vertex array object. * @@ -94,6 +120,7 @@ void _mesa_delete_array_object( GLcontext *ctx, struct gl_array_object *obj ) { (void) ctx; + unbind_array_object_vbos(ctx, obj); _glthread_DESTROY_MUTEX(obj->Mutex); _mesa_free(obj); } @@ -240,15 +267,6 @@ _mesa_remove_array_object( GLcontext *ctx, struct gl_array_object *obj ) } -static void -unbind_buffer_object( GLcontext *ctx, struct gl_buffer_object *bufObj ) -{ - if (bufObj != ctx->Shared->NullBufferObj) { - _mesa_reference_buffer_object(ctx, &bufObj, NULL); - } -} - - /**********************************************************************/ /* API Functions */ /**********************************************************************/ @@ -275,7 +293,7 @@ _mesa_BindVertexArrayAPPLE( GLuint id ) return; /* rebinding the same array object- no change */ /* - * Get pointer to new array object (newBufObj) + * Get pointer to new array object (newObj) */ if (id == 0) { /* The spec says there is no array object named 0, but we use @@ -334,7 +352,6 @@ _mesa_DeleteVertexArraysAPPLE(GLsizei n, const GLuint *ids) if ( obj != NULL ) { ASSERT( obj->Name == ids[i] ); - /* If the array object is currently bound, the spec says "the binding * for that object reverts to zero and the default vertex array * becomes current." @@ -343,28 +360,13 @@ _mesa_DeleteVertexArraysAPPLE(GLsizei n, const GLuint *ids) CALL_BindVertexArrayAPPLE( ctx->Exec, (0) ); } -#if FEATURE_ARB_vertex_buffer_object - /* Unbind any buffer objects that might be bound to arrays in - * this array object. - */ - unbind_buffer_object( ctx, obj->Vertex.BufferObj ); - unbind_buffer_object( ctx, obj->Normal.BufferObj ); - unbind_buffer_object( ctx, obj->Color.BufferObj ); - unbind_buffer_object( ctx, obj->SecondaryColor.BufferObj ); - unbind_buffer_object( ctx, obj->FogCoord.BufferObj ); - unbind_buffer_object( ctx, obj->Index.BufferObj ); - for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) { - unbind_buffer_object( ctx, obj->TexCoord[i].BufferObj ); - } - unbind_buffer_object( ctx, obj->EdgeFlag.BufferObj ); - for (i = 0; i < VERT_ATTRIB_MAX; i++) { - unbind_buffer_object( ctx, obj->VertexAttrib[i].BufferObj ); - } -#endif - /* The ID is immediately freed for re-use */ _mesa_remove_array_object(ctx, obj); - ctx->Driver.DeleteArrayObject(ctx, obj); + + /* Unreference the array object. + * If refcount hits zero, the object will be deleted. + */ + _mesa_reference_array_object(ctx, &obj, NULL); } } -- cgit v1.2.3 From fa95ecb467d656e293a12c089b3e85fcbbadb848 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 7 May 2009 14:33:18 -0600 Subject: mesa: make the array object save/remove functions static --- src/mesa/main/arrayobj.c | 14 +++++++------- src/mesa/main/arrayobj.h | 7 ------- 2 files changed, 7 insertions(+), 14 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c index b4d1a77b97..8ec73b9526 100644 --- a/src/mesa/main/arrayobj.c +++ b/src/mesa/main/arrayobj.c @@ -243,8 +243,8 @@ _mesa_initialize_array_object( GLcontext *ctx, /** * Add the given array object to the array object pool. */ -void -_mesa_save_array_object( GLcontext *ctx, struct gl_array_object *obj ) +static void +save_array_object( GLcontext *ctx, struct gl_array_object *obj ) { if (obj->Name > 0) { /* insert into hash table */ @@ -257,8 +257,8 @@ _mesa_save_array_object( GLcontext *ctx, struct gl_array_object *obj ) * Remove the given array object from the array object pool. * Do not deallocate the array object though. */ -void -_mesa_remove_array_object( GLcontext *ctx, struct gl_array_object *obj ) +static void +remove_array_object( GLcontext *ctx, struct gl_array_object *obj ) { if (obj->Name > 0) { /* remove from hash table */ @@ -312,7 +312,7 @@ _mesa_BindVertexArrayAPPLE( GLuint id ) _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindVertexArrayAPPLE"); return; } - _mesa_save_array_object(ctx, newObj); + save_array_object(ctx, newObj); } } @@ -361,7 +361,7 @@ _mesa_DeleteVertexArraysAPPLE(GLsizei n, const GLuint *ids) } /* The ID is immediately freed for re-use */ - _mesa_remove_array_object(ctx, obj); + remove_array_object(ctx, obj); /* Unreference the array object. * If refcount hits zero, the object will be deleted. @@ -415,7 +415,7 @@ _mesa_GenVertexArraysAPPLE(GLsizei n, GLuint *arrays) _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenVertexArraysAPPLE"); return; } - _mesa_save_array_object(ctx, obj); + save_array_object(ctx, obj); arrays[i] = first + i; } diff --git a/src/mesa/main/arrayobj.h b/src/mesa/main/arrayobj.h index 9c4036af5a..9c2f340cfa 100644 --- a/src/mesa/main/arrayobj.h +++ b/src/mesa/main/arrayobj.h @@ -56,13 +56,6 @@ extern void _mesa_initialize_array_object( GLcontext *ctx, struct gl_array_object *obj, GLuint name ); -extern void -_mesa_save_array_object( GLcontext *ctx, struct gl_array_object *obj ); - -extern void -_mesa_remove_array_object( GLcontext *ctx, struct gl_array_object *obj ); - - /* * API functions -- cgit v1.2.3 From b25168c34c60760a33ca9e8336ac76cf1219f143 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Fri, 1 May 2009 18:52:54 +0100 Subject: mesa: Make _mesa_share_state thread safe. --- src/mesa/main/context.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 1a290f251a..ddbc631e67 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1394,14 +1394,21 @@ _mesa_share_state(GLcontext *ctx, GLcontext *ctxToShare) { if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) { struct gl_shared_state *oldSharedState = ctx->Shared; + GLint RefCount; ctx->Shared = ctxToShare->Shared; + + _glthread_LOCK_MUTEX(ctx->Shared->Mutex); ctx->Shared->RefCount++; + _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); update_default_objects(ctx); - oldSharedState->RefCount--; - if (oldSharedState->RefCount == 0) { + _glthread_LOCK_MUTEX(oldSharedState->Mutex); + RefCount = --oldSharedState->RefCount; + _glthread_UNLOCK_MUTEX(oldSharedState->Mutex); + + if (RefCount == 0) { _mesa_free_shared_state(ctx, oldSharedState); } -- cgit v1.2.3 From 87fbc9a14ed2bdd24d84c38431abbf7b0c275998 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 8 May 2009 12:44:38 -0600 Subject: mesa: issue warning for out of bounds array indexes --- src/mesa/main/api_validate.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/mesa/main') diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index 27049486ee..d5c604c56a 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -184,6 +184,8 @@ _mesa_validate_DrawElements(GLcontext *ctx, ctx->Array.ElementArrayBufferObj); if (max >= ctx->Array._MaxElement) { /* the max element is out of bounds of one or more enabled arrays */ + _mesa_warning(ctx, "glDrawElements() index=%u is " + "out of bounds (max=%u)", max, ctx->Array._MaxElement); return GL_FALSE; } } -- cgit v1.2.3 From 17a354a119370df9196a010a31fc71cd8712ec46 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 8 May 2009 14:34:15 -0600 Subject: mesa: assertions to check for too many vertex outputs or fragment inputs --- src/mesa/main/context.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/mesa/main') diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index ddbc631e67..5e0f2d7b1b 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -602,6 +602,10 @@ _mesa_init_constants(GLcontext *ctx) ASSERT(MAX_NV_VERTEX_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS); ASSERT(MAX_NV_VERTEX_PROGRAM_INPUTS <= VERT_ATTRIB_MAX); ASSERT(MAX_NV_VERTEX_PROGRAM_OUTPUTS <= VERT_RESULT_MAX); + + /* check that we don't exceed various 32-bit bitfields */ + ASSERT(VERT_RESULT_MAX <= 32); + ASSERT(FRAG_ATTRIB_MAX <= 32); } -- cgit v1.2.3 From 4e762395ef7e8c332c16fd0c11025cfa52763a45 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 8 May 2009 14:34:43 -0600 Subject: mesa: raise MAX_VARYING (number of shader varying vars) to 16 16 is the limit for now because of various 32-bit bitfields. --- src/mesa/main/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h index 2a9fdf9ca0..888e08ff93 100644 --- a/src/mesa/main/config.h +++ b/src/mesa/main/config.h @@ -187,7 +187,7 @@ #define MAX_PROGRAM_TEMPS 256 #define MAX_PROGRAM_ADDRESS_REGS 2 #define MAX_UNIFORMS 1024 /**< number of vec4 uniforms */ -#define MAX_VARYING 8 /**< number of float[4] vectors */ +#define MAX_VARYING 16 /**< number of float[4] vectors */ #define MAX_SAMPLERS MAX_TEXTURE_IMAGE_UNITS #define MAX_PROGRAM_INPUTS 32 #define MAX_PROGRAM_OUTPUTS 32 -- cgit v1.2.3 From c230767d6956b63a2b101acb48f98823bb5dd31a Mon Sep 17 00:00:00 2001 From: Robert Ellison Date: Fri, 8 May 2009 11:13:57 -0600 Subject: mesa: Fixed a texture memory leak The current texture for any particular texture unit is given an additional reference in update_texture_state(); but if the context is closed before that texture can be released (which is quite frequent in normal use, unless a program unbinds and deletes the texture and renders without it to force a call to update_texture_state(), the memory is lost. This affects general Mesa; but the i965 is particularly affected because it allocates a considerable amount of additional memory for each allocated texture. --- src/mesa/main/texstate.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/mesa/main') diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 5453331c67..6e0c0c688a 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -791,6 +791,9 @@ _mesa_free_texture_data(GLcontext *ctx) /* unreference current textures */ for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) { + /* The _Current texture could account for another reference */ + _mesa_reference_texobj(&ctx->Texture.Unit[u]._Current, NULL); + for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { _mesa_reference_texobj(&ctx->Texture.Unit[u].CurrentTex[tgt], NULL); } -- cgit v1.2.3