Add support for ARB_vertex_shader attrib binding and query.

Clean-up ARB_shaderobjects code a bit.
This commit is contained in:
Michal Krol 2006-04-18 10:30:29 +00:00
parent fcdc6a7d24
commit d55de658b5
8 changed files with 2507 additions and 1958 deletions

View file

@ -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;
}

View file

@ -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);
};

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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);

View file

@ -68,6 +68,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.
*/
@ -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 *);

View file

@ -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)
{
self->table = NULL;
self->count = 0;
}
static GLvoid slang_active_uniforms_dtr (slang_active_uniforms *self)
static GLvoid slang_attrib_bindings_ctr (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);
self->binding_count = 0;
for (i = 0; i < MAX_VERTEX_ATTRIBS; i++)
self->slots[i].addr = ~0;
}
static GLboolean slang_active_uniforms_add (slang_active_uniforms *self, slang_export_data_quant *q,
const char *name)
static GLvoid slang_attrib_bindings_dtr (slang_attrib_bindings *self)
{
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)
for (i = 0; i < self->binding_count; i++)
slang_alloc_free (self->bindings[i].name);
}
static GLuint can_allocate_attrib_slots (slang_attrib_bindings *self, GLuint index, GLuint count)
{
GLuint i;
for (i = 0; i < count; i++)
if (self->slots[index + i].addr != ~0)
break;
return i;
}
static GLuint allocate_attrib_slots (slang_attrib_bindings *self, GLuint count)
{
GLuint i;
for (i = 0; i <= MAX_VERTEX_ATTRIBS - count; i++)
{
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;
}
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;
assert (slang_export_data_quant_simple (q));
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);
}
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->table[n].quant = q;
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 = 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 insert_uniform (slang_active_uniforms *u, 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 save, i;
const GLuint fields = slang_export_data_quant_fields (q);
slang_string_concat (name, ".");
save = slang_string_length (name);
for (i = 0; i < fields; i++)
{
if (!insert_uniform (u, &q->structure[i], name, atoms))
return GL_FALSE;
name[save] = '\0';
}
return GL_TRUE;
}
return slang_active_uniforms_add (u, q, name);
}
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_uniforms (&prog->active_uniforms, &units[i]->exp_data))
if (!gather_active_variables (&prog->active_attribs, &units[i]->exp_data,
slang_exp_attribute))
return GL_FALSE;
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))

View file

@ -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];