From 5b01c5e9d2c0283cc31981b6c85dc6392144b3db Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 19 Dec 2006 18:02:03 -0700 Subject: Overhaul of GLSL API functions, dispatching, etc. --- src/mesa/shader/prog_parameter.c | 19 + src/mesa/shader/prog_parameter.h | 4 +- src/mesa/shader/shader_api.c | 1585 ++++++++++++++------------------------ src/mesa/shader/shader_api.h | 111 ++- 4 files changed, 693 insertions(+), 1026 deletions(-) (limited to 'src') diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c index 7094d6fc03..84e92d7ed0 100644 --- a/src/mesa/shader/prog_parameter.c +++ b/src/mesa/shader/prog_parameter.c @@ -444,3 +444,22 @@ _mesa_clone_parameter_list(const struct gl_program_parameter_list *list) return clone; } + + +/** + * Find longest name of any parameter in list. + */ +GLuint +_mesa_parameter_longest_name(const struct gl_program_parameter_list *list) +{ + 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; + } + return maxLen; +} + diff --git a/src/mesa/shader/prog_parameter.h b/src/mesa/shader/prog_parameter.h index c60ef543b7..fb82757d83 100644 --- a/src/mesa/shader/prog_parameter.h +++ b/src/mesa/shader/prog_parameter.h @@ -115,9 +115,11 @@ _mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList, GLsizei nameLen, const char *name); extern GLboolean -_mesa_lookup_parameter_constant(const struct gl_program_parameter_list *paramList, +_mesa_lookup_parameter_constant(const struct gl_program_parameter_list *list, const GLfloat v[], GLsizei vSize, GLint *posOut, GLuint *swizzleOut); +extern GLuint +_mesa_parameter_longest_name(const struct gl_program_parameter_list *list); #endif /* PROG_PARAMETER_H */ diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index aaaf942cf5..ab2fd438c8 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.3 * - * Copyright (C) 2004-2006 Brian Paul All Rights Reserved. + * Copyright (C) 2004-2007 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -24,24 +24,22 @@ /** * \file shader_api.c - * API functions for shader objects + * Implementation of GLSL-related API functions * \author Brian Paul */ /** * XXX things to do: * 1. Check that the right error code is generated for all _mesa_error() calls. - * + * 2. Insert FLUSH_VERTICES calls in various places */ #include "glheader.h" #include "context.h" #include "hash.h" -#include "macros.h" #include "program.h" #include "prog_parameter.h" -#include "shaderobjects.h" #include "shader_api.h" #include "slang_compile.h" @@ -49,100 +47,106 @@ -GLvoid GLAPIENTRY -_mesa_DeleteObjectARB(GLhandleARB obj) -{ -#if 000 - if (obj != 0) { - GET_CURRENT_CONTEXT(ctx); - GET_GENERIC(gen, obj, "glDeleteObjectARB"); - - if (gen != NULL) { - (**gen).Delete(gen); - RELEASE_GENERIC(gen); - } - } -#endif -} -GLhandleARB GLAPIENTRY -_mesa_GetHandleARB(GLenum pname) +/** + * Copy string from to , up to maxLength characters, returning + * length of in . + * \param src the strings source + * \param maxLength max chars to copy + * \param length returns number of chars copied + * \param dst the string destination + */ +static void +copy_string(GLchar *dst, GLsizei maxLength, GLsizei *length, const GLchar *src) { -#if 0 - GET_CURRENT_CONTEXT(ctx); + GLsizei len; + for (len = 0; len < maxLength - 1 && src && src[len]; len++) + dst[len] = src[len]; + if (maxLength > 0) + dst[len] = 0; + if (length) + *length = len; +} - switch (pname) { - case GL_PROGRAM_OBJECT_ARB: - { - struct gl2_program_intf **pro = ctx->ShaderObjects.CurrentProgram; - if (pro != NULL) - return (**pro)._container._generic. - GetName((struct gl2_generic_intf **) (pro)); - } - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB"); - } -#endif - return 0; -} -GLvoid GLAPIENTRY -_mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader) +/** + * Called via ctx->Driver.AttachShader() + */ +void +_mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader) { - GET_CURRENT_CONTEXT(ctx); struct gl_linked_program *linked = _mesa_lookup_linked_program(ctx, program); struct gl_program *prog = _mesa_lookup_shader(ctx, shader); const GLuint n = linked->NumShaders; - GLuint i, j; + GLuint i; if (!linked || !prog) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glDetachObjectARB(bad program or shader name)"); + "glAttachShader(bad program or shader name)"); return; } for (i = 0; i < n; i++) { if (linked->Shaders[i] == prog) { - struct gl_program **newList; - /* found it */ - /* alloc new list */ - newList = (struct gl_program **) - _mesa_malloc((n - 1) * sizeof(struct gl_program *)); - if (!newList) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachObjectARB"); - return; - } - for (j = 0; j < i; j++) { - newList[j] = linked->Shaders[j]; - } - while (++i < n) - newList[j++] = linked->Shaders[i]; - _mesa_free(linked->Shaders); - linked->Shaders = newList; + /* already attached */ return; } } - _mesa_error(ctx, GL_INVALID_OPERATION, - "glDetachObjectARB(shader not found)"); + /* grow list */ + linked->Shaders = (struct gl_program **) + _mesa_realloc(linked->Shaders, + n * sizeof(struct gl_program *), + (n + 1) * sizeof(struct gl_program *)); + if (!linked->Shaders) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader"); + return; + } + + /* append */ + linked->Shaders[n] = prog; + prog->RefCount++; + linked->NumShaders++; } -GLhandleARB GLAPIENTRY -_mesa_CreateShaderObjectARB(GLenum shaderType) +void +_mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index, + const GLchar *name) +{ + struct gl_linked_program *linked + = _mesa_lookup_linked_program(ctx, program); + + if (!linked) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glBindAttribLocation(program)"); + return; + } + +#if 0 /* XXXX */ + if (name == NULL || index >= MAX_VERTEX_ATTRIBS) + _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocationARB"); + else if (IS_NAME_WITH_GL_PREFIX(name)) + _mesa_error(ctx, GL_INVALID_OPERATION, "glBindAttribLocationARB"); + else + (**pro).OverrideAttribBinding(pro, index, name); + RELEASE_PROGRAM(pro); +#endif +} + + +GLuint +_mesa_create_shader(GLcontext *ctx, GLenum type) { - GET_CURRENT_CONTEXT(ctx); struct gl_program *newProg; GLuint name; name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1); - switch (shaderType) { + switch (type) { case GL_FRAGMENT_SHADER_ARB: /* alloc new gl_fragment_program */ newProg = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, name); @@ -152,7 +156,7 @@ _mesa_CreateShaderObjectARB(GLenum shaderType) newProg = ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, name); break; default: - _mesa_error(ctx, GL_INVALID_ENUM, "CreateShaderObject(shaderType)"); + _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(type)"); return 0; } @@ -162,1119 +166,660 @@ _mesa_CreateShaderObjectARB(GLenum shaderType) } - -GLvoid GLAPIENTRY -_mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count, - const GLcharARB ** string, const GLint * length) +GLuint +_mesa_create_program(GLcontext *ctx) { - GET_CURRENT_CONTEXT(ctx); - struct gl_program *shader; - GLint *offsets; - GLsizei i; - GLcharARB *source; - - if (string == NULL) { - _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB"); - return; - } - - shader = _mesa_lookup_shader(ctx, shaderObj); - if (!shader) { - _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB(shaderObj)"); - return; - } - - /* - * This array holds offsets of where the appropriate string ends, thus the - * last element will be set to the total length of the source code. - */ - offsets = (GLint *) _mesa_malloc(count * sizeof(GLint)); - if (offsets == NULL) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB"); - return; - } - - for (i = 0; i < count; i++) { - if (string[i] == NULL) { - _mesa_free((GLvoid *) offsets); - _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB(null string)"); - return; - } - if (length == NULL || length[i] < 0) - offsets[i] = _mesa_strlen(string[i]); - else - offsets[i] = length[i]; - /* accumulate string lengths */ - if (i > 0) - offsets[i] += offsets[i - 1]; - } + GLuint name; + struct gl_linked_program *linked; - source = (GLcharARB *) _mesa_malloc((offsets[count - 1] + 1) * - sizeof(GLcharARB)); - if (source == NULL) { - _mesa_free((GLvoid *) offsets); - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB"); - return; - } + name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ProgramObjects, 1); + linked = _mesa_new_linked_program(ctx, name); - for (i = 0; i < count; i++) { - GLint start = (i > 0) ? offsets[i - 1] : 0; - _mesa_memcpy(source + start, string[i], - (offsets[i] - start) * sizeof(GLcharARB)); - } - source[offsets[count - 1]] = '\0'; + _mesa_HashInsert(ctx->Shared->ProgramObjects, name, linked); - /* free old shader source string and install new one */ - if (shader->String) { - _mesa_free(shader->String); - } - shader->String = (GLubyte *) source; + return name; } -GLvoid GLAPIENTRY -_mesa_CompileShaderARB(GLhandleARB shaderObj) +void +_mesa_delete_program2(GLcontext *ctx, GLuint name) { - GET_CURRENT_CONTEXT(ctx); - struct gl_program *prog = _mesa_lookup_shader(ctx, shaderObj); - slang_info_log info_log; - slang_code_object obj; - slang_unit_type type; + struct gl_linked_program *linked; - if (!prog) { - _mesa_error(ctx, GL_INVALID_VALUE, "glCompileShader(shaderObj)"); + linked = _mesa_lookup_linked_program(ctx, name); + if (!linked) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glDeleteProgram(name)"); return; } - slang_info_log_construct(&info_log); - _slang_code_object_ctr(&obj); - - if (prog->Target == GL_VERTEX_PROGRAM_ARB) { - type = slang_unit_vertex_shader; - } - else { - assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB); - type = slang_unit_fragment_shader; - } - - if (_slang_compile((const char*) prog->String, &obj, - type, &info_log, prog)) { - /* - prog->CompileStatus = GL_TRUE; - */ - } - else { - /* - prog->CompileStatus = GL_FALSE; - */ - _mesa_problem(ctx, "Program did not compile!"); - } + /* XXX refcounting! */ + _mesa_HashRemove(ctx->Shared->ProgramObjects, name); + _mesa_delete_linked_program(ctx, linked); } -GLhandleARB GLAPIENTRY -_mesa_CreateProgramObjectARB(GLvoid) +void +_mesa_delete_shader(GLcontext *ctx, GLuint shader) { - GET_CURRENT_CONTEXT(ctx); - GLuint name; - struct gl_linked_program *linked; - - name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ProgramObjects, 1); - linked = _mesa_new_linked_program(ctx, name); - - _mesa_HashInsert(ctx->Shared->ProgramObjects, name, linked); + /* XXX refcounting! */ - return name; + /* + _mesa_DeleteObjectARB(shader); + */ } -GLvoid GLAPIENTRY -_mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader) +void +_mesa_detach_shader(GLcontext *ctx, GLuint program, GLuint shader) { - GET_CURRENT_CONTEXT(ctx); struct gl_linked_program *linked = _mesa_lookup_linked_program(ctx, program); - struct gl_program *prog = _mesa_lookup_shader(ctx, shader); const GLuint n = linked->NumShaders; - GLuint i; + GLuint i, j; - if (!linked || !prog) { + if (!linked) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glAttachShader(bad program or shader name)"); + "glDetachShader(bad program or shader name)"); return; } for (i = 0; i < n; i++) { - if (linked->Shaders[i] == prog) { - /* already attached */ + if (linked->Shaders[i]->Id == shader) { + struct gl_program **newList; + /* found it */ + /* alloc new, smaller array */ + newList = (struct gl_program **) + _mesa_malloc((n - 1) * sizeof(struct gl_program *)); + if (!newList) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader"); + return; + } + for (j = 0; j < i; j++) { + newList[j] = linked->Shaders[j]; + } + while (++i < n) + newList[j++] = linked->Shaders[i]; + _mesa_free(linked->Shaders); + + /* XXX refcounting! */ + + linked->Shaders = newList; return; } } - /* grow list */ - linked->Shaders = (struct gl_program **) - _mesa_realloc(linked->Shaders, - n * sizeof(struct gl_program *), - (n + 1) * sizeof(struct gl_program *)); - /* append */ - linked->Shaders[n] = prog; - prog->RefCount++; - linked->NumShaders++; + /* not found */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glDetachShader(shader not found)"); } - - -GLvoid GLAPIENTRY -_mesa_LinkProgramARB(GLhandleARB programObj) +void +_mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index, + GLsizei maxLength, GLsizei *length, GLint *size, + GLenum *type, GLchar *nameOut) { - GET_CURRENT_CONTEXT(ctx); - struct gl_linked_program *linked; + static const GLenum vec_types[] = { + GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4 + }; + struct gl_linked_program *linked + = _mesa_lookup_linked_program(ctx, program); + GLint sz; - linked = _mesa_lookup_linked_program(ctx, programObj); if (!linked) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glLinkProgram(programObj)"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniform"); return; } - _slang_link2(ctx, programObj, linked); -} + if (!linked->Attributes || index >= linked->Attributes->NumParameters) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)"); + return; + } + copy_string(nameOut, maxLength, length, + linked->Attributes->Parameters[index].Name); + sz = linked->Attributes->Parameters[index].Size; + if (size) + *size = sz; + if (type) + *type = vec_types[sz]; /* XXX this is a temporary hack */ +} -GLvoid GLAPIENTRY -_mesa_UseProgramObjectARB(GLhandleARB programObj) -{ - GET_CURRENT_CONTEXT(ctx); - struct gl_linked_program *linked; - FLUSH_VERTICES(ctx, _NEW_PROGRAM); +/** + * Called via ctx->Driver.GetActiveUniform(). + */ +void +_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_linked_program *linked + = _mesa_lookup_linked_program(ctx, program); + GLint sz; - linked = _mesa_lookup_linked_program(ctx, programObj); if (!linked) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glUseProgramObjectARB(programObj)"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniform"); + return; + } + + if (!linked->Uniforms || index >= linked->Uniforms->NumParameters) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)"); return; } - ctx->ShaderObjects.Linked = linked; + copy_string(nameOut, maxLength, length, + linked->Uniforms->Parameters[index].Name); + sz = linked->Uniforms->Parameters[index].Size; + if (size) + *size = sz; + if (type) + *type = vec_types[sz]; /* XXX this is a temporary hack */ } -GLvoid GLAPIENTRY -_mesa_ValidateProgramARB(GLhandleARB programObj) +/** + * Called via ctx->Driver.GetAttachedShaders(). + */ +void +_mesa_get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount, + GLsizei *count, GLuint *obj) { -#if 0 - GET_CURRENT_CONTEXT(ctx); - GET_PROGRAM(pro, programObj, "glValidateProgramARB"); - - if (pro != NULL) { - (**pro).Validate(pro); - RELEASE_PROGRAM(pro); + struct gl_linked_program *linked + = _mesa_lookup_linked_program(ctx, program); + if (linked) { + GLuint i; + for (i = 0; i < maxCount && i < linked->NumShaders; i++) { + obj[i] = linked->Shaders[i]->Id; + } + if (count) + *count = i; + } + else { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetAttachedShaders"); } -#endif } -/** - * Helper function for all the _mesa_Uniform*() functions below. - */ -static INLINE void -uniform(GLint location, GLsizei count, const GLvoid *values, GLenum type, - const char *caller) +GLint +_mesa_get_attrib_location(GLcontext *ctx, GLuint program, + const GLchar *name) { - GET_CURRENT_CONTEXT(ctx); + struct gl_linked_program *linked + = _mesa_lookup_linked_program(ctx, program); - if (ctx->ShaderObjects.Linked) { - struct gl_linked_program *linked = ctx->ShaderObjects.Linked; - if (location >= 0 && location < linked->Uniforms->NumParameters) { - GLfloat *v = linked->Uniforms->ParameterValues[location]; - const GLfloat *fValues = (const GLfloat *) values; /* XXX */ - GLint i; - if (type == GL_FLOAT_VEC4) - count *= 4; - else if (type == GL_FLOAT_VEC3) - count *= 3; - else - abort(); - - for (i = 0; i < count; i++) - v[i] = fValues[i]; - return; - } - } -} - - -GLvoid GLAPIENTRY -_mesa_Uniform1fARB(GLint location, GLfloat v0) -{ - uniform(location, 1, &v0, GL_FLOAT, "glUniform1fARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1) -{ - GLfloat v[2]; - v[0] = v0; - v[1] = v1; - uniform(location, 1, v, GL_FLOAT_VEC2, "glUniform2fARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) -{ - GLfloat v[3]; - v[0] = v0; - v[1] = v1; - v[2] = v2; - uniform(location, 1, v, GL_FLOAT_VEC3, "glUniform3fARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, - GLfloat v3) -{ - GLfloat v[4]; - v[0] = v0; - v[1] = v1; - v[2] = v2; - v[3] = v3; - uniform(location, 1, v, GL_FLOAT_VEC4, "glUniform4fARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform1iARB(GLint location, GLint v0) -{ - uniform(location, 1, &v0, GL_INT, "glUniform1iARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform2iARB(GLint location, GLint v0, GLint v1) -{ - GLint v[2]; - v[0] = v0; - v[1] = v1; - uniform(location, 1, v, GL_INT_VEC2, "glUniform2iARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2) -{ - GLint v[3]; - v[0] = v0; - v[1] = v1; - v[2] = v2; - uniform(location, 1, v, GL_INT_VEC3, "glUniform3iARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) -{ - GLint v[4]; - v[0] = v0; - v[1] = v1; - v[2] = v2; - v[3] = v3; - uniform(location, 1, v, GL_INT_VEC4, "glUniform4iARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform1fvARB(GLint location, GLsizei count, const GLfloat * value) -{ - uniform(location, count, value, GL_FLOAT, "glUniform1fvARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value) -{ - uniform(location, count, value, GL_FLOAT_VEC2, "glUniform2fvARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform3fvARB(GLint location, GLsizei count, const GLfloat * value) -{ - uniform(location, count, value, GL_FLOAT_VEC3, "glUniform3fvARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value) -{ - uniform(location, count, value, GL_FLOAT_VEC4, "glUniform4fvARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform1ivARB(GLint location, GLsizei count, const GLint * value) -{ - uniform(location, count, value, GL_INT, "glUniform1ivARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value) -{ - uniform(location, count, value, GL_INT_VEC2, "glUniform2ivARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value) -{ - uniform(location, count, value, GL_INT_VEC3, "glUniform3ivARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value) -{ - uniform(location, count, value, GL_INT_VEC4, "glUniform4ivARB"); -} - - -/** - * Helper function used by UniformMatrix**vARB() functions below. - */ -static void -uniform_matrix(GLint cols, GLint rows, const char *caller, - GLenum matrixType, - GLint location, GLsizei count, GLboolean transpose, - const GLfloat *values) -{ - const GLint matElements = rows * cols; - GET_CURRENT_CONTEXT(ctx); - -#ifdef OLD - GET_CURRENT_LINKED_PROGRAM(pro, caller); -#endif - - if (values == NULL) { - _mesa_error(ctx, GL_INVALID_VALUE, caller); - return; - } - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (transpose) { - GLfloat *trans, *pt; - const GLfloat *pv; - GLint i, j, k; - - trans = (GLfloat *) _mesa_malloc(count * matElements * sizeof(GLfloat)); - if (!trans) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, caller); - return; - } - - pt = trans; - pv = values; - for (i = 0; i < count; i++) { - /* transpose from pv matrix into pt matrix */ - for (j = 0; j < cols; j++) { - for (k = 0; k < rows; k++) { - /* XXX verify this */ - pt[j * rows + k] = pv[k * cols + j]; - } - } - pt += matElements; - pv += matElements; - } - -#ifdef OLD - if (!(**pro).WriteUniform(pro, location, count, trans, matrixType)) - _mesa_error(ctx, GL_INVALID_OPERATION, caller); -#endif - _mesa_free(trans); - } - else { -#ifdef OLD - if (!(**pro).WriteUniform(pro, location, count, values, matrixType)) - _mesa_error(ctx, GL_INVALID_OPERATION, caller); -#endif - } -} - - -GLvoid GLAPIENTRY -_mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose, - const GLfloat * value) -{ - uniform_matrix(2, 2, "glUniformMatrix2fvARB", GL_FLOAT_MAT2, - location, count, transpose, value); -} - -GLvoid GLAPIENTRY -_mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose, - const GLfloat * value) -{ - uniform_matrix(3, 3, "glUniformMatrix3fvARB", GL_FLOAT_MAT3, - location, count, transpose, value); -} - -GLvoid GLAPIENTRY -_mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose, - const GLfloat * value) -{ - uniform_matrix(4, 4, "glUniformMatrix4fvARB", GL_FLOAT_MAT4, - location, count, transpose, value); -} - -static GLboolean -_mesa_get_object_parameter(GLhandleARB obj, GLenum pname, GLvoid * params, - GLboolean * integral, GLint * size) -{ -#if 000 - GET_CURRENT_CONTEXT(ctx); - GLint *ipar = (GLint *) params; - - /* set default values */ - *integral = GL_TRUE; /* indicates param type, TRUE: GLint, FALSE: GLfloat */ - *size = 1; /* param array size */ - - switch (pname) { - case GL_OBJECT_TYPE_ARB: - case GL_OBJECT_DELETE_STATUS_ARB: - case GL_OBJECT_INFO_LOG_LENGTH_ARB: - { - GET_GENERIC(gen, obj, "glGetObjectParameterivARB"); - - if (gen == NULL) - return GL_FALSE; - - switch (pname) { - case GL_OBJECT_TYPE_ARB: - *ipar = (**gen).GetType(gen); - break; - case GL_OBJECT_DELETE_STATUS_ARB: - *ipar = (**gen).GetDeleteStatus(gen); - break; - case GL_OBJECT_INFO_LOG_LENGTH_ARB: - *ipar = (**gen).GetInfoLogLength(gen); - break; - } - - RELEASE_GENERIC(gen); - } - break; - case GL_OBJECT_SUBTYPE_ARB: - case GL_OBJECT_COMPILE_STATUS_ARB: - case GL_OBJECT_SHADER_SOURCE_LENGTH_ARB: - { - GET_SHADER(sha, obj, "glGetObjectParameterivARB"); - - if (sha == NULL) - return GL_FALSE; - - switch (pname) { - case GL_OBJECT_SUBTYPE_ARB: - *ipar = (**sha).GetSubType(sha); - break; - case GL_OBJECT_COMPILE_STATUS_ARB: - *ipar = (**sha).GetCompileStatus(sha); - break; - case GL_OBJECT_SHADER_SOURCE_LENGTH_ARB: - { - const GLcharARB *src = (**sha).GetSource(sha); - if (src == NULL) - *ipar = 0; - else - *ipar = _mesa_strlen(src) + 1; - } - break; - } - - RELEASE_SHADER(sha); - } - break; - case GL_OBJECT_LINK_STATUS_ARB: - case GL_OBJECT_VALIDATE_STATUS_ARB: - case GL_OBJECT_ATTACHED_OBJECTS_ARB: - case GL_OBJECT_ACTIVE_UNIFORMS_ARB: - case GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB: - { - GET_PROGRAM(pro, obj, "glGetObjectParameterivARB"); - - if (pro == NULL) - return GL_FALSE; - - switch (pname) { - case GL_OBJECT_LINK_STATUS_ARB: - *ipar = (**pro).GetLinkStatus(pro); - break; - case GL_OBJECT_VALIDATE_STATUS_ARB: - *ipar = (**pro).GetValidateStatus(pro); - break; - case GL_OBJECT_ATTACHED_OBJECTS_ARB: - *ipar = - (**pro)._container. - GetAttachedCount((struct gl2_container_intf **) (pro)); - break; - case GL_OBJECT_ACTIVE_UNIFORMS_ARB: - *ipar = (**pro).GetActiveUniformCount(pro); - break; - case GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB: - *ipar = (**pro).GetActiveUniformMaxLength(pro); - break; - case GL_OBJECT_ACTIVE_ATTRIBUTES_ARB: - *ipar = (**pro).GetActiveAttribCount(pro); - break; - case GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB: - *ipar = (**pro).GetActiveAttribMaxLength(pro); - break; - } - - RELEASE_PROGRAM(pro); - } - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetObjectParameterivARB"); - return GL_FALSE; - } -#endif - return GL_TRUE; -} - -GLvoid GLAPIENTRY -_mesa_GetObjectParameterfvARB(GLhandleARB obj, GLenum pname, GLfloat * params) -{ - GET_CURRENT_CONTEXT(ctx); - GLboolean integral; - GLint size; - - if (params == NULL) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterfvARB"); - return; - } - - assert(sizeof(GLfloat) == sizeof(GLint)); - - if (_mesa_get_object_parameter(obj, pname, (GLvoid *) params, - &integral, &size)) { - if (integral) { - GLint i; - for (i = 0; i < size; i++) - params[i] = (GLfloat) ((GLint *) params)[i]; - } - } -} - -GLvoid GLAPIENTRY -_mesa_GetObjectParameterivARB(GLhandleARB obj, GLenum pname, GLint * params) -{ - GET_CURRENT_CONTEXT(ctx); - GLboolean integral; - GLint size; - - if (params == NULL) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB"); - return; - } - - assert(sizeof(GLfloat) == sizeof(GLint)); - - if (_mesa_get_object_parameter(obj, pname, (GLvoid *) params, - &integral, &size)) { - if (!integral) { - GLint i; - for (i = 0; i < size; i++) - params[i] = (GLint) ((GLfloat *) params)[i]; - } + if (!linked) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetAttribLocation"); + return -1; } -} - - -/** - * Copy string from to , up to maxLength characters, returning - * length of in . - * \param src the strings source - * \param maxLength max chars to copy - * \param length returns numberof chars copied - * \param dst the string destination - */ -static GLvoid -copy_string(const GLcharARB * src, GLsizei maxLength, GLsizei * length, - GLcharARB * dst) -{ - GLsizei len; - for (len = 0; len < maxLength - 1 && src && src[len]; len++) - dst[len] = src[len]; - if (maxLength > 0) - dst[len] = 0; - if (length) - *length = len; -} - -GLvoid GLAPIENTRY -_mesa_GetInfoLogARB(GLhandleARB obj, GLsizei maxLength, GLsizei * length, - GLcharARB * infoLog) -{ -#if 0 - GET_CURRENT_CONTEXT(ctx); - GET_GENERIC(gen, obj, "glGetInfoLogARB"); - - if (gen == NULL) - return; - - if (infoLog == NULL) - _mesa_error(ctx, GL_INVALID_VALUE, "glGetInfoLogARB"); - else { - GLsizei actualsize = (**gen).GetInfoLogLength(gen); - if (actualsize > maxLength) - actualsize = maxLength; - (**gen).GetInfoLog(gen, actualsize, infoLog); - if (length != NULL) - *length = (actualsize > 0) ? actualsize - 1 : 0; + if (!linked->LinkStatus) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetAttribLocation(program not linked)"); + return -1; } - RELEASE_GENERIC(gen); -#endif -} + if (!name) + return -1; -GLvoid GLAPIENTRY -_mesa_GetAttachedObjectsARB(GLhandleARB containerObj, GLsizei maxCount, - GLsizei * count, GLhandleARB * obj) -{ -#if 0 - GET_CURRENT_CONTEXT(ctx); - GET_CONTAINER(con, containerObj, "glGetAttachedObjectsARB"); - - if (con == NULL) - return; - - if (obj == NULL) - _mesa_error(ctx, GL_INVALID_VALUE, "glGetAttachedObjectsARB"); - else { - GLsizei cnt, i; - - cnt = (**con).GetAttachedCount(con); - if (cnt > maxCount) - cnt = maxCount; - if (count != NULL) - *count = cnt; - - for (i = 0; i < cnt; i++) { - struct gl2_generic_intf **x = (**con).GetAttached(con, i); - obj[i] = (**x).GetName(x); - RELEASE_GENERIC(x); - } - } - RELEASE_CONTAINER(con); -#endif -} - -GLint GLAPIENTRY -_mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB * name) -{ - GET_CURRENT_CONTEXT(ctx); - - if (ctx->ShaderObjects.Linked) { - const struct gl_linked_program *linked = ctx->ShaderObjects.Linked; - GLuint loc; - for (loc = 0; loc < linked->Uniforms->NumParameters; loc++) { - const struct gl_program_parameter *u - = linked->Uniforms->Parameters + loc; - if (u->Type == PROGRAM_UNIFORM && !strcmp(u->Name, name)) { - return loc; + if (linked->Attributes) { + GLuint i; + for (i = 0; i < linked->Attributes->NumParameters; i++) { + if (!strcmp(linked->Attributes->Parameters[i].Name, name)) { + return i; } } } return -1; - -} - - -GLvoid GLAPIENTRY -_mesa_GetActiveUniformARB(GLhandleARB programObj, GLuint index, - GLsizei maxLength, GLsizei * length, GLint * size, - GLenum * type, GLcharARB * name) -{ -#if 0 - GET_CURRENT_CONTEXT(ctx); - GET_PROGRAM(pro, programObj, "glGetActiveUniformARB"); - - if (pro == NULL) - return; - - if (size == NULL || type == NULL || name == NULL) - _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformARB"); - else { - if (index < (**pro).GetActiveUniformCount(pro)) - (**pro).GetActiveUniform(pro, index, maxLength, length, size, type, - name); - else - _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformARB"); - } - RELEASE_PROGRAM(pro); -#endif -} - - -GLvoid GLAPIENTRY -_mesa_GetUniformfvARB(GLhandleARB programObj, GLint location, GLfloat * params) -{ -#if 0 - GET_CURRENT_CONTEXT(ctx); - GET_LINKED_PROGRAM(pro, programObj, "glGetUniformfvARB"); - - if (!pro) - return; - - if (!(**pro).ReadUniform(pro, location, 1, params, GL_FLOAT)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfvARB"); - - RELEASE_PROGRAM(pro); -#endif -} - - -GLvoid GLAPIENTRY -_mesa_GetUniformivARB(GLhandleARB programObj, GLint location, GLint * params) -{ -#if 0 - GET_CURRENT_CONTEXT(ctx); - GET_LINKED_PROGRAM(pro, programObj, "glGetUniformivARB"); - - if (!pro) - return; - - if (!(**pro).ReadUniform(pro, location, 1, params, GL_INT)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformivARB"); - RELEASE_PROGRAM(pro); -#endif -} - -GLvoid GLAPIENTRY -_mesa_GetShaderSourceARB(GLhandleARB obj, GLsizei maxLength, GLsizei * length, - GLcharARB * sourceOut) -{ - GET_CURRENT_CONTEXT(ctx); - struct gl_program *shader = _mesa_lookup_shader(ctx, obj); - - if (!shader) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderSourceARB(obj)"); - return; - } - - copy_string((GLcharARB *) shader->String, maxLength, length, sourceOut); -} - - -/* GL_ARB_vertex_shader */ - -GLvoid GLAPIENTRY -_mesa_BindAttribLocationARB(GLhandleARB programObj, GLuint index, - const GLcharARB * name) -{ -#if 0 - GET_CURRENT_CONTEXT(ctx); - GET_PROGRAM(pro, programObj, "glBindAttribLocationARB"); - - if (pro == NULL) - return; - - if (name == NULL || index >= MAX_VERTEX_ATTRIBS) - _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocationARB"); - else if (IS_NAME_WITH_GL_PREFIX(name)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glBindAttribLocationARB"); - else - (**pro).OverrideAttribBinding(pro, index, name); - RELEASE_PROGRAM(pro); -#endif -} - - -GLvoid GLAPIENTRY -_mesa_GetActiveAttribARB(GLhandleARB programObj, GLuint index, - GLsizei maxLength, GLsizei * length, GLint * size, - GLenum * type, GLcharARB * name) -{ -#if 0 - GET_CURRENT_CONTEXT(ctx); - GET_PROGRAM(pro, programObj, "glGetActiveAttribARB"); - - if (pro == NULL) - return; - - if (name == NULL || index >= (**pro).GetActiveAttribCount(pro)) - _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttribARB"); - else - (**pro).GetActiveAttrib(pro, index, maxLength, length, size, type, - name); - RELEASE_PROGRAM(pro); -#endif } -GLint GLAPIENTRY -_mesa_GetAttribLocationARB(GLhandleARB programObj, const GLcharARB * name) +GLuint +_mesa_get_handle(GLcontext *ctx, GLenum pname) { #if 0 GET_CURRENT_CONTEXT(ctx); - GLint loc = -1; - GET_LINKED_PROGRAM(pro, programObj, "glGetAttribLocationARB"); - - if (!pro) - return -1; - - if (name == NULL) - _mesa_error(ctx, GL_INVALID_VALUE, "glGetAttribLocationARB"); - else if (!IS_NAME_WITH_GL_PREFIX(name)) - loc = (**pro).GetAttribLocation(pro, name); - RELEASE_PROGRAM(pro); - return loc; -#endif - return 0; -} - - -/** - ** OpenGL 2.0 functions which basically wrap the ARB_shader functions - **/ - -void GLAPIENTRY -_mesa_AttachShader(GLuint program, GLuint shader) -{ - _mesa_AttachObjectARB(program, shader); -} - - -GLuint GLAPIENTRY -_mesa_CreateShader(GLenum type) -{ - return (GLuint) _mesa_CreateShaderObjectARB(type); -} - -GLuint GLAPIENTRY -_mesa_CreateProgram(void) -{ - return (GLuint) _mesa_CreateProgramObjectARB(); -} - - -void GLAPIENTRY -_mesa_DeleteProgram(GLuint name) -{ - GET_CURRENT_CONTEXT(ctx); - struct gl_linked_program *linked; - - linked = _mesa_lookup_linked_program(ctx, name); - if (!linked) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glDeleteProgram(name)"); - return; - } - - _mesa_HashRemove(ctx->Shared->ProgramObjects, name); - _mesa_delete_linked_program(ctx, linked); -} - - -void GLAPIENTRY -_mesa_DeleteShader(GLuint shader) -{ - _mesa_DeleteObjectARB(shader); -} - -void GLAPIENTRY -_mesa_DetachShader(GLuint program, GLuint shader) -{ - _mesa_DetachObjectARB(program, shader); -} -void GLAPIENTRY -_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount, - GLsizei *count, GLuint *obj) -{ - { - GET_CURRENT_CONTEXT(ctx); - struct gl_linked_program *linked - = _mesa_lookup_linked_program(ctx, program); - if (linked) { - GLuint i; - for (i = 0; i < maxCount && i < linked->NumShaders; i++) { - obj[i] = linked->Shaders[i]->Id; - } - if (count) - *count = i; - } - else { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetAttachedShaders"); + switch (pname) { + case GL_PROGRAM_OBJECT_ARB: + { + struct gl2_program_intf **pro = ctx->Shader.CurrentProgram; + + if (pro != NULL) + return (**pro)._container._generic. + GetName((struct gl2_generic_intf **) (pro)); } + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB"); } +#endif + return 0; } -void GLAPIENTRY -_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params) +void +_mesa_get_programiv(GLcontext *ctx, GLuint program, + GLenum pname, GLint *params) { -#if 0 - GET_CURRENT_CONTEXT(ctx); - GET_PROGRAM(pro, program, "glGetProgramiv"); + struct gl_linked_program *linked + = _mesa_lookup_linked_program(ctx, program); - if (!pro) + if (!linked) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)"); return; + } switch (pname) { case GL_DELETE_STATUS: - *params = (**pro)._container._generic.GetDeleteStatus((struct gl2_generic_intf **) pro); + *params = linked->DeletePending; break; case GL_LINK_STATUS: - *params = (**pro).GetLinkStatus(pro); + *params = linked->LinkStatus; break; case GL_VALIDATE_STATUS: - *params = (**pro).GetValidateStatus(pro); + *params = linked->Validated; break; case GL_INFO_LOG_LENGTH: - *params = (**pro)._container._generic.GetInfoLogLength( (struct gl2_generic_intf **) pro ); + *params = linked->InfoLog ? strlen(linked->InfoLog) : 0; break; case GL_ATTACHED_SHADERS: - *params = (**pro)._container.GetAttachedCount( (struct gl2_container_intf **) pro ); + *params = linked->NumShaders; break; case GL_ACTIVE_ATTRIBUTES: - *params = (**pro).GetActiveAttribCount(pro); + *params = linked->Uniforms ? linked->Uniforms->NumParameters : 0; break; case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: - *params = (**pro).GetActiveAttribMaxLength(pro); + *params = _mesa_parameter_longest_name(linked->Attributes); break; case GL_ACTIVE_UNIFORMS: - *params = (**pro).GetActiveUniformCount(pro); + *params = linked->Uniforms ? linked->Uniforms->NumParameters : 0; break; case GL_ACTIVE_UNIFORM_MAX_LENGTH: - *params = (**pro).GetActiveUniformMaxLength(pro); + *params = _mesa_parameter_longest_name(linked->Uniforms); break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)"); return; } -#endif } -void GLAPIENTRY -_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize, - GLsizei *length, GLchar *infoLog) -{ - _mesa_GetInfoLogARB(program, bufSize, length, infoLog); -} - - -void GLAPIENTRY -_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params) +void +_mesa_get_shaderiv(GLcontext *ctx, GLuint name, GLenum pname, GLint *params) { #if 0 - GET_CURRENT_CONTEXT(ctx); - GET_SHADER(sh, shader, "glGetShaderiv"); + struct gl_program *shader = _mesa_lookup_shader(ctx, name); - if (!sh) + if (!shader) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderiv(shader)"); return; - + } +#else + struct gl_shader *shader; +#endif switch (pname) { case GL_SHADER_TYPE: - *params = (**sh).GetSubType(sh); + *params = shader->Type; break; case GL_DELETE_STATUS: - *params = (**sh)._generic.GetDeleteStatus((struct gl2_generic_intf **) sh); + *params = shader->DeletePending; break; case GL_COMPILE_STATUS: - *params = (**sh).GetCompileStatus(sh); + *params = shader->CompileStatus; break; case GL_INFO_LOG_LENGTH: - *params = (**sh)._generic.GetInfoLogLength((struct gl2_generic_intf **)sh); + *params = shader->InfoLog ? strlen(shader->InfoLog) : 0; break; case GL_SHADER_SOURCE_LENGTH: - { - const GLchar *src = (**sh).GetSource(sh); - *params = src ? (_mesa_strlen(src) + 1) : 0; - } + *params = shader->Source ? strlen((char *) shader->Source) : 0; break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)"); return; } -#endif } -void GLAPIENTRY -_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize, - GLsizei *length, GLchar *infoLog) +void +_mesa_get_program_info_log(GLcontext *ctx, GLuint program, GLsizei bufSize, + GLsizei *length, GLchar *infoLog) { - _mesa_GetInfoLogARB(shader, bufSize, length, infoLog); + struct gl_linked_program *linked + = _mesa_lookup_linked_program(ctx, program); + if (!linked) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(program)"); + return; + } + /* XXX also test length, infoLog params for NULL? */ + copy_string(linked->InfoLog, bufSize, length, infoLog); } -GLboolean GLAPIENTRY -_mesa_IsProgram(GLuint name) +void +_mesa_get_shader_info_log(GLcontext *ctx, GLuint shader, GLsizei bufSize, + GLsizei *length, GLchar *infoLog) +{ + struct gl_program *shProg = _mesa_lookup_shader(ctx, shader); + if (!shProg) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(shader)"); + return; + } + /* + copy_string(shProg->InfoLog, bufSize, length, infoLog); + */ +} + + +/** + * Called via ctx->Driver.GetShaderSource(). + */ +void +_mesa_get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength, + GLsizei *length, GLchar *sourceOut) +{ + struct gl_program *shProg = _mesa_lookup_shader(ctx, shader); + if (!shProg) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderSource(shader)"); + return; + } + copy_string((GLchar *) shProg->String, maxLength, length, sourceOut); +} + + +/** + * Called via ctx->Driver.GetUniformfv(). + */ +void +_mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location, + GLfloat *params) +{ + struct gl_linked_program *linked + = _mesa_lookup_linked_program(ctx, program); + if (linked) { + GLuint i; + if (location >= 0 && location < linked->Uniforms->NumParameters) { + for (i = 0; i < linked->Uniforms->Parameters[location].Size; i++) { + params[i] = linked->Uniforms->ParameterValues[location][i]; + } + } + else { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetUniformfv(location)"); + } + } + else { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)"); + } +} + + +/** + * Called via ctx->Driver.GetUniformLocation(). + */ +GLint +_mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name) +{ + if (ctx->Shader.CurrentProgram) { + const struct gl_linked_program *linked = ctx->Shader.CurrentProgram; + GLuint loc; + for (loc = 0; loc < linked->Uniforms->NumParameters; loc++) { + const struct gl_program_parameter *u + = linked->Uniforms->Parameters + loc; + if (u->Type == PROGRAM_UNIFORM && !strcmp(u->Name, name)) { + return loc; + } + } + } + return -1; + +} + + +GLboolean +_mesa_is_program(GLcontext *ctx, GLuint name) { - GET_CURRENT_CONTEXT(ctx); struct gl_linked_program *linked = _mesa_lookup_linked_program(ctx, name); - if (linked) - return GL_TRUE; - else - return GL_FALSE; + return linked ? GL_TRUE : GL_FALSE; } -GLboolean GLAPIENTRY -_mesa_IsShader(GLuint name) +GLboolean +_mesa_is_shader(GLcontext *ctx, GLuint name) { - GET_CURRENT_CONTEXT(ctx); struct gl_program *shader = _mesa_lookup_shader(ctx, name); - if (shader) - return GL_TRUE; - else - return GL_FALSE; + return shader ? GL_TRUE : GL_FALSE; } -/** - ** 2.1 functions - **/ -void GLAPIENTRY -_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value) +/** + * Called via ctx->Driver.ShaderSource() + */ +void +_mesa_shader_source(GLcontext *ctx, GLuint shader, const GLchar *source) { - uniform_matrix(2, 3, "glUniformMatrix2x3fv", GL_FLOAT_MAT2x3, - location, count, transpose, value); + struct gl_program *shProg = _mesa_lookup_shader(ctx, shader); + if (!shProg) { + _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSource(shaderObj)"); + return; + } + + /* free old shader source string and install new one */ + if (shProg->String) { + _mesa_free(shProg->String); + } + shProg->String = (GLubyte *) source; } -void GLAPIENTRY -_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value) + +/** + * Called via ctx->Driver.CompileShader() + */ +void +_mesa_compile_shader(GLcontext *ctx, GLuint shaderObj) { - uniform_matrix(3, 2, "glUniformMatrix3x2fv", GL_FLOAT_MAT3x2, - location, count, transpose, value); + struct gl_program *prog = _mesa_lookup_shader(ctx, shaderObj); + slang_info_log info_log; + slang_code_object obj; + slang_unit_type type; + + if (!prog) { + _mesa_error(ctx, GL_INVALID_VALUE, "glCompileShader(shaderObj)"); + return; + } + + slang_info_log_construct(&info_log); + _slang_code_object_ctr(&obj); + + if (prog->Target == GL_VERTEX_PROGRAM_ARB) { + type = slang_unit_vertex_shader; + } + else { + assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB); + type = slang_unit_fragment_shader; + } + + if (_slang_compile((const char*) prog->String, &obj, + type, &info_log, prog)) { + /* + prog->CompileStatus = GL_TRUE; + */ + } + else { + /* + prog->CompileStatus = GL_FALSE; + */ + _mesa_problem(ctx, "Program did not compile!"); + } } -void GLAPIENTRY -_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value) + +/** + * Called via ctx->Driver.LinkProgram() + */ +void +_mesa_link_program(GLcontext *ctx, GLuint program) { - uniform_matrix(2, 4, "glUniformMatrix2x4fv", GL_FLOAT_MAT2x4, - location, count, transpose, value); + struct gl_linked_program *linked; + + linked = _mesa_lookup_linked_program(ctx, program); + if (!linked) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glLinkProgram(program)"); + return; + } + + _slang_link2(ctx, program, linked); +} + + +/** + * Called via ctx->Driver.UseProgram() + */ +void +_mesa_use_program(GLcontext *ctx, GLuint program) +{ + /* XXXX need to handle reference counting here! */ + if (program) { + struct gl_linked_program *linked; + linked = _mesa_lookup_linked_program(ctx, program); + if (!linked) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glUseProgramObjectARB(programObj)"); + return; + } + ctx->Shader.CurrentProgram = linked; + } + else { + /* don't use a shader program */ + ctx->Shader.CurrentProgram = NULL; + } } -void GLAPIENTRY -_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value) + +/** + * Called via ctx->Driver.Uniform(). + */ +void +_mesa_uniform(GLcontext *ctx, GLint location, GLsizei count, + const GLvoid *values, GLenum type) { - uniform_matrix(4, 2, "glUniformMatrix4x2fv", GL_FLOAT_MAT4x2, - location, count, transpose, value); + if (ctx->Shader.CurrentProgram) { + struct gl_linked_program *linked = ctx->Shader.CurrentProgram; + if (location >= 0 && location < linked->Uniforms->NumParameters) { + GLfloat *v = linked->Uniforms->ParameterValues[location]; + const GLfloat *fValues = (const GLfloat *) values; /* XXX */ + GLint i; + if (type == GL_FLOAT_VEC4) + count *= 4; + else if (type == GL_FLOAT_VEC3) + count *= 3; + else + abort(); + + for (i = 0; i < count; i++) + v[i] = fValues[i]; + return; + } + } + else { + _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(program not linked)"); + } } -void GLAPIENTRY -_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value) + +/** + * Called by ctx->Driver.UniformMatrix(). + */ +void +_mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows, + GLenum matrixType, GLint location, GLsizei count, + GLboolean transpose, const GLfloat *values) { - uniform_matrix(3, 4, "glUniformMatrix3x4fv", GL_FLOAT_MAT3x4, - location, count, transpose, value); + const char *caller = "glUniformMatrix"; + const GLint matElements = rows * cols; + + if (values == NULL) { + _mesa_error(ctx, GL_INVALID_VALUE, caller); + return; + } + + FLUSH_VERTICES(ctx, _NEW_PROGRAM); + + if (transpose) { + GLfloat *trans, *pt; + const GLfloat *pv; + GLint i, j, k; + + trans = (GLfloat *) _mesa_malloc(count * matElements * sizeof(GLfloat)); + if (!trans) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, caller); + return; + } + + pt = trans; + pv = values; + for (i = 0; i < count; i++) { + /* transpose from pv matrix into pt matrix */ + for (j = 0; j < cols; j++) { + for (k = 0; k < rows; k++) { + /* XXX verify this */ + pt[j * rows + k] = pv[k * cols + j]; + } + } + pt += matElements; + pv += matElements; + } + +#ifdef OLD + if (!(**pro).WriteUniform(pro, location, count, trans, matrixType)) + _mesa_error(ctx, GL_INVALID_OPERATION, caller); +#endif + _mesa_free(trans); + } + else { +#ifdef OLD + if (!(**pro).WriteUniform(pro, location, count, values, matrixType)) + _mesa_error(ctx, GL_INVALID_OPERATION, caller); +#endif + } } -void GLAPIENTRY -_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value) + +void +_mesa_validate_program(GLcontext *ctx, GLuint program) { - uniform_matrix(4, 3, "glUniformMatrix4x3fv", GL_FLOAT_MAT4x3, - location, count, transpose, value); + struct gl_linked_program *linked; + linked = _mesa_lookup_linked_program(ctx, program); + if (!linked) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glValidateProgram(program)"); + return; + } + /* XXX temporary */ + linked->Validated = GL_TRUE; + + /* From the GL spec: + any two active samplers in the current program object are of + different types, but refer to the same texture image unit, + + any active sampler in the current program object refers to a texture + image unit where fixed-function fragment processing accesses a + texture target that does not match the sampler type, or + + the sum of the number of active samplers in the program and the + number of texture image units enabled for fixed-function fragment + processing exceeds the combined limit on the total number of texture + image units allowed. + */ } + +/**********************************************************************/ + + /** * Create a new GLSL program object. */ @@ -1376,15 +921,9 @@ _mesa_lookup_shader(GLcontext *ctx, GLuint name) } -GLvoid -_mesa_init_shaderobjects(GLcontext * ctx) +void +_mesa_init_shader_state(GLcontext * ctx) { - - ctx->ShaderObjects.CurrentProgram = NULL; - ctx->ShaderObjects._FragmentShaderPresent = GL_FALSE; - ctx->ShaderObjects._VertexShaderPresent = GL_FALSE; - -#if 0 - _mesa_init_shaderobjects_3dlabs(ctx); -#endif + ctx->Shader._FragmentShaderPresent = GL_FALSE; + ctx->Shader._VertexShaderPresent = GL_FALSE; } diff --git a/src/mesa/shader/shader_api.h b/src/mesa/shader/shader_api.h index 388692b623..723f92690d 100644 --- a/src/mesa/shader/shader_api.h +++ b/src/mesa/shader/shader_api.h @@ -31,6 +31,13 @@ #include "mtypes.h" +/** + * Internal functions + */ + +extern void +_mesa_init_shader_state(GLcontext * ctx); + extern struct gl_linked_program * _mesa_new_linked_program(GLcontext *ctx, GLuint name); @@ -52,8 +59,108 @@ extern struct gl_program * _mesa_lookup_shader(GLcontext *ctx, GLuint name); -extern GLvoid -_mesa_init_shaderobjects(GLcontext * ctx); +/** + * API/Driver functions + */ + +extern void +_mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader); + +extern void +_mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index, + const GLchar *name); + +extern void +_mesa_compile_shader(GLcontext *ctx, GLuint shaderObj); + +extern GLuint +_mesa_create_shader(GLcontext *ctx, GLenum type); + +extern GLuint +_mesa_create_program(GLcontext *ctx); + +extern void +_mesa_delete_program2(GLcontext *ctx, GLuint name); + +extern void +_mesa_delete_shader(GLcontext *ctx, GLuint shader); + +extern void +_mesa_detach_shader(GLcontext *ctx, GLuint program, GLuint shader); + +extern void +_mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index, + GLsizei maxLength, GLsizei *length, GLint *size, + GLenum *type, GLchar *name); + +extern void +_mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index, + GLsizei maxLength, GLsizei *length, GLint *size, + GLenum *type, GLchar *name); + +extern void +_mesa_get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount, + GLsizei *count, GLuint *obj); + +extern GLint +_mesa_get_attrib_location(GLcontext *ctx, GLuint program, + const GLchar *name); + +extern GLuint +_mesa_get_handle(GLcontext *ctx, GLenum pname); + +extern void +_mesa_get_programiv(GLcontext *ctx, GLuint program, + GLenum pname, GLint *params); + +extern void +_mesa_get_program_info_log(GLcontext *ctx, GLuint program, GLsizei bufSize, + GLsizei *length, GLchar *infoLog); + +extern void +_mesa_get_shaderiv(GLcontext *ctx, GLuint shader, GLenum pname, GLint *params); + +extern void +_mesa_get_shader_info_log(GLcontext *ctx, GLuint shader, GLsizei bufSize, + GLsizei *length, GLchar *infoLog); + +extern void +_mesa_get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength, + GLsizei *length, GLchar *sourceOut); + +extern void +_mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location, + GLfloat *params); + +extern GLint +_mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name); + +extern GLboolean +_mesa_is_program(GLcontext *ctx, GLuint name); + +extern GLboolean +_mesa_is_shader(GLcontext *ctx, GLuint name); + +extern void +_mesa_link_program(GLcontext *ctx, GLuint program); + +extern void +_mesa_shader_source(GLcontext *ctx, GLuint shader, const GLchar *source); + +extern void +_mesa_uniform(GLcontext *ctx, GLint location, GLsizei count, + const GLvoid *values, GLenum type); + +void +_mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows, + GLenum matrixType, GLint location, GLsizei count, + GLboolean transpose, const GLfloat *values); + +extern void +_mesa_use_program(GLcontext *ctx, GLuint program); + +extern void +_mesa_validate_program(GLcontext *ctx, GLuint program); #endif /* SHADER_API_H */ -- cgit v1.2.3