From 9f66025f54a3a9cc33cba56ec7c9f59721ddbec7 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 11 Apr 2007 09:00:56 -0600 Subject: fix invalid error detection problem in _mesa_bind_attrib_location(), bug 10602 --- src/mesa/shader/shader_api.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'src/mesa/shader/shader_api.c') diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index 1831d0fb2e7..cf42a5843ec 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -323,7 +323,13 @@ _mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index, return; } - oldIndex = _mesa_get_attrib_location(ctx, program, name); + if (shProg->LinkStatus) { + /* get current index/location for the attribute */ + oldIndex = _mesa_get_attrib_location(ctx, program, name); + } + else { + oldIndex = -1; + } /* this will replace the current value if it's already in the list */ i = _mesa_add_attribute(shProg->Attributes, name, size, index); @@ -331,14 +337,12 @@ _mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index, _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindAttribLocation"); } - if (shProg->VertexProgram && oldIndex >= 0) { + if (shProg->VertexProgram && oldIndex >= 0 && oldIndex != index) { + /* If the index changed, need to search/replace references to that attribute + * in the vertex program. + */ _slang_remap_attribute(&shProg->VertexProgram->Base, oldIndex, index); } - -#if 0 - printf("===== post BindAttrib:\n"); - _mesa_print_program(&shProg->VertexProgram->Base); -#endif } -- cgit v1.2.3 From 3c008a014f7c1d14209b70b4b030bf7738aa16d7 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 12 Apr 2007 15:22:32 -0600 Subject: New _mesa_reference_shader/program() function to consolidate refcounting. Note that (unlike texture objects), shader handles remain valid (in the hash table) after glDeleteShader/Program() if the refcount isn't zero. --- src/mesa/shader/shader_api.c | 202 ++++++++++++++++++++++++++++++++----------- src/mesa/shader/shader_api.h | 13 +++ 2 files changed, 166 insertions(+), 49 deletions(-) (limited to 'src/mesa/shader/shader_api.c') diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index cf42a5843ec..47622fdd521 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -68,15 +68,12 @@ _mesa_new_shader_program(GLcontext *ctx, GLuint name) /** - * Free the data that hangs off a shader program object, but not the object - * itself. + * Clear (free) the shader program state that gets produced by linking. */ void -_mesa_free_shader_program_data(GLcontext *ctx, - struct gl_shader_program *shProg) +_mesa_clear_shader_program_data(GLcontext *ctx, + struct gl_shader_program *shProg) { - assert(shProg->Type == GL_SHADER_PROGRAM); - if (shProg->VertexProgram) { if (shProg->VertexProgram->Base.Parameters == shProg->Uniforms) { /* to prevent a double-free in the next call */ @@ -95,7 +92,6 @@ _mesa_free_shader_program_data(GLcontext *ctx, shProg->FragmentProgram = NULL; } - if (shProg->Uniforms) { _mesa_free_parameter_list(shProg->Uniforms); shProg->Uniforms = NULL; @@ -108,12 +104,38 @@ _mesa_free_shader_program_data(GLcontext *ctx, } +/** + * Free all the data that hangs off a shader program object, but not the + * object itself. + */ +void +_mesa_free_shader_program_data(GLcontext *ctx, + struct gl_shader_program *shProg) +{ + GLuint i; + + assert(shProg->Type == GL_SHADER_PROGRAM); + + _mesa_clear_shader_program_data(ctx, shProg); + + /* detach shaders */ + for (i = 0; i < shProg->NumShaders; i++) { + _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL); + } + if (shProg->Shaders) { + _mesa_free(shProg->Shaders); + shProg->Shaders = NULL; + } +} + + /** * Free/delete a shader program object. */ void _mesa_free_shader_program(GLcontext *ctx, struct gl_shader_program *shProg) { + printf("FREE SHADER PROG %d\n", shProg->Name); _mesa_free_shader_program_data(ctx, shProg); if (shProg->Shaders) { _mesa_free(shProg->Shaders); @@ -123,6 +145,52 @@ _mesa_free_shader_program(GLcontext *ctx, struct gl_shader_program *shProg) } +/** + * Set ptr to point to shProg. + * If ptr is pointing to another object, decrement its refcount (and delete + * if refcount hits zero). + * Then set ptr to point to shProg, incrementing its refcount. + */ +/* XXX this could be static */ +void +_mesa_reference_shader_program(GLcontext *ctx, + struct gl_shader_program **ptr, + struct gl_shader_program *shProg) +{ + assert(ptr); + if (*ptr == shProg) { + /* no-op */ + return; + } + if (*ptr) { + /* Unreference the old shader program */ + GLboolean deleteFlag = GL_FALSE; + struct gl_shader_program *old = *ptr; + + ASSERT(old->RefCount > 0); + old->RefCount--; + /*printf("SHPROG DECR %p (%d) to %d\n", + (void*) old, old->Name, old->RefCount);*/ + deleteFlag = (old->RefCount == 0); + + if (deleteFlag) { + _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name); + _mesa_free_shader_program(ctx, old); + } + + *ptr = NULL; + } + assert(!*ptr); + + if (shProg) { + shProg->RefCount++; + printf("SHPROG INCR %p (%d) to %d\n", + (void*) shProg, shProg->Name, shProg->RefCount); + *ptr = shProg; + } +} + + /** * Lookup a GLSL program object. */ @@ -168,6 +236,7 @@ void _mesa_free_shader(GLcontext *ctx, struct gl_shader *sh) { GLuint i; + printf("FREE SHADER %d\n", sh->Name); if (sh->Source) _mesa_free((void *) sh->Source); if (sh->InfoLog) @@ -182,6 +251,52 @@ _mesa_free_shader(GLcontext *ctx, struct gl_shader *sh) } +/** + * Set ptr to point to sh. + * If ptr is pointing to another shader, decrement its refcount (and delete + * if refcount hits zero). + * Then set ptr to point to sh, incrementing its refcount. + */ +/* XXX this could be static */ +void +_mesa_reference_shader(GLcontext *ctx, struct gl_shader **ptr, + struct gl_shader *sh) +{ + assert(ptr); + if (*ptr == sh) { + /* no-op */ + return; + } + if (*ptr) { + /* Unreference the old shader */ + GLboolean deleteFlag = GL_FALSE; + struct gl_shader *old = *ptr; + + ASSERT(old->RefCount > 0); + old->RefCount--; + printf("SHADER DECR %p (%d) to %d\n", + (void*) old, old->Name, old->RefCount); + deleteFlag = (old->RefCount == 0); + + if (deleteFlag) { + _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name); + _mesa_free_shader(ctx, old); + } + + *ptr = NULL; + } + assert(!*ptr); + + if (sh) { + /* reference new */ + sh->RefCount++; + printf("SHADER INCR %p (%d) to %d\n", + (void*) sh, sh->Name, sh->RefCount); + *ptr = sh; + } +} + + /** * Lookup a GLSL shader object. */ @@ -227,13 +342,7 @@ _mesa_init_shader_state(GLcontext * ctx) void _mesa_free_shader_state(GLcontext *ctx) { - if (ctx->Shader.CurrentProgram) { - ctx->Shader.CurrentProgram->RefCount--; - if (ctx->Shader.CurrentProgram->RefCount <= 0) { - _mesa_free_shader_program(ctx, ctx->Shader.CurrentProgram); - ctx->Shader.CurrentProgram = NULL; - } - } + _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, NULL); } @@ -294,8 +403,8 @@ _mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader) } /* append */ - shProg->Shaders[n] = sh; - sh->RefCount++; + shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */ + _mesa_reference_shader(ctx, &shProg->Shaders[n], sh); shProg->NumShaders++; } @@ -381,13 +490,27 @@ _mesa_create_program(GLcontext *ctx) _mesa_HashInsert(ctx->Shared->ShaderObjects, name, shProg); + assert(shProg->RefCount == 1); + return name; } +/** + * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's + * DeleteProgramARB. + */ void _mesa_delete_program2(GLcontext *ctx, GLuint name) { + /* + * NOTE: deleting shaders/programs works a bit differently than + * texture objects (and buffer objects, etc). Shader/program + * handles/IDs exist in the hash table until the object is really + * deleted (refcount==0). With texture objects, the handle/ID is + * removed from the hash table in glDeleteTextures() while the tex + * object itself might linger until its refcount goes to zero. + */ struct gl_shader_program *shProg; shProg = _mesa_lookup_shader_program(ctx, name); @@ -396,16 +519,10 @@ _mesa_delete_program2(GLcontext *ctx, GLuint name) return; } - /* always remove from hash table */ - _mesa_HashRemove(ctx->Shared->ShaderObjects, name); - shProg->DeletePending = GL_TRUE; - /* decrement refcount, delete if zero */ - shProg->RefCount--; - if (shProg->RefCount <= 0) { - _mesa_free_shader_program(ctx, shProg); - } + /* effectively, decr shProg's refcount */ + _mesa_reference_shader_program(ctx, &shProg, NULL); } @@ -418,10 +535,9 @@ _mesa_delete_shader(GLcontext *ctx, GLuint shader) } sh->DeletePending = GL_TRUE; - sh->RefCount--; - if (sh->RefCount <= 0) { - _mesa_free_shader(ctx, sh); - } + + /* effectively, decr sh's refcount */ + _mesa_reference_shader(ctx, &sh, NULL); } @@ -441,14 +557,11 @@ _mesa_detach_shader(GLcontext *ctx, GLuint program, GLuint shader) for (i = 0; i < n; i++) { if (shProg->Shaders[i]->Name == shader) { - struct gl_shader **newList; /* found it */ + struct gl_shader **newList; - shProg->Shaders[i]->RefCount--; - if (shProg->Shaders[i]->RefCount == 0) { - /* delete now */ - _mesa_free_shader(ctx, shProg->Shaders[i]); - } + /* derefernce */ + _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL); /* alloc new, smaller array */ newList = (struct gl_shader **) @@ -876,6 +989,8 @@ _mesa_link_program(GLcontext *ctx, GLuint program) void _mesa_use_program(GLcontext *ctx, GLuint program) { + struct gl_shader_program *shProg; + if (ctx->Shader.CurrentProgram && ctx->Shader.CurrentProgram->Name == program) { /* no-op */ @@ -884,30 +999,19 @@ _mesa_use_program(GLcontext *ctx, GLuint program) FLUSH_VERTICES(ctx, _NEW_PROGRAM); - /* unbind old */ - if (ctx->Shader.CurrentProgram) { - ctx->Shader.CurrentProgram->RefCount--; - if (ctx->Shader.CurrentProgram->RefCount <= 0) { - _mesa_free_shader_program(ctx, ctx->Shader.CurrentProgram); - } - ctx->Shader.CurrentProgram = NULL; - } - if (program) { - struct gl_shader_program *shProg; shProg = _mesa_lookup_shader_program(ctx, program); if (!shProg) { _mesa_error(ctx, GL_INVALID_VALUE, "glUseProgramObjectARB(programObj)"); return; } - ctx->Shader.CurrentProgram = shProg; - shProg->RefCount++; } else { - /* don't use a shader program */ - ctx->Shader.CurrentProgram = NULL; - } + shProg = NULL; + } + + _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, shProg); } diff --git a/src/mesa/shader/shader_api.h b/src/mesa/shader/shader_api.h index 16ed1a0c108..27e5870d705 100644 --- a/src/mesa/shader/shader_api.h +++ b/src/mesa/shader/shader_api.h @@ -44,6 +44,10 @@ _mesa_free_shader_state(GLcontext *ctx); extern struct gl_shader_program * _mesa_new_shader_program(GLcontext *ctx, GLuint name); +extern void +_mesa_clear_shader_program_data(GLcontext *ctx, + struct gl_shader_program *shProg); + extern void _mesa_free_shader_program_data(GLcontext *ctx, struct gl_shader_program *shProg); @@ -51,6 +55,11 @@ _mesa_free_shader_program_data(GLcontext *ctx, extern void _mesa_free_shader_program(GLcontext *ctx, struct gl_shader_program *shProg); +extern void +_mesa_reference_shader_program(GLcontext *ctx, + struct gl_shader_program **ptr, + struct gl_shader_program *shProg); + extern struct gl_shader_program * _mesa_lookup_shader_program(GLcontext *ctx, GLuint name); @@ -61,6 +70,10 @@ _mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type); extern void _mesa_free_shader(GLcontext *ctx, struct gl_shader *sh); +extern void +_mesa_reference_shader(GLcontext *ctx, struct gl_shader **ptr, + struct gl_shader *sh); + extern struct gl_shader * _mesa_lookup_shader(GLcontext *ctx, GLuint name); -- cgit v1.2.3 From 99193e4f7454bf5a9cfa0bc3ee6935d8cc85b7fa Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 12 Apr 2007 15:45:02 -0600 Subject: disable debug printfs --- src/mesa/shader/shader_api.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'src/mesa/shader/shader_api.c') diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index 47622fdd521..fc1ae287f4f 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -135,7 +135,6 @@ _mesa_free_shader_program_data(GLcontext *ctx, void _mesa_free_shader_program(GLcontext *ctx, struct gl_shader_program *shProg) { - printf("FREE SHADER PROG %d\n", shProg->Name); _mesa_free_shader_program_data(ctx, shProg); if (shProg->Shaders) { _mesa_free(shProg->Shaders); @@ -184,8 +183,8 @@ _mesa_reference_shader_program(GLcontext *ctx, if (shProg) { shProg->RefCount++; - printf("SHPROG INCR %p (%d) to %d\n", - (void*) shProg, shProg->Name, shProg->RefCount); + /*printf("SHPROG INCR %p (%d) to %d\n", + (void*) shProg, shProg->Name, shProg->RefCount);*/ *ptr = shProg; } } @@ -236,7 +235,6 @@ void _mesa_free_shader(GLcontext *ctx, struct gl_shader *sh) { GLuint i; - printf("FREE SHADER %d\n", sh->Name); if (sh->Source) _mesa_free((void *) sh->Source); if (sh->InfoLog) @@ -274,8 +272,8 @@ _mesa_reference_shader(GLcontext *ctx, struct gl_shader **ptr, ASSERT(old->RefCount > 0); old->RefCount--; - printf("SHADER DECR %p (%d) to %d\n", - (void*) old, old->Name, old->RefCount); + /*printf("SHADER DECR %p (%d) to %d\n", + (void*) old, old->Name, old->RefCount);*/ deleteFlag = (old->RefCount == 0); if (deleteFlag) { @@ -290,8 +288,8 @@ _mesa_reference_shader(GLcontext *ctx, struct gl_shader **ptr, if (sh) { /* reference new */ sh->RefCount++; - printf("SHADER INCR %p (%d) to %d\n", - (void*) sh, sh->Name, sh->RefCount); + /*printf("SHADER INCR %p (%d) to %d\n", + (void*) sh, sh->Name, sh->RefCount);*/ *ptr = sh; } } -- cgit v1.2.3 From 6d3d9c1c6de33646b63d47892863939ee1b1e624 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 18 Apr 2007 14:19:17 -0600 Subject: Replace _mesa_parameter_longest_name() with _mesa_longest_parameter_name(). The later takes a type parameter so we can match uniforms or attributes/inputs. Used by the GL_ACTIVE_ATTRIBUTE_MAX_LENGTH and GL_ACTIVE_UNIFORM_MAX_LENGTH queries. Fixes problem reported by Brad King in VTK. --- src/mesa/shader/prog_parameter.c | 13 ++++++++----- src/mesa/shader/prog_parameter.h | 4 +++- src/mesa/shader/shader_api.c | 4 ++-- 3 files changed, 13 insertions(+), 8 deletions(-) (limited to 'src/mesa/shader/shader_api.c') diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c index 2c8a3407634..fe90ca6d7bb 100644 --- a/src/mesa/shader/prog_parameter.c +++ b/src/mesa/shader/prog_parameter.c @@ -586,18 +586,21 @@ _mesa_clone_parameter_list(const struct gl_program_parameter_list *list) /** - * Find longest name of any parameter in list. + * Find longest name of all uniform parameters in list. */ GLuint -_mesa_parameter_longest_name(const struct gl_program_parameter_list *list) +_mesa_longest_parameter_name(const struct gl_program_parameter_list *list, + enum register_file type) { GLuint i, maxLen = 0; if (!list) return 0; for (i = 0; i < list->NumParameters; i++) { - GLuint len = _mesa_strlen(list->Parameters[i].Name); - if (len > maxLen) - maxLen = len; + if (list->Parameters[i].Type == type) { + GLuint len = _mesa_strlen(list->Parameters[i].Name); + if (len > maxLen) + maxLen = len; + } } return maxLen; } diff --git a/src/mesa/shader/prog_parameter.h b/src/mesa/shader/prog_parameter.h index 3d32a64f383..879623b127a 100644 --- a/src/mesa/shader/prog_parameter.h +++ b/src/mesa/shader/prog_parameter.h @@ -131,6 +131,8 @@ _mesa_lookup_parameter_constant(const struct gl_program_parameter_list *list, GLint *posOut, GLuint *swizzleOut); extern GLuint -_mesa_parameter_longest_name(const struct gl_program_parameter_list *list); +_mesa_longest_parameter_name(const struct gl_program_parameter_list *list, + enum register_file type); + #endif /* PROG_PARAMETER_H */ diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index fc1ae287f4f..41646e7664d 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -763,13 +763,13 @@ _mesa_get_programiv(GLcontext *ctx, GLuint program, *params = shProg->Attributes ? shProg->Attributes->NumParameters : 0; break; case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: - *params = _mesa_parameter_longest_name(shProg->Attributes); + *params = _mesa_longest_parameter_name(shProg->Attributes, PROGRAM_INPUT); break; case GL_ACTIVE_UNIFORMS: *params = shProg->Uniforms ? shProg->Uniforms->NumParameters : 0; break; case GL_ACTIVE_UNIFORM_MAX_LENGTH: - *params = _mesa_parameter_longest_name(shProg->Uniforms); + *params = _mesa_longest_parameter_name(shProg->Uniforms, PROGRAM_UNIFORM); break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)"); -- cgit v1.2.3 From f3e8c32376d8bdf1c48a0a2ad97eddcde7fc2f00 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 18 Apr 2007 14:53:23 -0600 Subject: s/GL_SHADER_PROGRAM/GL_SHADER_PROGRAM_MESA/ (a Mesa-specific token) --- src/mesa/main/context.c | 2 +- src/mesa/main/mtypes.h | 2 +- src/mesa/shader/shader_api.c | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/mesa/shader/shader_api.c') diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 93442b91aaa..9dc7b11e361 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -629,7 +629,7 @@ delete_shader_cb(GLuint id, void *data, void *userData) } else { struct gl_shader_program *shProg = (struct gl_shader_program *) data; - ASSERT(shProg->Type == GL_SHADER_PROGRAM); + ASSERT(shProg->Type == GL_SHADER_PROGRAM_MESA); _mesa_free_shader_program(ctx, shProg); } } diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 89cdc790897..0044494bd3c 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -47,7 +47,7 @@ /** * Special, internal token */ -#define GL_SHADER_PROGRAM 0x9999 +#define GL_SHADER_PROGRAM_MESA 0x9999 /** diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index 41646e7664d..004c9c8ec3a 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -58,7 +58,7 @@ _mesa_new_shader_program(GLcontext *ctx, GLuint name) struct gl_shader_program *shProg; shProg = CALLOC_STRUCT(gl_shader_program); if (shProg) { - shProg->Type = GL_SHADER_PROGRAM; + shProg->Type = GL_SHADER_PROGRAM_MESA; shProg->Name = name; shProg->RefCount = 1; shProg->Attributes = _mesa_new_parameter_list(); @@ -114,7 +114,7 @@ _mesa_free_shader_program_data(GLcontext *ctx, { GLuint i; - assert(shProg->Type == GL_SHADER_PROGRAM); + assert(shProg->Type == GL_SHADER_PROGRAM_MESA); _mesa_clear_shader_program_data(ctx, shProg); @@ -204,7 +204,7 @@ _mesa_lookup_shader_program(GLcontext *ctx, GLuint name) * in the same hash table. Check the object's type to be sure it's * what we're expecting. */ - if (shProg && shProg->Type != GL_SHADER_PROGRAM) { + if (shProg && shProg->Type != GL_SHADER_PROGRAM_MESA) { return NULL; } return shProg; @@ -308,7 +308,7 @@ _mesa_lookup_shader(GLcontext *ctx, GLuint name) * in the same hash table. Check the object's type to be sure it's * what we're expecting. */ - if (sh && sh->Type == GL_SHADER_PROGRAM) { + if (sh && sh->Type == GL_SHADER_PROGRAM_MESA) { assert(sh->Type == GL_VERTEX_SHADER || sh->Type == GL_FRAGMENT_SHADER); return NULL; -- cgit v1.2.3 From bac15c8db87261ea168caa98d818bd6917ca14d6 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 18 Apr 2007 14:55:18 -0600 Subject: Remove bad assertions, decrement NumShaders in _mesa_detach_shader(). Fixes crashes w/ Brad King's depth peeling test. --- src/mesa/shader/shader_api.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/mesa/shader/shader_api.c') diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index 004c9c8ec3a..0c4f4837fbf 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -309,8 +309,6 @@ _mesa_lookup_shader(GLcontext *ctx, GLuint name) * what we're expecting. */ if (sh && sh->Type == GL_SHADER_PROGRAM_MESA) { - assert(sh->Type == GL_VERTEX_SHADER || - sh->Type == GL_FRAGMENT_SHADER); return NULL; } return sh; @@ -576,6 +574,7 @@ _mesa_detach_shader(GLcontext *ctx, GLuint program, GLuint shader) _mesa_free(shProg->Shaders); shProg->Shaders = newList; + shProg->NumShaders = n - 1; return; } } -- cgit v1.2.3 From aaa57412c1a682730f27f08bd89a79b8b81f982f Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 18 Apr 2007 15:22:43 -0600 Subject: fix error strings, add a sanity check --- src/mesa/shader/shader_api.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/mesa/shader/shader_api.c') diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index 0c4f4837fbf..a8ca7d62212 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -575,6 +575,18 @@ _mesa_detach_shader(GLcontext *ctx, GLuint program, GLuint shader) shProg->Shaders = newList; shProg->NumShaders = n - 1; + +#ifdef DEBUG + /* sanity check */ + { + for (j = 0; j < shProg->NumShaders; j++) { + assert(shProg->Shaders[j]->Type == GL_VERTEX_SHADER || + shProg->Shaders[j]->Type == GL_FRAGMENT_SHADER); + assert(shProg->Shaders[j]->RefCount > 0); + } + } +#endif + return; } } @@ -598,12 +610,12 @@ _mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index, GLint sz; if (!shProg) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform"); + _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib"); return; } if (!shProg->Attributes || index >= shProg->Attributes->NumParameters) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)"); + _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)"); return; } -- cgit v1.2.3 From 274ac7a801766a0ae766219ec6a40ed52e479d07 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 18 Apr 2007 16:05:53 -0600 Subject: Fix some bugs related to querying active uniforms. --- src/mesa/shader/prog_parameter.c | 17 ++++++++++++++++ src/mesa/shader/prog_parameter.h | 4 ++++ src/mesa/shader/shader_api.c | 42 ++++++++++++++++++++++++++++++---------- 3 files changed, 53 insertions(+), 10 deletions(-) (limited to 'src/mesa/shader/shader_api.c') diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c index fe90ca6d7bb..e2f1047463f 100644 --- a/src/mesa/shader/prog_parameter.c +++ b/src/mesa/shader/prog_parameter.c @@ -605,3 +605,20 @@ _mesa_longest_parameter_name(const struct gl_program_parameter_list *list, return maxLen; } + +/** + * Count the number of parameters in the last that match the given type. + */ +GLuint +_mesa_num_parameters_of_type(const struct gl_program_parameter_list *list, + enum register_file type) +{ + GLuint i, count = 0; + if (list) { + for (i = 0; i < list->NumParameters; i++) { + if (list->Parameters[i].Type == type) + count++; + } + } + return count; +} diff --git a/src/mesa/shader/prog_parameter.h b/src/mesa/shader/prog_parameter.h index 879623b127a..2e0feb972ec 100644 --- a/src/mesa/shader/prog_parameter.h +++ b/src/mesa/shader/prog_parameter.h @@ -134,5 +134,9 @@ extern GLuint _mesa_longest_parameter_name(const struct gl_program_parameter_list *list, enum register_file type); +extern GLuint +_mesa_num_parameters_of_type(const struct gl_program_parameter_list *list, + enum register_file type); + #endif /* PROG_PARAMETER_H */ diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index a8ca7d62212..74bdef061b5 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -38,6 +38,7 @@ #include "glheader.h" #include "context.h" #include "hash.h" +#include "macros.h" #include "program.h" #include "prog_parameter.h" #include "prog_print.h" @@ -643,6 +644,7 @@ _mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index, struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, program); GLint sz; + GLuint ind, j; if (!shProg) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform"); @@ -654,13 +656,26 @@ _mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index, return; } - copy_string(nameOut, maxLength, length, - shProg->Uniforms->Parameters[index].Name); - sz = shProg->Uniforms->Parameters[index].Size; - if (size) - *size = sz; - if (type) - *type = vec_types[sz]; /* XXX this is a temporary hack */ + ind = 0; + for (j = 0; j < shProg->Uniforms->NumParameters; j++) { + if (shProg->Uniforms->Parameters[j].Type == PROGRAM_UNIFORM || + shProg->Uniforms->Parameters[j].Type == PROGRAM_SAMPLER) { + if (ind == index) { + /* found it */ + copy_string(nameOut, maxLength, length, + shProg->Uniforms->Parameters[j].Name); + sz = shProg->Uniforms->Parameters[j].Size; + if (size) + *size = sz; + if (type) + *type = vec_types[sz-1]; /* XXX this is a temporary hack */ + return; + } + ind++; + } + } + + _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)"); } @@ -774,13 +789,20 @@ _mesa_get_programiv(GLcontext *ctx, GLuint program, *params = shProg->Attributes ? shProg->Attributes->NumParameters : 0; break; case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: - *params = _mesa_longest_parameter_name(shProg->Attributes, PROGRAM_INPUT); + *params = _mesa_longest_parameter_name(shProg->Attributes, + PROGRAM_INPUT) + 1; break; case GL_ACTIVE_UNIFORMS: - *params = shProg->Uniforms ? shProg->Uniforms->NumParameters : 0; + *params + = _mesa_num_parameters_of_type(shProg->Uniforms, PROGRAM_UNIFORM) + + _mesa_num_parameters_of_type(shProg->Uniforms, PROGRAM_SAMPLER); break; case GL_ACTIVE_UNIFORM_MAX_LENGTH: - *params = _mesa_longest_parameter_name(shProg->Uniforms, PROGRAM_UNIFORM); + *params = MAX2( + _mesa_longest_parameter_name(shProg->Uniforms, PROGRAM_UNIFORM), + _mesa_longest_parameter_name(shProg->Uniforms, PROGRAM_SAMPLER)); + if (*params > 0) + (*params)++; /* add one for terminating zero */ break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)"); -- cgit v1.2.3 From c93e883b205a679aa80f6228459890f9118ad909 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 18 Apr 2007 16:27:35 -0600 Subject: Start fixing some issues with uniform variables and their types. --- src/mesa/shader/prog_parameter.c | 31 ++++++++++++++++++------------- src/mesa/shader/prog_parameter.h | 7 ++++--- src/mesa/shader/shader_api.c | 9 ++------- src/mesa/shader/slang/slang_codegen.c | 7 +++++-- src/mesa/shader/slang/slang_link.c | 4 ++-- 5 files changed, 31 insertions(+), 27 deletions(-) (limited to 'src/mesa/shader/shader_api.c') diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c index e2f1047463f..7f17be74f72 100644 --- a/src/mesa/shader/prog_parameter.c +++ b/src/mesa/shader/prog_parameter.c @@ -81,7 +81,7 @@ _mesa_free_parameter_list(struct gl_program_parameter_list *paramList) GLint _mesa_add_parameter(struct gl_program_parameter_list *paramList, enum register_file type, const char *name, - GLuint size, const GLfloat *values, + GLuint size, GLenum datatype, const GLfloat *values, const gl_state_index state[STATE_LENGTH]) { const GLuint oldNum = paramList->NumParameters; @@ -126,6 +126,7 @@ _mesa_add_parameter(struct gl_program_parameter_list *paramList, p->Name = name ? _mesa_strdup(name) : NULL; p->Type = type; p->Size = size; + p->DataType = datatype; if (values) { COPY_4V(paramList->ParameterValues[oldNum + i], values); values += 4; @@ -156,7 +157,7 @@ _mesa_add_named_parameter(struct gl_program_parameter_list *paramList, const char *name, const GLfloat values[4]) { return _mesa_add_parameter(paramList, PROGRAM_NAMED_PARAM, name, - 4, values, NULL); + 4, GL_NONE, values, NULL); } @@ -187,7 +188,7 @@ _mesa_add_named_constant(struct gl_program_parameter_list *paramList, #endif size = 4; /** XXX fix */ return _mesa_add_parameter(paramList, PROGRAM_CONSTANT, name, - size, values, NULL); + size, GL_NONE, values, NULL); } @@ -239,7 +240,7 @@ _mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList, /* add a new parameter to store this constant */ pos = _mesa_add_parameter(paramList, PROGRAM_CONSTANT, NULL, - size, values, NULL); + size, GL_NONE, values, NULL); if (pos >= 0 && swizzleOut) { if (size == 1) *swizzleOut = SWIZZLE_XXXX; @@ -252,16 +253,19 @@ _mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList, GLint _mesa_add_uniform(struct gl_program_parameter_list *paramList, - const char *name, GLuint size) + const char *name, GLuint size, GLenum datatype) { GLint i = _mesa_lookup_parameter_index(paramList, -1, name); + ASSERT(datatype != GL_NONE); if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_UNIFORM) { + ASSERT(paramList->Parameters[i].Size == size); + ASSERT(paramList->Parameters[i].DataType == datatype); /* already in list */ return i; } else { i = _mesa_add_parameter(paramList, PROGRAM_UNIFORM, name, - size, NULL, NULL); + size, datatype, NULL, NULL); return i; } @@ -270,7 +274,7 @@ _mesa_add_uniform(struct gl_program_parameter_list *paramList, GLint _mesa_add_sampler(struct gl_program_parameter_list *paramList, - const char *name) + const char *name, GLenum datatype) { GLint i = _mesa_lookup_parameter_index(paramList, -1, name); if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_SAMPLER) { @@ -280,7 +284,7 @@ _mesa_add_sampler(struct gl_program_parameter_list *paramList, else { const GLint size = 1; i = _mesa_add_parameter(paramList, PROGRAM_SAMPLER, name, - size, NULL, NULL); + size, datatype, NULL, NULL); return i; } } @@ -301,7 +305,7 @@ _mesa_add_varying(struct gl_program_parameter_list *paramList, else { assert(size == 4); i = _mesa_add_parameter(paramList, PROGRAM_VARYING, name, - size, NULL, NULL); + size, GL_NONE, NULL, NULL); return i; } } @@ -330,7 +334,7 @@ _mesa_add_attribute(struct gl_program_parameter_list *paramList, if (size < 0) size = 4; i = _mesa_add_parameter(paramList, PROGRAM_INPUT, name, - size, NULL, state); + size, GL_NONE, NULL, state); } return i; } @@ -396,7 +400,8 @@ _mesa_add_state_reference(struct gl_program_parameter_list *paramList, name = _mesa_program_state_string(stateTokens); index = _mesa_add_parameter(paramList, PROGRAM_STATE_VAR, name, - size, NULL, (gl_state_index *) stateTokens); + size, GL_NONE, + NULL, (gl_state_index *) stateTokens); paramList->StateFlags |= _mesa_program_state_flags(stateTokens); /* free name string here since we duplicated it in add_parameter() */ @@ -565,8 +570,8 @@ _mesa_clone_parameter_list(const struct gl_program_parameter_list *list) for (i = 0; i < list->NumParameters; i++) { struct gl_program_parameter *p = list->Parameters + i; GLuint size = MIN2(p->Size, 4); - GLint j = _mesa_add_parameter(clone, p->Type, p->Name, - size, list->ParameterValues[i], NULL); + GLint j = _mesa_add_parameter(clone, p->Type, p->Name, size, p->DataType, + list->ParameterValues[i], NULL); ASSERT(j >= 0); /* copy state indexes */ if (p->Type == PROGRAM_STATE_VAR) { diff --git a/src/mesa/shader/prog_parameter.h b/src/mesa/shader/prog_parameter.h index 2e0feb972ec..09ff851ea73 100644 --- a/src/mesa/shader/prog_parameter.h +++ b/src/mesa/shader/prog_parameter.h @@ -46,6 +46,7 @@ struct gl_program_parameter { const char *Name; /**< Null-terminated string */ enum register_file Type; /**< PROGRAM_NAMED_PARAM, CONSTANT or STATE_VAR */ + GLenum DataType; /**< GL_FLOAT, GL_FLOAT_VEC2, etc */ GLuint Size; /**< Number of components (1..4) */ /** * A sequence of STATE_* tokens and integers to identify GL state. @@ -80,7 +81,7 @@ _mesa_clone_parameter_list(const struct gl_program_parameter_list *list); extern GLint _mesa_add_parameter(struct gl_program_parameter_list *paramList, enum register_file type, const char *name, - GLuint size, const GLfloat *values, + GLuint size, GLenum datatype, const GLfloat *values, const gl_state_index state[STATE_LENGTH]); extern GLint @@ -99,11 +100,11 @@ _mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList, extern GLint _mesa_add_uniform(struct gl_program_parameter_list *paramList, - const char *name, GLuint size); + const char *name, GLuint size, GLenum datatype); extern GLint _mesa_add_sampler(struct gl_program_parameter_list *paramList, - const char *name); + const char *name, GLenum datatype); extern GLint _mesa_add_varying(struct gl_program_parameter_list *paramList, diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index 74bdef061b5..418ef5c7239 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -638,12 +638,8 @@ _mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLchar *nameOut) { - static const GLenum vec_types[] = { - GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4 - }; struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, program); - GLint sz; GLuint ind, j; if (!shProg) { @@ -664,11 +660,10 @@ _mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index, /* found it */ copy_string(nameOut, maxLength, length, shProg->Uniforms->Parameters[j].Name); - sz = shProg->Uniforms->Parameters[j].Size; if (size) - *size = sz; + *size = shProg->Uniforms->Parameters[j].Size; if (type) - *type = vec_types[sz-1]; /* XXX this is a temporary hack */ + *type = shProg->Uniforms->Parameters[j].DataType; return; } ind++; diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 06bceea7d0f..d8c06f064d9 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -2829,7 +2829,8 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var, * store->Index = sampler uniform location * store->Size = texture type index (1D, 2D, 3D, cube, etc) */ - GLint samplerUniform = _mesa_add_sampler(prog->Parameters, varName); + GLenum datatype = GL_SAMPLER_2D; + GLint samplerUniform = _mesa_add_sampler(prog->Parameters, varName, datatype); store = _slang_new_ir_storage(PROGRAM_SAMPLER, samplerUniform, texIndex); if (dbg) printf("SAMPLER "); } @@ -2839,7 +2840,9 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var, * MAX2(var->array_len, 1); if (prog) { /* user-defined uniform */ - GLint uniformLoc = _mesa_add_uniform(prog->Parameters, varName, size); + GLenum datatype = GL_FLOAT_VEC4; /* XXX */ + GLint uniformLoc = _mesa_add_uniform(prog->Parameters, varName, + size, datatype); store = _slang_new_ir_storage(PROGRAM_UNIFORM, uniformLoc, size); } else { diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index 360af0922fa..48c0d68375e 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -202,10 +202,10 @@ link_uniform_vars(struct gl_shader_program *shProg, struct gl_program *prog) j = _mesa_add_state_reference(shProg->Uniforms, p->StateIndexes); break; case PROGRAM_UNIFORM: - j = _mesa_add_uniform(shProg->Uniforms, p->Name, p->Size); + j = _mesa_add_uniform(shProg->Uniforms, p->Name, p->Size, p->DataType); break; case PROGRAM_SAMPLER: - j = _mesa_add_sampler(shProg->Uniforms, p->Name); + j = _mesa_add_sampler(shProg->Uniforms, p->Name, p->DataType); break; default: _mesa_problem(NULL, "bad parameter type in link_uniform_vars()"); -- cgit v1.2.3 From 4b7c6fc5a655bfb8f165cb94521bc49521303a35 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 19 Apr 2007 15:23:34 -0600 Subject: free shProg->Attributes in _mesa_free_shader_program_data() --- src/mesa/shader/shader_api.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/mesa/shader/shader_api.c') diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index 418ef5c7239..64f2a9fa126 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -119,6 +119,11 @@ _mesa_free_shader_program_data(GLcontext *ctx, _mesa_clear_shader_program_data(ctx, shProg); + if (shProg->Attributes) { + _mesa_free_parameter_list(shProg->Attributes); + shProg->Attributes = NULL; + } + /* detach shaders */ for (i = 0; i < shProg->NumShaders; i++) { _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL); -- cgit v1.2.3 From 3e4302fe3b3cf0d559b1288f3965f800ee35cd41 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 9 May 2007 08:04:32 -0600 Subject: Check that texture units/samplers specified with glUniform1i() are legal. --- src/mesa/shader/shader_api.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/mesa/shader/shader_api.c') diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index 64f2a9fa126..3a54e68d0de 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5.3 + * Version: 7.0 * * Copyright (C) 2004-2007 Brian Paul All Rights Reserved. * @@ -1072,12 +1072,20 @@ _mesa_uniform(GLcontext *ctx, GLint location, GLsizei count, * If we're setting a sampler, we must use glUniformi1()! */ if (shProg->Uniforms->Parameters[location].Type == PROGRAM_SAMPLER) { + GLint unit; if (type != GL_INT || count != 1) { _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(only glUniform1i can be used " "to set sampler uniforms)"); return; } + /* check that the sampler (tex unit index) is legal */ + unit = ((GLint *) values)[0]; + if (unit >= ctx->Const.MaxTextureImageUnits) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glUniform1(invalid sampler/tex unit index)"); + return; + } } if (count < 0) { -- cgit v1.2.3