diff options
author | Michal Krol <[email protected]> | 2006-04-18 10:30:29 +0000 |
---|---|---|
committer | Michal Krol <[email protected]> | 2006-04-18 10:30:29 +0000 |
commit | d55de658b559437272a88a5e8743304996044fff (patch) | |
tree | a157346af0c19e2ff77accf60a53e78b1fc25b56 | |
parent | fcdc6a7d2488defd66bc7e8398c6d8c9a6190a1a (diff) |
Add support for ARB_vertex_shader attrib binding and query.
Clean-up ARB_shaderobjects code a bit.
-rw-r--r-- | src/mesa/shader/shaderobjects.c | 259 | ||||
-rw-r--r-- | src/mesa/shader/shaderobjects.h | 17 | ||||
-rwxr-xr-x | src/mesa/shader/shaderobjects_3dlabs.c | 3481 | ||||
-rwxr-xr-x | src/mesa/shader/shaderobjects_3dlabs.h | 100 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_export.c | 5 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_export.h | 7 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_link.c | 462 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_link.h | 114 |
8 files changed, 2497 insertions, 1948 deletions
diff --git a/src/mesa/shader/shaderobjects.c b/src/mesa/shader/shaderobjects.c index a98c310bac4..fee259a9f38 100644 --- a/src/mesa/shader/shaderobjects.c +++ b/src/mesa/shader/shaderobjects.c @@ -99,9 +99,9 @@ _QUERY_INTERFACE(x, I_SHADER, UIID_SHADER, function);\ } while (0) -#define _LINKED_PROGRAM(x, function)\ +#define _LINKED_PROGRAM(x, function, release)\ if ((**x).GetLinkStatus (x) == GL_FALSE) {\ - RELEASE_PROGRAM(x);\ + if (release) RELEASE_PROGRAM(x);\ _mesa_error (ctx, GL_INVALID_OPERATION, function);\ break;\ } @@ -111,7 +111,7 @@ do {\ _LOOKUP_HANDLE(handle, function);\ _QUERY_INTERFACE(x, I_PROGRAM, UIID_PROGRAM, function);\ - _LINKED_PROGRAM(x, function);\ + _LINKED_PROGRAM(x, function, GL_TRUE);\ } while (0) #define _CURRENT_PROGRAM(x, function)\ @@ -125,9 +125,11 @@ I_PROGRAM x = NULL;\ do {\ _CURRENT_PROGRAM(x, function);\ - _LINKED_PROGRAM(x, function);\ + _LINKED_PROGRAM(x, function, GL_FALSE);\ } while (0) +#define IS_NAME_WITH_GL_PREFIX(x) ((x)[0] == 'g' && (x)[1] == 'l' && (x)[2] == '_') + GLvoid GLAPIENTRY _mesa_DeleteObjectARB (GLhandleARB obj) @@ -379,7 +381,7 @@ _mesa_Uniform1fARB (GLint location, GLfloat v0) if (pro != NULL) { - if (!_slang_write_uniform (pro, location, 1, &v0, GL_FLOAT)) + if (!(**pro).WriteUniform (pro, location, 1, &v0, GL_FLOAT)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform1fARB"); } } @@ -398,7 +400,7 @@ _mesa_Uniform2fARB (GLint location, GLfloat v0, GLfloat v1) v[0] = v0; v[1] = v1; - if (!_slang_write_uniform (pro, location, 1, v, GL_FLOAT_VEC2)) + if (!(**pro).WriteUniform (pro, location, 1, v, GL_FLOAT_VEC2)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform2fARB"); } } @@ -418,7 +420,7 @@ _mesa_Uniform3fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2) v[1] = v1; v[2] = v2; - if (!_slang_write_uniform (pro, location, 1, v, GL_FLOAT_VEC3)) + if (!(**pro).WriteUniform (pro, location, 1, v, GL_FLOAT_VEC3)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform3fARB"); } } @@ -439,7 +441,7 @@ _mesa_Uniform4fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v[2] = v2; v[3] = v3; - if (!_slang_write_uniform (pro, location, 1, v, GL_FLOAT_VEC4)) + if (!(**pro).WriteUniform (pro, location, 1, v, GL_FLOAT_VEC4)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform4fARB"); } } @@ -454,7 +456,7 @@ _mesa_Uniform1iARB (GLint location, GLint v0) if (pro != NULL) { - if (!_slang_write_uniform (pro, location, 1, &v0, GL_INT)) + if (!(**pro).WriteUniform (pro, location, 1, &v0, GL_INT)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform1iARB"); } } @@ -473,7 +475,7 @@ _mesa_Uniform2iARB (GLint location, GLint v0, GLint v1) v[0] = v0; v[1] = v1; - if (!_slang_write_uniform (pro, location, 1, v, GL_INT_VEC2)) + if (!(**pro).WriteUniform (pro, location, 1, v, GL_INT_VEC2)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform2iARB"); } } @@ -493,7 +495,7 @@ _mesa_Uniform3iARB (GLint location, GLint v0, GLint v1, GLint v2) v[1] = v1; v[2] = v2; - if (!_slang_write_uniform (pro, location, 1, v, GL_INT_VEC3)) + if (!(**pro).WriteUniform (pro, location, 1, v, GL_INT_VEC3)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform3iARB"); } } @@ -514,7 +516,7 @@ _mesa_Uniform4iARB (GLint location, GLint v0, GLint v1, GLint v2, GLint v3) v[2] = v2; v[3] = v3; - if (!_slang_write_uniform (pro, location, 1, v, GL_INT_VEC4)) + if (!(**pro).WriteUniform (pro, location, 1, v, GL_INT_VEC4)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform4iARB"); } } @@ -525,11 +527,17 @@ _mesa_Uniform1fvARB (GLint location, GLsizei count, const GLfloat *value) GET_CURRENT_CONTEXT(ctx); GET_CURRENT_LINKED_PROGRAM(pro, "glUniform1fvARB"); + if (value == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glUniform1fvARB"); + return; + } + FLUSH_VERTICES(ctx, _NEW_PROGRAM); if (pro != NULL) { - if (!_slang_write_uniform (pro, location, count, value, GL_FLOAT)) + if (!(**pro).WriteUniform (pro, location, count, value, GL_FLOAT)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform1fvARB"); } } @@ -540,11 +548,17 @@ _mesa_Uniform2fvARB (GLint location, GLsizei count, const GLfloat *value) GET_CURRENT_CONTEXT(ctx); GET_CURRENT_LINKED_PROGRAM(pro, "glUniform2fvARB"); + if (value == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glUniform2fvARB"); + return; + } + FLUSH_VERTICES(ctx, _NEW_PROGRAM); if (pro != NULL) { - if (!_slang_write_uniform (pro, location, count, value, GL_FLOAT_VEC2)) + if (!(**pro).WriteUniform (pro, location, count, value, GL_FLOAT_VEC2)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform2fvARB"); } } @@ -555,11 +569,17 @@ _mesa_Uniform3fvARB (GLint location, GLsizei count, const GLfloat *value) GET_CURRENT_CONTEXT(ctx); GET_CURRENT_LINKED_PROGRAM(pro, "glUniform3fvARB"); + if (value == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glUniform3fvARB"); + return; + } + FLUSH_VERTICES(ctx, _NEW_PROGRAM); if (pro != NULL) { - if (!_slang_write_uniform (pro, location, count, value, GL_FLOAT_VEC3)) + if (!(**pro).WriteUniform (pro, location, count, value, GL_FLOAT_VEC3)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform3fvARB"); } } @@ -570,11 +590,17 @@ _mesa_Uniform4fvARB (GLint location, GLsizei count, const GLfloat *value) GET_CURRENT_CONTEXT(ctx); GET_CURRENT_LINKED_PROGRAM(pro, "glUniform4fvARB"); + if (value == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glUniform4fvARB"); + return; + } + FLUSH_VERTICES(ctx, _NEW_PROGRAM); if (pro != NULL) { - if (!_slang_write_uniform (pro, location, count, value, GL_FLOAT_VEC4)) + if (!(**pro).WriteUniform (pro, location, count, value, GL_FLOAT_VEC4)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform4fvARB"); } } @@ -585,11 +611,17 @@ _mesa_Uniform1ivARB (GLint location, GLsizei count, const GLint *value) GET_CURRENT_CONTEXT(ctx); GET_CURRENT_LINKED_PROGRAM(pro, "glUniform1ivARB"); + if (value == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glUniform1ivARB"); + return; + } + FLUSH_VERTICES(ctx, _NEW_PROGRAM); if (pro != NULL) { - if (!_slang_write_uniform (pro, location, count, value, GL_INT)) + if (!(**pro).WriteUniform (pro, location, count, value, GL_INT)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform1ivARB"); } } @@ -600,11 +632,17 @@ _mesa_Uniform2ivARB (GLint location, GLsizei count, const GLint *value) GET_CURRENT_CONTEXT(ctx); GET_CURRENT_LINKED_PROGRAM(pro, "glUniform2ivARB"); + if (value == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glUniform2ivARB"); + return; + } + FLUSH_VERTICES(ctx, _NEW_PROGRAM); if (pro != NULL) { - if (!_slang_write_uniform (pro, location, count, value, GL_INT_VEC2)) + if (!(**pro).WriteUniform (pro, location, count, value, GL_INT_VEC2)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform2ivARB"); } } @@ -615,11 +653,17 @@ _mesa_Uniform3ivARB (GLint location, GLsizei count, const GLint *value) GET_CURRENT_CONTEXT(ctx); GET_CURRENT_LINKED_PROGRAM(pro, "glUniform3ivARB"); + if (value == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glUniform3ivARB"); + return; + } + FLUSH_VERTICES(ctx, _NEW_PROGRAM); if (pro != NULL) { - if (!_slang_write_uniform (pro, location, count, value, GL_INT_VEC3)) + if (!(**pro).WriteUniform (pro, location, count, value, GL_INT_VEC3)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform3ivARB"); } } @@ -630,11 +674,17 @@ _mesa_Uniform4ivARB (GLint location, GLsizei count, const GLint *value) GET_CURRENT_CONTEXT(ctx); GET_CURRENT_LINKED_PROGRAM(pro, "glUniform4ivARB"); + if (value == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glUniform4ivARB"); + return; + } + FLUSH_VERTICES(ctx, _NEW_PROGRAM); if (pro != NULL) { - if (!_slang_write_uniform (pro, location, count, value, GL_INT_VEC4)) + if (!(**pro).WriteUniform (pro, location, count, value, GL_INT_VEC4)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform4ivARB"); } } @@ -645,6 +695,12 @@ _mesa_UniformMatrix2fvARB (GLint location, GLsizei count, GLboolean transpose, c GET_CURRENT_CONTEXT(ctx); GET_CURRENT_LINKED_PROGRAM(pro, "glUniformMatrix2fvARB"); + if (value == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glUniformMatrix2fvARB"); + return; + } + FLUSH_VERTICES(ctx, _NEW_PROGRAM); if (pro != NULL) @@ -667,13 +723,13 @@ _mesa_UniformMatrix2fvARB (GLint location, GLsizei count, GLboolean transpose, c pt[2] = pv[1]; pt[3] = pv[3]; } - if (!_slang_write_uniform (pro, location, count, trans, GL_FLOAT_MAT2)) + if (!(**pro).WriteUniform (pro, location, count, trans, GL_FLOAT_MAT2)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniformMatrix2fvARB"); _mesa_free (trans); } else { - if (!_slang_write_uniform (pro, location, count, value, GL_FLOAT_MAT2)) + if (!(**pro).WriteUniform (pro, location, count, value, GL_FLOAT_MAT2)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniformMatrix2fvARB"); } } @@ -685,6 +741,12 @@ _mesa_UniformMatrix3fvARB (GLint location, GLsizei count, GLboolean transpose, c GET_CURRENT_CONTEXT(ctx); GET_CURRENT_LINKED_PROGRAM(pro, "glUniformMatrix3fvARB"); + if (value == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glUniformMatrix3fvARB"); + return; + } + FLUSH_VERTICES(ctx, _NEW_PROGRAM); if (pro != NULL) @@ -712,13 +774,13 @@ _mesa_UniformMatrix3fvARB (GLint location, GLsizei count, GLboolean transpose, c pt[7] = pv[5]; pt[8] = pv[8]; } - if (!_slang_write_uniform (pro, location, count, trans, GL_FLOAT_MAT3)) + if (!(**pro).WriteUniform (pro, location, count, trans, GL_FLOAT_MAT3)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniformMatrix3fvARB"); _mesa_free (trans); } else { - if (!_slang_write_uniform (pro, location, count, value, GL_FLOAT_MAT3)) + if (!(**pro).WriteUniform (pro, location, count, value, GL_FLOAT_MAT3)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniformMatrix3fvARB"); } } @@ -730,6 +792,12 @@ _mesa_UniformMatrix4fvARB (GLint location, GLsizei count, GLboolean transpose, c GET_CURRENT_CONTEXT(ctx); GET_CURRENT_LINKED_PROGRAM(pro, "glUniformMatrix4fvARB"); + if (value == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glUniformMatrix4fvARB"); + return; + } + FLUSH_VERTICES(ctx, _NEW_PROGRAM); if (pro != NULL) @@ -749,13 +817,13 @@ _mesa_UniformMatrix4fvARB (GLint location, GLsizei count, GLboolean transpose, c { _math_transposef (pt, pv); } - if (!_slang_write_uniform (pro, location, count, trans, GL_FLOAT_MAT4)) + if (!(**pro).WriteUniform (pro, location, count, trans, GL_FLOAT_MAT4)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniformMatrix4fvARB"); _mesa_free (trans); } else { - if (!_slang_write_uniform (pro, location, count, value, GL_FLOAT_MAT4)) + if (!(**pro).WriteUniform (pro, location, count, value, GL_FLOAT_MAT4)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniformMatrix4fvARB"); } } @@ -861,10 +929,16 @@ _mesa_get_object_parameter (GLhandleARB obj, GLenum pname, GLvoid *params, GLboo *ipar = (**pro)._container.GetAttachedCount ((I_CONTAINER) pro); break; case GL_OBJECT_ACTIVE_UNIFORMS_ARB: - *ipar = _slang_get_active_uniform_count (pro); + *ipar = (**pro).GetActiveUniformCount (pro); break; case GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB: - *ipar = _slang_get_active_uniform_max_length (pro); + *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; } @@ -882,9 +956,16 @@ _mesa_get_object_parameter (GLhandleARB obj, GLenum pname, GLvoid *params, GLboo 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)) @@ -900,9 +981,16 @@ _mesa_GetObjectParameterfvARB (GLhandleARB obj, GLenum pname, GLfloat *params) 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)) @@ -944,11 +1032,14 @@ _mesa_GetInfoLogARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLchar GET_CURRENT_CONTEXT(ctx); GET_GENERIC(gen, obj, "glGetInfoLogARB"); - if (gen != NULL) - { - copy_string((**gen).GetInfoLog (gen), maxLength, length, infoLog); - RELEASE_GENERIC(gen); - } + if (gen == NULL) + return; + + if (infoLog == NULL) + _mesa_error (ctx, GL_INVALID_VALUE, "glGetInfoLogARB"); + else + copy_string ((**gen).GetInfoLog (gen), maxLength, length, infoLog); + RELEASE_GENERIC(gen); } GLvoid GLAPIENTRY @@ -956,11 +1047,17 @@ _mesa_GetAttachedObjectsARB (GLhandleARB containerObj, GLsizei maxCount, GLsizei GLhandleARB *obj) { GET_CURRENT_CONTEXT(ctx); - GLsizei cnt, i; GET_CONTAINER(con, containerObj, "glGetAttachedObjectsARB"); - if (con != NULL) + 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; @@ -973,8 +1070,8 @@ _mesa_GetAttachedObjectsARB (GLhandleARB containerObj, GLsizei maxCount, GLsizei obj[i] = (**x).GetName (x); RELEASE_GENERIC(x); } - RELEASE_CONTAINER(con); } + RELEASE_CONTAINER(con); } GLint GLAPIENTRY @@ -984,12 +1081,17 @@ _mesa_GetUniformLocationARB (GLhandleARB programObj, const GLcharARB *name) GLint loc = -1; GET_LINKED_PROGRAM(pro, programObj, "glGetUniformLocationARB"); - if (pro != NULL) + if (pro == NULL) + return -1; + + if (name == NULL) + _mesa_error (ctx, GL_INVALID_VALUE, "glGetUniformLocationARB"); + else { - if (name != NULL && (name[0] != 'g' || name[1] != 'l' || name[2] != '_')) - loc = _slang_get_uniform_location (pro, name); - RELEASE_PROGRAM(pro); + if (!IS_NAME_WITH_GL_PREFIX(name)) + loc = (**pro).GetUniformLocation (pro, name); } + RELEASE_PROGRAM(pro); return loc; } @@ -1000,14 +1102,19 @@ _mesa_GetActiveUniformARB (GLhandleARB programObj, GLuint index, GLsizei maxLeng GET_CURRENT_CONTEXT(ctx); GET_PROGRAM(pro, programObj, "glGetActiveUniformARB"); - if (pro != NULL) + if (pro == NULL) + return; + + if (size == NULL || type == NULL || name == NULL) + _mesa_error (ctx, GL_INVALID_VALUE, "glGetActiveUniformARB"); + else { - if (index < _slang_get_active_uniform_count (pro)) - _slang_get_active_uniform (pro, index, maxLength, length, size, type, name); + 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); } + RELEASE_PROGRAM(pro); } GLvoid GLAPIENTRY @@ -1042,11 +1149,14 @@ _mesa_GetShaderSourceARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, G GET_CURRENT_CONTEXT(ctx); GET_SHADER(sha, obj, "glGetShaderSourceARB"); - if (sha != NULL) - { - copy_string((**sha).GetSource (sha), maxLength, length, source); - RELEASE_SHADER(sha); - } + if (sha == NULL) + return; + + if (source == NULL) + _mesa_error (ctx, GL_INVALID_VALUE, "glGetShaderSourceARB"); + else + copy_string ((**sha).GetSource (sha), maxLength, length, source); + RELEASE_SHADER(sha); } /* GL_ARB_vertex_shader */ @@ -1057,28 +1167,33 @@ _mesa_BindAttribLocationARB (GLhandleARB programObj, GLuint index, const GLcharA GET_CURRENT_CONTEXT(ctx); GET_PROGRAM(pro, programObj, "glBindAttribLocationARB"); - if (pro != NULL) - { - if (name != NULL && (name[0] != 'g' || name[1] != 'l' || name[2] != '_')) - { - /* TODO */ - } - RELEASE_PROGRAM(pro); - } + 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); } GLvoid GLAPIENTRY _mesa_GetActiveAttribARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, - GLint *size, GLenum *type, GLcharARB *name) + GLint *size, GLenum *type, GLcharARB *name) { GET_CURRENT_CONTEXT(ctx); GET_PROGRAM(pro, programObj, "glGetActiveAttribARB"); - if (pro != NULL) - { - /* TODO */ - RELEASE_PROGRAM(pro); - } + 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); } GLint GLAPIENTRY @@ -1086,16 +1201,16 @@ _mesa_GetAttribLocationARB (GLhandleARB programObj, const GLcharARB *name) { GET_CURRENT_CONTEXT(ctx); GLint loc = -1; - GET_PROGRAM(pro, programObj, "glGetAttribLocationARB"); + GET_LINKED_PROGRAM(pro, programObj, "glGetAttribLocationARB"); - if (pro != NULL) - { - if (name != NULL && (name[0] != 'g' || name[1] != 'l' || name[2] != '_')) - { - /* TODO */ - } - RELEASE_PROGRAM(pro); - } + if (pro == NULL) + 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; } diff --git a/src/mesa/shader/shaderobjects.h b/src/mesa/shader/shaderobjects.h index 19c4e8d3f8a..86a069ad6a9 100644 --- a/src/mesa/shader/shaderobjects.h +++ b/src/mesa/shader/shaderobjects.h @@ -88,11 +88,24 @@ struct gl2_program_intf GLvoid (* Validate) (struct gl2_program_intf **); GLvoid (* UpdateFixedUniforms) (struct gl2_program_intf **); GLvoid (* UpdateFixedAttribute) (struct gl2_program_intf **, GLuint, GLvoid *, GLuint, GLuint, - GLboolean); + GLboolean); GLvoid (* UpdateFixedVarying) (struct gl2_program_intf **, GLuint, GLvoid *, GLuint, GLuint, - GLboolean); + GLboolean); GLvoid (* GetTextureImageUsage) (struct gl2_program_intf **, GLbitfield *); GLboolean (* IsShaderPresent) (struct gl2_program_intf **, GLenum); + GLvoid (* GetActiveUniform) (struct gl2_program_intf **, GLuint index, GLsizei maxLength, + GLsizei *length, GLint *size, GLenum *type, GLchar *name); + GLuint (* GetActiveUniformMaxLength) (struct gl2_program_intf **); + GLuint (* GetActiveUniformCount) (struct gl2_program_intf **); + GLint (* GetUniformLocation) (struct gl2_program_intf **, const GLchar *name); + GLboolean (* WriteUniform) (struct gl2_program_intf **, GLint loc, GLsizei count, + const GLvoid *data, GLenum type); + GLvoid (* GetActiveAttrib) (struct gl2_program_intf **, GLuint index, GLsizei maxLength, + GLsizei *length, GLint *size, GLenum *type, GLchar *name); + GLuint (* GetActiveAttribMaxLength) (struct gl2_program_intf **); + GLuint (* GetActiveAttribCount) (struct gl2_program_intf **); + GLint (* GetAttribLocation) (struct gl2_program_intf **, const GLchar *name); + GLvoid (* OverrideAttribBinding) (struct gl2_program_intf **, GLuint, const GLchar *); GLvoid (* UpdateVarying) (struct gl2_program_intf **, GLuint, GLfloat *, GLboolean); }; diff --git a/src/mesa/shader/shaderobjects_3dlabs.c b/src/mesa/shader/shaderobjects_3dlabs.c index fa38a1c9af3..73c9e7d4367 100755 --- a/src/mesa/shader/shaderobjects_3dlabs.c +++ b/src/mesa/shader/shaderobjects_3dlabs.c @@ -1,1704 +1,1777 @@ -/*
- * Mesa 3-D graphics library
- * Version: 6.5
- *
- * Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * \file shaderobjects_3dlabs.c
- * shader objects definitions for 3dlabs compiler
- * \author Michal Krol
- */
-
-/* Set this to 1 when we are ready to use 3dlabs' front-end */
-#define USE_3DLABS_FRONTEND 0
-
-#include "imports.h"
-#include "hash.h"
-#include "macros.h"
-#include "shaderobjects.h"
-#include "shaderobjects_3dlabs.h"
-
-#if USE_3DLABS_FRONTEND
-#include "slang_mesa.h"
-#include "Public/ShaderLang.h"
-#else
-#include "slang_link.h"
-#endif
-
-struct gl2_unknown_obj
-{
- GLuint reference_count;
- void (* _destructor) (struct gl2_unknown_intf **);
-};
-
-struct gl2_unknown_impl
-{
- struct gl2_unknown_intf *_vftbl;
- struct gl2_unknown_obj _obj;
-};
-
-static void
-_unknown_destructor (struct gl2_unknown_intf **intf)
-{
-}
-
-static void
-_unknown_AddRef (struct gl2_unknown_intf **intf)
-{
- struct gl2_unknown_impl *impl = (struct gl2_unknown_impl *) intf;
-
- impl->_obj.reference_count++;
-}
-
-static void
-_unknown_Release (struct gl2_unknown_intf **intf)
-{
- struct gl2_unknown_impl *impl = (struct gl2_unknown_impl *) intf;
-
- impl->_obj.reference_count--;
- if (impl->_obj.reference_count == 0)
- {
- impl->_obj._destructor (intf);
- _mesa_free ((void *) intf);
- }
-}
-
-static struct gl2_unknown_intf **
-_unknown_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
-{
- if (uiid == UIID_UNKNOWN)
- {
- (**intf).AddRef (intf);
- return intf;
- }
- return NULL;
-}
-
-static struct gl2_unknown_intf _unknown_vftbl = {
- _unknown_AddRef,
- _unknown_Release,
- _unknown_QueryInterface
-};
-
-static void
-_unknown_constructor (struct gl2_unknown_impl *impl)
-{
- impl->_vftbl = &_unknown_vftbl;
- impl->_obj.reference_count = 1;
- impl->_obj._destructor = _unknown_destructor;
-}
-
-struct gl2_unkinner_obj
-{
- struct gl2_unknown_intf **unkouter;
-};
-
-struct gl2_unkinner_impl
-{
- struct gl2_unknown_intf *_vftbl;
- struct gl2_unkinner_obj _obj;
-};
-
-static void
-_unkinner_destructor (struct gl2_unknown_intf **intf)
-{
-}
-
-static void
-_unkinner_AddRef (struct gl2_unknown_intf **intf)
-{
- struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf;
-
- (**impl->_obj.unkouter).AddRef (impl->_obj.unkouter);
-}
-
-static void
-_unkinner_Release (struct gl2_unknown_intf **intf)
-{
- struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf;
-
- (**impl->_obj.unkouter).Release (impl->_obj.unkouter);
-}
-
-static struct gl2_unknown_intf **
-_unkinner_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
-{
- struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf;
-
- return (**impl->_obj.unkouter).QueryInterface (impl->_obj.unkouter, uiid);
-}
-
-static struct gl2_unknown_intf _unkinner_vftbl = {
- _unkinner_AddRef,
- _unkinner_Release,
- _unkinner_QueryInterface
-};
-
-static void
-_unkinner_constructor (struct gl2_unkinner_impl *impl, struct gl2_unknown_intf **outer)
-{
- impl->_vftbl = &_unkinner_vftbl;
- impl->_obj.unkouter = outer;
-}
-
-struct gl2_generic_obj
-{
- struct gl2_unknown_obj _unknown;
- GLhandleARB name;
- GLboolean delete_status;
- GLcharARB *info_log;
-};
-
-struct gl2_generic_impl
-{
- struct gl2_generic_intf *_vftbl;
- struct gl2_generic_obj _obj;
-};
-
-static void
-_generic_destructor (struct gl2_unknown_intf **intf)
-{
- GET_CURRENT_CONTEXT(ctx);
- struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
-
- _mesa_free ((void *) impl->_obj.info_log);
-
- _glthread_LOCK_MUTEX (ctx->Shared->Mutex);
- _mesa_HashRemove (ctx->Shared->GL2Objects, impl->_obj.name);
- _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex);
-
- _unknown_destructor (intf);
-}
-
-static struct gl2_unknown_intf **
-_generic_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
-{
- if (uiid == UIID_GENERIC)
- {
- (**intf).AddRef (intf);
- return intf;
- }
- return _unknown_QueryInterface (intf, uiid);
-}
-
-static void
-_generic_Delete (struct gl2_generic_intf **intf)
-{
- struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
-
- if (impl->_obj.delete_status == GL_FALSE)
- {
- impl->_obj.delete_status = GL_TRUE;
- (**intf)._unknown.Release ((struct gl2_unknown_intf **) intf);
- }
-}
-
-static GLhandleARB
-_generic_GetName (struct gl2_generic_intf **intf)
-{
- struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
-
- return impl->_obj.name;
-}
-
-static GLboolean
-_generic_GetDeleteStatus (struct gl2_generic_intf **intf)
-{
- struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
-
- return impl->_obj.delete_status;
-}
-
-static const GLcharARB *
-_generic_GetInfoLog (struct gl2_generic_intf **intf)
-{
- struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
-
- return impl->_obj.info_log;
-}
-
-static struct gl2_generic_intf _generic_vftbl = {
- {
- _unknown_AddRef,
- _unknown_Release,
- _generic_QueryInterface
- },
- _generic_Delete,
- NULL, /* abstract GetType */
- _generic_GetName,
- _generic_GetDeleteStatus,
- _generic_GetInfoLog
-};
-
-static void
-_generic_constructor (struct gl2_generic_impl *impl)
-{
- GET_CURRENT_CONTEXT(ctx);
-
- _unknown_constructor ((struct gl2_unknown_impl *) impl);
- impl->_vftbl = &_generic_vftbl;
- impl->_obj._unknown._destructor = _generic_destructor;
- impl->_obj.delete_status = GL_FALSE;
- impl->_obj.info_log = NULL;
-
- _glthread_LOCK_MUTEX (ctx->Shared->Mutex);
- impl->_obj.name = _mesa_HashFindFreeKeyBlock (ctx->Shared->GL2Objects, 1);
- _mesa_HashInsert (ctx->Shared->GL2Objects, impl->_obj.name, (void *) impl);
- _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex);
-}
-
-struct gl2_container_obj
-{
- struct gl2_generic_obj _generic;
- struct gl2_generic_intf ***attached;
- GLuint attached_count;
-};
-
-struct gl2_container_impl
-{
- struct gl2_container_intf *_vftbl;
- struct gl2_container_obj _obj;
-};
-
-static void
-_container_destructor (struct gl2_unknown_intf **intf)
-{
- struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
- GLuint i;
-
- for (i = 0; i < impl->_obj.attached_count; i++)
- {
- struct gl2_generic_intf **x = impl->_obj.attached[i];
- (**x)._unknown.Release ((struct gl2_unknown_intf **) x);
- }
-
- _generic_destructor (intf);
-}
-
-static struct gl2_unknown_intf **
-_container_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
-{
- if (uiid == UIID_CONTAINER)
- {
- (**intf).AddRef (intf);
- return intf;
- }
- return _generic_QueryInterface (intf, uiid);
-}
-
-static GLboolean
-_container_Attach (struct gl2_container_intf **intf, struct gl2_generic_intf **att)
-{
- GET_CURRENT_CONTEXT(ctx);
- struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
- GLuint i;
-
- for (i = 0; i < impl->_obj.attached_count; i++)
- if (impl->_obj.attached[i] == att)
- {
- _mesa_error (ctx, GL_INVALID_OPERATION, "_container_Attach");
- return GL_FALSE;
- }
-
- impl->_obj.attached = (struct gl2_generic_intf ***) _mesa_realloc (impl->_obj.attached,
- impl->_obj.attached_count * sizeof (*impl->_obj.attached), (impl->_obj.attached_count + 1) *
- sizeof (*impl->_obj.attached));
- if (impl->_obj.attached == NULL)
- return GL_FALSE;
-
- impl->_obj.attached[impl->_obj.attached_count] = att;
- impl->_obj.attached_count++;
- (**att)._unknown.AddRef ((struct gl2_unknown_intf **) att);
- return GL_TRUE;
-}
-
-static GLboolean
-_container_Detach (struct gl2_container_intf **intf, struct gl2_generic_intf **att)
-{
- GET_CURRENT_CONTEXT(ctx);
- struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
- GLuint i, j;
-
- for (i = 0; i < impl->_obj.attached_count; i++)
- if (impl->_obj.attached[i] == att)
- {
- for (j = i; j < impl->_obj.attached_count - 1; j++)
- impl->_obj.attached[j] = impl->_obj.attached[j + 1];
- impl->_obj.attached = (struct gl2_generic_intf ***) _mesa_realloc (impl->_obj.attached,
- impl->_obj.attached_count * sizeof (*impl->_obj.attached),
- (impl->_obj.attached_count - 1) * sizeof (*impl->_obj.attached));
- impl->_obj.attached_count--;
- (**att)._unknown.Release ((struct gl2_unknown_intf **) att);
- return GL_TRUE;
- }
-
- _mesa_error (ctx, GL_INVALID_OPERATION, "_container_Detach");
- return GL_FALSE;
-}
-
-static GLsizei
-_container_GetAttachedCount (struct gl2_container_intf **intf)
-{
- struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
-
- return impl->_obj.attached_count;
-}
-
-static struct gl2_generic_intf **
-_container_GetAttached (struct gl2_container_intf **intf, GLuint index)
-{
- struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
-
- (**impl->_obj.attached[index])._unknown.AddRef (
- (struct gl2_unknown_intf **)impl->_obj.attached[index]);
- return impl->_obj.attached[index];
-}
-
-static struct gl2_container_intf _container_vftbl = {
- {
- {
- _unknown_AddRef,
- _unknown_Release,
- _container_QueryInterface
- },
- _generic_Delete,
- NULL, /* abstract GetType */
- _generic_GetName,
- _generic_GetDeleteStatus,
- _generic_GetInfoLog
- },
- _container_Attach,
- _container_Detach,
- _container_GetAttachedCount,
- _container_GetAttached
-};
-
-static void
-_container_constructor (struct gl2_container_impl *impl)
-{
- _generic_constructor ((struct gl2_generic_impl *) impl);
- impl->_vftbl = &_container_vftbl;
- impl->_obj._generic._unknown._destructor = _container_destructor;
- impl->_obj.attached = NULL;
- impl->_obj.attached_count = 0;
-}
-
-struct gl2_3dlabs_shhandle_obj
-{
- struct gl2_unkinner_obj _unknown;
-#if USE_3DLABS_FRONTEND
- ShHandle handle;
-#endif
-};
-
-struct gl2_3dlabs_shhandle_impl
-{
- struct gl2_3dlabs_shhandle_intf *_vftbl;
- struct gl2_3dlabs_shhandle_obj _obj;
-};
-
-static void
-_3dlabs_shhandle_destructor (struct gl2_unknown_intf **intf)
-{
-#if USE_3DLABS_FRONTEND
- struct gl2_3dlabs_shhandle_impl *impl = (struct gl2_3dlabs_shhandle_impl *) intf;
- ShDestruct (impl->_obj.handle);
-#endif
- _unkinner_destructor (intf);
-}
-
-static GLvoid *
-_3dlabs_shhandle_GetShHandle (struct gl2_3dlabs_shhandle_intf **intf)
-{
-#if USE_3DLABS_FRONTEND
- struct gl2_3dlabs_shhandle_impl *impl = (struct gl2_3dlabs_shhandle_impl *) intf;
- return impl->_obj.handle;
-#else
- return NULL;
-#endif
-}
-
-static struct gl2_3dlabs_shhandle_intf _3dlabs_shhandle_vftbl = {
- {
- _unkinner_AddRef,
- _unkinner_Release,
- _unkinner_QueryInterface
- },
- _3dlabs_shhandle_GetShHandle
-};
-
-static void
-_3dlabs_shhandle_constructor (struct gl2_3dlabs_shhandle_impl *impl, struct gl2_unknown_intf **outer)
-{
- _unkinner_constructor ((struct gl2_unkinner_impl *) impl, outer);
- impl->_vftbl = &_3dlabs_shhandle_vftbl;
-#if USE_3DLABS_FRONTEND
- impl->_obj.handle = NULL;
-#endif
-}
-
-struct gl2_shader_obj
-{
- struct gl2_generic_obj _generic;
- struct gl2_3dlabs_shhandle_impl _3dlabs_shhandle;
- GLboolean compile_status;
- GLcharARB *source;
- GLint *offsets;
- GLsizei offset_count;
- slang_translation_unit unit;
-};
-
-struct gl2_shader_impl
-{
- struct gl2_shader_intf *_vftbl;
- struct gl2_shader_obj _obj;
-};
-
-static void
-_shader_destructor (struct gl2_unknown_intf **intf)
-{
- struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
-
- _mesa_free ((void *) impl->_obj.source);
- _mesa_free ((void *) impl->_obj.offsets);
- _3dlabs_shhandle_destructor ((struct gl2_unknown_intf **) &impl->_obj._3dlabs_shhandle._vftbl);
- _generic_destructor (intf);
-}
-
-static struct gl2_unknown_intf **
-_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
-{
-#if USE_3DLABS_FRONTEND
- struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
-#endif
-
- if (uiid == UIID_SHADER)
- {
- (**intf).AddRef (intf);
- return intf;
- }
-#if USE_3DLABS_FRONTEND
- if (uiid == UIID_3DLABS_SHHANDLE)
- {
- (**intf).AddRef (intf);
- return (struct gl2_unknown_intf **) &impl->_obj._3dlabs_shhandle._vftbl;
- }
-#endif
- return _generic_QueryInterface (intf, uiid);
-}
-
-static GLenum
-_shader_GetType (struct gl2_generic_intf **intf)
-{
- return GL_SHADER_OBJECT_ARB;
-}
-
-static GLboolean
-_shader_GetCompileStatus (struct gl2_shader_intf **intf)
-{
- struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
-
- return impl->_obj.compile_status;
-}
-
-static GLvoid
-_shader_SetSource (struct gl2_shader_intf **intf, GLcharARB *src, GLint *off, GLsizei cnt)
-{
- struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
-
- _mesa_free ((void *) impl->_obj.source);
- impl->_obj.source = src;
- _mesa_free ((void *) impl->_obj.offsets);
- impl->_obj.offsets = off;
- impl->_obj.offset_count = cnt;
-}
-
-static const GLcharARB *
-_shader_GetSource (struct gl2_shader_intf **intf)
-{
- struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
-
- return impl->_obj.source;
-}
-
-static GLvoid
-_shader_Compile (struct gl2_shader_intf **intf)
-{
- struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
-#if USE_3DLABS_FRONTEND
- char **strings;
- TBuiltInResource res;
-#else
- slang_unit_type type;
- slang_info_log info_log;
-#endif
-
- impl->_obj.compile_status = GL_FALSE;
- _mesa_free ((void *) impl->_obj._generic.info_log);
- impl->_obj._generic.info_log = NULL;
-
-#if USE_3DLABS_FRONTEND
- /* 3dlabs compiler expects us to feed it with null-terminated string array,
- we've got only one big string with offsets, so we must split it; but when
- there's only one string to deal with, we pass its address directly */
-
- if (impl->_obj.offset_count <= 1)
- strings = &impl->_obj.source;
- else
- {
- GLsizei i, offset = 0;
-
- strings = (char **) _mesa_malloc (impl->_obj.offset_count * sizeof (char *));
- if (strings == NULL)
- return;
-
- for (i = 0; i < impl->_obj.offset_count; i++)
- {
- GLsizei size = impl->_obj.offsets[i] - offset;
-
- strings[i] = (char *) _mesa_malloc ((size + 1) * sizeof (char));
- if (strings[i] == NULL)
- {
- GLsizei j;
-
- for (j = 0; j < i; j++)
- _mesa_free (strings[j]);
- _mesa_free (strings);
- return;
- }
-
- _mesa_memcpy (strings[i], impl->_obj.source + offset, size * sizeof (char));
- strings[i][size] = '\0';
- offset = impl->_obj.offsets[i];
- }
- }
-
- /* TODO set these fields to some REAL numbers */
- res.maxLights = 8;
- res.maxClipPlanes = 6;
- res.maxTextureUnits = 2;
- res.maxTextureCoords = 2;
- res.maxVertexAttribs = 8;
- res.maxVertexUniformComponents = 64;
- res.maxVaryingFloats = 8;
- res.maxVertexTextureImageUnits = 2;
- res.maxCombinedTextureImageUnits = 2;
- res.maxTextureImageUnits = 2;
- res.maxFragmentUniformComponents = 64;
- res.maxDrawBuffers = 1;
-
- if (ShCompile (impl->_obj._3dlabs_shhandle._obj.handle, strings, impl->_obj.offset_count,
- EShOptFull, &res, 0))
- impl->_obj.compile_status = GL_TRUE;
- if (impl->_obj.offset_count > 1)
- {
- GLsizei i;
-
- for (i = 0; i < impl->_obj.offset_count; i++)
- _mesa_free (strings[i]);
- _mesa_free (strings);
- }
-
- impl->_obj._generic.info_log = _mesa_strdup (ShGetInfoLog (
- impl->_obj._3dlabs_shhandle._obj.handle));
-#else
- if (impl->_vftbl->GetSubType (intf) == GL_FRAGMENT_SHADER)
- type = slang_unit_fragment_shader;
- else
- type = slang_unit_vertex_shader;
- slang_info_log_construct (&info_log);
- if (_slang_compile (impl->_obj.source, &impl->_obj.unit, type, &info_log))
- {
- impl->_obj.compile_status = GL_TRUE;
- }
- if (info_log.text != NULL)
- impl->_obj._generic.info_log = _mesa_strdup (info_log.text);
- else
- impl->_obj._generic.info_log = _mesa_strdup ("");
- slang_info_log_destruct (&info_log);
-#endif
-}
-
-static struct gl2_shader_intf _shader_vftbl = {
- {
- {
- _unknown_AddRef,
- _unknown_Release,
- _shader_QueryInterface
- },
- _generic_Delete,
- _shader_GetType,
- _generic_GetName,
- _generic_GetDeleteStatus,
- _generic_GetInfoLog
- },
- NULL, /* abstract GetSubType */
- _shader_GetCompileStatus,
- _shader_SetSource,
- _shader_GetSource,
- _shader_Compile
-};
-
-static void
-_shader_constructor (struct gl2_shader_impl *impl)
-{
- _generic_constructor ((struct gl2_generic_impl *) impl);
- _3dlabs_shhandle_constructor (&impl->_obj._3dlabs_shhandle, (struct gl2_unknown_intf **)
- &impl->_vftbl);
- impl->_vftbl = &_shader_vftbl;
- impl->_obj._generic._unknown._destructor = _shader_destructor;
- impl->_obj.compile_status = GL_FALSE;
- impl->_obj.source = NULL;
- impl->_obj.offsets = NULL;
- impl->_obj.offset_count = 0;
-}
-
-struct gl2_program_obj
-{
- struct gl2_container_obj _container;
- GLboolean link_status;
- GLboolean validate_status;
-#if USE_3DLABS_FRONTEND
- ShHandle linker;
- ShHandle uniforms;
-#endif
- slang_program prog;
-};
-
-struct gl2_program_impl
-{
- struct gl2_program_intf *_vftbl;
- struct gl2_program_obj _obj;
-};
-
-static void
-_program_destructor (struct gl2_unknown_intf **intf)
-{
- struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
-#if USE_3DLABS_FRONTEND
- ShDestruct (impl->_obj.linker);
- ShDestruct (impl->_obj.uniforms);
-#endif
- _container_destructor (intf);
- slang_program_dtr (&impl->_obj.prog);
-}
-
-static struct gl2_unknown_intf **
-_program_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
-{
- if (uiid == UIID_PROGRAM)
- {
- (**intf).AddRef (intf);
- return intf;
- }
- return _container_QueryInterface (intf, uiid);
-}
-
-static GLenum
-_program_GetType (struct gl2_generic_intf **intf)
-{
- return GL_PROGRAM_OBJECT_ARB;
-}
-
-static GLboolean
-_program_Attach (struct gl2_container_intf **intf, struct gl2_generic_intf **att)
-{
- GET_CURRENT_CONTEXT(ctx);
- struct gl2_unknown_intf **sha;
-
- sha = (**att)._unknown.QueryInterface ((struct gl2_unknown_intf **) att, UIID_SHADER);
- if (sha == NULL)
- {
- _mesa_error (ctx, GL_INVALID_OPERATION, "_program_Attach");
- return GL_FALSE;
- }
-
- (**sha).Release (sha);
- return _container_Attach (intf, att);
-}
-
-static GLboolean
-_program_GetLinkStatus (struct gl2_program_intf **intf)
-{
- struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
-
- return impl->_obj.link_status;
-}
-
-static GLboolean
-_program_GetValidateStatus (struct gl2_program_intf **intf)
-{
- struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
-
- return impl->_obj.validate_status;
-}
-
-static GLvoid
-_program_Link (struct gl2_program_intf **intf)
-{
- struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
-#if USE_3DLABS_FRONTEND
- ShHandle *handles;
-#endif
- GLuint i, count;
- slang_translation_unit *units[2];
-
- impl->_obj.link_status = GL_FALSE;
- _mesa_free ((void *) impl->_obj._container._generic.info_log);
- impl->_obj._container._generic.info_log = NULL;
- slang_program_dtr (&impl->_obj.prog);
- slang_program_ctr (&impl->_obj.prog);
-
-#if USE_3DLABS_FRONTEND
- handles = (ShHandle *) _mesa_malloc (impl->_obj._container.attached_count * sizeof (ShHandle));
- if (handles == NULL)
- return;
-
- for (i = 0; i < impl->_obj._container.attached_count; i++)
- {
- struct gl2_generic_intf **gen = impl->_obj._container.attached[i];
- struct gl2_3dlabs_shhandle_intf **sh;
-
- sh = (struct gl2_3dlabs_shhandle_intf **) (**gen)._unknown.QueryInterface (
- (struct gl2_unknown_intf **) gen, UIID_3DLABS_SHHANDLE);
- if (sh != NULL)
- {
- handles[i] = (**sh).GetShHandle (sh);
- (**sh)._unknown.Release ((struct gl2_unknown_intf **) sh);
- }
- else
- {
- _mesa_free (handles);
- return;
- }
- }
-
- if (ShLink (impl->_obj.linker, handles, impl->_obj._container.attached_count,
- impl->_obj.uniforms, NULL, NULL))
- impl->_obj.link_status = GL_TRUE;
-
- impl->_obj._container._generic.info_log = _mesa_strdup (ShGetInfoLog (impl->_obj.linker));
-#else
- count = impl->_obj._container.attached_count;
- if (count == 0 || count > 2)
- return;
- for (i = 0; i < count; i++)
- {
- struct gl2_generic_intf **obj;
- struct gl2_unknown_intf **unk;
- struct gl2_shader_impl *sha;
-
- obj = impl->_obj._container.attached[i];
- unk = (**obj)._unknown.QueryInterface ((struct gl2_unknown_intf **) obj, UIID_SHADER);
- (**obj)._unknown.Release ((struct gl2_unknown_intf **) obj);
- if (unk == NULL)
- return;
- sha = (struct gl2_shader_impl *) unk;
- units[i] = &sha->_obj.unit;
- (**unk).Release (unk);
- }
-
- impl->_obj.link_status = _slang_link (&impl->_obj.prog, units, count);
- if (impl->_obj.link_status)
- impl->_obj._container._generic.info_log = _mesa_strdup ("Link OK.\n");
- else
- impl->_obj._container._generic.info_log = _mesa_strdup ("Link failed.\n");
-#endif
-}
-
-static GLvoid
-_program_Validate (struct gl2_program_intf **intf)
-{
- struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
-
- impl->_obj.validate_status = GL_FALSE;
- _mesa_free ((void *) impl->_obj._container._generic.info_log);
- impl->_obj._container._generic.info_log = NULL;
-
- /* TODO validate */
-}
-
-static GLvoid
-write_common_fixed (slang_program *pro, GLuint index, const GLvoid *src, GLuint off, GLuint size)
-{
- GLuint i;
-
- for (i = 0; i < SLANG_SHADER_MAX; i++)
- {
- GLuint addr;
-
- addr = pro->common_fixed_entries[i][index];
- if (addr != ~0)
- {
- GLubyte *dst;
-
- dst = (GLubyte *) pro->machines[i]->mem + addr + off * size;
- _mesa_memcpy (dst, src, size);
- }
- }
-}
-
-static GLvoid
-write_common_fixed_mat4 (slang_program *pro, GLmatrix *matrix, GLuint off, GLuint i, GLuint ii,
- GLuint it, GLuint iit)
-{
- GLfloat mat[16];
-
- /* we want inverse matrix */
- if (!matrix->inv)
- {
- /* allocate inverse matrix and make it dirty */
- _math_matrix_alloc_inv (matrix);
- _math_matrix_loadf (matrix, matrix->m);
- }
- _math_matrix_analyse (matrix);
-
- write_common_fixed (pro, i, matrix->m, off, 16 * sizeof (GLfloat));
-
- /* inverse */
- write_common_fixed (pro, ii, matrix->inv, off, 16 * sizeof (GLfloat));
-
- /* transpose */
- _math_transposef (mat, matrix->m);
- write_common_fixed (pro, it, mat, off, 16 * sizeof (GLfloat));
-
- /* inverse transpose */
- _math_transposef (mat, matrix->inv);
- write_common_fixed (pro, iit, mat, off, 16 * sizeof (GLfloat));
-}
-
-static GLvoid
-write_common_fixed_material (GLcontext *ctx, slang_program *pro, GLuint i, GLuint e, GLuint a,
- GLuint d, GLuint sp, GLuint sh)
-{
- GLfloat v[17];
-
- COPY_4FV(v, ctx->Light.Material.Attrib[e]);
- COPY_4FV((v + 4), ctx->Light.Material.Attrib[a]);
- COPY_4FV((v + 8), ctx->Light.Material.Attrib[d]);
- COPY_4FV((v + 12), ctx->Light.Material.Attrib[sp]);
- v[16] = ctx->Light.Material.Attrib[sh][0];
- write_common_fixed (pro, i, v, 0, 17 * sizeof (GLfloat));
-}
-
-static GLvoid
-write_common_fixed_light_model_product (GLcontext *ctx, slang_program *pro, GLuint i, GLuint e,
- GLuint a)
-{
- GLfloat v[4];
-
- SCALE_4V(v, ctx->Light.Material.Attrib[a], ctx->Light.Model.Ambient);
- ACC_4V(v, ctx->Light.Material.Attrib[e]);
- write_common_fixed (pro, i, v, 0, 4 * sizeof (GLfloat));
-}
-
-static GLvoid
-write_common_fixed_light_product (GLcontext *ctx, slang_program *pro, GLuint off, GLuint i, GLuint a,
- GLuint d, GLuint s)
-{
- GLfloat v[12];
-
- SCALE_4V(v, ctx->Light.Light[off].Ambient, ctx->Light.Material.Attrib[a]);
- SCALE_4V((v + 4), ctx->Light.Light[off].Diffuse, ctx->Light.Material.Attrib[d]);
- SCALE_4V((v + 8), ctx->Light.Light[off].Specular, ctx->Light.Material.Attrib[s]);
- write_common_fixed (pro, i, v, off, 12 * sizeof (GLfloat));
-}
-
-static GLvoid
-_program_UpdateFixedUniforms (struct gl2_program_intf **intf)
-{
- GET_CURRENT_CONTEXT(ctx);
- struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
- slang_program *pro = &impl->_obj.prog;
- GLuint i;
- GLfloat v[29];
- GLfloat *p;
-
- /* MODELVIEW matrix */
- write_common_fixed_mat4 (pro, ctx->ModelviewMatrixStack.Top, 0,
- SLANG_COMMON_FIXED_MODELVIEWMATRIX,
- SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSE,
- SLANG_COMMON_FIXED_MODELVIEWMATRIXTRANSPOSE,
- SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSETRANSPOSE);
-
- /* PROJECTION matrix */
- write_common_fixed_mat4 (pro, ctx->ProjectionMatrixStack.Top, 0,
- SLANG_COMMON_FIXED_PROJECTIONMATRIX,
- SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSE,
- SLANG_COMMON_FIXED_PROJECTIONMATRIXTRANSPOSE,
- SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSETRANSPOSE);
-
- /* MVP matrix */
- write_common_fixed_mat4 (pro, &ctx->_ModelProjectMatrix, 0,
- SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIX,
- SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSE,
- SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXTRANSPOSE,
- SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSETRANSPOSE);
-
- for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++)
- {
- /* TEXTURE matrix */
- write_common_fixed_mat4 (pro, ctx->TextureMatrixStack[i].Top, i,
- SLANG_COMMON_FIXED_TEXTUREMATRIX,
- SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSE,
- SLANG_COMMON_FIXED_TEXTUREMATRIXTRANSPOSE,
- SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSETRANSPOSE);
-
- /* EYE_PLANE texture-coordinate generation */
- write_common_fixed (pro, SLANG_COMMON_FIXED_EYEPLANES, ctx->Texture.Unit[i].EyePlaneS,
- i, 4 * sizeof (GLfloat));
- write_common_fixed (pro, SLANG_COMMON_FIXED_EYEPLANET, ctx->Texture.Unit[i].EyePlaneT,
- i, 4 * sizeof (GLfloat));
- write_common_fixed (pro, SLANG_COMMON_FIXED_EYEPLANER, ctx->Texture.Unit[i].EyePlaneR,
- i, 4 * sizeof (GLfloat));
- write_common_fixed (pro, SLANG_COMMON_FIXED_EYEPLANEQ, ctx->Texture.Unit[i].EyePlaneQ,
- i, 4 * sizeof (GLfloat));
-
- /* OBJECT_PLANE texture-coordinate generation */
- write_common_fixed (pro, SLANG_COMMON_FIXED_OBJECTPLANES, ctx->Texture.Unit[i].ObjectPlaneS,
- i, 4 * sizeof (GLfloat));
- write_common_fixed (pro, SLANG_COMMON_FIXED_OBJECTPLANET, ctx->Texture.Unit[i].ObjectPlaneT,
- i, 4 * sizeof (GLfloat));
- write_common_fixed (pro, SLANG_COMMON_FIXED_OBJECTPLANER, ctx->Texture.Unit[i].ObjectPlaneR,
- i, 4 * sizeof (GLfloat));
- write_common_fixed (pro, SLANG_COMMON_FIXED_OBJECTPLANEQ, ctx->Texture.Unit[i].ObjectPlaneQ,
- i, 4 * sizeof (GLfloat));
- }
-
- /* NORMAL matrix - upper 3x3 inverse transpose of MODELVIEW matrix */
- p = ctx->ModelviewMatrixStack.Top->inv;
- v[0] = p[0];
- v[1] = p[4];
- v[2] = p[8];
- v[3] = p[1];
- v[4] = p[5];
- v[5] = p[9];
- v[6] = p[2];
- v[7] = p[6];
- v[8] = p[10];
- write_common_fixed (pro, SLANG_COMMON_FIXED_NORMALMATRIX, v, 0, 9 * sizeof (GLfloat));
-
- /* normal scale */
- write_common_fixed (pro, SLANG_COMMON_FIXED_NORMALSCALE, &ctx->_ModelViewInvScale, 0, sizeof (GLfloat));
-
- /* depth range parameters */
- v[0] = ctx->Viewport.Near;
- v[1] = ctx->Viewport.Far;
- v[2] = ctx->Viewport.Far - ctx->Viewport.Near;
- write_common_fixed (pro, SLANG_COMMON_FIXED_DEPTHRANGE, v, 0, 3 * sizeof (GLfloat));
-
- /* CLIP_PLANEi */
- for (i = 0; i < ctx->Const.MaxClipPlanes; i++)
- {
- write_common_fixed (pro, SLANG_COMMON_FIXED_CLIPPLANE, ctx->Transform.EyeUserPlane[i], i,
- 4 * sizeof (GLfloat));
- }
-
- /* point parameters */
- v[0] = ctx->Point.Size;
- v[1] = ctx->Point.MinSize;
- v[2] = ctx->Point.MaxSize;
- v[3] = ctx->Point.Threshold;
- COPY_3FV((v + 4), ctx->Point.Params);
- write_common_fixed (pro, SLANG_COMMON_FIXED_POINT, v, 0, 7 * sizeof (GLfloat));
-
- /* material parameters */
- write_common_fixed_material (ctx, pro, SLANG_COMMON_FIXED_FRONTMATERIAL,
- MAT_ATTRIB_FRONT_EMISSION,
- MAT_ATTRIB_FRONT_AMBIENT,
- MAT_ATTRIB_FRONT_DIFFUSE,
- MAT_ATTRIB_FRONT_SPECULAR,
- MAT_ATTRIB_FRONT_SHININESS);
- write_common_fixed_material (ctx, pro, SLANG_COMMON_FIXED_BACKMATERIAL,
- MAT_ATTRIB_BACK_EMISSION,
- MAT_ATTRIB_BACK_AMBIENT,
- MAT_ATTRIB_BACK_DIFFUSE,
- MAT_ATTRIB_BACK_SPECULAR,
- MAT_ATTRIB_BACK_SHININESS);
-
- for (i = 0; i < ctx->Const.MaxLights; i++)
- {
- /* light source parameters */
- COPY_4FV(v, ctx->Light.Light[i].Ambient);
- COPY_4FV((v + 4), ctx->Light.Light[i].Diffuse);
- COPY_4FV((v + 8), ctx->Light.Light[i].Specular);
- COPY_4FV((v + 12), ctx->Light.Light[i].EyePosition);
- COPY_2FV((v + 16), ctx->Light.Light[i].EyePosition);
- v[18] = ctx->Light.Light[i].EyePosition[2] + 1.0f;
- NORMALIZE_3FV((v + 16));
- v[19] = 0.0f;
- COPY_3V((v + 20), ctx->Light.Light[i].EyeDirection);
- v[23] = ctx->Light.Light[i].SpotExponent;
- v[24] = ctx->Light.Light[i].SpotCutoff;
- v[25] = ctx->Light.Light[i]._CosCutoffNeg;
- v[26] = ctx->Light.Light[i].ConstantAttenuation;
- v[27] = ctx->Light.Light[i].LinearAttenuation;
- v[28] = ctx->Light.Light[i].QuadraticAttenuation;
- write_common_fixed (pro, SLANG_COMMON_FIXED_LIGHTSOURCE, v, i, 29 * sizeof (GLfloat));
-
- /* light product */
- write_common_fixed_light_product (ctx, pro, i, SLANG_COMMON_FIXED_FRONTLIGHTPRODUCT,
- MAT_ATTRIB_FRONT_AMBIENT,
- MAT_ATTRIB_FRONT_DIFFUSE,
- MAT_ATTRIB_FRONT_SPECULAR);
- write_common_fixed_light_product (ctx, pro, i, SLANG_COMMON_FIXED_BACKLIGHTPRODUCT,
- MAT_ATTRIB_BACK_AMBIENT,
- MAT_ATTRIB_BACK_DIFFUSE,
- MAT_ATTRIB_BACK_SPECULAR);
- }
-
- /* light model parameters */
- write_common_fixed (pro, SLANG_COMMON_FIXED_LIGHTMODEL, ctx->Light.Model.Ambient, 0, 4 * sizeof (GLfloat));
-
- /* light model product */
- write_common_fixed_light_model_product (ctx, pro, SLANG_COMMON_FIXED_FRONTLIGHTMODELPRODUCT,
- MAT_ATTRIB_FRONT_EMISSION,
- MAT_ATTRIB_FRONT_AMBIENT);
- write_common_fixed_light_model_product (ctx, pro, SLANG_COMMON_FIXED_BACKLIGHTMODELPRODUCT,
- MAT_ATTRIB_BACK_EMISSION,
- MAT_ATTRIB_BACK_AMBIENT);
-
- /* TEXTURE_ENV_COLOR */
- for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++)
- {
- write_common_fixed (pro, SLANG_COMMON_FIXED_TEXTUREENVCOLOR, ctx->Texture.Unit[i].EnvColor,
- i, 4 * sizeof (GLfloat));
- }
-
- /* fog parameters */
- COPY_4FV(v, ctx->Fog.Color);
- v[4] = ctx->Fog.Density;
- v[5] = ctx->Fog.Start;
- v[6] = ctx->Fog.End;
- v[7] = ctx->Fog._Scale;
- write_common_fixed (pro, SLANG_COMMON_FIXED_FOG, v, 0, 8 * sizeof (GLfloat));
-}
-
-static GLvoid
-_program_UpdateFixedAttribute (struct gl2_program_intf **intf, GLuint index, GLvoid *data,
- GLuint offset, GLuint size, GLboolean write)
-{
- struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
- slang_program *pro = &impl->_obj.prog;
- GLuint addr;
-
- addr = pro->vertex_fixed_entries[index];
- if (addr != ~0)
- {
- GLubyte *mem;
-
- mem = (GLubyte *) pro->machines[SLANG_SHADER_VERTEX]->mem + addr + offset * size;
- if (write)
- _mesa_memcpy (mem, data, size);
- else
- _mesa_memcpy (data, mem, size);
- }
-}
-
-static GLvoid
-_program_UpdateFixedVarying (struct gl2_program_intf **intf, GLuint index, GLvoid *data,
- GLuint offset, GLuint size, GLboolean write)
-{
- struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
- slang_program *pro = &impl->_obj.prog;
- GLuint addr;
-
- addr = pro->fragment_fixed_entries[index];
- if (addr != ~0)
- {
- GLubyte *mem;
-
- mem = (GLubyte *) pro->machines[SLANG_SHADER_FRAGMENT]->mem + addr + offset * size;
- if (write)
- _mesa_memcpy (mem, data, size);
- else
- _mesa_memcpy (data, mem, size);
- }
-}
-
-static GLvoid
-_program_GetTextureImageUsage (struct gl2_program_intf **intf, GLbitfield *teximageusage)
-{
- GET_CURRENT_CONTEXT(ctx);
- struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
- slang_program *pro = &impl->_obj.prog;
- GLuint i;
-
- for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++)
- teximageusage[i] = 0;
-
- for (i = 0; i < pro->texture_usage.count; i++)
- {
- GLuint n, addr, j;
-
- n = slang_export_data_quant_elements (pro->texture_usage.table[i].quant);
- addr = pro->texture_usage.table[i].frag_address;
- for (j = 0; j < n; j++)
- {
- GLubyte *mem;
- GLuint image;
-
- mem = (GLubyte *) pro->machines[SLANG_SHADER_FRAGMENT]->mem + addr + j * 4;
- image = (GLuint) *((GLfloat *) mem);
- if (image >= 0 && image < ctx->Const.MaxTextureImageUnits)
- {
- switch (slang_export_data_quant_type (pro->texture_usage.table[i].quant))
- {
- case GL_SAMPLER_1D_ARB:
- case GL_SAMPLER_1D_SHADOW_ARB:
- teximageusage[image] |= TEXTURE_1D_BIT;
- break;
- case GL_SAMPLER_2D_ARB:
- case GL_SAMPLER_2D_SHADOW_ARB:
- teximageusage[image] |= TEXTURE_2D_BIT;
- break;
- case GL_SAMPLER_3D_ARB:
- teximageusage[image] |= TEXTURE_3D_BIT;
- break;
- case GL_SAMPLER_CUBE_ARB:
- teximageusage[image] |= TEXTURE_CUBE_BIT;
- break;
- }
- }
- }
- }
-
- /* TODO: make sure that for 0<=i<=MaxTextureImageUint bitcount(teximageuint[i])<=0 */
-}
-
-static GLboolean
-_program_IsShaderPresent (struct gl2_program_intf **intf, GLenum subtype)
-{
- struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
- slang_program *pro = &impl->_obj.prog;
-
- switch (subtype)
- {
- case GL_VERTEX_SHADER_ARB:
- return pro->machines[SLANG_SHADER_VERTEX] != NULL;
- case GL_FRAGMENT_SHADER_ARB:
- return pro->machines[SLANG_SHADER_FRAGMENT] != NULL;
- default:
- return GL_FALSE;
- }
-}
-
-static GLvoid
-_program_UpdateVarying (struct gl2_program_intf **intf, GLuint index, GLfloat *value,
- GLboolean vert)
-{
- struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
- slang_program *pro = &impl->_obj.prog;
- GLuint addr;
-
- if (index >= pro->varyings.total)
- return;
- if (vert)
- addr = pro->varyings.slots[index].vert_addr / 4;
- else
- addr = pro->varyings.slots[index].frag_addr / 4;
- if (addr != ~0)
- {
- if (vert)
- *value = pro->machines[SLANG_SHADER_VERTEX]->mem[addr]._float;
- else
- pro->machines[SLANG_SHADER_FRAGMENT]->mem[addr]._float = *value;
- }
-}
-
-static struct gl2_program_intf _program_vftbl = {
- {
- {
- {
- _unknown_AddRef,
- _unknown_Release,
- _program_QueryInterface
- },
- _generic_Delete,
- _program_GetType,
- _generic_GetName,
- _generic_GetDeleteStatus,
- _generic_GetInfoLog
- },
- _program_Attach,
- _container_Detach,
- _container_GetAttachedCount,
- _container_GetAttached
- },
- _program_GetLinkStatus,
- _program_GetValidateStatus,
- _program_Link,
- _program_Validate,
- _program_UpdateFixedUniforms,
- _program_UpdateFixedAttribute,
- _program_UpdateFixedVarying,
- _program_GetTextureImageUsage,
- _program_IsShaderPresent,
- _program_UpdateVarying
-};
-
-static void
-_program_constructor (struct gl2_program_impl *impl)
-{
- _container_constructor ((struct gl2_container_impl *) impl);
- impl->_vftbl = &_program_vftbl;
- impl->_obj._container._generic._unknown._destructor = _program_destructor;
- impl->_obj.link_status = GL_FALSE;
- impl->_obj.validate_status = GL_FALSE;
-#if USE_3DLABS_FRONTEND
- impl->_obj.linker = ShConstructLinker (EShExVertexFragment, 0);
- impl->_obj.uniforms = ShConstructUniformMap ();
-#endif
- slang_program_ctr (&impl->_obj.prog);
-}
-
-struct gl2_fragment_shader_obj
-{
- struct gl2_shader_obj _shader;
-};
-
-struct gl2_fragment_shader_impl
-{
- struct gl2_fragment_shader_intf *_vftbl;
- struct gl2_fragment_shader_obj _obj;
-};
-
-static void
-_fragment_shader_destructor (struct gl2_unknown_intf **intf)
-{
- struct gl2_fragment_shader_impl *impl = (struct gl2_fragment_shader_impl *) intf;
-
- (void) impl;
- /* TODO free fragment shader data */
-
- _shader_destructor (intf);
-}
-
-static struct gl2_unknown_intf **
-_fragment_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
-{
- if (uiid == UIID_FRAGMENT_SHADER)
- {
- (**intf).AddRef (intf);
- return intf;
- }
- return _shader_QueryInterface (intf, uiid);
-}
-
-static GLenum
-_fragment_shader_GetSubType (struct gl2_shader_intf **intf)
-{
- return GL_FRAGMENT_SHADER_ARB;
-}
-
-static struct gl2_fragment_shader_intf _fragment_shader_vftbl = {
- {
- {
- {
- _unknown_AddRef,
- _unknown_Release,
- _fragment_shader_QueryInterface
- },
- _generic_Delete,
- _shader_GetType,
- _generic_GetName,
- _generic_GetDeleteStatus,
- _generic_GetInfoLog
- },
- _fragment_shader_GetSubType,
- _shader_GetCompileStatus,
- _shader_SetSource,
- _shader_GetSource,
- _shader_Compile
- }
-};
-
-static void
-_fragment_shader_constructor (struct gl2_fragment_shader_impl *impl)
-{
- _shader_constructor ((struct gl2_shader_impl *) impl);
- impl->_vftbl = &_fragment_shader_vftbl;
- impl->_obj._shader._generic._unknown._destructor = _fragment_shader_destructor;
-#if USE_3DLABS_FRONTEND
- impl->_obj._shader._3dlabs_shhandle._obj.handle = ShConstructCompiler (EShLangFragment, 0);
-#endif
-}
-
-struct gl2_vertex_shader_obj
-{
- struct gl2_shader_obj _shader;
-};
-
-struct gl2_vertex_shader_impl
-{
- struct gl2_vertex_shader_intf *_vftbl;
- struct gl2_vertex_shader_obj _obj;
-};
-
-static void
-_vertex_shader_destructor (struct gl2_unknown_intf **intf)
-{
- struct gl2_vertex_shader_impl *impl = (struct gl2_vertex_shader_impl *) intf;
-
- (void) impl;
- /* TODO free vertex shader data */
-
- _shader_destructor (intf);
-}
-
-static struct gl2_unknown_intf **
-_vertex_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
-{
- if (uiid == UIID_VERTEX_SHADER)
- {
- (**intf).AddRef (intf);
- return intf;
- }
- return _shader_QueryInterface (intf, uiid);
-}
-
-static GLenum
-_vertex_shader_GetSubType (struct gl2_shader_intf **intf)
-{
- return GL_VERTEX_SHADER_ARB;
-}
-
-static struct gl2_vertex_shader_intf _vertex_shader_vftbl = {
- {
- {
- {
- _unknown_AddRef,
- _unknown_Release,
- _vertex_shader_QueryInterface
- },
- _generic_Delete,
- _shader_GetType,
- _generic_GetName,
- _generic_GetDeleteStatus,
- _generic_GetInfoLog
- },
- _vertex_shader_GetSubType,
- _shader_GetCompileStatus,
- _shader_SetSource,
- _shader_GetSource,
- _shader_Compile
- }
-};
-
-static void
-_vertex_shader_constructor (struct gl2_vertex_shader_impl *impl)
-{
- _shader_constructor ((struct gl2_shader_impl *) impl);
- impl->_vftbl = &_vertex_shader_vftbl;
- impl->_obj._shader._generic._unknown._destructor = _vertex_shader_destructor;
-#if USE_3DLABS_FRONTEND
- impl->_obj._shader._3dlabs_shhandle._obj.handle = ShConstructCompiler (EShLangVertex, 0);
-#endif
-}
-
-GLhandleARB
-_mesa_3dlabs_create_shader_object (GLenum shaderType)
-{
- switch (shaderType)
- {
- case GL_FRAGMENT_SHADER_ARB:
- {
- struct gl2_fragment_shader_impl *x = (struct gl2_fragment_shader_impl *)
- _mesa_malloc (sizeof (struct gl2_fragment_shader_impl));
-
- if (x != NULL)
- {
- _fragment_shader_constructor (x);
- return x->_obj._shader._generic.name;
- }
- }
- break;
- case GL_VERTEX_SHADER_ARB:
- {
- struct gl2_vertex_shader_impl *x = (struct gl2_vertex_shader_impl *)
- _mesa_malloc (sizeof (struct gl2_vertex_shader_impl));
-
- if (x != NULL)
- {
- _vertex_shader_constructor (x);
- return x->_obj._shader._generic.name;
- }
- }
- break;
- }
-
- return 0;
-}
-
-GLhandleARB
-_mesa_3dlabs_create_program_object (void)
-{
- struct gl2_program_impl *x = (struct gl2_program_impl *)
- _mesa_malloc (sizeof (struct gl2_program_impl));
-
- if (x != NULL)
- {
- _program_constructor (x);
- return x->_obj._container._generic.name;
- }
-
- return 0;
-}
-
-#include "slang_assemble.h"
-#include "slang_execute.h"
-
-int _slang_fetch_discard (struct gl2_program_intf **pro, GLboolean *val)
-{
- struct gl2_program_impl *impl;
-
- impl = (struct gl2_program_impl *) pro;
- *val = impl->_obj.prog.machines[SLANG_SHADER_FRAGMENT]->kill ? GL_TRUE : GL_FALSE;
- return 1;
-}
-
-static GLvoid exec_shader (struct gl2_program_intf **pro, GLuint i)
-{
- struct gl2_program_impl *impl;
- slang_program *p;
-
- impl = (struct gl2_program_impl *) pro;
- p = &impl->_obj.prog;
-
- slang_machine_init (p->machines[i]);
- p->machines[i]->ip = p->code[i][SLANG_COMMON_CODE_MAIN];
-
- _slang_execute2 (p->assemblies[i], p->machines[i]);
-}
-
-GLvoid _slang_exec_fragment_shader (struct gl2_program_intf **pro)
-{
- exec_shader (pro, SLANG_SHADER_FRAGMENT);
-}
-
-GLvoid _slang_exec_vertex_shader (struct gl2_program_intf **pro)
-{
- exec_shader (pro, SLANG_SHADER_VERTEX);
-}
-
-GLint _slang_get_uniform_location (struct gl2_program_intf **pro, const char *name)
-{
- struct gl2_program_impl *impl;
- slang_uniform_bindings *bind;
- GLuint i;
-
- impl = (struct gl2_program_impl *) pro;
- bind = &impl->_obj.prog.uniforms;
- for (i = 0; i < bind->count; i++)
- if (_mesa_strcmp (bind->table[i].name, name) == 0)
- return i;
- return -1;
-}
-
-GLboolean _slang_write_uniform (struct gl2_program_intf **pro, GLint loc, GLsizei count,
- const GLvoid *data, GLenum type)
-{
- struct gl2_program_impl *impl;
- slang_uniform_bindings *bind;
- slang_uniform_binding *b;
- GLuint i;
- GLboolean convert_float_to_bool = GL_FALSE;
- GLboolean convert_int_to_bool = GL_FALSE;
- GLboolean convert_int_to_float = GL_FALSE;
- GLboolean types_match = GL_FALSE;
-
- if (loc == -1)
- return GL_TRUE;
-
- impl = (struct gl2_program_impl *) pro;
- bind = &impl->_obj.prog.uniforms;
- if (loc >= bind->count)
- return GL_FALSE;
-
- b = &bind->table[loc];
- /* TODO: check sizes */
- if (slang_export_data_quant_struct (b->quant))
- return GL_FALSE;
-
- switch (slang_export_data_quant_type (b->quant))
- {
- case GL_BOOL_ARB:
- types_match = (type == GL_FLOAT) || (type == GL_INT);
- if (type == GL_FLOAT)
- convert_float_to_bool = GL_TRUE;
- else
- convert_int_to_bool = GL_TRUE;
- break;
- case GL_BOOL_VEC2_ARB:
- types_match = (type == GL_FLOAT_VEC2_ARB) || (type == GL_INT_VEC2_ARB);
- if (type == GL_FLOAT_VEC2_ARB)
- convert_float_to_bool = GL_TRUE;
- else
- convert_int_to_bool = GL_TRUE;
- break;
- case GL_BOOL_VEC3_ARB:
- types_match = (type == GL_FLOAT_VEC3_ARB) || (type == GL_INT_VEC3_ARB);
- if (type == GL_FLOAT_VEC3_ARB)
- convert_float_to_bool = GL_TRUE;
- else
- convert_int_to_bool = GL_TRUE;
- break;
- case GL_BOOL_VEC4_ARB:
- types_match = (type == GL_FLOAT_VEC4_ARB) || (type == GL_INT_VEC4_ARB);
- if (type == GL_FLOAT_VEC4_ARB)
- convert_float_to_bool = GL_TRUE;
- else
- convert_int_to_bool = GL_TRUE;
- break;
- case GL_SAMPLER_1D_ARB:
- case GL_SAMPLER_2D_ARB:
- case GL_SAMPLER_3D_ARB:
- case GL_SAMPLER_CUBE_ARB:
- case GL_SAMPLER_1D_SHADOW_ARB:
- case GL_SAMPLER_2D_SHADOW_ARB:
- types_match = (type == GL_INT);
- break;
- default:
- types_match = (type == slang_export_data_quant_type (b->quant));
- break;
- }
-
- if (!types_match)
- return GL_FALSE;
-
- switch (type)
- {
- case GL_INT:
- case GL_INT_VEC2_ARB:
- case GL_INT_VEC3_ARB:
- case GL_INT_VEC4_ARB:
- convert_int_to_float = GL_TRUE;
- break;
- }
-
- if (convert_float_to_bool)
- {
- for (i = 0; i < SLANG_SHADER_MAX; i++)
- if (b->address[i] != ~0)
- {
- const GLfloat *src = (GLfloat *) (data);
- GLfloat *dst = (GLfloat *) (&impl->_obj.prog.machines[i]->mem[b->address[i] / 4]);
- GLuint j;
- GLuint total = count * slang_export_data_quant_components (b->quant);
-
- for (j = 0; j < total; j++)
- dst[j] = src[j] != 0.0f ? 1.0f : 0.0f;
- }
- }
- else if (convert_int_to_bool)
- {
- for (i = 0; i < SLANG_SHADER_MAX; i++)
- if (b->address[i] != ~0)
- {
- const GLuint *src = (GLuint *) (data);
- GLfloat *dst = (GLfloat *) (&impl->_obj.prog.machines[i]->mem[b->address[i] / 4]);
- GLuint j;
- GLuint total = count * slang_export_data_quant_components (b->quant);
-
- for (j = 0; j < total; j++)
- dst[j] = src[j] ? 1.0f : 0.0f;
- }
- }
- else if (convert_int_to_float)
- {
- for (i = 0; i < SLANG_SHADER_MAX; i++)
- if (b->address[i] != ~0)
- {
- const GLuint *src = (GLuint *) (data);
- GLfloat *dst = (GLfloat *) (&impl->_obj.prog.machines[i]->mem[b->address[i] / 4]);
- GLuint j;
- GLuint total = count * slang_export_data_quant_components (b->quant);
-
- for (j = 0; j < total; j++)
- dst[j] = (GLfloat) src[j];
- }
- }
- else
- {
- for (i = 0; i < SLANG_SHADER_MAX; i++)
- if (b->address[i] != ~0)
- {
- _mesa_memcpy (&impl->_obj.prog.machines[i]->mem[b->address[i] / 4], data,
- count * slang_export_data_quant_size (b->quant));
- }
- }
- return GL_TRUE;
-}
-
-GLuint _slang_get_active_uniform_count (struct gl2_program_intf **pro)
-{
- struct gl2_program_impl *impl;
-
- impl = (struct gl2_program_impl *) pro;
- return impl->_obj.prog.active_uniforms.count;
-}
-
-GLuint _slang_get_active_uniform_max_length (struct gl2_program_intf **pro)
-{
- struct gl2_program_impl *impl;
- GLuint i, len = 0;
-
- impl = (struct gl2_program_impl *) pro;
- for (i = 0; i < impl->_obj.prog.active_uniforms.count; i++)
- {
- GLuint n = _mesa_strlen (impl->_obj.prog.active_uniforms.table[i].name);
- if (n > len)
- len = n;
- }
- return len;
-}
-
-GLvoid _slang_get_active_uniform (struct gl2_program_intf **pro, GLuint index, GLsizei maxLength,
- GLsizei *length, GLint *size, GLenum *type, char *name)
-{
- struct gl2_program_impl *impl;
- slang_active_uniform *u;
- GLsizei len;
-
- impl = (struct gl2_program_impl *) pro;
- u = &impl->_obj.prog.active_uniforms.table[index];
-
- len = _mesa_strlen (u->name);
- if (len >= maxLength)
- len = maxLength - 1;
- _mesa_memcpy (name, u->name, len);
- name[len] = '\0';
- if (length != NULL)
- *length = len;
- *type = slang_export_data_quant_type (u->quant);
- *size = slang_export_data_quant_elements (u->quant);
-}
-
-void
-_mesa_init_shaderobjects_3dlabs (GLcontext *ctx)
-{
-#if USE_3DLABS_FRONTEND
- _glslang_3dlabs_InitProcess ();
- _glslang_3dlabs_ShInitialize ();
-#endif
-}
-
+/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file shaderobjects_3dlabs.c + * shader objects definitions for 3dlabs compiler + * \author Michal Krol + */ + +/* Set this to 1 when we are ready to use 3dlabs' front-end */ +#define USE_3DLABS_FRONTEND 0 + +#include "imports.h" +#include "hash.h" +#include "macros.h" +#include "shaderobjects.h" +#include "shaderobjects_3dlabs.h" + +#if USE_3DLABS_FRONTEND +#include "slang_mesa.h" +#include "Public/ShaderLang.h" +#else +#include "slang_link.h" +#endif + +struct gl2_unknown_obj +{ + GLuint reference_count; + void (* _destructor) (struct gl2_unknown_intf **); +}; + +struct gl2_unknown_impl +{ + struct gl2_unknown_intf *_vftbl; + struct gl2_unknown_obj _obj; +}; + +static void +_unknown_destructor (struct gl2_unknown_intf **intf) +{ +} + +static void +_unknown_AddRef (struct gl2_unknown_intf **intf) +{ + struct gl2_unknown_impl *impl = (struct gl2_unknown_impl *) intf; + + impl->_obj.reference_count++; +} + +static void +_unknown_Release (struct gl2_unknown_intf **intf) +{ + struct gl2_unknown_impl *impl = (struct gl2_unknown_impl *) intf; + + impl->_obj.reference_count--; + if (impl->_obj.reference_count == 0) + { + impl->_obj._destructor (intf); + _mesa_free ((void *) intf); + } +} + +static struct gl2_unknown_intf ** +_unknown_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) +{ + if (uiid == UIID_UNKNOWN) + { + (**intf).AddRef (intf); + return intf; + } + return NULL; +} + +static struct gl2_unknown_intf _unknown_vftbl = { + _unknown_AddRef, + _unknown_Release, + _unknown_QueryInterface +}; + +static void +_unknown_constructor (struct gl2_unknown_impl *impl) +{ + impl->_vftbl = &_unknown_vftbl; + impl->_obj.reference_count = 1; + impl->_obj._destructor = _unknown_destructor; +} + +struct gl2_unkinner_obj +{ + struct gl2_unknown_intf **unkouter; +}; + +struct gl2_unkinner_impl +{ + struct gl2_unknown_intf *_vftbl; + struct gl2_unkinner_obj _obj; +}; + +static void +_unkinner_destructor (struct gl2_unknown_intf **intf) +{ +} + +static void +_unkinner_AddRef (struct gl2_unknown_intf **intf) +{ + struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf; + + (**impl->_obj.unkouter).AddRef (impl->_obj.unkouter); +} + +static void +_unkinner_Release (struct gl2_unknown_intf **intf) +{ + struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf; + + (**impl->_obj.unkouter).Release (impl->_obj.unkouter); +} + +static struct gl2_unknown_intf ** +_unkinner_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) +{ + struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf; + + return (**impl->_obj.unkouter).QueryInterface (impl->_obj.unkouter, uiid); +} + +static struct gl2_unknown_intf _unkinner_vftbl = { + _unkinner_AddRef, + _unkinner_Release, + _unkinner_QueryInterface +}; + +static void +_unkinner_constructor (struct gl2_unkinner_impl *impl, struct gl2_unknown_intf **outer) +{ + impl->_vftbl = &_unkinner_vftbl; + impl->_obj.unkouter = outer; +} + +struct gl2_generic_obj +{ + struct gl2_unknown_obj _unknown; + GLhandleARB name; + GLboolean delete_status; + GLcharARB *info_log; +}; + +struct gl2_generic_impl +{ + struct gl2_generic_intf *_vftbl; + struct gl2_generic_obj _obj; +}; + +static void +_generic_destructor (struct gl2_unknown_intf **intf) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf; + + _mesa_free ((void *) impl->_obj.info_log); + + _glthread_LOCK_MUTEX (ctx->Shared->Mutex); + _mesa_HashRemove (ctx->Shared->GL2Objects, impl->_obj.name); + _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex); + + _unknown_destructor (intf); +} + +static struct gl2_unknown_intf ** +_generic_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) +{ + if (uiid == UIID_GENERIC) + { + (**intf).AddRef (intf); + return intf; + } + return _unknown_QueryInterface (intf, uiid); +} + +static void +_generic_Delete (struct gl2_generic_intf **intf) +{ + struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf; + + if (impl->_obj.delete_status == GL_FALSE) + { + impl->_obj.delete_status = GL_TRUE; + (**intf)._unknown.Release ((struct gl2_unknown_intf **) intf); + } +} + +static GLhandleARB +_generic_GetName (struct gl2_generic_intf **intf) +{ + struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf; + + return impl->_obj.name; +} + +static GLboolean +_generic_GetDeleteStatus (struct gl2_generic_intf **intf) +{ + struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf; + + return impl->_obj.delete_status; +} + +static const GLcharARB * +_generic_GetInfoLog (struct gl2_generic_intf **intf) +{ + struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf; + + return impl->_obj.info_log; +} + +static struct gl2_generic_intf _generic_vftbl = { + { + _unknown_AddRef, + _unknown_Release, + _generic_QueryInterface + }, + _generic_Delete, + NULL, /* abstract GetType */ + _generic_GetName, + _generic_GetDeleteStatus, + _generic_GetInfoLog +}; + +static void +_generic_constructor (struct gl2_generic_impl *impl) +{ + GET_CURRENT_CONTEXT(ctx); + + _unknown_constructor ((struct gl2_unknown_impl *) impl); + impl->_vftbl = &_generic_vftbl; + impl->_obj._unknown._destructor = _generic_destructor; + impl->_obj.delete_status = GL_FALSE; + impl->_obj.info_log = NULL; + + _glthread_LOCK_MUTEX (ctx->Shared->Mutex); + impl->_obj.name = _mesa_HashFindFreeKeyBlock (ctx->Shared->GL2Objects, 1); + _mesa_HashInsert (ctx->Shared->GL2Objects, impl->_obj.name, (void *) impl); + _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex); +} + +struct gl2_container_obj +{ + struct gl2_generic_obj _generic; + struct gl2_generic_intf ***attached; + GLuint attached_count; +}; + +struct gl2_container_impl +{ + struct gl2_container_intf *_vftbl; + struct gl2_container_obj _obj; +}; + +static void +_container_destructor (struct gl2_unknown_intf **intf) +{ + struct gl2_container_impl *impl = (struct gl2_container_impl *) intf; + GLuint i; + + for (i = 0; i < impl->_obj.attached_count; i++) + { + struct gl2_generic_intf **x = impl->_obj.attached[i]; + (**x)._unknown.Release ((struct gl2_unknown_intf **) x); + } + + _generic_destructor (intf); +} + +static struct gl2_unknown_intf ** +_container_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) +{ + if (uiid == UIID_CONTAINER) + { + (**intf).AddRef (intf); + return intf; + } + return _generic_QueryInterface (intf, uiid); +} + +static GLboolean +_container_Attach (struct gl2_container_intf **intf, struct gl2_generic_intf **att) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_container_impl *impl = (struct gl2_container_impl *) intf; + GLuint i; + + for (i = 0; i < impl->_obj.attached_count; i++) + if (impl->_obj.attached[i] == att) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "_container_Attach"); + return GL_FALSE; + } + + impl->_obj.attached = (struct gl2_generic_intf ***) _mesa_realloc (impl->_obj.attached, + impl->_obj.attached_count * sizeof (*impl->_obj.attached), (impl->_obj.attached_count + 1) * + sizeof (*impl->_obj.attached)); + if (impl->_obj.attached == NULL) + return GL_FALSE; + + impl->_obj.attached[impl->_obj.attached_count] = att; + impl->_obj.attached_count++; + (**att)._unknown.AddRef ((struct gl2_unknown_intf **) att); + return GL_TRUE; +} + +static GLboolean +_container_Detach (struct gl2_container_intf **intf, struct gl2_generic_intf **att) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_container_impl *impl = (struct gl2_container_impl *) intf; + GLuint i, j; + + for (i = 0; i < impl->_obj.attached_count; i++) + if (impl->_obj.attached[i] == att) + { + for (j = i; j < impl->_obj.attached_count - 1; j++) + impl->_obj.attached[j] = impl->_obj.attached[j + 1]; + impl->_obj.attached = (struct gl2_generic_intf ***) _mesa_realloc (impl->_obj.attached, + impl->_obj.attached_count * sizeof (*impl->_obj.attached), + (impl->_obj.attached_count - 1) * sizeof (*impl->_obj.attached)); + impl->_obj.attached_count--; + (**att)._unknown.Release ((struct gl2_unknown_intf **) att); + return GL_TRUE; + } + + _mesa_error (ctx, GL_INVALID_OPERATION, "_container_Detach"); + return GL_FALSE; +} + +static GLsizei +_container_GetAttachedCount (struct gl2_container_intf **intf) +{ + struct gl2_container_impl *impl = (struct gl2_container_impl *) intf; + + return impl->_obj.attached_count; +} + +static struct gl2_generic_intf ** +_container_GetAttached (struct gl2_container_intf **intf, GLuint index) +{ + struct gl2_container_impl *impl = (struct gl2_container_impl *) intf; + + (**impl->_obj.attached[index])._unknown.AddRef ( + (struct gl2_unknown_intf **)impl->_obj.attached[index]); + return impl->_obj.attached[index]; +} + +static struct gl2_container_intf _container_vftbl = { + { + { + _unknown_AddRef, + _unknown_Release, + _container_QueryInterface + }, + _generic_Delete, + NULL, /* abstract GetType */ + _generic_GetName, + _generic_GetDeleteStatus, + _generic_GetInfoLog + }, + _container_Attach, + _container_Detach, + _container_GetAttachedCount, + _container_GetAttached +}; + +static void +_container_constructor (struct gl2_container_impl *impl) +{ + _generic_constructor ((struct gl2_generic_impl *) impl); + impl->_vftbl = &_container_vftbl; + impl->_obj._generic._unknown._destructor = _container_destructor; + impl->_obj.attached = NULL; + impl->_obj.attached_count = 0; +} + +struct gl2_3dlabs_shhandle_obj +{ + struct gl2_unkinner_obj _unknown; +#if USE_3DLABS_FRONTEND + ShHandle handle; +#endif +}; + +struct gl2_3dlabs_shhandle_impl +{ + struct gl2_3dlabs_shhandle_intf *_vftbl; + struct gl2_3dlabs_shhandle_obj _obj; +}; + +static void +_3dlabs_shhandle_destructor (struct gl2_unknown_intf **intf) +{ +#if USE_3DLABS_FRONTEND + struct gl2_3dlabs_shhandle_impl *impl = (struct gl2_3dlabs_shhandle_impl *) intf; + ShDestruct (impl->_obj.handle); +#endif + _unkinner_destructor (intf); +} + +static GLvoid * +_3dlabs_shhandle_GetShHandle (struct gl2_3dlabs_shhandle_intf **intf) +{ +#if USE_3DLABS_FRONTEND + struct gl2_3dlabs_shhandle_impl *impl = (struct gl2_3dlabs_shhandle_impl *) intf; + return impl->_obj.handle; +#else + return NULL; +#endif +} + +static struct gl2_3dlabs_shhandle_intf _3dlabs_shhandle_vftbl = { + { + _unkinner_AddRef, + _unkinner_Release, + _unkinner_QueryInterface + }, + _3dlabs_shhandle_GetShHandle +}; + +static void +_3dlabs_shhandle_constructor (struct gl2_3dlabs_shhandle_impl *impl, struct gl2_unknown_intf **outer) +{ + _unkinner_constructor ((struct gl2_unkinner_impl *) impl, outer); + impl->_vftbl = &_3dlabs_shhandle_vftbl; +#if USE_3DLABS_FRONTEND + impl->_obj.handle = NULL; +#endif +} + +struct gl2_shader_obj +{ + struct gl2_generic_obj _generic; + struct gl2_3dlabs_shhandle_impl _3dlabs_shhandle; + GLboolean compile_status; + GLcharARB *source; + GLint *offsets; + GLsizei offset_count; + slang_translation_unit unit; +}; + +struct gl2_shader_impl +{ + struct gl2_shader_intf *_vftbl; + struct gl2_shader_obj _obj; +}; + +static void +_shader_destructor (struct gl2_unknown_intf **intf) +{ + struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; + + _mesa_free ((void *) impl->_obj.source); + _mesa_free ((void *) impl->_obj.offsets); + _3dlabs_shhandle_destructor ((struct gl2_unknown_intf **) &impl->_obj._3dlabs_shhandle._vftbl); + _generic_destructor (intf); +} + +static struct gl2_unknown_intf ** +_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) +{ +#if USE_3DLABS_FRONTEND + struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; +#endif + + if (uiid == UIID_SHADER) + { + (**intf).AddRef (intf); + return intf; + } +#if USE_3DLABS_FRONTEND + if (uiid == UIID_3DLABS_SHHANDLE) + { + (**intf).AddRef (intf); + return (struct gl2_unknown_intf **) &impl->_obj._3dlabs_shhandle._vftbl; + } +#endif + return _generic_QueryInterface (intf, uiid); +} + +static GLenum +_shader_GetType (struct gl2_generic_intf **intf) +{ + return GL_SHADER_OBJECT_ARB; +} + +static GLboolean +_shader_GetCompileStatus (struct gl2_shader_intf **intf) +{ + struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; + + return impl->_obj.compile_status; +} + +static GLvoid +_shader_SetSource (struct gl2_shader_intf **intf, GLcharARB *src, GLint *off, GLsizei cnt) +{ + struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; + + _mesa_free ((void *) impl->_obj.source); + impl->_obj.source = src; + _mesa_free ((void *) impl->_obj.offsets); + impl->_obj.offsets = off; + impl->_obj.offset_count = cnt; +} + +static const GLcharARB * +_shader_GetSource (struct gl2_shader_intf **intf) +{ + struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; + + return impl->_obj.source; +} + +static GLvoid +_shader_Compile (struct gl2_shader_intf **intf) +{ + struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; +#if USE_3DLABS_FRONTEND + char **strings; + TBuiltInResource res; +#else + slang_unit_type type; + slang_info_log info_log; +#endif + + impl->_obj.compile_status = GL_FALSE; + _mesa_free ((void *) impl->_obj._generic.info_log); + impl->_obj._generic.info_log = NULL; + +#if USE_3DLABS_FRONTEND + /* 3dlabs compiler expects us to feed it with null-terminated string array, + we've got only one big string with offsets, so we must split it; but when + there's only one string to deal with, we pass its address directly */ + + if (impl->_obj.offset_count <= 1) + strings = &impl->_obj.source; + else + { + GLsizei i, offset = 0; + + strings = (char **) _mesa_malloc (impl->_obj.offset_count * sizeof (char *)); + if (strings == NULL) + return; + + for (i = 0; i < impl->_obj.offset_count; i++) + { + GLsizei size = impl->_obj.offsets[i] - offset; + + strings[i] = (char *) _mesa_malloc ((size + 1) * sizeof (char)); + if (strings[i] == NULL) + { + GLsizei j; + + for (j = 0; j < i; j++) + _mesa_free (strings[j]); + _mesa_free (strings); + return; + } + + _mesa_memcpy (strings[i], impl->_obj.source + offset, size * sizeof (char)); + strings[i][size] = '\0'; + offset = impl->_obj.offsets[i]; + } + } + + /* TODO set these fields to some REAL numbers */ + res.maxLights = 8; + res.maxClipPlanes = 6; + res.maxTextureUnits = 2; + res.maxTextureCoords = 2; + res.maxVertexAttribs = 8; + res.maxVertexUniformComponents = 64; + res.maxVaryingFloats = 8; + res.maxVertexTextureImageUnits = 2; + res.maxCombinedTextureImageUnits = 2; + res.maxTextureImageUnits = 2; + res.maxFragmentUniformComponents = 64; + res.maxDrawBuffers = 1; + + if (ShCompile (impl->_obj._3dlabs_shhandle._obj.handle, strings, impl->_obj.offset_count, + EShOptFull, &res, 0)) + impl->_obj.compile_status = GL_TRUE; + if (impl->_obj.offset_count > 1) + { + GLsizei i; + + for (i = 0; i < impl->_obj.offset_count; i++) + _mesa_free (strings[i]); + _mesa_free (strings); + } + + impl->_obj._generic.info_log = _mesa_strdup (ShGetInfoLog ( + impl->_obj._3dlabs_shhandle._obj.handle)); +#else + if (impl->_vftbl->GetSubType (intf) == GL_FRAGMENT_SHADER) + type = slang_unit_fragment_shader; + else + type = slang_unit_vertex_shader; + slang_info_log_construct (&info_log); + if (_slang_compile (impl->_obj.source, &impl->_obj.unit, type, &info_log)) + { + impl->_obj.compile_status = GL_TRUE; + } + if (info_log.text != NULL) + impl->_obj._generic.info_log = _mesa_strdup (info_log.text); + else + impl->_obj._generic.info_log = _mesa_strdup (""); + slang_info_log_destruct (&info_log); +#endif +} + +static struct gl2_shader_intf _shader_vftbl = { + { + { + _unknown_AddRef, + _unknown_Release, + _shader_QueryInterface + }, + _generic_Delete, + _shader_GetType, + _generic_GetName, + _generic_GetDeleteStatus, + _generic_GetInfoLog + }, + NULL, /* abstract GetSubType */ + _shader_GetCompileStatus, + _shader_SetSource, + _shader_GetSource, + _shader_Compile +}; + +static void +_shader_constructor (struct gl2_shader_impl *impl) +{ + _generic_constructor ((struct gl2_generic_impl *) impl); + _3dlabs_shhandle_constructor (&impl->_obj._3dlabs_shhandle, (struct gl2_unknown_intf **) + &impl->_vftbl); + impl->_vftbl = &_shader_vftbl; + impl->_obj._generic._unknown._destructor = _shader_destructor; + impl->_obj.compile_status = GL_FALSE; + impl->_obj.source = NULL; + impl->_obj.offsets = NULL; + impl->_obj.offset_count = 0; +} + +struct gl2_program_obj +{ + struct gl2_container_obj _container; + GLboolean link_status; + GLboolean validate_status; +#if USE_3DLABS_FRONTEND + ShHandle linker; + ShHandle uniforms; +#endif + slang_program prog; +}; + +struct gl2_program_impl +{ + struct gl2_program_intf *_vftbl; + struct gl2_program_obj _obj; +}; + +static void +_program_destructor (struct gl2_unknown_intf **intf) +{ + struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; +#if USE_3DLABS_FRONTEND + ShDestruct (impl->_obj.linker); + ShDestruct (impl->_obj.uniforms); +#endif + _container_destructor (intf); + slang_program_dtr (&impl->_obj.prog); +} + +static struct gl2_unknown_intf ** +_program_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) +{ + if (uiid == UIID_PROGRAM) + { + (**intf).AddRef (intf); + return intf; + } + return _container_QueryInterface (intf, uiid); +} + +static GLenum +_program_GetType (struct gl2_generic_intf **intf) +{ + return GL_PROGRAM_OBJECT_ARB; +} + +static GLboolean +_program_Attach (struct gl2_container_intf **intf, struct gl2_generic_intf **att) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_unknown_intf **sha; + + sha = (**att)._unknown.QueryInterface ((struct gl2_unknown_intf **) att, UIID_SHADER); + if (sha == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "_program_Attach"); + return GL_FALSE; + } + + (**sha).Release (sha); + return _container_Attach (intf, att); +} + +static GLboolean +_program_GetLinkStatus (struct gl2_program_intf **intf) +{ + struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; + + return impl->_obj.link_status; +} + +static GLboolean +_program_GetValidateStatus (struct gl2_program_intf **intf) +{ + struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; + + return impl->_obj.validate_status; +} + +static GLvoid +_program_Link (struct gl2_program_intf **intf) +{ + struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; +#if USE_3DLABS_FRONTEND + ShHandle *handles; +#endif + GLuint i, count; + slang_translation_unit *units[2]; + + impl->_obj.link_status = GL_FALSE; + _mesa_free ((void *) impl->_obj._container._generic.info_log); + impl->_obj._container._generic.info_log = NULL; + slang_program_dtr (&impl->_obj.prog); + slang_program_ctr (&impl->_obj.prog); + +#if USE_3DLABS_FRONTEND + handles = (ShHandle *) _mesa_malloc (impl->_obj._container.attached_count * sizeof (ShHandle)); + if (handles == NULL) + return; + + for (i = 0; i < impl->_obj._container.attached_count; i++) + { + struct gl2_generic_intf **gen = impl->_obj._container.attached[i]; + struct gl2_3dlabs_shhandle_intf **sh; + + sh = (struct gl2_3dlabs_shhandle_intf **) (**gen)._unknown.QueryInterface ( + (struct gl2_unknown_intf **) gen, UIID_3DLABS_SHHANDLE); + if (sh != NULL) + { + handles[i] = (**sh).GetShHandle (sh); + (**sh)._unknown.Release ((struct gl2_unknown_intf **) sh); + } + else + { + _mesa_free (handles); + return; + } + } + + if (ShLink (impl->_obj.linker, handles, impl->_obj._container.attached_count, + impl->_obj.uniforms, NULL, NULL)) + impl->_obj.link_status = GL_TRUE; + + impl->_obj._container._generic.info_log = _mesa_strdup (ShGetInfoLog (impl->_obj.linker)); +#else + count = impl->_obj._container.attached_count; + if (count == 0 || count > 2) + return; + for (i = 0; i < count; i++) + { + struct gl2_generic_intf **obj; + struct gl2_unknown_intf **unk; + struct gl2_shader_impl *sha; + + obj = impl->_obj._container.attached[i]; + unk = (**obj)._unknown.QueryInterface ((struct gl2_unknown_intf **) obj, UIID_SHADER); + (**obj)._unknown.Release ((struct gl2_unknown_intf **) obj); + if (unk == NULL) + return; + sha = (struct gl2_shader_impl *) unk; + units[i] = &sha->_obj.unit; + (**unk).Release (unk); + } + + impl->_obj.link_status = _slang_link (&impl->_obj.prog, units, count); + if (impl->_obj.link_status) + impl->_obj._container._generic.info_log = _mesa_strdup ("Link OK.\n"); + else + impl->_obj._container._generic.info_log = _mesa_strdup ("Link failed.\n"); +#endif +} + +static GLvoid +_program_Validate (struct gl2_program_intf **intf) +{ + struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; + + impl->_obj.validate_status = GL_FALSE; + _mesa_free ((void *) impl->_obj._container._generic.info_log); + impl->_obj._container._generic.info_log = NULL; + + /* TODO validate */ +} + +static GLvoid +write_common_fixed (slang_program *pro, GLuint index, const GLvoid *src, GLuint off, GLuint size) +{ + GLuint i; + + for (i = 0; i < SLANG_SHADER_MAX; i++) + { + GLuint addr; + + addr = pro->common_fixed_entries[i][index]; + if (addr != ~0) + { + GLubyte *dst; + + dst = (GLubyte *) pro->machines[i]->mem + addr + off * size; + _mesa_memcpy (dst, src, size); + } + } +} + +static GLvoid +write_common_fixed_mat4 (slang_program *pro, GLmatrix *matrix, GLuint off, GLuint i, GLuint ii, + GLuint it, GLuint iit) +{ + GLfloat mat[16]; + + /* we want inverse matrix */ + if (!matrix->inv) + { + /* allocate inverse matrix and make it dirty */ + _math_matrix_alloc_inv (matrix); + _math_matrix_loadf (matrix, matrix->m); + } + _math_matrix_analyse (matrix); + + write_common_fixed (pro, i, matrix->m, off, 16 * sizeof (GLfloat)); + + /* inverse */ + write_common_fixed (pro, ii, matrix->inv, off, 16 * sizeof (GLfloat)); + + /* transpose */ + _math_transposef (mat, matrix->m); + write_common_fixed (pro, it, mat, off, 16 * sizeof (GLfloat)); + + /* inverse transpose */ + _math_transposef (mat, matrix->inv); + write_common_fixed (pro, iit, mat, off, 16 * sizeof (GLfloat)); +} + +static GLvoid +write_common_fixed_material (GLcontext *ctx, slang_program *pro, GLuint i, GLuint e, GLuint a, + GLuint d, GLuint sp, GLuint sh) +{ + GLfloat v[17]; + + COPY_4FV(v, ctx->Light.Material.Attrib[e]); + COPY_4FV((v + 4), ctx->Light.Material.Attrib[a]); + COPY_4FV((v + 8), ctx->Light.Material.Attrib[d]); + COPY_4FV((v + 12), ctx->Light.Material.Attrib[sp]); + v[16] = ctx->Light.Material.Attrib[sh][0]; + write_common_fixed (pro, i, v, 0, 17 * sizeof (GLfloat)); +} + +static GLvoid +write_common_fixed_light_model_product (GLcontext *ctx, slang_program *pro, GLuint i, GLuint e, + GLuint a) +{ + GLfloat v[4]; + + SCALE_4V(v, ctx->Light.Material.Attrib[a], ctx->Light.Model.Ambient); + ACC_4V(v, ctx->Light.Material.Attrib[e]); + write_common_fixed (pro, i, v, 0, 4 * sizeof (GLfloat)); +} + +static GLvoid +write_common_fixed_light_product (GLcontext *ctx, slang_program *pro, GLuint off, GLuint i, GLuint a, + GLuint d, GLuint s) +{ + GLfloat v[12]; + + SCALE_4V(v, ctx->Light.Light[off].Ambient, ctx->Light.Material.Attrib[a]); + SCALE_4V((v + 4), ctx->Light.Light[off].Diffuse, ctx->Light.Material.Attrib[d]); + SCALE_4V((v + 8), ctx->Light.Light[off].Specular, ctx->Light.Material.Attrib[s]); + write_common_fixed (pro, i, v, off, 12 * sizeof (GLfloat)); +} + +static GLvoid +_program_UpdateFixedUniforms (struct gl2_program_intf **intf) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; + slang_program *pro = &impl->_obj.prog; + GLuint i; + GLfloat v[29]; + GLfloat *p; + + /* MODELVIEW matrix */ + write_common_fixed_mat4 (pro, ctx->ModelviewMatrixStack.Top, 0, + SLANG_COMMON_FIXED_MODELVIEWMATRIX, + SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSE, + SLANG_COMMON_FIXED_MODELVIEWMATRIXTRANSPOSE, + SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSETRANSPOSE); + + /* PROJECTION matrix */ + write_common_fixed_mat4 (pro, ctx->ProjectionMatrixStack.Top, 0, + SLANG_COMMON_FIXED_PROJECTIONMATRIX, + SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSE, + SLANG_COMMON_FIXED_PROJECTIONMATRIXTRANSPOSE, + SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSETRANSPOSE); + + /* MVP matrix */ + write_common_fixed_mat4 (pro, &ctx->_ModelProjectMatrix, 0, + SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIX, + SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSE, + SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXTRANSPOSE, + SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSETRANSPOSE); + + for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) + { + /* TEXTURE matrix */ + write_common_fixed_mat4 (pro, ctx->TextureMatrixStack[i].Top, i, + SLANG_COMMON_FIXED_TEXTUREMATRIX, + SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSE, + SLANG_COMMON_FIXED_TEXTUREMATRIXTRANSPOSE, + SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSETRANSPOSE); + + /* EYE_PLANE texture-coordinate generation */ + write_common_fixed (pro, SLANG_COMMON_FIXED_EYEPLANES, ctx->Texture.Unit[i].EyePlaneS, + i, 4 * sizeof (GLfloat)); + write_common_fixed (pro, SLANG_COMMON_FIXED_EYEPLANET, ctx->Texture.Unit[i].EyePlaneT, + i, 4 * sizeof (GLfloat)); + write_common_fixed (pro, SLANG_COMMON_FIXED_EYEPLANER, ctx->Texture.Unit[i].EyePlaneR, + i, 4 * sizeof (GLfloat)); + write_common_fixed (pro, SLANG_COMMON_FIXED_EYEPLANEQ, ctx->Texture.Unit[i].EyePlaneQ, + i, 4 * sizeof (GLfloat)); + + /* OBJECT_PLANE texture-coordinate generation */ + write_common_fixed (pro, SLANG_COMMON_FIXED_OBJECTPLANES, ctx->Texture.Unit[i].ObjectPlaneS, + i, 4 * sizeof (GLfloat)); + write_common_fixed (pro, SLANG_COMMON_FIXED_OBJECTPLANET, ctx->Texture.Unit[i].ObjectPlaneT, + i, 4 * sizeof (GLfloat)); + write_common_fixed (pro, SLANG_COMMON_FIXED_OBJECTPLANER, ctx->Texture.Unit[i].ObjectPlaneR, + i, 4 * sizeof (GLfloat)); + write_common_fixed (pro, SLANG_COMMON_FIXED_OBJECTPLANEQ, ctx->Texture.Unit[i].ObjectPlaneQ, + i, 4 * sizeof (GLfloat)); + } + + /* NORMAL matrix - upper 3x3 inverse transpose of MODELVIEW matrix */ + p = ctx->ModelviewMatrixStack.Top->inv; + v[0] = p[0]; + v[1] = p[4]; + v[2] = p[8]; + v[3] = p[1]; + v[4] = p[5]; + v[5] = p[9]; + v[6] = p[2]; + v[7] = p[6]; + v[8] = p[10]; + write_common_fixed (pro, SLANG_COMMON_FIXED_NORMALMATRIX, v, 0, 9 * sizeof (GLfloat)); + + /* normal scale */ + write_common_fixed (pro, SLANG_COMMON_FIXED_NORMALSCALE, &ctx->_ModelViewInvScale, 0, sizeof (GLfloat)); + + /* depth range parameters */ + v[0] = ctx->Viewport.Near; + v[1] = ctx->Viewport.Far; + v[2] = ctx->Viewport.Far - ctx->Viewport.Near; + write_common_fixed (pro, SLANG_COMMON_FIXED_DEPTHRANGE, v, 0, 3 * sizeof (GLfloat)); + + /* CLIP_PLANEi */ + for (i = 0; i < ctx->Const.MaxClipPlanes; i++) + { + write_common_fixed (pro, SLANG_COMMON_FIXED_CLIPPLANE, ctx->Transform.EyeUserPlane[i], i, + 4 * sizeof (GLfloat)); + } + + /* point parameters */ + v[0] = ctx->Point.Size; + v[1] = ctx->Point.MinSize; + v[2] = ctx->Point.MaxSize; + v[3] = ctx->Point.Threshold; + COPY_3FV((v + 4), ctx->Point.Params); + write_common_fixed (pro, SLANG_COMMON_FIXED_POINT, v, 0, 7 * sizeof (GLfloat)); + + /* material parameters */ + write_common_fixed_material (ctx, pro, SLANG_COMMON_FIXED_FRONTMATERIAL, + MAT_ATTRIB_FRONT_EMISSION, + MAT_ATTRIB_FRONT_AMBIENT, + MAT_ATTRIB_FRONT_DIFFUSE, + MAT_ATTRIB_FRONT_SPECULAR, + MAT_ATTRIB_FRONT_SHININESS); + write_common_fixed_material (ctx, pro, SLANG_COMMON_FIXED_BACKMATERIAL, + MAT_ATTRIB_BACK_EMISSION, + MAT_ATTRIB_BACK_AMBIENT, + MAT_ATTRIB_BACK_DIFFUSE, + MAT_ATTRIB_BACK_SPECULAR, + MAT_ATTRIB_BACK_SHININESS); + + for (i = 0; i < ctx->Const.MaxLights; i++) + { + /* light source parameters */ + COPY_4FV(v, ctx->Light.Light[i].Ambient); + COPY_4FV((v + 4), ctx->Light.Light[i].Diffuse); + COPY_4FV((v + 8), ctx->Light.Light[i].Specular); + COPY_4FV((v + 12), ctx->Light.Light[i].EyePosition); + COPY_2FV((v + 16), ctx->Light.Light[i].EyePosition); + v[18] = ctx->Light.Light[i].EyePosition[2] + 1.0f; + NORMALIZE_3FV((v + 16)); + v[19] = 0.0f; + COPY_3V((v + 20), ctx->Light.Light[i].EyeDirection); + v[23] = ctx->Light.Light[i].SpotExponent; + v[24] = ctx->Light.Light[i].SpotCutoff; + v[25] = ctx->Light.Light[i]._CosCutoffNeg; + v[26] = ctx->Light.Light[i].ConstantAttenuation; + v[27] = ctx->Light.Light[i].LinearAttenuation; + v[28] = ctx->Light.Light[i].QuadraticAttenuation; + write_common_fixed (pro, SLANG_COMMON_FIXED_LIGHTSOURCE, v, i, 29 * sizeof (GLfloat)); + + /* light product */ + write_common_fixed_light_product (ctx, pro, i, SLANG_COMMON_FIXED_FRONTLIGHTPRODUCT, + MAT_ATTRIB_FRONT_AMBIENT, + MAT_ATTRIB_FRONT_DIFFUSE, + MAT_ATTRIB_FRONT_SPECULAR); + write_common_fixed_light_product (ctx, pro, i, SLANG_COMMON_FIXED_BACKLIGHTPRODUCT, + MAT_ATTRIB_BACK_AMBIENT, + MAT_ATTRIB_BACK_DIFFUSE, + MAT_ATTRIB_BACK_SPECULAR); + } + + /* light model parameters */ + write_common_fixed (pro, SLANG_COMMON_FIXED_LIGHTMODEL, ctx->Light.Model.Ambient, 0, 4 * sizeof (GLfloat)); + + /* light model product */ + write_common_fixed_light_model_product (ctx, pro, SLANG_COMMON_FIXED_FRONTLIGHTMODELPRODUCT, + MAT_ATTRIB_FRONT_EMISSION, + MAT_ATTRIB_FRONT_AMBIENT); + write_common_fixed_light_model_product (ctx, pro, SLANG_COMMON_FIXED_BACKLIGHTMODELPRODUCT, + MAT_ATTRIB_BACK_EMISSION, + MAT_ATTRIB_BACK_AMBIENT); + + /* TEXTURE_ENV_COLOR */ + for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) + { + write_common_fixed (pro, SLANG_COMMON_FIXED_TEXTUREENVCOLOR, ctx->Texture.Unit[i].EnvColor, + i, 4 * sizeof (GLfloat)); + } + + /* fog parameters */ + COPY_4FV(v, ctx->Fog.Color); + v[4] = ctx->Fog.Density; + v[5] = ctx->Fog.Start; + v[6] = ctx->Fog.End; + v[7] = ctx->Fog._Scale; + write_common_fixed (pro, SLANG_COMMON_FIXED_FOG, v, 0, 8 * sizeof (GLfloat)); +} + +static GLvoid +_program_UpdateFixedAttribute (struct gl2_program_intf **intf, GLuint index, GLvoid *data, + GLuint offset, GLuint size, GLboolean write) +{ + struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; + slang_program *pro = &impl->_obj.prog; + GLuint addr; + + addr = pro->vertex_fixed_entries[index]; + if (addr != ~0) + { + GLubyte *mem; + + mem = (GLubyte *) pro->machines[SLANG_SHADER_VERTEX]->mem + addr + offset * size; + if (write) + _mesa_memcpy (mem, data, size); + else + _mesa_memcpy (data, mem, size); + } +} + +static GLvoid +_program_UpdateFixedVarying (struct gl2_program_intf **intf, GLuint index, GLvoid *data, + GLuint offset, GLuint size, GLboolean write) +{ + struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; + slang_program *pro = &impl->_obj.prog; + GLuint addr; + + addr = pro->fragment_fixed_entries[index]; + if (addr != ~0) + { + GLubyte *mem; + + mem = (GLubyte *) pro->machines[SLANG_SHADER_FRAGMENT]->mem + addr + offset * size; + if (write) + _mesa_memcpy (mem, data, size); + else + _mesa_memcpy (data, mem, size); + } +} + +static GLvoid +_program_GetTextureImageUsage (struct gl2_program_intf **intf, GLbitfield *teximageusage) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; + slang_program *pro = &impl->_obj.prog; + GLuint i; + + for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) + teximageusage[i] = 0; + + for (i = 0; i < pro->texture_usage.count; i++) + { + GLuint n, addr, j; + + n = slang_export_data_quant_elements (pro->texture_usage.table[i].quant); + addr = pro->texture_usage.table[i].frag_address; + for (j = 0; j < n; j++) + { + GLubyte *mem; + GLuint image; + + mem = (GLubyte *) pro->machines[SLANG_SHADER_FRAGMENT]->mem + addr + j * 4; + image = (GLuint) *((GLfloat *) mem); + if (image >= 0 && image < ctx->Const.MaxTextureImageUnits) + { + switch (slang_export_data_quant_type (pro->texture_usage.table[i].quant)) + { + case GL_SAMPLER_1D_ARB: + case GL_SAMPLER_1D_SHADOW_ARB: + teximageusage[image] |= TEXTURE_1D_BIT; + break; + case GL_SAMPLER_2D_ARB: + case GL_SAMPLER_2D_SHADOW_ARB: + teximageusage[image] |= TEXTURE_2D_BIT; + break; + case GL_SAMPLER_3D_ARB: + teximageusage[image] |= TEXTURE_3D_BIT; + break; + case GL_SAMPLER_CUBE_ARB: + teximageusage[image] |= TEXTURE_CUBE_BIT; + break; + } + } + } + } + + /* TODO: make sure that for 0<=i<=MaxTextureImageUint bitcount(teximageuint[i])<=0 */ +} + +static GLboolean +_program_IsShaderPresent (struct gl2_program_intf **intf, GLenum subtype) +{ + struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; + slang_program *pro = &impl->_obj.prog; + + switch (subtype) + { + case GL_VERTEX_SHADER_ARB: + return pro->machines[SLANG_SHADER_VERTEX] != NULL; + case GL_FRAGMENT_SHADER_ARB: + return pro->machines[SLANG_SHADER_FRAGMENT] != NULL; + default: + return GL_FALSE; + } +} + +static GLvoid +get_active_variable (slang_active_variable *var, GLsizei maxLength, GLsizei *length, GLint *size, + GLenum *type, GLchar *name) +{ + GLsizei len; + + len = _mesa_strlen (var->name); + if (len >= maxLength) + len = maxLength - 1; + if (length != NULL) + *length = len; + *size = slang_export_data_quant_elements (var->quant); + *type = slang_export_data_quant_type (var->quant); + _mesa_memcpy (name, var->name, len); + name[len] = '\0'; +} + +static GLuint +get_active_variable_max_length (slang_active_variables *vars) +{ + GLuint i, len = 0; + + for (i = 0; i < vars->count; i++) + { + GLuint n = _mesa_strlen (vars->table[i].name); + if (n > len) + len = n; + } + return len; +} + +static GLvoid +_program_GetActiveUniform (struct gl2_program_intf **intf, GLuint index, GLsizei maxLength, + GLsizei *length, GLint *size, GLenum *type, GLchar *name) +{ + struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); + slang_active_variable *u = &impl->_obj.prog.active_uniforms.table[index]; + + get_active_variable (u, maxLength, length, size, type, name); +} + +static GLuint +_program_GetActiveUniformMaxLength (struct gl2_program_intf **intf) +{ + struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); + + return get_active_variable_max_length (&impl->_obj.prog.active_uniforms); +} + +static GLuint +_program_GetActiveUniformCount (struct gl2_program_intf **intf) +{ + struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); + + return impl->_obj.prog.active_uniforms.count; +} + +static GLint +_program_GetUniformLocation (struct gl2_program_intf **intf, const GLchar *name) +{ + struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); + slang_uniform_bindings *bind = &impl->_obj.prog.uniforms; + GLuint i; + + for (i = 0; i < bind->count; i++) + if (_mesa_strcmp (bind->table[i].name, name) == 0) + return i; + return -1; +} + +static GLboolean +_program_WriteUniform (struct gl2_program_intf **intf, GLint loc, GLsizei count, const GLvoid *data, + GLenum type) +{ + struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); + slang_uniform_bindings *uniforms = &impl->_obj.prog.uniforms; + slang_uniform_binding *uniform; + GLuint i; + GLboolean convert_float_to_bool = GL_FALSE; + GLboolean convert_int_to_bool = GL_FALSE; + GLboolean convert_int_to_float = GL_FALSE; + GLboolean types_match = GL_FALSE; + + if (loc == -1) + return GL_TRUE; + if (loc >= uniforms->count) + return GL_FALSE; + + uniform = &uniforms->table[loc]; + /* TODO: check sizes */ + if (slang_export_data_quant_struct (uniform->quant)) + return GL_FALSE; + + switch (slang_export_data_quant_type (uniform->quant)) + { + case GL_BOOL_ARB: + types_match = (type == GL_FLOAT) || (type == GL_INT); + if (type == GL_FLOAT) + convert_float_to_bool = GL_TRUE; + else + convert_int_to_bool = GL_TRUE; + break; + case GL_BOOL_VEC2_ARB: + types_match = (type == GL_FLOAT_VEC2_ARB) || (type == GL_INT_VEC2_ARB); + if (type == GL_FLOAT_VEC2_ARB) + convert_float_to_bool = GL_TRUE; + else + convert_int_to_bool = GL_TRUE; + break; + case GL_BOOL_VEC3_ARB: + types_match = (type == GL_FLOAT_VEC3_ARB) || (type == GL_INT_VEC3_ARB); + if (type == GL_FLOAT_VEC3_ARB) + convert_float_to_bool = GL_TRUE; + else + convert_int_to_bool = GL_TRUE; + break; + case GL_BOOL_VEC4_ARB: + types_match = (type == GL_FLOAT_VEC4_ARB) || (type == GL_INT_VEC4_ARB); + if (type == GL_FLOAT_VEC4_ARB) + convert_float_to_bool = GL_TRUE; + else + convert_int_to_bool = GL_TRUE; + break; + case GL_SAMPLER_1D_ARB: + case GL_SAMPLER_2D_ARB: + case GL_SAMPLER_3D_ARB: + case GL_SAMPLER_CUBE_ARB: + case GL_SAMPLER_1D_SHADOW_ARB: + case GL_SAMPLER_2D_SHADOW_ARB: + types_match = (type == GL_INT); + break; + default: + types_match = (type == slang_export_data_quant_type (uniform->quant)); + break; + } + + if (!types_match) + return GL_FALSE; + + switch (type) + { + case GL_INT: + case GL_INT_VEC2_ARB: + case GL_INT_VEC3_ARB: + case GL_INT_VEC4_ARB: + convert_int_to_float = GL_TRUE; + break; + } + + if (convert_float_to_bool) + { + for (i = 0; i < SLANG_SHADER_MAX; i++) + if (uniform->address[i] != ~0) + { + const GLfloat *src = (GLfloat *) (data); + GLfloat *dst = (GLfloat *) + (&impl->_obj.prog.machines[i]->mem[uniform->address[i] / 4]); + GLuint j; + GLuint total = count * slang_export_data_quant_components (uniform->quant); + + for (j = 0; j < total; j++) + dst[j] = src[j] != 0.0f ? 1.0f : 0.0f; + } + } + else if (convert_int_to_bool) + { + for (i = 0; i < SLANG_SHADER_MAX; i++) + if (uniform->address[i] != ~0) + { + const GLuint *src = (GLuint *) (data); + GLfloat *dst = (GLfloat *) + (&impl->_obj.prog.machines[i]->mem[uniform->address[i] / 4]); + GLuint j; + GLuint total = count * slang_export_data_quant_components (uniform->quant); + + for (j = 0; j < total; j++) + dst[j] = src[j] ? 1.0f : 0.0f; + } + } + else if (convert_int_to_float) + { + for (i = 0; i < SLANG_SHADER_MAX; i++) + if (uniform->address[i] != ~0) + { + const GLuint *src = (GLuint *) (data); + GLfloat *dst = (GLfloat *) + (&impl->_obj.prog.machines[i]->mem[uniform->address[i] / 4]); + GLuint j; + GLuint total = count * slang_export_data_quant_components (uniform->quant); + + for (j = 0; j < total; j++) + dst[j] = (GLfloat) src[j]; + } + } + else + { + for (i = 0; i < SLANG_SHADER_MAX; i++) + if (uniform->address[i] != ~0) + { + _mesa_memcpy (&impl->_obj.prog.machines[i]->mem[uniform->address[i] / 4], data, + count * slang_export_data_quant_size (uniform->quant)); + } + } + return GL_TRUE; +} + +static GLvoid +_program_GetActiveAttrib (struct gl2_program_intf **intf, GLuint index, GLsizei maxLength, + GLsizei *length, GLint *size, GLenum *type, GLchar *name) +{ + struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); + slang_active_variable *a = &impl->_obj.prog.active_attribs.table[index]; + + get_active_variable (a, maxLength, length, size, type, name); +} + +static GLuint +_program_GetActiveAttribMaxLength (struct gl2_program_intf **intf) +{ + struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); + + return get_active_variable_max_length (&impl->_obj.prog.active_attribs); +} + +static GLuint +_program_GetActiveAttribCount (struct gl2_program_intf **intf) +{ + struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); + + return impl->_obj.prog.active_attribs.count; +} + +static GLint +_program_GetAttribLocation (struct gl2_program_intf **intf, const GLchar *name) +{ + struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); + slang_attrib_bindings *attribs = &impl->_obj.prog.attribs; + GLuint i; + + for (i = 0; i < attribs->binding_count; i++) + if (_mesa_strcmp (attribs->bindings[i].name, name) == 0) + return attribs->bindings[i].first_slot_index; + return -1; +} + +static GLvoid +_program_OverrideAttribBinding (struct gl2_program_intf **intf, GLuint index, const GLchar *name) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); + slang_program *pro = &impl->_obj.prog; + + if (!slang_attrib_overrides_add (&pro->attrib_overrides, index, name)) + _mesa_error (ctx, GL_OUT_OF_MEMORY, "_program_OverrideAttribBinding"); +} + +static GLvoid +_program_UpdateVarying (struct gl2_program_intf **intf, GLuint index, GLfloat *value, + GLboolean vert) +{ + struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; + slang_program *pro = &impl->_obj.prog; + GLuint addr; + + if (index >= pro->varyings.slot_count) + return; + if (vert) + addr = pro->varyings.slots[index].vert_addr / 4; + else + addr = pro->varyings.slots[index].frag_addr / 4; + if (addr != ~0) + { + if (vert) + *value = pro->machines[SLANG_SHADER_VERTEX]->mem[addr]._float; + else + pro->machines[SLANG_SHADER_FRAGMENT]->mem[addr]._float = *value; + } +} + +static struct gl2_program_intf _program_vftbl = { + { + { + { + _unknown_AddRef, + _unknown_Release, + _program_QueryInterface + }, + _generic_Delete, + _program_GetType, + _generic_GetName, + _generic_GetDeleteStatus, + _generic_GetInfoLog + }, + _program_Attach, + _container_Detach, + _container_GetAttachedCount, + _container_GetAttached + }, + _program_GetLinkStatus, + _program_GetValidateStatus, + _program_Link, + _program_Validate, + _program_UpdateFixedUniforms, + _program_UpdateFixedAttribute, + _program_UpdateFixedVarying, + _program_GetTextureImageUsage, + _program_IsShaderPresent, + _program_GetActiveUniform, + _program_GetActiveUniformMaxLength, + _program_GetActiveUniformCount, + _program_GetUniformLocation, + _program_WriteUniform, + _program_GetActiveAttrib, + _program_GetActiveAttribMaxLength, + _program_GetActiveAttribCount, + _program_GetAttribLocation, + _program_OverrideAttribBinding, + _program_UpdateVarying +}; + +static void +_program_constructor (struct gl2_program_impl *impl) +{ + _container_constructor ((struct gl2_container_impl *) impl); + impl->_vftbl = &_program_vftbl; + impl->_obj._container._generic._unknown._destructor = _program_destructor; + impl->_obj.link_status = GL_FALSE; + impl->_obj.validate_status = GL_FALSE; +#if USE_3DLABS_FRONTEND + impl->_obj.linker = ShConstructLinker (EShExVertexFragment, 0); + impl->_obj.uniforms = ShConstructUniformMap (); +#endif + slang_program_ctr (&impl->_obj.prog); +} + +struct gl2_fragment_shader_obj +{ + struct gl2_shader_obj _shader; +}; + +struct gl2_fragment_shader_impl +{ + struct gl2_fragment_shader_intf *_vftbl; + struct gl2_fragment_shader_obj _obj; +}; + +static void +_fragment_shader_destructor (struct gl2_unknown_intf **intf) +{ + struct gl2_fragment_shader_impl *impl = (struct gl2_fragment_shader_impl *) intf; + + (void) impl; + /* TODO free fragment shader data */ + + _shader_destructor (intf); +} + +static struct gl2_unknown_intf ** +_fragment_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) +{ + if (uiid == UIID_FRAGMENT_SHADER) + { + (**intf).AddRef (intf); + return intf; + } + return _shader_QueryInterface (intf, uiid); +} + +static GLenum +_fragment_shader_GetSubType (struct gl2_shader_intf **intf) +{ + return GL_FRAGMENT_SHADER_ARB; +} + +static struct gl2_fragment_shader_intf _fragment_shader_vftbl = { + { + { + { + _unknown_AddRef, + _unknown_Release, + _fragment_shader_QueryInterface + }, + _generic_Delete, + _shader_GetType, + _generic_GetName, + _generic_GetDeleteStatus, + _generic_GetInfoLog + }, + _fragment_shader_GetSubType, + _shader_GetCompileStatus, + _shader_SetSource, + _shader_GetSource, + _shader_Compile + } +}; + +static void +_fragment_shader_constructor (struct gl2_fragment_shader_impl *impl) +{ + _shader_constructor ((struct gl2_shader_impl *) impl); + impl->_vftbl = &_fragment_shader_vftbl; + impl->_obj._shader._generic._unknown._destructor = _fragment_shader_destructor; +#if USE_3DLABS_FRONTEND + impl->_obj._shader._3dlabs_shhandle._obj.handle = ShConstructCompiler (EShLangFragment, 0); +#endif +} + +struct gl2_vertex_shader_obj +{ + struct gl2_shader_obj _shader; +}; + +struct gl2_vertex_shader_impl +{ + struct gl2_vertex_shader_intf *_vftbl; + struct gl2_vertex_shader_obj _obj; +}; + +static void +_vertex_shader_destructor (struct gl2_unknown_intf **intf) +{ + struct gl2_vertex_shader_impl *impl = (struct gl2_vertex_shader_impl *) intf; + + (void) impl; + /* TODO free vertex shader data */ + + _shader_destructor (intf); +} + +static struct gl2_unknown_intf ** +_vertex_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) +{ + if (uiid == UIID_VERTEX_SHADER) + { + (**intf).AddRef (intf); + return intf; + } + return _shader_QueryInterface (intf, uiid); +} + +static GLenum +_vertex_shader_GetSubType (struct gl2_shader_intf **intf) +{ + return GL_VERTEX_SHADER_ARB; +} + +static struct gl2_vertex_shader_intf _vertex_shader_vftbl = { + { + { + { + _unknown_AddRef, + _unknown_Release, + _vertex_shader_QueryInterface + }, + _generic_Delete, + _shader_GetType, + _generic_GetName, + _generic_GetDeleteStatus, + _generic_GetInfoLog + }, + _vertex_shader_GetSubType, + _shader_GetCompileStatus, + _shader_SetSource, + _shader_GetSource, + _shader_Compile + } +}; + +static void +_vertex_shader_constructor (struct gl2_vertex_shader_impl *impl) +{ + _shader_constructor ((struct gl2_shader_impl *) impl); + impl->_vftbl = &_vertex_shader_vftbl; + impl->_obj._shader._generic._unknown._destructor = _vertex_shader_destructor; +#if USE_3DLABS_FRONTEND + impl->_obj._shader._3dlabs_shhandle._obj.handle = ShConstructCompiler (EShLangVertex, 0); +#endif +} + +GLhandleARB +_mesa_3dlabs_create_shader_object (GLenum shaderType) +{ + switch (shaderType) + { + case GL_FRAGMENT_SHADER_ARB: + { + struct gl2_fragment_shader_impl *x = (struct gl2_fragment_shader_impl *) + _mesa_malloc (sizeof (struct gl2_fragment_shader_impl)); + + if (x != NULL) + { + _fragment_shader_constructor (x); + return x->_obj._shader._generic.name; + } + } + break; + case GL_VERTEX_SHADER_ARB: + { + struct gl2_vertex_shader_impl *x = (struct gl2_vertex_shader_impl *) + _mesa_malloc (sizeof (struct gl2_vertex_shader_impl)); + + if (x != NULL) + { + _vertex_shader_constructor (x); + return x->_obj._shader._generic.name; + } + } + break; + } + + return 0; +} + +GLhandleARB +_mesa_3dlabs_create_program_object (void) +{ + struct gl2_program_impl *x = (struct gl2_program_impl *) + _mesa_malloc (sizeof (struct gl2_program_impl)); + + if (x != NULL) + { + _program_constructor (x); + return x->_obj._container._generic.name; + } + + return 0; +} + +#include "slang_assemble.h" +#include "slang_execute.h" + +int _slang_fetch_discard (struct gl2_program_intf **pro, GLboolean *val) +{ + struct gl2_program_impl *impl; + + impl = (struct gl2_program_impl *) pro; + *val = impl->_obj.prog.machines[SLANG_SHADER_FRAGMENT]->kill ? GL_TRUE : GL_FALSE; + return 1; +} + +static GLvoid exec_shader (struct gl2_program_intf **pro, GLuint i) +{ + struct gl2_program_impl *impl; + slang_program *p; + + impl = (struct gl2_program_impl *) pro; + p = &impl->_obj.prog; + + slang_machine_init (p->machines[i]); + p->machines[i]->ip = p->code[i][SLANG_COMMON_CODE_MAIN]; + + _slang_execute2 (p->assemblies[i], p->machines[i]); +} + +GLvoid _slang_exec_fragment_shader (struct gl2_program_intf **pro) +{ + exec_shader (pro, SLANG_SHADER_FRAGMENT); +} + +GLvoid _slang_exec_vertex_shader (struct gl2_program_intf **pro) +{ + exec_shader (pro, SLANG_SHADER_VERTEX); +} + +void +_mesa_init_shaderobjects_3dlabs (GLcontext *ctx) +{ +#if USE_3DLABS_FRONTEND + _glslang_3dlabs_InitProcess (); + _glslang_3dlabs_ShInitialize (); +#endif +} + diff --git a/src/mesa/shader/shaderobjects_3dlabs.h b/src/mesa/shader/shaderobjects_3dlabs.h index d82079d8f31..8bf273ae9d7 100755 --- a/src/mesa/shader/shaderobjects_3dlabs.h +++ b/src/mesa/shader/shaderobjects_3dlabs.h @@ -1,56 +1,44 @@ -/*
- * Mesa 3-D graphics library
- * Version: 6.5
- *
- * Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef SHADEROBJECTS_3DLABS_H
-#define SHADEROBJECTS_3DLABS_H
-
-extern int _slang_fetch_discard (struct gl2_program_intf **pro, GLboolean *val);
-
-extern GLvoid _slang_exec_fragment_shader (struct gl2_program_intf **pro);
-
-extern GLvoid _slang_exec_vertex_shader (struct gl2_program_intf **pro);
-
-extern GLint _slang_get_uniform_location (struct gl2_program_intf **pro, const char *name);
-
-extern GLboolean _slang_write_uniform (struct gl2_program_intf **pro, GLint loc, GLsizei count,
- const GLvoid *data, GLenum type);
-
-extern GLuint _slang_get_active_uniform_count (struct gl2_program_intf **pro);
-
-extern GLuint _slang_get_active_uniform_max_length (struct gl2_program_intf **pro);
-
-extern GLvoid _slang_get_active_uniform (struct gl2_program_intf **pro, GLuint index, GLsizei maxLength,
- GLsizei *length, GLint *size, GLenum *type, char *name);
-
-extern GLhandleARB
-_mesa_3dlabs_create_shader_object (GLenum);
-
-extern GLhandleARB
-_mesa_3dlabs_create_program_object (GLvoid);
-
-extern void
-_mesa_init_shaderobjects_3dlabs (GLcontext *ctx);
-
-#endif
-
+/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef SHADEROBJECTS_3DLABS_H +#define SHADEROBJECTS_3DLABS_H + +extern int _slang_fetch_discard (struct gl2_program_intf **pro, GLboolean *val); + +extern GLvoid _slang_exec_fragment_shader (struct gl2_program_intf **pro); + +extern GLvoid _slang_exec_vertex_shader (struct gl2_program_intf **pro); + +extern GLhandleARB +_mesa_3dlabs_create_shader_object (GLenum); + +extern GLhandleARB +_mesa_3dlabs_create_program_object (GLvoid); + +extern void +_mesa_init_shaderobjects_3dlabs (GLcontext *ctx); + +#endif + diff --git a/src/mesa/shader/slang/slang_export.c b/src/mesa/shader/slang/slang_export.c index 515c03fb641..dcf64244b74 100644 --- a/src/mesa/shader/slang/slang_export.c +++ b/src/mesa/shader/slang/slang_export.c @@ -79,6 +79,11 @@ GLboolean slang_export_data_quant_struct (slang_export_data_quant *self) return self->structure != NULL;
}
+GLboolean slang_export_data_quant_simple (slang_export_data_quant *self)
+{
+ return self->array_len == 0 && self->structure == NULL;
+}
+
GLenum slang_export_data_quant_type (slang_export_data_quant *self)
{
assert (self->structure == NULL);
diff --git a/src/mesa/shader/slang/slang_export.h b/src/mesa/shader/slang/slang_export.h index c158eb44431..aaf00773c1e 100644 --- a/src/mesa/shader/slang/slang_export.h +++ b/src/mesa/shader/slang/slang_export.h @@ -69,6 +69,11 @@ GLboolean slang_export_data_quant_array (slang_export_data_quant *); GLboolean slang_export_data_quant_struct (slang_export_data_quant *);
/*
+ * Returns GL_TRUE if the quant is neither an array nor a structure.
+ */
+GLboolean slang_export_data_quant_simple (slang_export_data_quant *);
+
+/*
* Returns basic type of the quant. It must not be a structure.
*/
GLenum slang_export_data_quant_type (slang_export_data_quant *);
@@ -81,7 +86,7 @@ GLuint slang_export_data_quant_fields (slang_export_data_quant *); /*
* Return number of elements in the quant.
* For arrays, return the size of the array.
- * For scalars, return 1.
+ * Otherwise, return 1.
*/
GLuint slang_export_data_quant_elements (slang_export_data_quant *);
diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index a72ec2eaa0b..9d61a29e912 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -32,6 +32,151 @@ #include "slang_link.h"
#include "slang_analyse.h"
+static GLboolean entry_has_gl_prefix (slang_atom name, slang_atom_pool *atoms)
+{
+ const char *str = slang_atom_pool_id (atoms, name);
+ return str[0] == 'g' && str[1] == 'l' && str[2] == '_';
+}
+
+/*
+ * slang_active_variables
+ */
+
+static GLvoid slang_active_variables_ctr (slang_active_variables *self)
+{
+ self->table = NULL;
+ self->count = 0;
+}
+
+static GLvoid slang_active_variables_dtr (slang_active_variables *self)
+{
+ GLuint i;
+
+ for (i = 0; i < self->count; i++)
+ slang_alloc_free (self->table[i].name);
+ slang_alloc_free (self->table);
+}
+
+static GLboolean add_simple_variable (slang_active_variables *self, slang_export_data_quant *q,
+ const char *name)
+{
+ const GLuint n = self->count;
+
+ self->table = (slang_active_variable *) slang_alloc_realloc (self->table,
+ n * sizeof (slang_active_variable), (n + 1) * sizeof (slang_active_variable));
+ if (self->table == NULL)
+ return GL_FALSE;
+
+ self->table[n].quant = q;
+ self->table[n].name = slang_string_duplicate (name);
+ if (self->table[n].name == NULL)
+ return GL_FALSE;
+ self->count++;
+
+ return GL_TRUE;
+}
+
+static GLboolean add_complex_variable (slang_active_variables *self, slang_export_data_quant *q,
+ char *name, slang_atom_pool *atoms)
+{
+ slang_string_concat (name, slang_atom_pool_id (atoms, q->name));
+ if (slang_export_data_quant_array (q))
+ slang_string_concat (name, "[0]");
+
+ if (slang_export_data_quant_struct (q))
+ {
+ GLuint dot_pos, i;
+ const GLuint fields = slang_export_data_quant_fields (q);
+
+ slang_string_concat (name, ".");
+ dot_pos = slang_string_length (name);
+
+ for (i = 0; i < fields; i++)
+ {
+ if (!add_complex_variable (self, &q->structure[i], name, atoms))
+ return GL_FALSE;
+
+ name[dot_pos] = '\0';
+ }
+
+ return GL_TRUE;
+ }
+
+ return add_simple_variable (self, q, name);
+}
+
+static GLboolean gather_active_variables (slang_active_variables *self,
+ slang_export_data_table *tbl, slang_export_data_access access)
+{
+ GLuint i;
+
+ for (i = 0; i < tbl->count; i++)
+ if (tbl->entries[i].access == access)
+ {
+ char name[1024] = "";
+
+ if (!add_complex_variable (self, &tbl->entries[i].quant, name, tbl->atoms))
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+/*
+ * slang_attrib_overrides
+ */
+
+static GLvoid slang_attrib_overrides_ctr (slang_attrib_overrides *self)
+{
+ self->table = NULL;
+ self->count = 0;
+}
+
+static GLvoid slang_attrib_overrides_dtr (slang_attrib_overrides *self)
+{
+ GLuint i;
+
+ for (i = 0; i < self->count; i++)
+ slang_alloc_free (self->table[i].name);
+ slang_alloc_free (self->table);
+}
+
+GLboolean slang_attrib_overrides_add (slang_attrib_overrides *self, GLuint index, const GLchar *name)
+{
+ const GLuint n = self->count;
+ GLuint i;
+
+ for (i = 0; i < n; i++)
+ if (slang_string_compare (name, self->table[i].name) == 0)
+ {
+ self->table[i].index = index;
+ return GL_TRUE;
+ }
+
+ self->table = (slang_attrib_override *) slang_alloc_realloc (self->table,
+ n * sizeof (slang_attrib_override), (n + 1) * sizeof (slang_attrib_override));
+ if (self->table == NULL)
+ return GL_FALSE;
+
+ self->table[n].index = index;
+ self->table[n].name = slang_string_duplicate (name);
+ if (self->table[n].name == NULL)
+ return GL_FALSE;
+ self->count++;
+
+ return GL_TRUE;
+}
+
+static GLuint lookup_attrib_override (slang_attrib_overrides *self, const GLchar *name)
+{
+ GLuint i;
+
+ for (i = 0; self->count; i++)
+ if (slang_string_compare (name, self->table[i].name) == 0)
+ return self->table[i].index;
+ return MAX_VERTEX_ATTRIBS;
+}
+
/*
* slang_uniform_bindings
*/
@@ -51,8 +196,8 @@ static GLvoid slang_uniform_bindings_dtr (slang_uniform_bindings *self) slang_alloc_free (self->table);
}
-static GLboolean slang_uniform_bindings_add (slang_uniform_bindings *self, slang_export_data_quant *q,
- const char *name, GLuint index, GLuint address)
+static GLboolean add_simple_uniform_binding (slang_uniform_bindings *self,
+ slang_export_data_quant *q, const char *name, GLuint index, GLuint addr)
{
const GLuint n = self->count;
GLuint i;
@@ -60,7 +205,7 @@ static GLboolean slang_uniform_bindings_add (slang_uniform_bindings *self, slang for (i = 0; i < n; i++)
if (slang_string_compare (self->table[i].name, name) == 0)
{
- self->table[i].address[index] = address;
+ self->table[i].address[index] = addr;
return GL_TRUE;
}
@@ -68,19 +213,21 @@ static GLboolean slang_uniform_bindings_add (slang_uniform_bindings *self, slang n * sizeof (slang_uniform_binding), (n + 1) * sizeof (slang_uniform_binding));
if (self->table == NULL)
return GL_FALSE;
+
self->table[n].quant = q;
self->table[n].name = slang_string_duplicate (name);
- for (i = 0; i < SLANG_SHADER_MAX; i++)
- self->table[n].address[i] = ~0;
- self->table[n].address[index] = address;
if (self->table[n].name == NULL)
return GL_FALSE;
+ for (i = 0; i < SLANG_SHADER_MAX; i++)
+ self->table[n].address[i] = ~0;
+ self->table[n].address[index] = addr;
self->count++;
+
return GL_TRUE;
}
-static GLboolean insert_uniform_binding (slang_uniform_bindings *bind, slang_export_data_quant *q,
- char *name, slang_atom_pool *atoms, GLuint index, GLuint addr)
+static GLboolean add_complex_uniform_binding (slang_uniform_bindings *self,
+ slang_export_data_quant *q, char *name, slang_atom_pool *atoms, GLuint index, GLuint addr)
{
GLuint count, i;
@@ -88,41 +235,44 @@ static GLboolean insert_uniform_binding (slang_uniform_bindings *bind, slang_exp count = slang_export_data_quant_elements (q);
for (i = 0; i < count; i++)
{
- GLuint save;
+ GLuint bracket_pos;
- save = slang_string_length (name);
+ bracket_pos = slang_string_length (name);
if (slang_export_data_quant_array (q))
_mesa_sprintf (name + slang_string_length (name), "[%d]", i);
if (slang_export_data_quant_struct (q))
{
- GLuint save, i;
+ GLuint dot_pos, i;
const GLuint fields = slang_export_data_quant_fields (q);
slang_string_concat (name, ".");
- save = slang_string_length (name);
+ dot_pos = slang_string_length (name);
for (i = 0; i < fields; i++)
{
- if (!insert_uniform_binding (bind, &q->structure[i], name, atoms, index, addr))
+ if (!add_complex_uniform_binding (self, &q->structure[i], name, atoms, index, addr))
return GL_FALSE;
- name[save] = '\0';
+
+ name[dot_pos] = '\0';
addr += slang_export_data_quant_size (&q->structure[i]);
}
}
else
{
- if (!slang_uniform_bindings_add (bind, q, name, index, addr))
+ if (!add_simple_uniform_binding (self, q, name, index, addr))
return GL_FALSE;
+
addr += slang_export_data_quant_size (q);
}
- name[save] = '\0';
+
+ name[bracket_pos] = '\0';
}
return GL_TRUE;
}
-static GLboolean gather_uniform_bindings (slang_uniform_bindings *bind,
+static GLboolean gather_uniform_bindings (slang_uniform_bindings *self,
slang_export_data_table *tbl, GLuint index)
{
GLuint i;
@@ -132,8 +282,8 @@ static GLboolean gather_uniform_bindings (slang_uniform_bindings *bind, {
char name[1024] = "";
- if (!insert_uniform_binding (bind, &tbl->entries[i].quant, name, tbl->atoms, index,
- tbl->entries[i].address))
+ if (!add_complex_uniform_binding (self, &tbl->entries[i].quant, name, tbl->atoms, index,
+ tbl->entries[i].address))
return GL_FALSE;
}
@@ -141,80 +291,145 @@ static GLboolean gather_uniform_bindings (slang_uniform_bindings *bind, }
/*
- * slang_active_uniforms
+ * slang_attrib_bindings
*/
-static GLvoid slang_active_uniforms_ctr (slang_active_uniforms *self)
+static GLvoid slang_attrib_bindings_ctr (slang_attrib_bindings *self)
{
- self->table = NULL;
- self->count = 0;
+ GLuint i;
+
+ self->binding_count = 0;
+ for (i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+ self->slots[i].addr = ~0;
}
-static GLvoid slang_active_uniforms_dtr (slang_active_uniforms *self)
+static GLvoid slang_attrib_bindings_dtr (slang_attrib_bindings *self)
{
GLuint i;
- for (i = 0; i < self->count; i++)
- slang_alloc_free (self->table[i].name);
- slang_alloc_free (self->table);
+ for (i = 0; i < self->binding_count; i++)
+ slang_alloc_free (self->bindings[i].name);
}
-static GLboolean slang_active_uniforms_add (slang_active_uniforms *self, slang_export_data_quant *q,
- const char *name)
+static GLuint can_allocate_attrib_slots (slang_attrib_bindings *self, GLuint index, GLuint count)
{
- const GLuint n = self->count;
+ GLuint i;
- self->table = (slang_active_uniform *) slang_alloc_realloc (self->table,
- n * sizeof (slang_active_uniform), (n + 1) * sizeof (slang_active_uniform));
- if (self->table == NULL)
- return GL_FALSE;
- self->table[n].quant = q;
- self->table[n].name = slang_string_duplicate (name);
- if (self->table[n].name == NULL)
- return GL_FALSE;
- self->count++;
- return GL_TRUE;
+ for (i = 0; i < count; i++)
+ if (self->slots[index + i].addr != ~0)
+ break;
+ return i;
}
-static GLboolean insert_uniform (slang_active_uniforms *u, slang_export_data_quant *q, char *name,
- slang_atom_pool *atoms)
+static GLuint allocate_attrib_slots (slang_attrib_bindings *self, GLuint count)
{
- slang_string_concat (name, slang_atom_pool_id (atoms, q->name));
- if (slang_export_data_quant_array (q))
- slang_string_concat (name, "[0]");
+ GLuint i;
- if (slang_export_data_quant_struct (q))
+ for (i = 0; i <= MAX_VERTEX_ATTRIBS - count; i++)
{
- GLuint save, i;
- const GLuint fields = slang_export_data_quant_fields (q);
+ GLuint size;
+
+ size = can_allocate_attrib_slots (self, i, count);
+ if (size == count)
+ return i;
+
+ /* speed-up the search a bit */
+ i += count;
+ }
+ return MAX_VERTEX_ATTRIBS;
+}
- slang_string_concat (name, ".");
- save = slang_string_length (name);
+static GLboolean add_attrib_binding (slang_attrib_bindings *self, slang_export_data_quant *q,
+ const char *name, GLuint addr, GLuint index_override)
+{
+ const GLuint n = self->binding_count;
+ GLuint slot_span, slot_index;
+ GLuint i;
- for (i = 0; i < fields; i++)
- {
- if (!insert_uniform (u, &q->structure[i], name, atoms))
- return GL_FALSE;
- name[save] = '\0';
- }
+ assert (slang_export_data_quant_simple (q));
- return GL_TRUE;
+ switch (slang_export_data_quant_type (q))
+ {
+ case GL_FLOAT:
+ case GL_FLOAT_VEC2:
+ case GL_FLOAT_VEC3:
+ case GL_FLOAT_VEC4:
+ slot_span = 1;
+ break;
+ case GL_FLOAT_MAT2:
+ slot_span = 2;
+ break;
+ case GL_FLOAT_MAT3:
+ slot_span = 3;
+ break;
+ case GL_FLOAT_MAT4:
+ slot_span = 4;
+ break;
+ default:
+ assert (0);
}
- return slang_active_uniforms_add (u, q, name);
+ if (index_override == MAX_VERTEX_ATTRIBS)
+ slot_index = allocate_attrib_slots (self, slot_span);
+ else if (can_allocate_attrib_slots (self, index_override, slot_span) == slot_span)
+ slot_index = index_override;
+ else
+ slot_index = MAX_VERTEX_ATTRIBS;
+
+ if (slot_index == MAX_VERTEX_ATTRIBS)
+ {
+ /* TODO: info log: error: MAX_VERTEX_ATTRIBS exceeded */
+ return GL_FALSE;
+ }
+
+ self->bindings[n].quant = q;
+ self->bindings[n].name = slang_string_duplicate (name);
+ if (self->bindings[n].name == NULL)
+ return GL_FALSE;
+ self->bindings[n].first_slot_index = slot_index;
+ self->binding_count++;
+
+ for (i = 0; i < slot_span; i++)
+ self->slots[self->bindings[n].first_slot_index + i].addr = addr + i * 4;
+
+ return GL_TRUE;
}
-static GLboolean gather_active_uniforms (slang_active_uniforms *u, slang_export_data_table *tbl)
+static GLboolean gather_attrib_bindings (slang_attrib_bindings *self, slang_export_data_table *tbl,
+ slang_attrib_overrides *ovr)
{
GLuint i;
+ /* First pass. Gather attribs that have overriden index slots. */
for (i = 0; i < tbl->count; i++)
- if (tbl->entries[i].access == slang_exp_uniform)
+ if (tbl->entries[i].access == slang_exp_attribute &&
+ !entry_has_gl_prefix (tbl->entries[i].quant.name, tbl->atoms))
{
- char name[1024] = "";
+ slang_export_data_quant *quant = &tbl->entries[i].quant;
+ const GLchar *id = slang_atom_pool_id (tbl->atoms, quant->name);
+ GLuint index = lookup_attrib_override (ovr, id);
- if (!insert_uniform (u, &tbl->entries[i].quant, name, tbl->atoms))
- return GL_FALSE;
+ if (index != MAX_VERTEX_ATTRIBS)
+ {
+ if (!add_attrib_binding (self, quant, id, tbl->entries[i].address, index))
+ return GL_FALSE;
+ }
+ }
+
+ /* Second pass. Gather attribs that have *NOT* overriden index slots. */
+ for (i = 0; i < tbl->count; i++)
+ if (tbl->entries[i].access == slang_exp_attribute &&
+ !entry_has_gl_prefix (tbl->entries[i].quant.name, tbl->atoms))
+ {
+ slang_export_data_quant *quant = &tbl->entries[i].quant;
+ const GLchar *id = slang_atom_pool_id (tbl->atoms, quant->name);
+ GLuint index = lookup_attrib_override (ovr, id);
+
+ if (index == MAX_VERTEX_ATTRIBS)
+ {
+ if (!add_attrib_binding (self, quant, id, tbl->entries[i].address, index))
+ return GL_FALSE;
+ }
}
return GL_TRUE;
@@ -226,75 +441,68 @@ static GLboolean gather_active_uniforms (slang_active_uniforms *u, slang_export_ static GLvoid slang_varying_bindings_ctr (slang_varying_bindings *self)
{
- self->count = 0;
- self->total = 0;
+ self->binding_count = 0;
+ self->slot_count = 0;
}
static GLvoid slang_varying_bindings_dtr (slang_varying_bindings *self)
{
GLuint i;
- for (i = 0; i < self->count; i++)
- slang_alloc_free (self->table[i].name);
+ for (i = 0; i < self->binding_count; i++)
+ slang_alloc_free (self->bindings[i].name);
}
-static GLvoid update_varying_slots (slang_varying_slot *slots, GLuint count, GLboolean vert,
- GLuint address, GLuint do_offset)
+static GLvoid update_varying_slots (slang_varying_slot *slots, GLuint count, GLboolean is_vert,
+ GLuint addr, GLuint do_offset)
{
GLuint i;
for (i = 0; i < count; i++)
- if (vert)
- slots[i].vert_addr = address + i * 4 * do_offset;
- else
- slots[i].frag_addr = address + i * 4 * do_offset;
+ *(is_vert ? &slots[i].vert_addr : &slots[i].frag_addr) = addr + i * 4 * do_offset;
}
-static GLboolean slang_varying_bindings_add (slang_varying_bindings *self,
- slang_export_data_quant *q, const char *name, GLboolean vert, GLuint address)
+static GLboolean add_varying_binding (slang_varying_bindings *self,
+ slang_export_data_quant *q, const char *name, GLboolean is_vert, GLuint addr)
{
- const GLuint n = self->count;
- const GLuint total_components =
+ const GLuint n = self->binding_count;
+ const GLuint slot_span =
slang_export_data_quant_components (q) * slang_export_data_quant_elements (q);
GLuint i;
for (i = 0; i < n; i++)
- if (slang_string_compare (self->table[i].name, name) == 0)
+ if (slang_string_compare (self->bindings[i].name, name) == 0)
{
/* TODO: data quantities must match, or else link fails */
- update_varying_slots (&self->slots[self->table[i].slot], total_components, vert,
- address, 1);
+ update_varying_slots (&self->slots[self->bindings[i].first_slot_index], slot_span,
+ is_vert, addr, 1);
return GL_TRUE;
}
- if (self->total + total_components > MAX_VARYING_FLOATS)
+ if (self->slot_count + slot_span > MAX_VARYING_FLOATS)
{
/* TODO: info log: error: MAX_VARYING_FLOATS exceeded */
return GL_FALSE;
}
- self->table[n].quant = q;
- self->table[n].slot = self->total;
- self->table[n].name = slang_string_duplicate (name);
- if (self->table[n].name == NULL)
+ self->bindings[n].quant = q;
+ self->bindings[n].name = slang_string_duplicate (name);
+ if (self->bindings[n].name == NULL)
return GL_FALSE;
- self->count++;
+ self->bindings[n].first_slot_index = self->slot_count;
+ self->binding_count++;
- update_varying_slots (&self->slots[self->table[n].slot], total_components, vert, address, 1);
- update_varying_slots (&self->slots[self->table[n].slot], total_components, !vert, ~0, 0);
- self->total += total_components;
+ update_varying_slots (&self->slots[self->bindings[n].first_slot_index], slot_span, is_vert,
+ addr, 1);
+ update_varying_slots (&self->slots[self->bindings[n].first_slot_index], slot_span, !is_vert,
+ ~0, 0);
+ self->slot_count += slot_span;
return GL_TRUE;
}
-static GLboolean entry_has_gl_prefix (slang_atom name, slang_atom_pool *atoms)
-{
- const char *str = slang_atom_pool_id (atoms, name);
- return str[0] == 'g' && str[1] == 'l' && str[2] == '_';
-}
-
-static GLboolean gather_varying_bindings (slang_varying_bindings *bind,
- slang_export_data_table *tbl, GLboolean vert)
+static GLboolean gather_varying_bindings (slang_varying_bindings *self,
+ slang_export_data_table *tbl, GLboolean is_vert)
{
GLuint i;
@@ -302,9 +510,8 @@ static GLboolean gather_varying_bindings (slang_varying_bindings *bind, if (tbl->entries[i].access == slang_exp_varying &&
!entry_has_gl_prefix (tbl->entries[i].quant.name, tbl->atoms))
{
- if (!slang_varying_bindings_add (bind, &tbl->entries[i].quant,
- slang_atom_pool_id (tbl->atoms, tbl->entries[i].quant.name), vert,
- tbl->entries[i].address))
+ if (!add_varying_binding (self, &tbl->entries[i].quant, slang_atom_pool_id (tbl->atoms,
+ tbl->entries[i].quant.name), is_vert, tbl->entries[i].address))
return GL_FALSE;
}
@@ -334,8 +541,11 @@ GLvoid slang_program_ctr (slang_program *self) {
GLuint i;
+ slang_active_variables_ctr (&self->active_uniforms);
+ slang_active_variables_ctr (&self->active_attribs);
+ slang_attrib_overrides_ctr (&self->attrib_overrides);
slang_uniform_bindings_ctr (&self->uniforms);
- slang_active_uniforms_ctr (&self->active_uniforms);
+ slang_attrib_bindings_ctr (&self->attribs);
slang_varying_bindings_ctr (&self->varyings);
slang_texture_usages_ctr (&self->texture_usage);
for (i = 0; i < SLANG_SHADER_MAX; i++)
@@ -357,12 +567,47 @@ GLvoid slang_program_ctr (slang_program *self) GLvoid slang_program_dtr (slang_program *self)
{
+ slang_active_variables_dtr (&self->active_uniforms);
+ slang_active_variables_dtr (&self->active_attribs);
+ slang_attrib_overrides_dtr (&self->attrib_overrides);
slang_uniform_bindings_dtr (&self->uniforms);
- slang_active_uniforms_dtr (&self->active_uniforms);
+ slang_attrib_bindings_dtr (&self->attribs);
slang_varying_bindings_dtr (&self->varyings);
slang_texture_usages_dtr (&self->texture_usage);
}
+static GLvoid slang_program_rst (slang_program *self)
+{
+ GLuint i;
+
+ slang_active_variables_dtr (&self->active_uniforms);
+ slang_active_variables_dtr (&self->active_attribs);
+ slang_uniform_bindings_dtr (&self->uniforms);
+ slang_attrib_bindings_dtr (&self->attribs);
+ slang_varying_bindings_dtr (&self->varyings);
+ slang_texture_usages_dtr (&self->texture_usage);
+
+ slang_active_variables_ctr (&self->active_uniforms);
+ slang_active_variables_ctr (&self->active_attribs);
+ slang_uniform_bindings_ctr (&self->uniforms);
+ slang_attrib_bindings_ctr (&self->attribs);
+ slang_varying_bindings_ctr (&self->varyings);
+ slang_texture_usages_ctr (&self->texture_usage);
+ for (i = 0; i < SLANG_SHADER_MAX; i++)
+ {
+ GLuint j;
+
+ for (j = 0; j < SLANG_COMMON_FIXED_MAX; j++)
+ self->common_fixed_entries[i][j] = ~0;
+ for (j = 0; j < SLANG_COMMON_CODE_MAX; j++)
+ self->code[i][j] = ~0;
+ }
+ for (i = 0; i < SLANG_VERTEX_FIXED_MAX; i++)
+ self->vertex_fixed_entries[i] = ~0;
+ for (i = 0; i < SLANG_FRAGMENT_FIXED_MAX; i++)
+ self->fragment_fixed_entries[i] = ~0;
+}
+
/*
* _slang_link()
*/
@@ -494,6 +739,8 @@ GLboolean _slang_link (slang_program *prog, slang_translation_unit **units, GLui {
GLuint i;
+ slang_program_rst (prog);
+
for (i = 0; i < count; i++)
{
GLuint index;
@@ -507,11 +754,18 @@ GLboolean _slang_link (slang_program *prog, slang_translation_unit **units, GLui {
index = SLANG_SHADER_VERTEX;
resolve_vertex_fixed (prog->vertex_fixed_entries, &units[i]->exp_data);
+ if (!gather_attrib_bindings (&prog->attribs, &units[i]->exp_data,
+ &prog->attrib_overrides))
+ return GL_FALSE;
}
- if (!gather_uniform_bindings (&prog->uniforms, &units[i]->exp_data, index))
+ if (!gather_active_variables (&prog->active_uniforms, &units[i]->exp_data,
+ slang_exp_uniform))
+ return GL_FALSE;
+ if (!gather_active_variables (&prog->active_attribs, &units[i]->exp_data,
+ slang_exp_attribute))
return GL_FALSE;
- if (!gather_active_uniforms (&prog->active_uniforms, &units[i]->exp_data))
+ if (!gather_uniform_bindings (&prog->uniforms, &units[i]->exp_data, index))
return GL_FALSE;
if (!gather_varying_bindings (&prog->varyings, &units[i]->exp_data,
index == SLANG_SHADER_VERTEX))
diff --git a/src/mesa/shader/slang/slang_link.h b/src/mesa/shader/slang/slang_link.h index e74c2565621..6f63a9d31dd 100644 --- a/src/mesa/shader/slang/slang_link.h +++ b/src/mesa/shader/slang/slang_link.h @@ -38,6 +38,61 @@ enum SLANG_SHADER_MAX
};
+/* Active variables.
+ *
+ * Active uniforms or attribs can be queried by the application to get a list of uniforms
+ * or attribs actually used by shaders (uniforms) or vertex shader (attribs).
+ */
+
+typedef struct
+{
+ slang_export_data_quant *quant;
+ char *name;
+} slang_active_variable;
+
+typedef struct
+{
+ slang_active_variable *table;
+ GLuint count;
+} slang_active_variables;
+
+/*
+ * Attrib binding override.
+ *
+ * The application can override GL attrib binding by specifying its preferred index assignment
+ * for a given attrib name. Those overrides are taken into account while linking the program.
+ */
+
+typedef struct
+{
+ GLuint index;
+ GLchar *name;
+} slang_attrib_override;
+
+typedef struct
+{
+ slang_attrib_override *table;
+ GLuint count;
+} slang_attrib_overrides;
+
+GLboolean slang_attrib_overrides_add (slang_attrib_overrides *, GLuint, const GLchar *);
+
+/*
+ * Uniform bindings.
+ *
+ * Each slang_uniform_binding holds an array of addresses to actual memory locations in those
+ * shader types that use that uniform. Uniform bindings are held in an array and accessed
+ * by array index which is seen to the application as a uniform location.
+ *
+ * When the application writes to a particular uniform, it specifies its location.
+ * This location is treated as an array index to slang_uniform_bindings::table and tested
+ * against slang_uniform_bindings::count limit. The result is a pointer to slang_uniform_binding.
+ * The type of data being written to uniform is tested against slang_uniform_binding::quant.
+ * If the types are compatible, the array slang_uniform_binding::address is iterated for
+ * each shader type and if the address is valid (i.e. the uniform is used by this shader type),
+ * the new uniform value is written at that address.
+ */
+
typedef struct
{
slang_export_data_quant *quant;
@@ -51,17 +106,42 @@ typedef struct GLuint count;
} slang_uniform_bindings;
+/*
+ * Attrib bindings.
+ *
+ * There is a fixed number of vertex attrib vectors (attrib slots). The slang_attrib_slot::addr
+ * maps vertex attrib index to the actual memory location of the attrib in vertex shader.
+ * One vertex attrib can span over many attrib slots (this is the case for matrices). The
+ * slang_attrib_binding::first_slot_index holds the first slot index that the attrib is bound to.
+ */
+
typedef struct
{
slang_export_data_quant *quant;
char *name;
-} slang_active_uniform;
+ GLuint first_slot_index;
+} slang_attrib_binding;
typedef struct
{
- slang_active_uniform *table;
- GLuint count;
-} slang_active_uniforms;
+ GLuint addr;
+} slang_attrib_slot;
+
+typedef struct
+{
+ slang_attrib_binding bindings[MAX_VERTEX_ATTRIBS];
+ GLuint binding_count;
+ slang_attrib_slot slots[MAX_VERTEX_ATTRIBS];
+} slang_attrib_bindings;
+
+/*
+ * Varying bindings.
+ *
+ * There is a fixed number of varying floats (varying slots). The slang_varying_slot::vert_addr
+ * maps varying float index to the actual memory location of the output variable in vertex shader.
+ * The slang_varying_slot::frag_addr maps varying float index to the actual memory location of
+ * the input variable in fragment shader.
+ */
typedef struct
{
@@ -73,17 +153,30 @@ typedef struct {
slang_export_data_quant *quant;
char *name;
- GLuint slot;
+ GLuint first_slot_index;
} slang_varying_binding;
typedef struct
{
- slang_varying_binding table[MAX_VARYING_FLOATS];
- GLuint count;
+ slang_varying_binding bindings[MAX_VARYING_FLOATS];
+ GLuint binding_count;
slang_varying_slot slots[MAX_VARYING_FLOATS];
- GLuint total;
+ GLuint slot_count;
} slang_varying_bindings;
+/*
+ * Texture usage.
+ *
+ * A slang_texture_usage struct holds indirect information about texture image unit usage. The
+ * slang_texture_usages::table is derived from active uniform table by extracting only uniforms
+ * that are samplers.
+ *
+ * To collect current texture usage one must iterate the slang_texture_usages::table and read
+ * uniform at address slang_texture_usage::frag_address to get texture unit index. This
+ * index, coupled with texture access type (target) taken from slang_texture_usage::quant
+ * forms texture usage for that texture unit.
+ */
+
typedef struct
{
slang_export_data_quant *quant;
@@ -192,8 +285,11 @@ enum typedef struct
{
+ slang_active_variables active_uniforms;
+ slang_active_variables active_attribs;
+ slang_attrib_overrides attrib_overrides;
slang_uniform_bindings uniforms;
- slang_active_uniforms active_uniforms;
+ slang_attrib_bindings attribs;
slang_varying_bindings varyings;
slang_texture_usages texture_usage;
GLuint common_fixed_entries[SLANG_SHADER_MAX][SLANG_COMMON_FIXED_MAX];
|