diff options
author | Keith Whitwell <[email protected]> | 2007-01-16 11:22:57 +0000 |
---|---|---|
committer | Keith Whitwell <[email protected]> | 2007-01-16 11:22:57 +0000 |
commit | 6a3fdc3a1ea6c306d9543791bf172dd1052d7382 (patch) | |
tree | c372c6daff13e435e79914c2e40dfe9d370c337b /src/mesa/shader | |
parent | 0b412f8f156b46b0e7220a2b61e0f41781769f66 (diff) | |
parent | a03fc8277180e2171519165a724849e2254ef0b7 (diff) |
Merge branch 'master' of git+ssh://[email protected]/git/mesa/mesa into vbo-0.2
Conflicts:
src/mesa/array_cache/sources
src/mesa/drivers/dri/i965/brw_context.c
src/mesa/drivers/dri/i965/brw_draw.c
src/mesa/drivers/dri/i965/brw_fallback.c
src/mesa/drivers/dri/i965/brw_vs_emit.c
src/mesa/drivers/dri/i965/brw_vs_tnl.c
src/mesa/drivers/dri/mach64/mach64_context.c
src/mesa/main/extensions.c
src/mesa/main/getstring.c
src/mesa/tnl/sources
src/mesa/tnl/t_save_api.c
src/mesa/tnl/t_save_playback.c
src/mesa/tnl/t_vtx_api.c
src/mesa/tnl/t_vtx_exec.c
src/mesa/vbo/vbo_attrib.h
src/mesa/vbo/vbo_exec_api.c
src/mesa/vbo/vbo_save_api.c
src/mesa/vbo/vbo_save_draw.c
Diffstat (limited to 'src/mesa/shader')
38 files changed, 8695 insertions, 7775 deletions
diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c index 43e3bc183d4..72d49093721 100644 --- a/src/mesa/shader/arbprogparse.c +++ b/src/mesa/shader/arbprogparse.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5.2 + * Version: 6.5.1 * * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * @@ -77,12 +77,6 @@ struct arb_program }; -#ifndef __extension__ -#if !defined(__GNUC__) || (__GNUC__ < 2) || \ - ((__GNUC__ == 2) && (__GNUC_MINOR__ <= 7)) -# define __extension__ -#endif -#endif /* TODO: * Fragment Program Stuff: @@ -168,10 +162,11 @@ struct arb_program typedef GLubyte *production; + /** * This is the text describing the rules to parse the grammar */ -__extension__ static char arb_grammar_text[] = +LONGSTRING static char arb_grammar_text[] = #include "arbprogram_syn.h" ; @@ -1815,7 +1810,7 @@ parse_param_elements (GLcontext * ctx, const GLubyte ** inst, parse_constant (inst, const_values, Program, use); idx = _mesa_add_named_constant(Program->Base.Parameters, (char *) param_var->name, - const_values); + const_values, 4); if (param_var->param_binding_begin == ~0U) param_var->param_binding_begin = idx; param_var->param_binding_length++; @@ -3708,7 +3703,7 @@ parse_instructions(GLcontext * ctx, const GLubyte * inst, /* XXX temporary */ -__extension__ static char core_grammar_text[] = +LONGSTRING static char core_grammar_text[] = #include "grammar_syn.h" ; @@ -4053,7 +4048,8 @@ _mesa_parse_arb_fragment_program(GLcontext* ctx, GLenum target, program->Base.Parameters = ap.Base.Parameters; #if DEBUG_FP - _mesa_print_program(&program.Base); + _mesa_printf("____________Fragment program %u ________\n", program->Base.ID); + _mesa_print_program(&program->Base); #endif } @@ -4105,6 +4101,7 @@ _mesa_parse_arb_vertex_program(GLcontext *ctx, GLenum target, program->Base.Parameters = ap.Base.Parameters; #if DEBUG_VP + _mesa_printf("____________Vertex program %u __________\n", program->Base.ID); _mesa_print_program(&program->Base); #endif } diff --git a/src/mesa/shader/arbprogram.c b/src/mesa/shader/arbprogram.c index 89f2d20cc9a..bff80d7ee3a 100644 --- a/src/mesa/shader/arbprogram.c +++ b/src/mesa/shader/arbprogram.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.2 * * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * @@ -36,6 +36,7 @@ #include "imports.h" #include "macros.h" #include "mtypes.h" +#include "program.h" void GLAPIENTRY @@ -101,7 +102,7 @@ _mesa_GetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat *params) GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); - if (index == 0 || index >= MAX_VERTEX_PROGRAM_ATTRIBS) { + if (index >= MAX_VERTEX_PROGRAM_ATTRIBS) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribfvARB(index)"); return; } @@ -123,6 +124,11 @@ _mesa_GetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat *params) params[0] = ctx->Array.ArrayObj->VertexAttrib[index].Normalized; break; case GL_CURRENT_VERTEX_ATTRIB_ARB: + if (index == 0) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetVertexAttribfvARB(index==0)"); + return; + } FLUSH_CURRENT(ctx, 0); COPY_4V(params, ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index]); break; @@ -179,6 +185,31 @@ _mesa_GetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer) } +/** + * Determine if id names a vertex or fragment program. + * \note Not compiled into display lists. + * \note Called from both glIsProgramNV and glIsProgramARB. + * \param id is the program identifier + * \return GL_TRUE if id is a program, else GL_FALSE. + */ +GLboolean GLAPIENTRY +_mesa_IsProgramARB(GLuint id) +{ + struct gl_program *prog = NULL; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); + + if (id == 0) + return GL_FALSE; + + prog = _mesa_lookup_program(ctx, id); + if (prog && (prog != &_mesa_DummyProgram)) + return GL_TRUE; + else + return GL_FALSE; +} + + void GLAPIENTRY _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len, const GLvoid *string) @@ -736,6 +767,7 @@ void GLAPIENTRY _mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string) { const struct gl_program *prog; + char *dst = (char *) string; GET_CURRENT_CONTEXT(ctx); if (!ctx->_CurrentProgram) @@ -759,5 +791,8 @@ _mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string) return; } - _mesa_memcpy(string, prog->String, _mesa_strlen((char *) prog->String)); + if (prog->String) + _mesa_memcpy(dst, prog->String, _mesa_strlen((char *) prog->String)); + else + *dst = '\0'; } diff --git a/src/mesa/shader/arbprogram.h b/src/mesa/shader/arbprogram.h index 54a14bbb9f8..233f6629650 100644 --- a/src/mesa/shader/arbprogram.h +++ b/src/mesa/shader/arbprogram.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 5.1 + * Version: 6.5.2 * - * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. + * Copyright (C) 1999-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"), @@ -51,6 +51,10 @@ extern void GLAPIENTRY _mesa_GetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer); +extern GLboolean GLAPIENTRY +_mesa_IsProgramARB(GLuint id); + + extern void GLAPIENTRY _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len, const GLvoid *string); diff --git a/src/mesa/shader/atifragshader.c b/src/mesa/shader/atifragshader.c index d349a496dc7..4727c1a4365 100644 --- a/src/mesa/shader/atifragshader.c +++ b/src/mesa/shader/atifragshader.c @@ -400,6 +400,8 @@ _mesa_EndFragmentShaderATI(void) } } #endif + if (ctx->Driver.ProgramStringNotify) + ctx->Driver.ProgramStringNotify( ctx, GL_FRAGMENT_SHADER_ATI, NULL ); } void GLAPIENTRY diff --git a/src/mesa/shader/descrip.mms b/src/mesa/shader/descrip.mms index 95569a6f25c..d70cec38300 100644 --- a/src/mesa/shader/descrip.mms +++ b/src/mesa/shader/descrip.mms @@ -1,7 +1,6 @@ # Makefile for core library for VMS -# contributed by Jouk Jansen [email protected] -# Last revision : 1 June 2005 - +# contributed by Jouk Jansen [email protected] +# Last revision : 20 November 2006 .first define gl [---.include.gl] define math [-.math] @@ -16,7 +15,7 @@ VPATH = RCS INCDIR = [---.include],[.grammar],[-.main],[-.glapi],[.slang] LIBDIR = [---.lib] -CFLAGS = /include=($(INCDIR),[])/define=(PTHREADS=1)/name=(as_is,short)/float=ieee/ieee=denorm +CFLAGS = /include=($(INCDIR),[])/define=(PTHREADS=1,"__extension__=")/name=(as_is,short)/float=ieee/ieee=denorm SOURCES = \ atifragshader.c \ diff --git a/src/mesa/shader/grammar/sources b/src/mesa/shader/grammar/sources index b1f8530ee5d..a6bbfd3ffd3 100644 --- a/src/mesa/shader/grammar/sources +++ b/src/mesa/shader/grammar/sources @@ -1,2 +1,8 @@ MESA_SHADER_GRAMMAR_SOURCES = \ grammar_mesa.c + +MESA_SHADER_GRAMMAR_HEADERS = \ +grammar.c \ +grammar.h \ +grammar_mesa.h \ +grammar_syn.h diff --git a/src/mesa/shader/nvfragparse.c b/src/mesa/shader/nvfragparse.c index 5f3a30b7416..79e6dbd87b7 100644 --- a/src/mesa/shader/nvfragparse.c +++ b/src/mesa/shader/nvfragparse.c @@ -1041,7 +1041,7 @@ Parse_VectorSrc(struct parse_state *parseState, GLuint paramIndex; if (!Parse_ScalarConstant(parseState, values)) RETURN_ERROR; - paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values); + paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values, 4); srcReg->File = PROGRAM_NAMED_PARAM; srcReg->Index = paramIndex; } @@ -1052,7 +1052,7 @@ Parse_VectorSrc(struct parse_state *parseState, (void) Parse_String(parseState, "{"); if (!Parse_VectorConstant(parseState, values)) RETURN_ERROR; - paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values); + paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values, 4); srcReg->File = PROGRAM_NAMED_PARAM; srcReg->Index = paramIndex; } @@ -1142,7 +1142,7 @@ Parse_ScalarSrcReg(struct parse_state *parseState, (void) Parse_String(parseState, "{"); if (!Parse_VectorConstant(parseState, values)) RETURN_ERROR; - paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values); + paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values, 4); srcReg->File = PROGRAM_NAMED_PARAM; srcReg->Index = paramIndex; } @@ -1166,7 +1166,7 @@ Parse_ScalarSrcReg(struct parse_state *parseState, GLuint paramIndex; if (!Parse_ScalarConstant(parseState, values)) RETURN_ERROR; - paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values); + paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values, 4); srcReg->Index = paramIndex; srcReg->File = PROGRAM_NAMED_PARAM; needSuffix = GL_FALSE; diff --git a/src/mesa/shader/nvprogram.c b/src/mesa/shader/nvprogram.c index 0e9a01dcab8..4f160b14312 100644 --- a/src/mesa/shader/nvprogram.c +++ b/src/mesa/shader/nvprogram.c @@ -360,7 +360,7 @@ _mesa_GetVertexAttribdvNV(GLuint index, GLenum pname, GLdouble *params) GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); - if (index == 0 || index >= MAX_NV_VERTEX_PROGRAM_INPUTS) { + if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribdvNV(index)"); return; } @@ -376,6 +376,11 @@ _mesa_GetVertexAttribdvNV(GLuint index, GLenum pname, GLdouble *params) params[0] = ctx->Array.ArrayObj->VertexAttrib[index].Type; break; case GL_CURRENT_ATTRIB_NV: + if (index == 0) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetVertexAttribdvNV(index == 0)"); + return; + } FLUSH_CURRENT(ctx, 0); COPY_4V(params, ctx->Current.Attrib[index]); break; @@ -396,7 +401,7 @@ _mesa_GetVertexAttribfvNV(GLuint index, GLenum pname, GLfloat *params) GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); - if (index == 0 || index >= MAX_NV_VERTEX_PROGRAM_INPUTS) { + if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribdvNV(index)"); return; } @@ -412,6 +417,11 @@ _mesa_GetVertexAttribfvNV(GLuint index, GLenum pname, GLfloat *params) params[0] = (GLfloat) ctx->Array.ArrayObj->VertexAttrib[index].Type; break; case GL_CURRENT_ATTRIB_NV: + if (index == 0) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetVertexAttribfvNV(index == 0)"); + return; + } FLUSH_CURRENT(ctx, 0); COPY_4V(params, ctx->Current.Attrib[index]); break; @@ -432,7 +442,7 @@ _mesa_GetVertexAttribivNV(GLuint index, GLenum pname, GLint *params) GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); - if (index == 0 || index >= MAX_NV_VERTEX_PROGRAM_INPUTS) { + if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribdvNV(index)"); return; } @@ -448,6 +458,11 @@ _mesa_GetVertexAttribivNV(GLuint index, GLenum pname, GLint *params) params[0] = ctx->Array.ArrayObj->VertexAttrib[index].Type; break; case GL_CURRENT_ATTRIB_NV: + if (index == 0) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetVertexAttribivNV(index == 0)"); + return; + } FLUSH_CURRENT(ctx, 0); params[0] = (GLint) ctx->Current.Attrib[index][0]; params[1] = (GLint) ctx->Current.Attrib[index][1]; diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index 681584941e7..8442ba3248c 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -207,6 +207,7 @@ _mesa_init_program_struct( GLcontext *ctx, struct gl_program *prog, prog->Target = target; prog->Resident = GL_TRUE; prog->RefCount = 1; + prog->Format = GL_PROGRAM_FORMAT_ASCII_ARB; } return prog; @@ -284,6 +285,9 @@ _mesa_delete_program(GLcontext *ctx, struct gl_program *prog) (void) ctx; ASSERT(prog); + if (prog == &_mesa_DummyProgram) + return; + if (prog->String) _mesa_free(prog->String); @@ -430,14 +434,24 @@ _mesa_add_named_parameter(struct gl_program_parameter_list *paramList, * This will be used when the program contains something like this: * PARAM myVals = { 0, 1, 2, 3 }; * - * \param paramList - the parameter list - * \param values - four float values - * \return index of the new parameter. + * \param paramList the parameter list + * \param name the name for the constant + * \param values four float values + * \return index/position of the new parameter in the parameter list */ GLint _mesa_add_named_constant(struct gl_program_parameter_list *paramList, - const char *name, const GLfloat values[4]) + const char *name, const GLfloat values[4], + GLuint size) { +#if 0 /* disable this for now -- we need to save the name! */ + GLuint pos, swizzle; + ASSERT(size == 4); /* XXX future feature */ + /* check if we already have this constant */ + if (_mesa_lookup_parameter_constant(paramList, values, 4, &pos, &swizzle)) { + return pos; + } +#endif return add_parameter(paramList, name, values, PROGRAM_CONSTANT); } @@ -447,14 +461,20 @@ _mesa_add_named_constant(struct gl_program_parameter_list *paramList, * This will be used when the program contains something like this: * MOV r, { 0, 1, 2, 3 }; * - * \param paramList - the parameter list - * \param values - four float values - * \return index of the new parameter. + * \param paramList the parameter list + * \param values four float values + * \return index/position of the new parameter in the parameter list. */ GLint _mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList, - const GLfloat values[4]) + const GLfloat values[4], GLuint size) { + GLuint pos, swizzle; + ASSERT(size == 4); /* XXX future feature */ + /* check if we already have this constant */ + if (_mesa_lookup_parameter_constant(paramList, values, 4, &pos, &swizzle)) { + return pos; + } return add_parameter(paramList, NULL, values, PROGRAM_CONSTANT); } @@ -464,8 +484,8 @@ _mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList, * This will be used when the program contains something like this: * PARAM ambient = state.material.front.ambient; * - * \param paramList - the parameter list - * \param state - an array of 6 state tokens + * \param paramList the parameter list + * \param state an array of 6 state tokens * \return index of the new parameter. */ GLint @@ -500,7 +520,7 @@ _mesa_add_state_reference(struct gl_program_parameter_list *paramList, * \return pointer to the float[4] values. */ GLfloat * -_mesa_lookup_parameter_value(struct gl_program_parameter_list *paramList, +_mesa_lookup_parameter_value(const struct gl_program_parameter_list *paramList, GLsizei nameLen, const char *name) { GLuint i; @@ -530,11 +550,15 @@ _mesa_lookup_parameter_value(struct gl_program_parameter_list *paramList, /** - * Lookup a parameter index by name in the given parameter list. + * Given a program parameter name, find its position in the list of parameters. + * \param paramList the parameter list to search + * \param nameLen length of name (in chars). + * If length is negative, assume that name is null-terminated. + * \param name the name to search for * \return index of parameter in the list. */ GLint -_mesa_lookup_parameter_index(struct gl_program_parameter_list *paramList, +_mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList, GLsizei nameLen, const char *name) { GLint i; @@ -564,6 +588,61 @@ _mesa_lookup_parameter_index(struct gl_program_parameter_list *paramList, /** + * Look for a float vector in the given parameter list. The float vector + * may be of length 1, 2, 3 or 4. + * \param paramList the parameter list to search + * \param v the float vector to search for + * \param size number of element in v + * \param posOut returns the position of the constant, if found + * \param swizzleOut returns a swizzle mask describing location of the + * vector elements if found + * \return GL_TRUE if found, GL_FALSE if not found + */ +GLboolean +_mesa_lookup_parameter_constant(const struct gl_program_parameter_list *paramList, + const GLfloat v[], GLsizei vSize, + GLuint *posOut, GLuint *swizzleOut) +{ + GLuint i; + + assert(vSize >= 1); + assert(vSize <= 4); + + if (!paramList) + return -1; + + for (i = 0; i < paramList->NumParameters; i++) { + if (paramList->Parameters[i].Type == PROGRAM_CONSTANT) { + const GLint maxShift = 4 - vSize; + GLint shift, j; + for (shift = 0; shift <= maxShift; shift++) { + GLint matched = 0; + GLuint swizzle[4]; + swizzle[0] = swizzle[1] = swizzle[2] = swizzle[3] = 0; + /* XXX we could do out-of-order swizzle matches too, someday */ + for (j = 0; j < vSize; j++) { + assert(shift + j < 4); + if (paramList->ParameterValues[i][shift + j] == v[j]) { + matched++; + swizzle[j] = shift + j; + } + } + if (matched == vSize) { + /* found! */ + *posOut = i; + *swizzleOut = MAKE_SWIZZLE4(swizzle[0], swizzle[1], + swizzle[2], swizzle[3]); + return GL_TRUE; + } + } + } + } + + return GL_FALSE; +} + + +/** * Use the list of tokens in the state[] array to find global GL state * and return it in <value>. Usually, four values are returned in <value> * but matrix queries may return as many as 16 values. @@ -918,7 +997,9 @@ _mesa_fetch_state(GLcontext *ctx, const enum state_index state[], break; } default: - _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()"); + /* unknown state indexes are silently ignored + * should be handled by the driver. + */ return; } } @@ -995,7 +1076,9 @@ make_state_flags(const GLint state[]) case STATE_TEXRECT_SCALE: return _NEW_TEXTURE; default: - _mesa_problem(NULL, "unexpected int. state in make_state_flags()"); + /* unknown state indexes are silently ignored and + * no flag set, since it is handled by the driver. + */ return 0; } @@ -1267,7 +1350,7 @@ make_state_string(const GLint state[6]) case STATE_INTERNAL: break; default: - _mesa_problem(NULL, "Invalid state in maka_state_string"); + _mesa_problem(NULL, "Invalid state in make_state_string"); break; } @@ -1864,10 +1947,14 @@ _mesa_BindProgram(GLenum target, GLuint id) /* bind newProg */ if (target == GL_VERTEX_PROGRAM_ARB) { /* == GL_VERTEX_PROGRAM_NV */ + if (ctx->VertexProgram._Current == ctx->VertexProgram.Current) + ctx->VertexProgram._Current = (struct gl_vertex_program *) newProg; ctx->VertexProgram.Current = (struct gl_vertex_program *) newProg; } else if (target == GL_FRAGMENT_PROGRAM_NV || target == GL_FRAGMENT_PROGRAM_ARB) { + if (ctx->FragmentProgram._Current == ctx->FragmentProgram.Current) + ctx->FragmentProgram._Current = (struct gl_fragment_program *) newProg; ctx->FragmentProgram.Current = (struct gl_fragment_program *) newProg; } newProg->RefCount++; @@ -1886,7 +1973,7 @@ _mesa_BindProgram(GLenum target, GLuint id) * \note Not compiled into display lists. * \note Called by both glDeleteProgramsNV and glDeleteProgramsARB. */ -void GLAPIENTRY +void GLAPIENTRY _mesa_DeletePrograms(GLsizei n, const GLuint *ids) { GLint i; @@ -1973,30 +2060,6 @@ _mesa_GenPrograms(GLsizei n, GLuint *ids) } -/** - * Determine if id names a vertex or fragment program. - * \note Not compiled into display lists. - * \note Called from both glIsProgramNV and glIsProgramARB. - * \param id is the program identifier - * \return GL_TRUE if id is a program, else GL_FALSE. - */ -GLboolean GLAPIENTRY -_mesa_IsProgram(GLuint id) -{ - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); - - if (id == 0) - return GL_FALSE; - - if (_mesa_lookup_program(ctx, id)) - return GL_TRUE; - else - return GL_FALSE; -} - - - /**********************************************************************/ /* GL_MESA_program_debug extension */ /**********************************************************************/ diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h index cf3b1cc0990..af06c03598f 100644 --- a/src/mesa/shader/program.h +++ b/src/mesa/shader/program.h @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5.1 + * Version: 6.5.2 * * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * @@ -189,7 +189,8 @@ enum state_index { STATE_INTERNAL, /* Mesa additions */ STATE_NORMAL_SCALE, STATE_TEXRECT_SCALE, - STATE_POSITION_NORMALIZED /* normalized light position */ + STATE_POSITION_NORMALIZED, /* normalized light position */ + STATE_INTERNAL_DRIVER /* first available state index for drivers (must be last) */ }; @@ -238,30 +239,34 @@ _mesa_add_named_parameter(struct gl_program_parameter_list *paramList, extern GLint _mesa_add_named_constant(struct gl_program_parameter_list *paramList, - const char *name, const GLfloat values[4]); + const char *name, const GLfloat values[4], + GLuint size); extern GLint _mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList, - const GLfloat values[4]); + const GLfloat values[4], GLuint size); extern GLint _mesa_add_state_reference(struct gl_program_parameter_list *paramList, const GLint *stateTokens); extern GLfloat * -_mesa_lookup_parameter_value(struct gl_program_parameter_list *paramList, +_mesa_lookup_parameter_value(const struct gl_program_parameter_list *paramList, GLsizei nameLen, const char *name); extern GLint -_mesa_lookup_parameter_index(struct gl_program_parameter_list *paramList, +_mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList, GLsizei nameLen, const char *name); +extern GLboolean +_mesa_lookup_parameter_constant(const struct gl_program_parameter_list *paramList, + const GLfloat v[], GLsizei vSize, + GLuint *posOut, GLuint *swizzleOut); + extern void _mesa_load_state_parameters(GLcontext *ctx, struct gl_program_parameter_list *paramList); - - extern void _mesa_print_instruction(const struct prog_instruction *inst); @@ -290,9 +295,6 @@ _mesa_DeletePrograms(GLsizei n, const GLuint *ids); extern void GLAPIENTRY _mesa_GenPrograms(GLsizei n, GLuint *ids); -extern GLboolean GLAPIENTRY -_mesa_IsProgram(GLuint id); - /* diff --git a/src/mesa/shader/program_instruction.h b/src/mesa/shader/program_instruction.h index cdec0ceb2a5..ad3a6d4dd4e 100644 --- a/src/mesa/shader/program_instruction.h +++ b/src/mesa/shader/program_instruction.h @@ -286,7 +286,7 @@ struct prog_instruction GLuint CondUpdate:1; /** - * If prog_instruction::cc_update is \c GL_TRUE, this value selects the + * If prog_instruction::CondUpdate is \c GL_TRUE, this value selects the * condition code register that is to be updated. * * In GL_NV_fragment_program or GL_NV_vertex_program2 mode, only condition @@ -339,6 +339,11 @@ struct prog_instruction */ GLuint TexSrcTarget:3; /*@}*/ + + /** + * For BRA and CAL instructions, the location to jump to. + */ + GLuint BranchTarget; }; diff --git a/src/mesa/shader/programopt.c b/src/mesa/shader/programopt.c index 172d373b578..783177739d1 100644 --- a/src/mesa/shader/programopt.c +++ b/src/mesa/shader/programopt.c @@ -172,7 +172,7 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) fogVals[1] = 1.0 / SQRTF(log(2.0)); fogVals[2] = 0.0; fogVals[3] = 0.0; - fogConsts = _mesa_add_unnamed_constant(fprog->Base.Parameters, fogVals); + fogConsts = _mesa_add_unnamed_constant(fprog->Base.Parameters, fogVals, 4); /* Scan program to find where result.color is written */ inst = newInst; diff --git a/src/mesa/shader/shaderobjects.c b/src/mesa/shader/shaderobjects.c index f26ff12adf1..da4d5c84721 100644 --- a/src/mesa/shader/shaderobjects.c +++ b/src/mesa/shader/shaderobjects.c @@ -50,28 +50,34 @@ #define RELEASE_SHADER(x)\ (**x)._generic._unknown.Release ((struct gl2_unknown_intf **) (x)) + + static struct gl2_unknown_intf ** -lookup_handle (GLcontext *ctx, GLhandleARB handle, enum gl2_uiid uiid, const char *function) +lookup_handle(GLcontext * ctx, GLhandleARB handle, enum gl2_uiid uiid, + const char *function) { struct gl2_unknown_intf **unk; /* - * Note: _mesa_HashLookup() requires non-zero input values, so the passed-in handle value - * must be checked beforehand. + * Note: _mesa_HashLookup() requires non-zero input values, so the + * passed-in handle value must be checked beforehand. */ if (handle == 0) { - _mesa_error (ctx, GL_INVALID_VALUE, function); + _mesa_error(ctx, GL_INVALID_VALUE, function); return NULL; } - _glthread_LOCK_MUTEX (ctx->Shared->Mutex); - unk = (struct gl2_unknown_intf **) (_mesa_HashLookup (ctx->Shared->GL2Objects, handle)); - _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex); - if (unk == NULL) - _mesa_error (ctx, GL_INVALID_VALUE, function); + _glthread_LOCK_MUTEX(ctx->Shared->Mutex); + unk = (struct gl2_unknown_intf **) _mesa_HashLookup(ctx->Shared->GL2Objects, + handle); + _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); + + if (unk == NULL) { + _mesa_error(ctx, GL_INVALID_VALUE, function); + } else { - unk = (**unk).QueryInterface (unk, uiid); + unk = (**unk).QueryInterface(unk, uiid); if (unk == NULL) - _mesa_error (ctx, GL_INVALID_OPERATION, function); + _mesa_error(ctx, GL_INVALID_OPERATION, function); } return unk; } @@ -92,895 +98,635 @@ lookup_handle (GLcontext *ctx, GLhandleARB handle, enum gl2_uiid uiid, const cha struct gl2_shader_intf **x = (struct gl2_shader_intf **)\ lookup_handle (ctx, handle, UIID_SHADER, function); -#define GET_LINKED_PROGRAM(x, handle, function)\ - GET_PROGRAM(x, handle, function);\ - if (x != NULL && (**x).GetLinkStatus (x) == GL_FALSE) {\ - RELEASE_PROGRAM(x);\ - x = NULL;\ - _mesa_error (ctx, GL_INVALID_OPERATION, function);\ + +#define GET_LINKED_PROGRAM(x, handle, function) \ + GET_PROGRAM(x, handle, function); \ + if (x && (**x).GetLinkStatus(x) == GL_FALSE) { \ + RELEASE_PROGRAM(x); \ + _mesa_error(ctx, GL_INVALID_OPERATION, function); \ + x = NULL; \ } -#define GET_CURRENT_LINKED_PROGRAM(x, function)\ - struct gl2_program_intf **x = NULL;\ - if (ctx->ShaderObjects.CurrentProgram == NULL)\ - _mesa_error (ctx, GL_INVALID_OPERATION, function);\ - else {\ - x = ctx->ShaderObjects.CurrentProgram;\ - if (x != NULL && (**x).GetLinkStatus (x) == GL_FALSE) {\ - x = NULL;\ - _mesa_error (ctx, GL_INVALID_OPERATION, function);\ - }\ +#define GET_CURRENT_LINKED_PROGRAM(x, function) \ + struct gl2_program_intf **x = ctx->ShaderObjects.CurrentProgram; \ + if (!x || (**x).GetLinkStatus(x) == GL_FALSE) { \ + _mesa_error(ctx, GL_INVALID_OPERATION, function); \ + return; \ } + + #define IS_NAME_WITH_GL_PREFIX(x) ((x)[0] == 'g' && (x)[1] == 'l' && (x)[2] == '_') GLvoid GLAPIENTRY -_mesa_DeleteObjectARB (GLhandleARB obj) +_mesa_DeleteObjectARB(GLhandleARB obj) { - if (obj != 0) - { + if (obj != 0) { GET_CURRENT_CONTEXT(ctx); GET_GENERIC(gen, obj, "glDeleteObjectARB"); - if (gen != NULL) - { - (**gen).Delete (gen); + if (gen != NULL) { + (**gen).Delete(gen); RELEASE_GENERIC(gen); } } } GLhandleARB GLAPIENTRY -_mesa_GetHandleARB (GLenum pname) +_mesa_GetHandleARB(GLenum pname) { - GET_CURRENT_CONTEXT(ctx); + GET_CURRENT_CONTEXT(ctx); - switch (pname) - { + switch (pname) { case GL_PROGRAM_OBJECT_ARB: { struct gl2_program_intf **pro = ctx->ShaderObjects.CurrentProgram; if (pro != NULL) - return (**pro)._container._generic.GetName ((struct gl2_generic_intf **) (pro)); + return (**pro)._container._generic. + GetName((struct gl2_generic_intf **) (pro)); } break; - default: - _mesa_error (ctx, GL_INVALID_ENUM, "glGetHandleARB"); - } + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB"); + } - return 0; + return 0; } GLvoid GLAPIENTRY -_mesa_DetachObjectARB (GLhandleARB containerObj, GLhandleARB attachedObj) +_mesa_DetachObjectARB(GLhandleARB containerObj, GLhandleARB attachedObj) { - GET_CURRENT_CONTEXT(ctx); - GET_CONTAINER(con, containerObj, "glDetachObjectARB"); + GET_CURRENT_CONTEXT(ctx); + GET_CONTAINER(con, containerObj, "glDetachObjectARB"); - if (con != NULL) - { - GET_GENERIC(att, attachedObj, "glDetachObjectARB"); + if (con != NULL) { + GET_GENERIC(att, attachedObj, "glDetachObjectARB"); - if (att != NULL) - { - (**con).Detach (con, att); - RELEASE_GENERIC(att); - } - RELEASE_CONTAINER(con); - } + if (att != NULL) { + (**con).Detach(con, att); + RELEASE_GENERIC(att); + } + RELEASE_CONTAINER(con); + } } GLhandleARB GLAPIENTRY -_mesa_CreateShaderObjectARB (GLenum shaderType) +_mesa_CreateShaderObjectARB(GLenum shaderType) +{ + return _mesa_3dlabs_create_shader_object(shaderType); +} + +GLvoid GLAPIENTRY +_mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count, + const GLcharARB ** string, const GLint * length) { - return _mesa_3dlabs_create_shader_object (shaderType); + GET_CURRENT_CONTEXT(ctx); + GLint *offsets; + GLsizei i; + GLcharARB *source; + GET_SHADER(sha, shaderObj, "glShaderSourceARB"); + + if (sha == NULL) + return; + + if (string == NULL) { + RELEASE_SHADER(sha); + _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB"); + return; + } + + /* + * This array holds offsets of where the appropriate string ends, thus the last + * element will be set to the total length of the source code. + */ + offsets = (GLint *) _mesa_malloc(count * sizeof(GLint)); + if (offsets == NULL) { + RELEASE_SHADER(sha); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB"); + return; + } + + for (i = 0; i < count; i++) { + if (string[i] == NULL) { + _mesa_free((GLvoid *) offsets); + RELEASE_SHADER(sha); + _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB"); + return; + } + if (length == NULL || length[i] < 0) + offsets[i] = _mesa_strlen(string[i]); + else + offsets[i] = length[i]; + /* accumulate string lengths */ + if (i > 0) + offsets[i] += offsets[i - 1]; + } + + source = + (GLcharARB *) _mesa_malloc((offsets[count - 1] + 1) * + sizeof(GLcharARB)); + if (source == NULL) { + _mesa_free((GLvoid *) offsets); + RELEASE_SHADER(sha); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB"); + return; + } + + for (i = 0; i < count; i++) { + GLint start = (i > 0) ? offsets[i - 1] : 0; + _mesa_memcpy(source + start, string[i], + (offsets[i] - start) * sizeof(GLcharARB)); + } + source[offsets[count - 1]] = '\0'; + + (**sha).SetSource(sha, source, offsets, count); + RELEASE_SHADER(sha); } GLvoid GLAPIENTRY -_mesa_ShaderSourceARB (GLhandleARB shaderObj, GLsizei count, const GLcharARB **string, - const GLint *length) -{ - GET_CURRENT_CONTEXT(ctx); - GLint *offsets; - GLsizei i; - GLcharARB *source; - GET_SHADER(sha, shaderObj, "glShaderSourceARB"); - - if (sha == NULL) - return; - - if (string == NULL) - { - RELEASE_SHADER(sha); - _mesa_error (ctx, GL_INVALID_VALUE, "glShaderSourceARB"); - return; - } - - /* - * This array holds offsets of where the appropriate string ends, thus the last - * element will be set to the total length of the source code. - */ - offsets = (GLint *) _mesa_malloc (count * sizeof (GLint)); - if (offsets == NULL) - { - RELEASE_SHADER(sha); - _mesa_error (ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB"); - return; - } - - for (i = 0; i < count; i++) - { - if (string[i] == NULL) - { - _mesa_free ((GLvoid *) offsets); - RELEASE_SHADER(sha); - _mesa_error (ctx, GL_INVALID_VALUE, "glShaderSourceARB"); - return; - } - if (length == NULL || length[i] < 0) - offsets[i] = _mesa_strlen (string[i]); - else - offsets[i] = length[i]; - /* accumulate string lengths */ - if (i > 0) - offsets[i] += offsets[i - 1]; - } - - source = (GLcharARB *) _mesa_malloc ((offsets[count - 1] + 1) * sizeof (GLcharARB)); - if (source == NULL) - { - _mesa_free ((GLvoid *) offsets); - RELEASE_SHADER(sha); - _mesa_error (ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB"); - return; - } - - for (i = 0; i < count; i++) - { - GLint start = (i > 0) ? offsets[i - 1] : 0; - _mesa_memcpy (source + start, string[i], (offsets[i] - start) * sizeof (GLcharARB)); - } - source[offsets[count - 1]] = '\0'; - - (**sha).SetSource (sha, source, offsets, count); - RELEASE_SHADER(sha); -} - -GLvoid GLAPIENTRY -_mesa_CompileShaderARB (GLhandleARB shaderObj) -{ - GET_CURRENT_CONTEXT(ctx); - GET_SHADER(sha, shaderObj, "glCompileShaderARB"); - - if (sha != NULL) - { - (**sha).Compile (sha); - RELEASE_SHADER(sha); - } +_mesa_CompileShaderARB(GLhandleARB shaderObj) +{ + GET_CURRENT_CONTEXT(ctx); + GET_SHADER(sha, shaderObj, "glCompileShaderARB"); + + if (sha != NULL) { + (**sha).Compile(sha); + RELEASE_SHADER(sha); + } } GLhandleARB GLAPIENTRY -_mesa_CreateProgramObjectARB (GLvoid) +_mesa_CreateProgramObjectARB(GLvoid) { - return _mesa_3dlabs_create_program_object (); + return _mesa_3dlabs_create_program_object(); } GLvoid GLAPIENTRY -_mesa_AttachObjectARB (GLhandleARB containerObj, GLhandleARB obj) +_mesa_AttachObjectARB(GLhandleARB containerObj, GLhandleARB obj) { - GET_CURRENT_CONTEXT(ctx); - GET_CONTAINER(con, containerObj, "glAttachObjectARB"); + GET_CURRENT_CONTEXT(ctx); + GET_CONTAINER(con, containerObj, "glAttachObjectARB"); - if (con != NULL) - { - GET_GENERIC(att, obj, "glAttachObjectARB"); + if (con != NULL) { + GET_GENERIC(att, obj, "glAttachObjectARB"); - if (att != NULL) - { - (**con).Attach (con, att); - RELEASE_GENERIC(att); - } - RELEASE_CONTAINER(con); - } + if (att != NULL) { + (**con).Attach(con, att); + RELEASE_GENERIC(att); + } + RELEASE_CONTAINER(con); + } } GLvoid GLAPIENTRY -_mesa_LinkProgramARB (GLhandleARB programObj) +_mesa_LinkProgramARB(GLhandleARB programObj) { - GET_CURRENT_CONTEXT(ctx); - GET_PROGRAM(pro, programObj, "glLinkProgramARB"); - - if (pro != NULL) - { - (**pro).Link (pro); - if (pro == ctx->ShaderObjects.CurrentProgram) - { - if ((**pro).GetLinkStatus (pro)) - _mesa_UseProgramObjectARB (programObj); - else - _mesa_UseProgramObjectARB (0); - } - RELEASE_PROGRAM(pro); - } + GET_CURRENT_CONTEXT(ctx); + GET_PROGRAM(pro, programObj, "glLinkProgramARB"); + + if (pro != NULL) { + (**pro).Link(pro); + if (pro == ctx->ShaderObjects.CurrentProgram) { + if ((**pro).GetLinkStatus(pro)) + _mesa_UseProgramObjectARB(programObj); + else + _mesa_UseProgramObjectARB(0); + } + RELEASE_PROGRAM(pro); + } } GLvoid GLAPIENTRY -_mesa_UseProgramObjectARB (GLhandleARB programObj) +_mesa_UseProgramObjectARB(GLhandleARB programObj) { - GET_CURRENT_CONTEXT(ctx); + GET_CURRENT_CONTEXT(ctx); struct gl2_program_intf **program = NULL; - FLUSH_VERTICES(ctx, _NEW_PROGRAM); + FLUSH_VERTICES(ctx, _NEW_PROGRAM); - if (programObj != 0) - { - GET_PROGRAM(pro, programObj, "glUseProgramObjectARB"); + if (programObj != 0) { + GET_PROGRAM(pro, programObj, "glUseProgramObjectARB(program)"); - if (pro == NULL) - return; + if (pro == NULL) + return; - if ((**pro).GetLinkStatus (pro) == GL_FALSE) - { - RELEASE_PROGRAM(pro); - _mesa_error (ctx, GL_INVALID_OPERATION, "glUseProgramObjectARB"); - return; - } + if ((**pro).GetLinkStatus(pro) == GL_FALSE) { + RELEASE_PROGRAM(pro); + _mesa_error(ctx, GL_INVALID_OPERATION, "glUseProgramObjectARB(not linked)"); + return; + } - program = pro; + program = pro; - ctx->ShaderObjects._VertexShaderPresent = (**pro).IsShaderPresent (pro, GL_VERTEX_SHADER_ARB); - ctx->ShaderObjects._FragmentShaderPresent = (**pro).IsShaderPresent (pro, - GL_FRAGMENT_SHADER_ARB); - } - else - { - ctx->ShaderObjects._VertexShaderPresent = GL_FALSE; - ctx->ShaderObjects._FragmentShaderPresent = GL_FALSE; - } + ctx->ShaderObjects._VertexShaderPresent = + (**pro).IsShaderPresent(pro, GL_VERTEX_SHADER_ARB); + ctx->ShaderObjects._FragmentShaderPresent = + (**pro).IsShaderPresent(pro, GL_FRAGMENT_SHADER_ARB); + } + else { + ctx->ShaderObjects._VertexShaderPresent = GL_FALSE; + ctx->ShaderObjects._FragmentShaderPresent = GL_FALSE; + } - if (ctx->ShaderObjects.CurrentProgram != NULL) - RELEASE_PROGRAM(ctx->ShaderObjects.CurrentProgram); - ctx->ShaderObjects.CurrentProgram = program; + if (ctx->ShaderObjects.CurrentProgram != NULL) + RELEASE_PROGRAM(ctx->ShaderObjects.CurrentProgram); + ctx->ShaderObjects.CurrentProgram = program; } GLvoid GLAPIENTRY -_mesa_ValidateProgramARB (GLhandleARB programObj) +_mesa_ValidateProgramARB(GLhandleARB programObj) { - GET_CURRENT_CONTEXT(ctx); - GET_PROGRAM(pro, programObj, "glValidateProgramARB"); + GET_CURRENT_CONTEXT(ctx); + GET_PROGRAM(pro, programObj, "glValidateProgramARB"); - if (pro != NULL) - { - (**pro).Validate (pro); - RELEASE_PROGRAM(pro); - } + if (pro != NULL) { + (**pro).Validate(pro); + RELEASE_PROGRAM(pro); + } } -GLvoid GLAPIENTRY -_mesa_Uniform1fARB (GLint location, GLfloat v0) + +/** + * Helper function for all the _mesa_Uniform*() functions below. + */ +static INLINE void +uniform(GLint location, GLsizei count, const GLvoid *values, GLenum type, + const char *caller) { - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniform1fARB"); + GET_CURRENT_CONTEXT(ctx); + GET_CURRENT_LINKED_PROGRAM(pro, caller); - FLUSH_VERTICES(ctx, _NEW_PROGRAM); + FLUSH_VERTICES(ctx, _NEW_PROGRAM); - if (pro != NULL) - { - if (!(**pro).WriteUniform (pro, location, 1, &v0, GL_FLOAT)) - _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform1fARB"); - } + if (!(**pro).WriteUniform(pro, location, count, values, type)) + _mesa_error(ctx, GL_INVALID_OPERATION, caller); } + GLvoid GLAPIENTRY -_mesa_Uniform2fARB (GLint location, GLfloat v0, GLfloat v1) +_mesa_Uniform1fARB(GLint location, GLfloat v0) { - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniform2fARB"); - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (pro != NULL) - { - GLfloat v[2]; - v[0] = v0; - v[1] = v1; - - if (!(**pro).WriteUniform (pro, location, 1, v, GL_FLOAT_VEC2)) - _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform2fARB"); - } + uniform(location, 1, &v0, GL_FLOAT, "glUniform1fARB"); } GLvoid GLAPIENTRY -_mesa_Uniform3fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2) +_mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1) { - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniform3fARB"); - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (pro != NULL) - { - GLfloat v[3]; - v[0] = v0; - v[1] = v1; - v[2] = v2; - - if (!(**pro).WriteUniform (pro, location, 1, v, GL_FLOAT_VEC3)) - _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform3fARB"); - } + GLfloat v[2]; + v[0] = v0; + v[1] = v1; + uniform(location, 1, v, GL_FLOAT_VEC2, "glUniform2fARB"); } GLvoid GLAPIENTRY -_mesa_Uniform4fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) +_mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) { - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniform4fARB"); - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (pro != NULL) - { - GLfloat v[4]; - v[0] = v0; - v[1] = v1; - v[2] = v2; - v[3] = v3; - - if (!(**pro).WriteUniform (pro, location, 1, v, GL_FLOAT_VEC4)) - _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform4fARB"); - } + GLfloat v[3]; + v[0] = v0; + v[1] = v1; + v[2] = v2; + uniform(location, 1, v, GL_FLOAT_VEC3, "glUniform3fARB"); } GLvoid GLAPIENTRY -_mesa_Uniform1iARB (GLint location, GLint v0) +_mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, + GLfloat v3) { - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniform1iARB"); - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (pro != NULL) - { - if (!(**pro).WriteUniform (pro, location, 1, &v0, GL_INT)) - _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform1iARB"); - } + GLfloat v[4]; + v[0] = v0; + v[1] = v1; + v[2] = v2; + v[3] = v3; + uniform(location, 1, v, GL_FLOAT_VEC4, "glUniform4fARB"); } GLvoid GLAPIENTRY -_mesa_Uniform2iARB (GLint location, GLint v0, GLint v1) +_mesa_Uniform1iARB(GLint location, GLint v0) { - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniform2iARB"); - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (pro != NULL) - { - GLint v[2]; - v[0] = v0; - v[1] = v1; - - if (!(**pro).WriteUniform (pro, location, 1, v, GL_INT_VEC2)) - _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform2iARB"); - } + uniform(location, 1, &v0, GL_INT, "glUniform1iARB"); } GLvoid GLAPIENTRY -_mesa_Uniform3iARB (GLint location, GLint v0, GLint v1, GLint v2) +_mesa_Uniform2iARB(GLint location, GLint v0, GLint v1) { - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniform3iARB"); - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (pro != NULL) - { - GLint v[3]; - v[0] = v0; - v[1] = v1; - v[2] = v2; - - if (!(**pro).WriteUniform (pro, location, 1, v, GL_INT_VEC3)) - _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform3iARB"); - } + GLint v[2]; + v[0] = v0; + v[1] = v1; + uniform(location, 1, v, GL_INT_VEC2, "glUniform2iARB"); } GLvoid GLAPIENTRY -_mesa_Uniform4iARB (GLint location, GLint v0, GLint v1, GLint v2, GLint v3) +_mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2) { - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniform4iARB"); - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (pro != NULL) - { - GLint v[4]; - v[0] = v0; - v[1] = v1; - v[2] = v2; - v[3] = v3; - - if (!(**pro).WriteUniform (pro, location, 1, v, GL_INT_VEC4)) - _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform4iARB"); - } + GLint v[3]; + v[0] = v0; + v[1] = v1; + v[2] = v2; + uniform(location, 1, v, GL_INT_VEC3, "glUniform3iARB"); } GLvoid GLAPIENTRY -_mesa_Uniform1fvARB (GLint location, GLsizei count, const GLfloat *value) +_mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) { - 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 (!(**pro).WriteUniform (pro, location, count, value, GL_FLOAT)) - _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform1fvARB"); - } + GLint v[4]; + v[0] = v0; + v[1] = v1; + v[2] = v2; + v[3] = v3; + uniform(location, 1, v, GL_INT_VEC4, "glUniform4iARB"); } GLvoid GLAPIENTRY -_mesa_Uniform2fvARB (GLint location, GLsizei count, const GLfloat *value) +_mesa_Uniform1fvARB(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 (!(**pro).WriteUniform (pro, location, count, value, GL_FLOAT_VEC2)) - _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform2fvARB"); - } + uniform(location, count, value, GL_FLOAT, "glUniform1fvARB"); } GLvoid GLAPIENTRY -_mesa_Uniform3fvARB (GLint location, GLsizei count, const GLfloat *value) +_mesa_Uniform2fvARB(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 (!(**pro).WriteUniform (pro, location, count, value, GL_FLOAT_VEC3)) - _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform3fvARB"); - } + uniform(location, count, value, GL_FLOAT_VEC2, "glUniform2fvARB"); } GLvoid GLAPIENTRY -_mesa_Uniform4fvARB (GLint location, GLsizei count, const GLfloat *value) +_mesa_Uniform3fvARB(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 (!(**pro).WriteUniform (pro, location, count, value, GL_FLOAT_VEC4)) - _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform4fvARB"); - } + uniform(location, count, value, GL_FLOAT_VEC3, "glUniform3fvARB"); } GLvoid GLAPIENTRY -_mesa_Uniform1ivARB (GLint location, GLsizei count, const GLint *value) +_mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * 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 (!(**pro).WriteUniform (pro, location, count, value, GL_INT)) - _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform1ivARB"); - } + uniform(location, count, value, GL_FLOAT_VEC4, "glUniform4fvARB"); } GLvoid GLAPIENTRY -_mesa_Uniform2ivARB (GLint location, GLsizei count, const GLint *value) +_mesa_Uniform1ivARB(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; - } + uniform(location, count, value, GL_INT, "glUniform1ivARB"); +} - FLUSH_VERTICES(ctx, _NEW_PROGRAM); +GLvoid GLAPIENTRY +_mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value) +{ + uniform(location, count, value, GL_INT_VEC2, "glUniform2ivARB"); +} - if (pro != NULL) - { - if (!(**pro).WriteUniform (pro, location, count, value, GL_INT_VEC2)) - _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform2ivARB"); - } +GLvoid GLAPIENTRY +_mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value) +{ + uniform(location, count, value, GL_INT_VEC3, "glUniform3ivARB"); } GLvoid GLAPIENTRY -_mesa_Uniform3ivARB (GLint location, GLsizei count, const GLint *value) +_mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value) { - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniform3ivARB"); + uniform(location, count, value, GL_INT_VEC4, "glUniform4ivARB"); +} - if (value == NULL) - { - _mesa_error (ctx, GL_INVALID_VALUE, "glUniform3ivARB"); - return; - } - FLUSH_VERTICES(ctx, _NEW_PROGRAM); +/** + * Helper function used by UniformMatrix**vARB() functions below. + */ +static void +uniform_matrix(GLint cols, GLint rows, const char *caller, + GLenum matrixType, + GLint location, GLsizei count, GLboolean transpose, + const GLfloat *values) +{ + const GLint matElements = rows * cols; + GET_CURRENT_CONTEXT(ctx); + GET_CURRENT_LINKED_PROGRAM(pro, caller); - if (pro != NULL) - { - if (!(**pro).WriteUniform (pro, location, count, value, GL_INT_VEC3)) - _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform3ivARB"); - } -} + if (values == NULL) { + _mesa_error(ctx, GL_INVALID_VALUE, caller); + return; + } -GLvoid GLAPIENTRY -_mesa_Uniform4ivARB (GLint location, GLsizei count, const GLint *value) -{ - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, "glUniform4ivARB"); + FLUSH_VERTICES(ctx, _NEW_PROGRAM); - if (value == NULL) - { - _mesa_error (ctx, GL_INVALID_VALUE, "glUniform4ivARB"); - return; - } + if (transpose) { + GLfloat *trans, *pt; + const GLfloat *pv; + GLint i, j, k; - FLUSH_VERTICES(ctx, _NEW_PROGRAM); + trans = (GLfloat *) _mesa_malloc(count * matElements * sizeof(GLfloat)); + if (!trans) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, caller); + return; + } + + pt = trans; + pv = values; + for (i = 0; i < count; i++) { + /* transpose from pv matrix into pt matrix */ + for (j = 0; j < cols; j++) { + for (k = 0; k < rows; k++) { + /* XXX verify this */ + pt[j * rows + k] = pv[k * cols + j]; + } + } + pt += matElements; + pv += matElements; + } - if (pro != NULL) - { - if (!(**pro).WriteUniform (pro, location, count, value, GL_INT_VEC4)) - _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform4ivARB"); - } + if (!(**pro).WriteUniform(pro, location, count, trans, matrixType)) + _mesa_error(ctx, GL_INVALID_OPERATION, caller); + _mesa_free(trans); + } + else { + if (!(**pro).WriteUniform(pro, location, count, values, matrixType)) + _mesa_error(ctx, GL_INVALID_OPERATION, caller); + } } + GLvoid GLAPIENTRY -_mesa_UniformMatrix2fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) -{ - 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) - { - if (transpose) - { - GLfloat *trans, *pt; - const GLfloat *pv; - - trans = (GLfloat *) _mesa_malloc (count * 4 * sizeof (GLfloat)); - if (trans == NULL) - { - _mesa_error (ctx, GL_OUT_OF_MEMORY, "glUniformMatrix2fvARB"); - return; - } - for (pt = trans, pv = value; pt != trans + count * 4; pt += 4, pv += 4) - { - pt[0] = pv[0]; - pt[1] = pv[2]; - pt[2] = pv[1]; - pt[3] = pv[3]; - } - if (!(**pro).WriteUniform (pro, location, count, trans, GL_FLOAT_MAT2)) - _mesa_error (ctx, GL_INVALID_OPERATION, "glUniformMatrix2fvARB"); - _mesa_free (trans); - } - else - { - if (!(**pro).WriteUniform (pro, location, count, value, GL_FLOAT_MAT2)) - _mesa_error (ctx, GL_INVALID_OPERATION, "glUniformMatrix2fvARB"); - } - } +_mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose, + const GLfloat * value) +{ + uniform_matrix(2, 2, "glUniformMatrix2fvARB", GL_FLOAT_MAT2, + location, count, transpose, value); } GLvoid GLAPIENTRY -_mesa_UniformMatrix3fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) -{ - 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) - { - if (transpose) - { - GLfloat *trans, *pt; - const GLfloat *pv; - - trans = (GLfloat *) _mesa_malloc (count * 9 * sizeof (GLfloat)); - if (trans == NULL) - { - _mesa_error (ctx, GL_OUT_OF_MEMORY, "glUniformMatrix3fvARB"); - return; - } - for (pt = trans, pv = value; pt != trans + count * 9; pt += 9, pv += 9) - { - pt[0] = pv[0]; - pt[1] = pv[3]; - pt[2] = pv[6]; - pt[3] = pv[1]; - pt[4] = pv[4]; - pt[5] = pv[7]; - pt[6] = pv[2]; - pt[7] = pv[5]; - pt[8] = pv[8]; - } - if (!(**pro).WriteUniform (pro, location, count, trans, GL_FLOAT_MAT3)) - _mesa_error (ctx, GL_INVALID_OPERATION, "glUniformMatrix3fvARB"); - _mesa_free (trans); - } - else - { - if (!(**pro).WriteUniform (pro, location, count, value, GL_FLOAT_MAT3)) - _mesa_error (ctx, GL_INVALID_OPERATION, "glUniformMatrix3fvARB"); - } - } +_mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose, + const GLfloat * value) +{ + uniform_matrix(3, 3, "glUniformMatrix3fvARB", GL_FLOAT_MAT3, + location, count, transpose, value); } GLvoid GLAPIENTRY -_mesa_UniformMatrix4fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) -{ - 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) - { - if (transpose) - { - GLfloat *trans, *pt; - const GLfloat *pv; - - trans = (GLfloat *) _mesa_malloc (count * 16 * sizeof (GLfloat)); - if (trans == NULL) - { - _mesa_error (ctx, GL_OUT_OF_MEMORY, "glUniformMatrix4fvARB"); - return; - } - for (pt = trans, pv = value; pt != trans + count * 16; pt += 16, pv += 16) - { - _math_transposef (pt, pv); - } - if (!(**pro).WriteUniform (pro, location, count, trans, GL_FLOAT_MAT4)) - _mesa_error (ctx, GL_INVALID_OPERATION, "glUniformMatrix4fvARB"); - _mesa_free (trans); - } - else - { - if (!(**pro).WriteUniform (pro, location, count, value, GL_FLOAT_MAT4)) - _mesa_error (ctx, GL_INVALID_OPERATION, "glUniformMatrix4fvARB"); - } - } +_mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose, + const GLfloat * value) +{ + uniform_matrix(4, 4, "glUniformMatrix4fvARB", GL_FLOAT_MAT4, + location, count, transpose, value); } static GLboolean -_mesa_get_object_parameter (GLhandleARB obj, GLenum pname, GLvoid *params, GLboolean *integral, - GLint *size) -{ - GET_CURRENT_CONTEXT(ctx); - GLint *ipar = (GLint *) params; - - /* set default values */ - *integral = GL_TRUE; /* indicates param type, TRUE: GLint, FALSE: GLfloat */ - *size = 1; /* param array size */ - - switch (pname) - { - case GL_OBJECT_TYPE_ARB: - case GL_OBJECT_DELETE_STATUS_ARB: - case GL_OBJECT_INFO_LOG_LENGTH_ARB: - { - GET_GENERIC(gen, obj, "glGetObjectParameterivARB"); - - if (gen == NULL) - return GL_FALSE; - - switch (pname) - { - case GL_OBJECT_TYPE_ARB: - *ipar = (**gen).GetType (gen); - break; - case GL_OBJECT_DELETE_STATUS_ARB: - *ipar = (**gen).GetDeleteStatus (gen); - break; +_mesa_get_object_parameter(GLhandleARB obj, GLenum pname, GLvoid * params, + GLboolean * integral, GLint * size) +{ + GET_CURRENT_CONTEXT(ctx); + GLint *ipar = (GLint *) params; + + /* set default values */ + *integral = GL_TRUE; /* indicates param type, TRUE: GLint, FALSE: GLfloat */ + *size = 1; /* param array size */ + + switch (pname) { + case GL_OBJECT_TYPE_ARB: + case GL_OBJECT_DELETE_STATUS_ARB: + case GL_OBJECT_INFO_LOG_LENGTH_ARB: + { + GET_GENERIC(gen, obj, "glGetObjectParameterivARB"); + + if (gen == NULL) + return GL_FALSE; + + switch (pname) { + case GL_OBJECT_TYPE_ARB: + *ipar = (**gen).GetType(gen); + break; + case GL_OBJECT_DELETE_STATUS_ARB: + *ipar = (**gen).GetDeleteStatus(gen); + break; case GL_OBJECT_INFO_LOG_LENGTH_ARB: - *ipar = (**gen).GetInfoLogLength (gen); + *ipar = (**gen).GetInfoLogLength(gen); + break; + } + + RELEASE_GENERIC(gen); + } + break; + case GL_OBJECT_SUBTYPE_ARB: + case GL_OBJECT_COMPILE_STATUS_ARB: + case GL_OBJECT_SHADER_SOURCE_LENGTH_ARB: + { + GET_SHADER(sha, obj, "glGetObjectParameterivARB"); + + if (sha == NULL) + return GL_FALSE; + + switch (pname) { + case GL_OBJECT_SUBTYPE_ARB: + *ipar = (**sha).GetSubType(sha); + break; + case GL_OBJECT_COMPILE_STATUS_ARB: + *ipar = (**sha).GetCompileStatus(sha); + break; + case GL_OBJECT_SHADER_SOURCE_LENGTH_ARB: + { + const GLcharARB *src = (**sha).GetSource(sha); + if (src == NULL) + *ipar = 0; + else + *ipar = _mesa_strlen(src) + 1; + } + break; + } + + RELEASE_SHADER(sha); + } + break; + case GL_OBJECT_LINK_STATUS_ARB: + case GL_OBJECT_VALIDATE_STATUS_ARB: + case GL_OBJECT_ATTACHED_OBJECTS_ARB: + case GL_OBJECT_ACTIVE_UNIFORMS_ARB: + case GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB: + { + GET_PROGRAM(pro, obj, "glGetObjectParameterivARB"); + + if (pro == NULL) + return GL_FALSE; + + switch (pname) { + case GL_OBJECT_LINK_STATUS_ARB: + *ipar = (**pro).GetLinkStatus(pro); + break; + case GL_OBJECT_VALIDATE_STATUS_ARB: + *ipar = (**pro).GetValidateStatus(pro); break; - } - - RELEASE_GENERIC(gen); - } - break; - case GL_OBJECT_SUBTYPE_ARB: - case GL_OBJECT_COMPILE_STATUS_ARB: - case GL_OBJECT_SHADER_SOURCE_LENGTH_ARB: - { - GET_SHADER(sha, obj, "glGetObjectParameterivARB"); - - if (sha == NULL) - return GL_FALSE; - - switch (pname) - { - case GL_OBJECT_SUBTYPE_ARB: - *ipar = (**sha).GetSubType (sha); - break; - case GL_OBJECT_COMPILE_STATUS_ARB: - *ipar = (**sha).GetCompileStatus (sha); - break; - case GL_OBJECT_SHADER_SOURCE_LENGTH_ARB: - { - const GLcharARB *src = (**sha).GetSource (sha); - - if (src == NULL) - *ipar = 0; - else - *ipar = _mesa_strlen (src) + 1; - } - break; - } - - RELEASE_SHADER(sha); - } - break; - case GL_OBJECT_LINK_STATUS_ARB: - case GL_OBJECT_VALIDATE_STATUS_ARB: - case GL_OBJECT_ATTACHED_OBJECTS_ARB: - case GL_OBJECT_ACTIVE_UNIFORMS_ARB: - case GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB: - { - GET_PROGRAM(pro, obj, "glGetObjectParameterivARB"); - - if (pro == NULL) - return GL_FALSE; - - switch (pname) - { - case GL_OBJECT_LINK_STATUS_ARB: - *ipar = (**pro).GetLinkStatus (pro); - break; - case GL_OBJECT_VALIDATE_STATUS_ARB: - *ipar = (**pro).GetValidateStatus (pro); - break; case GL_OBJECT_ATTACHED_OBJECTS_ARB: - *ipar = (**pro)._container.GetAttachedCount ((struct gl2_container_intf **) (pro)); + *ipar = + (**pro)._container. + GetAttachedCount((struct gl2_container_intf **) (pro)); + break; + case GL_OBJECT_ACTIVE_UNIFORMS_ARB: + *ipar = (**pro).GetActiveUniformCount(pro); + break; + case GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB: + *ipar = (**pro).GetActiveUniformMaxLength(pro); + break; + case GL_OBJECT_ACTIVE_ATTRIBUTES_ARB: + *ipar = (**pro).GetActiveAttribCount(pro); break; - case GL_OBJECT_ACTIVE_UNIFORMS_ARB: - *ipar = (**pro).GetActiveUniformCount (pro); - break; - case GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB: - *ipar = (**pro).GetActiveUniformMaxLength (pro); - break; - case GL_OBJECT_ACTIVE_ATTRIBUTES_ARB: - *ipar = (**pro).GetActiveAttribCount (pro); - break; - case GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB: - *ipar = (**pro).GetActiveAttribMaxLength (pro); - break; - } - - RELEASE_PROGRAM(pro); - } - break; - default: - _mesa_error (ctx, GL_INVALID_ENUM, "glGetObjectParameterivARB"); - return GL_FALSE; - } - - return GL_TRUE; + case GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB: + *ipar = (**pro).GetActiveAttribMaxLength(pro); + break; + } + + RELEASE_PROGRAM(pro); + } + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetObjectParameterivARB"); + return GL_FALSE; + } + + return GL_TRUE; } GLvoid GLAPIENTRY -_mesa_GetObjectParameterfvARB (GLhandleARB obj, GLenum pname, GLfloat *params) +_mesa_GetObjectParameterfvARB(GLhandleARB obj, GLenum pname, GLfloat * params) { - GET_CURRENT_CONTEXT(ctx); - GLboolean integral; - GLint size; + 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 (params == NULL) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterfvARB"); + return; + } - if (_mesa_get_object_parameter (obj, pname, (GLvoid *) params, &integral, &size)) - if (integral) - { - GLint i; + assert(sizeof(GLfloat) == sizeof(GLint)); - for (i = 0; i < size; i++) - params[i] = (GLfloat) ((GLint *) params)[i]; - } + if (_mesa_get_object_parameter(obj, pname, (GLvoid *) params, + &integral, &size)) { + if (integral) { + GLint i; + for (i = 0; i < size; i++) + params[i] = (GLfloat) ((GLint *) params)[i]; + } + } } GLvoid GLAPIENTRY -_mesa_GetObjectParameterivARB (GLhandleARB obj, GLenum pname, GLint *params) +_mesa_GetObjectParameterivARB(GLhandleARB obj, GLenum pname, GLint * params) { - GET_CURRENT_CONTEXT(ctx); - GLboolean integral; - GLint size; + 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 (params == NULL) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB"); + return; + } - if (_mesa_get_object_parameter (obj, pname, (GLvoid *) params, &integral, &size)) - if (!integral) - { - GLint i; + assert(sizeof(GLfloat) == sizeof(GLint)); - for (i = 0; i < size; i++) - params[i] = (GLint) ((GLfloat *) params)[i]; - } + if (_mesa_get_object_parameter(obj, pname, (GLvoid *) params, + &integral, &size)) { + if (!integral) { + GLint i; + for (i = 0; i < size; i++) + params[i] = (GLint) ((GLfloat *) params)[i]; + } + } } @@ -993,222 +739,453 @@ _mesa_GetObjectParameterivARB (GLhandleARB obj, GLenum pname, GLint *params) * \param dst the string destination */ static GLvoid -copy_string(const GLcharARB *src, GLsizei maxLength, GLsizei *length, - GLcharARB *dst) +copy_string(const GLcharARB * src, GLsizei maxLength, GLsizei * length, + GLcharARB * dst) { - GLsizei len; - for (len = 0; len < maxLength - 1 && src && src[len]; len++) - dst[len] = src[len]; - if (maxLength > 0) - dst[len] = 0; - if (length) - *length = len; + GLsizei len; + for (len = 0; len < maxLength - 1 && src && src[len]; len++) + dst[len] = src[len]; + if (maxLength > 0) + dst[len] = 0; + if (length) + *length = len; } GLvoid GLAPIENTRY -_mesa_GetInfoLogARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog) +_mesa_GetInfoLogARB(GLhandleARB obj, GLsizei maxLength, GLsizei * length, + GLcharARB * infoLog) { - GET_CURRENT_CONTEXT(ctx); - GET_GENERIC(gen, obj, "glGetInfoLogARB"); + GET_CURRENT_CONTEXT(ctx); + GET_GENERIC(gen, obj, "glGetInfoLogARB"); - if (gen == NULL) - return; + if (gen == NULL) + return; - if (infoLog == NULL) - _mesa_error (ctx, GL_INVALID_VALUE, "glGetInfoLogARB"); + if (infoLog == NULL) + _mesa_error(ctx, GL_INVALID_VALUE, "glGetInfoLogARB"); else { - GLsizei actualsize = (**gen).GetInfoLogLength (gen); + GLsizei actualsize = (**gen).GetInfoLogLength(gen); if (actualsize > maxLength) actualsize = maxLength; - (**gen).GetInfoLog (gen, actualsize, infoLog); + (**gen).GetInfoLog(gen, actualsize, infoLog); if (length != NULL) *length = (actualsize > 0) ? actualsize - 1 : 0; } - RELEASE_GENERIC(gen); + RELEASE_GENERIC(gen); } GLvoid GLAPIENTRY -_mesa_GetAttachedObjectsARB (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, - GLhandleARB *obj) +_mesa_GetAttachedObjectsARB(GLhandleARB containerObj, GLsizei maxCount, + GLsizei * count, GLhandleARB * obj) { - GET_CURRENT_CONTEXT(ctx); - GET_CONTAINER(con, containerObj, "glGetAttachedObjectsARB"); - - if (con == NULL) - return; - - if (obj == NULL) - _mesa_error (ctx, GL_INVALID_VALUE, "glGetAttachedObjectsARB"); - else - { - GLsizei cnt, i; + GET_CURRENT_CONTEXT(ctx); + GET_CONTAINER(con, containerObj, "glGetAttachedObjectsARB"); - cnt = (**con).GetAttachedCount (con); - if (cnt > maxCount) - cnt = maxCount; - if (count != NULL) - *count = cnt; + if (con == NULL) + return; - for (i = 0; i < cnt; i++) - { - struct gl2_generic_intf **x = (**con).GetAttached (con, i); - obj[i] = (**x).GetName (x); - RELEASE_GENERIC(x); - } - } - RELEASE_CONTAINER(con); + if (obj == NULL) + _mesa_error(ctx, GL_INVALID_VALUE, "glGetAttachedObjectsARB"); + else { + GLsizei cnt, i; + + cnt = (**con).GetAttachedCount(con); + if (cnt > maxCount) + cnt = maxCount; + if (count != NULL) + *count = cnt; + + for (i = 0; i < cnt; i++) { + struct gl2_generic_intf **x = (**con).GetAttached(con, i); + obj[i] = (**x).GetName(x); + RELEASE_GENERIC(x); + } + } + RELEASE_CONTAINER(con); } GLint GLAPIENTRY -_mesa_GetUniformLocationARB (GLhandleARB programObj, const GLcharARB *name) +_mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB * name) { - GET_CURRENT_CONTEXT(ctx); - GLint loc = -1; - GET_LINKED_PROGRAM(pro, programObj, "glGetUniformLocationARB"); + GET_CURRENT_CONTEXT(ctx); + GLint loc = -1; + GET_LINKED_PROGRAM(pro, programObj, "glGetUniformLocationARB"); - if (pro == NULL) - return -1; + if (!pro) + return -1; - if (name == NULL) - _mesa_error (ctx, GL_INVALID_VALUE, "glGetUniformLocationARB"); - else - { - if (!IS_NAME_WITH_GL_PREFIX(name)) - loc = (**pro).GetUniformLocation (pro, name); - } - RELEASE_PROGRAM(pro); - return loc; + if (name == NULL) + _mesa_error(ctx, GL_INVALID_VALUE, "glGetUniformLocationARB"); + else { + if (!IS_NAME_WITH_GL_PREFIX(name)) + loc = (**pro).GetUniformLocation(pro, name); + } + RELEASE_PROGRAM(pro); + return loc; } GLvoid GLAPIENTRY -_mesa_GetActiveUniformARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, - GLint *size, GLenum *type, GLcharARB *name) +_mesa_GetActiveUniformARB(GLhandleARB programObj, GLuint index, + GLsizei maxLength, GLsizei * length, GLint * size, + GLenum * type, GLcharARB * name) { - GET_CURRENT_CONTEXT(ctx); - GET_PROGRAM(pro, programObj, "glGetActiveUniformARB"); + GET_CURRENT_CONTEXT(ctx); + GET_PROGRAM(pro, programObj, "glGetActiveUniformARB"); - if (pro == NULL) - return; + if (pro == NULL) + return; - if (size == NULL || type == NULL || name == NULL) - _mesa_error (ctx, GL_INVALID_VALUE, "glGetActiveUniformARB"); - else - { - if (index < (**pro).GetActiveUniformCount (pro)) - (**pro).GetActiveUniform (pro, index, maxLength, length, size, type, name); - else - _mesa_error (ctx, GL_INVALID_VALUE, "glGetActiveUniformARB"); - } - RELEASE_PROGRAM(pro); + if (size == NULL || type == NULL || name == NULL) + _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformARB"); + else { + if (index < (**pro).GetActiveUniformCount(pro)) + (**pro).GetActiveUniform(pro, index, maxLength, length, size, type, + name); + else + _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformARB"); + } + RELEASE_PROGRAM(pro); } GLvoid GLAPIENTRY -_mesa_GetUniformfvARB (GLhandleARB programObj, GLint location, GLfloat *params) +_mesa_GetUniformfvARB(GLhandleARB programObj, GLint location, GLfloat * params) { - GET_CURRENT_CONTEXT(ctx); - GET_LINKED_PROGRAM(pro, programObj, "glGetUniformfvARB"); + GET_CURRENT_CONTEXT(ctx); + GET_LINKED_PROGRAM(pro, programObj, "glGetUniformfvARB"); + + if (!pro) + return; - if (pro != NULL) - { - /* TODO */ - RELEASE_PROGRAM(pro); - } + if (!(**pro).ReadUniform(pro, location, 1, params, GL_FLOAT)) + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfvARB"); + + RELEASE_PROGRAM(pro); } GLvoid GLAPIENTRY -_mesa_GetUniformivARB (GLhandleARB programObj, GLint location, GLint *params) +_mesa_GetUniformivARB(GLhandleARB programObj, GLint location, GLint * params) { - GET_CURRENT_CONTEXT(ctx); - GET_LINKED_PROGRAM(pro, programObj, "glGetUniformivARB"); + GET_CURRENT_CONTEXT(ctx); + GET_LINKED_PROGRAM(pro, programObj, "glGetUniformivARB"); + + if (!pro) + return; - if (pro != NULL) - { - /* TODO */ - RELEASE_PROGRAM(pro); - } + if (!(**pro).ReadUniform(pro, location, 1, params, GL_INT)) + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformivARB"); + RELEASE_PROGRAM(pro); } GLvoid GLAPIENTRY -_mesa_GetShaderSourceARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source) +_mesa_GetShaderSourceARB(GLhandleARB obj, GLsizei maxLength, GLsizei * length, + GLcharARB * source) { - GET_CURRENT_CONTEXT(ctx); - GET_SHADER(sha, obj, "glGetShaderSourceARB"); + GET_CURRENT_CONTEXT(ctx); + GET_SHADER(sha, obj, "glGetShaderSourceARB"); - if (sha == NULL) - return; + 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); + 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 */ GLvoid GLAPIENTRY -_mesa_BindAttribLocationARB (GLhandleARB programObj, GLuint index, const GLcharARB *name) +_mesa_BindAttribLocationARB(GLhandleARB programObj, GLuint index, + const GLcharARB * name) { - GET_CURRENT_CONTEXT(ctx); - GET_PROGRAM(pro, programObj, "glBindAttribLocationARB"); + GET_CURRENT_CONTEXT(ctx); + GET_PROGRAM(pro, programObj, "glBindAttribLocationARB"); + + if (pro == NULL) + return; + + if (name == NULL || index >= MAX_VERTEX_ATTRIBS) + _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocationARB"); + else if (IS_NAME_WITH_GL_PREFIX(name)) + _mesa_error(ctx, GL_INVALID_OPERATION, "glBindAttribLocationARB"); + else + (**pro).OverrideAttribBinding(pro, index, name); + RELEASE_PROGRAM(pro); +} - if (pro == NULL) - return; +GLvoid GLAPIENTRY +_mesa_GetActiveAttribARB(GLhandleARB programObj, GLuint index, + GLsizei maxLength, GLsizei * length, GLint * size, + GLenum * type, GLcharARB * name) +{ + GET_CURRENT_CONTEXT(ctx); + GET_PROGRAM(pro, programObj, "glGetActiveAttribARB"); + + if (pro == NULL) + return; + + if (name == NULL || index >= (**pro).GetActiveAttribCount(pro)) + _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttribARB"); + else + (**pro).GetActiveAttrib(pro, index, maxLength, length, size, type, + name); + RELEASE_PROGRAM(pro); +} - 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); +GLint GLAPIENTRY +_mesa_GetAttribLocationARB(GLhandleARB programObj, const GLcharARB * name) +{ + GET_CURRENT_CONTEXT(ctx); + GLint loc = -1; + GET_LINKED_PROGRAM(pro, programObj, "glGetAttribLocationARB"); + + if (!pro) + return -1; + + if (name == NULL) + _mesa_error(ctx, GL_INVALID_VALUE, "glGetAttribLocationARB"); + else if (!IS_NAME_WITH_GL_PREFIX(name)) + loc = (**pro).GetAttribLocation(pro, name); + RELEASE_PROGRAM(pro); + return loc; } -GLvoid GLAPIENTRY -_mesa_GetActiveAttribARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, - GLint *size, GLenum *type, GLcharARB *name) + +/** + ** OpenGL 2.0 functions which basically wrap the ARB_shader functions + **/ + +void GLAPIENTRY +_mesa_AttachShader(GLuint program, GLuint shader) { - GET_CURRENT_CONTEXT(ctx); - GET_PROGRAM(pro, programObj, "glGetActiveAttribARB"); + _mesa_AttachObjectARB(program, shader); +} - 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); +GLuint GLAPIENTRY +_mesa_CreateShader(GLenum type) +{ + return (GLuint) _mesa_CreateShaderObjectARB(type); } -GLint GLAPIENTRY -_mesa_GetAttribLocationARB (GLhandleARB programObj, const GLcharARB *name) +GLuint GLAPIENTRY +_mesa_CreateProgram(void) +{ + return (GLuint) _mesa_CreateProgramObjectARB(); +} + +void GLAPIENTRY +_mesa_DeleteProgram(GLuint program) +{ + _mesa_DeleteObjectARB(program); +} + + +void GLAPIENTRY +_mesa_DeleteShader(GLuint shader) { - GET_CURRENT_CONTEXT(ctx); - GLint loc = -1; - GET_LINKED_PROGRAM(pro, programObj, "glGetAttribLocationARB"); + _mesa_DeleteObjectARB(shader); +} - if (pro == NULL) - return -1; +void GLAPIENTRY +_mesa_DetachShader(GLuint program, GLuint shader) +{ + _mesa_DetachObjectARB(program, shader); +} - 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; +void GLAPIENTRY +_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount, + GLsizei *count, GLuint *obj) +{ + _mesa_GetAttachedObjectsARB(program, maxCount, count, obj); } +void GLAPIENTRY +_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params) +{ + GET_CURRENT_CONTEXT(ctx); + GET_PROGRAM(pro, program, "glGetProgramiv"); + + if (!pro) + return; + + switch (pname) { + case GL_DELETE_STATUS: + *params = (**pro)._container._generic.GetDeleteStatus((struct gl2_generic_intf **) pro); + break; + case GL_LINK_STATUS: + *params = (**pro).GetLinkStatus(pro); + break; + case GL_VALIDATE_STATUS: + *params = (**pro).GetValidateStatus(pro); + break; + case GL_INFO_LOG_LENGTH: + *params = (**pro)._container._generic.GetInfoLogLength( (struct gl2_generic_intf **) pro ); + break; + case GL_ATTACHED_SHADERS: + *params = (**pro)._container.GetAttachedCount( (struct gl2_container_intf **) pro ); + break; + case GL_ACTIVE_ATTRIBUTES: + *params = (**pro).GetActiveAttribCount(pro); + break; + case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: + *params = (**pro).GetActiveAttribMaxLength(pro); + break; + case GL_ACTIVE_UNIFORMS: + *params = (**pro).GetActiveUniformCount(pro); + break; + case GL_ACTIVE_UNIFORM_MAX_LENGTH: + *params = (**pro).GetActiveUniformMaxLength(pro); + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)"); + return; + } +} + +void GLAPIENTRY +_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize, + GLsizei *length, GLchar *infoLog) +{ + _mesa_GetInfoLogARB(program, bufSize, length, infoLog); +} + +void GLAPIENTRY +_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params) +{ + GET_CURRENT_CONTEXT(ctx); + GET_SHADER(sh, shader, "glGetShaderiv"); + + if (!sh) + return; + + switch (pname) { + case GL_SHADER_TYPE: + *params = (**sh).GetSubType(sh); + break; + case GL_DELETE_STATUS: + *params = (**sh)._generic.GetDeleteStatus((struct gl2_generic_intf **) sh); + break; + case GL_COMPILE_STATUS: + *params = (**sh).GetCompileStatus(sh); + break; + case GL_INFO_LOG_LENGTH: + *params = (**sh)._generic.GetInfoLogLength((struct gl2_generic_intf **)sh); + break; + case GL_SHADER_SOURCE_LENGTH: + { + const GLchar *src = (**sh).GetSource(sh); + *params = src ? (_mesa_strlen(src) + 1) : 0; + } + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)"); + return; + } +} + +void GLAPIENTRY +_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize, + GLsizei *length, GLchar *infoLog) +{ + _mesa_GetInfoLogARB(shader, bufSize, length, infoLog); +} + +GLboolean GLAPIENTRY +_mesa_IsProgram(GLuint program) +{ + GET_CURRENT_CONTEXT(ctx); + GET_PROGRAM(pro, program, "glIsProgram"); + if (pro) { + RELEASE_PROGRAM(pro); + return GL_TRUE; + } + else { + return GL_FALSE; + } +} + +GLboolean GLAPIENTRY +_mesa_IsShader(GLuint shader) +{ + GET_CURRENT_CONTEXT(ctx); + GET_SHADER(sh, shader, "glIsProgram"); + if (sh) { + RELEASE_SHADER(sh); + return GL_TRUE; + } + else { + return GL_FALSE; + } +} + + +/** + ** 2.1 functions + **/ + +void GLAPIENTRY +_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value) +{ + uniform_matrix(2, 3, "glUniformMatrix2x3fv", GL_FLOAT_MAT2x3, + location, count, transpose, value); +} + +void GLAPIENTRY +_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value) +{ + uniform_matrix(3, 2, "glUniformMatrix3x2fv", GL_FLOAT_MAT3x2, + location, count, transpose, value); +} + +void GLAPIENTRY +_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value) +{ + uniform_matrix(2, 4, "glUniformMatrix2x4fv", GL_FLOAT_MAT2x4, + location, count, transpose, value); +} + +void GLAPIENTRY +_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value) +{ + uniform_matrix(4, 2, "glUniformMatrix4x2fv", GL_FLOAT_MAT4x2, + location, count, transpose, value); +} + +void GLAPIENTRY +_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value) +{ + uniform_matrix(3, 4, "glUniformMatrix3x4fv", GL_FLOAT_MAT3x4, + location, count, transpose, value); +} + +void GLAPIENTRY +_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value) +{ + uniform_matrix(4, 3, "glUniformMatrix4x3fv", GL_FLOAT_MAT4x3, + location, count, transpose, value); +} + + + + + #endif GLvoid -_mesa_init_shaderobjects (GLcontext *ctx) +_mesa_init_shaderobjects(GLcontext * ctx) { - ctx->ShaderObjects.CurrentProgram = NULL; - ctx->ShaderObjects._FragmentShaderPresent = GL_FALSE; - ctx->ShaderObjects._VertexShaderPresent = GL_FALSE; + ctx->ShaderObjects.CurrentProgram = NULL; + ctx->ShaderObjects._FragmentShaderPresent = GL_FALSE; + ctx->ShaderObjects._VertexShaderPresent = GL_FALSE; - _mesa_init_shaderobjects_3dlabs (ctx); + _mesa_init_shaderobjects_3dlabs(ctx); } - diff --git a/src/mesa/shader/shaderobjects.h b/src/mesa/shader/shaderobjects.h index cc670216292..09ba807255e 100644 --- a/src/mesa/shader/shaderobjects.h +++ b/src/mesa/shader/shaderobjects.h @@ -104,6 +104,8 @@ 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); + GLboolean (* ReadUniform) (struct gl2_program_intf **, GLint loc, GLsizei count, + 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 **); @@ -270,6 +272,79 @@ _mesa_GetAttribLocationARB (GLhandleARB, const GLcharARB *); #endif /* FEATURE_ARB_vertex_shader */ + +/* 2.0 */ +extern void GLAPIENTRY +_mesa_AttachShader(GLuint program, GLuint shader); + +extern GLuint GLAPIENTRY +_mesa_CreateShader(GLenum); + +extern GLuint GLAPIENTRY +_mesa_CreateProgram(void); + +extern void GLAPIENTRY +_mesa_DeleteProgram(GLuint program); + +extern void GLAPIENTRY +_mesa_DeleteShader(GLuint shader); + +extern void GLAPIENTRY +_mesa_DetachShader(GLuint program, GLuint shader); + +extern void GLAPIENTRY +_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount, + GLsizei *count, GLuint *obj); + +extern void GLAPIENTRY +_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params); + +extern void GLAPIENTRY +_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize, + GLsizei *length, GLchar *infoLog); + +extern void GLAPIENTRY +_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params); + +extern void GLAPIENTRY +_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize, + GLsizei *length, GLchar *infoLog); + +extern GLboolean GLAPIENTRY +_mesa_IsProgram(GLuint program); + +extern GLboolean GLAPIENTRY +_mesa_IsShader(GLuint shader); + + + +/* 2.1 */ +extern void GLAPIENTRY +_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value); + +extern void GLAPIENTRY +_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value); + +extern void GLAPIENTRY +_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value); + +extern void GLAPIENTRY +_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value); + +extern void GLAPIENTRY +_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value); + +extern void GLAPIENTRY +_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value); + + + #endif /* FEATURE_ARB_shader_objects */ extern void diff --git a/src/mesa/shader/shaderobjects_3dlabs.c b/src/mesa/shader/shaderobjects_3dlabs.c index 96680f21405..3ead1a17841 100755 --- a/src/mesa/shader/shaderobjects_3dlabs.c +++ b/src/mesa/shader/shaderobjects_3dlabs.c @@ -48,217 +48,214 @@ struct gl2_unknown_obj { - GLuint reference_count; - void (* _destructor) (struct gl2_unknown_intf **); + GLuint reference_count; + void (*_destructor) (struct gl2_unknown_intf **); }; struct gl2_unknown_impl { - struct gl2_unknown_intf *_vftbl; - struct gl2_unknown_obj _obj; + struct gl2_unknown_intf *_vftbl; + struct gl2_unknown_obj _obj; }; static void -_unknown_destructor (struct gl2_unknown_intf **intf) +_unknown_destructor(struct gl2_unknown_intf **intf) { } static void -_unknown_AddRef (struct gl2_unknown_intf **intf) +_unknown_AddRef(struct gl2_unknown_intf **intf) { - struct gl2_unknown_impl *impl = (struct gl2_unknown_impl *) intf; + struct gl2_unknown_impl *impl = (struct gl2_unknown_impl *) intf; - impl->_obj.reference_count++; + impl->_obj.reference_count++; } static void -_unknown_Release (struct gl2_unknown_intf **intf) +_unknown_Release(struct gl2_unknown_intf **intf) { - struct gl2_unknown_impl *impl = (struct gl2_unknown_impl *) 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); - } + 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) +_unknown_QueryInterface(struct gl2_unknown_intf **intf, enum gl2_uiid uiid) { - if (uiid == UIID_UNKNOWN) - { - (**intf).AddRef (intf); - return intf; - } - return NULL; + if (uiid == UIID_UNKNOWN) { + (**intf).AddRef(intf); + return intf; + } + return NULL; } static struct gl2_unknown_intf _unknown_vftbl = { - _unknown_AddRef, - _unknown_Release, - _unknown_QueryInterface + _unknown_AddRef, + _unknown_Release, + _unknown_QueryInterface }; static void -_unknown_constructor (struct gl2_unknown_impl *impl) +_unknown_constructor(struct gl2_unknown_impl *impl) { - impl->_vftbl = &_unknown_vftbl; - impl->_obj.reference_count = 1; - impl->_obj._destructor = _unknown_destructor; + 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_unknown_intf **unkouter; }; struct gl2_unkinner_impl { - struct gl2_unknown_intf *_vftbl; - struct gl2_unkinner_obj _obj; + struct gl2_unknown_intf *_vftbl; + struct gl2_unkinner_obj _obj; }; static void -_unkinner_destructor (struct gl2_unknown_intf **intf) +_unkinner_destructor(struct gl2_unknown_intf **intf) { } static void -_unkinner_AddRef (struct gl2_unknown_intf **intf) +_unkinner_AddRef(struct gl2_unknown_intf **intf) { - struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf; + struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf; - (**impl->_obj.unkouter).AddRef (impl->_obj.unkouter); + (**impl->_obj.unkouter).AddRef(impl->_obj.unkouter); } static void -_unkinner_Release (struct gl2_unknown_intf **intf) +_unkinner_Release(struct gl2_unknown_intf **intf) { - struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf; + struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf; - (**impl->_obj.unkouter).Release (impl->_obj.unkouter); + (**impl->_obj.unkouter).Release(impl->_obj.unkouter); } static struct gl2_unknown_intf ** -_unkinner_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) +_unkinner_QueryInterface(struct gl2_unknown_intf **intf, enum gl2_uiid uiid) { - struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf; + struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf; - return (**impl->_obj.unkouter).QueryInterface (impl->_obj.unkouter, uiid); + return (**impl->_obj.unkouter).QueryInterface(impl->_obj.unkouter, uiid); } static struct gl2_unknown_intf _unkinner_vftbl = { - _unkinner_AddRef, - _unkinner_Release, - _unkinner_QueryInterface + _unkinner_AddRef, + _unkinner_Release, + _unkinner_QueryInterface }; static void -_unkinner_constructor (struct gl2_unkinner_impl *impl, struct gl2_unknown_intf **outer) +_unkinner_constructor(struct gl2_unkinner_impl *impl, + struct gl2_unknown_intf **outer) { - impl->_vftbl = &_unkinner_vftbl; - impl->_obj.unkouter = 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_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; + struct gl2_generic_intf *_vftbl; + struct gl2_generic_obj _obj; }; static void -_generic_destructor (struct gl2_unknown_intf **intf) +_generic_destructor(struct gl2_unknown_intf **intf) { - GET_CURRENT_CONTEXT(ctx); - struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf; + GET_CURRENT_CONTEXT(ctx); + struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf; - _mesa_free ((void *) impl->_obj.info_log); + _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); + _glthread_LOCK_MUTEX(ctx->Shared->Mutex); + _mesa_HashRemove(ctx->Shared->GL2Objects, impl->_obj.name); + _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); - _unknown_destructor (intf); + _unknown_destructor(intf); } static struct gl2_unknown_intf ** -_generic_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) +_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); + if (uiid == UIID_GENERIC) { + (**intf).AddRef(intf); + return intf; + } + return _unknown_QueryInterface(intf, uiid); } static void -_generic_Delete (struct gl2_generic_intf **intf) +_generic_Delete(struct gl2_generic_intf **intf) { - struct gl2_generic_impl *impl = (struct gl2_generic_impl *) 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); - } + 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) +_generic_GetName(struct gl2_generic_intf **intf) { - struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf; + struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf; - return impl->_obj.name; + return impl->_obj.name; } static GLboolean -_generic_GetDeleteStatus (struct gl2_generic_intf **intf) +_generic_GetDeleteStatus(struct gl2_generic_intf **intf) { - struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf; + struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf; - return impl->_obj.delete_status; + return impl->_obj.delete_status; } static GLvoid -_generic_GetInfoLog (struct gl2_generic_intf **intf, GLsizei maxlen, GLcharARB *infolog) +_generic_GetInfoLog(struct gl2_generic_intf **intf, GLsizei maxlen, + GLcharARB * infolog) { struct gl2_generic_impl *impl = (struct gl2_generic_impl *) (intf); if (maxlen > 0) { - _mesa_strncpy (infolog, impl->_obj.info_log, maxlen - 1); + _mesa_strncpy(infolog, impl->_obj.info_log, maxlen - 1); infolog[maxlen - 1] = '\0'; } } static GLsizei -_generic_GetInfoLogLength (struct gl2_generic_intf **intf) +_generic_GetInfoLogLength(struct gl2_generic_intf **intf) { struct gl2_generic_impl *impl = (struct gl2_generic_impl *) (intf); if (impl->_obj.info_log == NULL) return 1; - return _mesa_strlen (impl->_obj.info_log) + 1; + return _mesa_strlen(impl->_obj.info_log) + 1; } static struct gl2_generic_intf _generic_vftbl = { { - _unknown_AddRef, - _unknown_Release, - _generic_QueryInterface - }, + _unknown_AddRef, + _unknown_Release, + _generic_QueryInterface}, _generic_Delete, - NULL, /* abstract GetType */ + NULL, /* abstract GetType */ _generic_GetName, _generic_GetDeleteStatus, _generic_GetInfoLog, @@ -266,922 +263,950 @@ static struct gl2_generic_intf _generic_vftbl = { }; static void -_generic_constructor (struct gl2_generic_impl *impl) +_generic_constructor(struct gl2_generic_impl *impl) { - GET_CURRENT_CONTEXT(ctx); + 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; + _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); + _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_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; + struct gl2_container_intf *_vftbl; + struct gl2_container_obj _obj; }; static void -_container_destructor (struct gl2_unknown_intf **intf) +_container_destructor(struct gl2_unknown_intf **intf) { - struct gl2_container_impl *impl = (struct gl2_container_impl *) intf; - GLuint i; + 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); - } + 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); + _generic_destructor(intf); } static struct gl2_unknown_intf ** -_container_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) +_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); + 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) +_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; + 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; - } + 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 = (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; + 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; - } +_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; + _mesa_error(ctx, GL_INVALID_OPERATION, "_container_Detach"); + return GL_FALSE; } static GLsizei -_container_GetAttachedCount (struct gl2_container_intf **intf) +_container_GetAttachedCount(struct gl2_container_intf **intf) { - struct gl2_container_impl *impl = (struct gl2_container_impl *) intf; + struct gl2_container_impl *impl = (struct gl2_container_impl *) intf; - return impl->_obj.attached_count; + return impl->_obj.attached_count; } static struct gl2_generic_intf ** -_container_GetAttached (struct gl2_container_intf **intf, GLuint index) +_container_GetAttached(struct gl2_container_intf **intf, GLuint index) { - struct gl2_container_impl *impl = (struct gl2_container_impl *) intf; + 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]; + (**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, + { + { + _unknown_AddRef, + _unknown_Release, + _container_QueryInterface + }, + _generic_Delete, + NULL, /* abstract GetType */ + _generic_GetName, + _generic_GetDeleteStatus, _generic_GetInfoLog, _generic_GetInfoLogLength - }, - _container_Attach, - _container_Detach, - _container_GetAttachedCount, - _container_GetAttached + }, + _container_Attach, + _container_Detach, + _container_GetAttachedCount, + _container_GetAttached }; static void -_container_constructor (struct gl2_container_impl *impl) +_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; + _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; + struct gl2_unkinner_obj _unknown; #if USE_3DLABS_FRONTEND - ShHandle handle; + ShHandle handle; #endif }; struct gl2_3dlabs_shhandle_impl { - struct gl2_3dlabs_shhandle_intf *_vftbl; - struct gl2_3dlabs_shhandle_obj _obj; + struct gl2_3dlabs_shhandle_intf *_vftbl; + struct gl2_3dlabs_shhandle_obj _obj; }; static void -_3dlabs_shhandle_destructor (struct gl2_unknown_intf **intf) +_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); + struct gl2_3dlabs_shhandle_impl *impl = + (struct gl2_3dlabs_shhandle_impl *) intf; + ShDestruct(impl->_obj.handle); #endif - _unkinner_destructor (intf); + _unkinner_destructor(intf); } static GLvoid * -_3dlabs_shhandle_GetShHandle (struct gl2_3dlabs_shhandle_intf **intf) +_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; + struct gl2_3dlabs_shhandle_impl *impl = + (struct gl2_3dlabs_shhandle_impl *) intf; + return impl->_obj.handle; #else - return NULL; + return NULL; #endif } static struct gl2_3dlabs_shhandle_intf _3dlabs_shhandle_vftbl = { - { - _unkinner_AddRef, - _unkinner_Release, - _unkinner_QueryInterface - }, - _3dlabs_shhandle_GetShHandle + { + _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) +_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; + _unkinner_constructor((struct gl2_unkinner_impl *) impl, outer); + impl->_vftbl = &_3dlabs_shhandle_vftbl; #if USE_3DLABS_FRONTEND - impl->_obj.handle = NULL; + 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; + struct gl2_generic_obj _generic; + struct gl2_3dlabs_shhandle_impl _3dlabs_shhandle; + GLboolean compile_status; + GLcharARB *source; + GLint *offsets; + GLsizei offset_count; slang_code_object code; }; struct gl2_shader_impl { - struct gl2_shader_intf *_vftbl; - struct gl2_shader_obj _obj; + struct gl2_shader_intf *_vftbl; + struct gl2_shader_obj _obj; }; static void -_shader_destructor (struct gl2_unknown_intf **intf) +_shader_destructor(struct gl2_unknown_intf **intf) { - struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; + struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; - _mesa_free ((void *) impl->_obj.source); - _mesa_free ((void *) impl->_obj.offsets); - _slang_code_object_dtr (&impl->_obj.code); - _3dlabs_shhandle_destructor ((struct gl2_unknown_intf **) &impl->_obj._3dlabs_shhandle._vftbl); - _generic_destructor (intf); + _mesa_free((void *) impl->_obj.source); + _mesa_free((void *) impl->_obj.offsets); + _slang_code_object_dtr(&impl->_obj.code); + _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) +_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; + struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; #endif - if (uiid == UIID_SHADER) - { - (**intf).AddRef (intf); - return intf; - } + 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; - } + if (uiid == UIID_3DLABS_SHHANDLE) { + (**intf).AddRef(intf); + return (struct gl2_unknown_intf **) &impl->_obj._3dlabs_shhandle._vftbl; + } #endif - return _generic_QueryInterface (intf, uiid); + return _generic_QueryInterface(intf, uiid); } static GLenum -_shader_GetType (struct gl2_generic_intf **intf) +_shader_GetType(struct gl2_generic_intf **intf) { - return GL_SHADER_OBJECT_ARB; + return GL_SHADER_OBJECT_ARB; } static GLvoid -_shader_GetInfoLog (struct gl2_generic_intf **intf, GLsizei maxlen, GLcharARB *infolog) +_shader_GetInfoLog(struct gl2_generic_intf **intf, GLsizei maxlen, + GLcharARB * infolog) { struct gl2_shader_impl *impl = (struct gl2_shader_impl *) (intf); if (maxlen > 0) { if (impl->_obj._generic.info_log != NULL) { - GLsizei len = _mesa_strlen (impl->_obj._generic.info_log); + GLsizei len = _mesa_strlen(impl->_obj._generic.info_log); if (len > maxlen - 1) len = maxlen - 1; - _mesa_memcpy (infolog, impl->_obj._generic.info_log, len); + _mesa_memcpy(infolog, impl->_obj._generic.info_log, len); infolog += len; maxlen -= len; } if (impl->_obj.code.machine.infolog != NULL && impl->_obj.code.machine.infolog->text != NULL) { - GLsizei len = _mesa_strlen (impl->_obj.code.machine.infolog->text); + GLsizei len = _mesa_strlen(impl->_obj.code.machine.infolog->text); if (len > maxlen - 1) len = maxlen - 1; - _mesa_memcpy (infolog, impl->_obj.code.machine.infolog->text, len); + _mesa_memcpy(infolog, impl->_obj.code.machine.infolog->text, len); } infolog[maxlen - 1] = '\0'; } } static GLsizei -_shader_GetInfoLogLength (struct gl2_generic_intf **intf) +_shader_GetInfoLogLength(struct gl2_generic_intf **intf) { struct gl2_shader_impl *impl = (struct gl2_shader_impl *) (intf); GLsizei length = 1; if (impl->_obj._generic.info_log != NULL) - length += _mesa_strlen (impl->_obj._generic.info_log); + length += _mesa_strlen(impl->_obj._generic.info_log); if (impl->_obj.code.machine.infolog != NULL && impl->_obj.code.machine.infolog->text != NULL) - length += _mesa_strlen (impl->_obj.code.machine.infolog->text); + length += _mesa_strlen(impl->_obj.code.machine.infolog->text); return length; } static GLboolean -_shader_GetCompileStatus (struct gl2_shader_intf **intf) +_shader_GetCompileStatus(struct gl2_shader_intf **intf) { - struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; + struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; - return impl->_obj.compile_status; + return impl->_obj.compile_status; } static GLvoid -_shader_SetSource (struct gl2_shader_intf **intf, GLcharARB *src, GLint *off, GLsizei cnt) +_shader_SetSource(struct gl2_shader_intf **intf, GLcharARB * src, GLint * off, + GLsizei cnt) { - struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; + 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; + _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) +_shader_GetSource(struct gl2_shader_intf **intf) { - struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; + struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; - return impl->_obj.source; + return impl->_obj.source; } static GLvoid -_shader_Compile (struct gl2_shader_intf **intf) +_shader_Compile(struct gl2_shader_intf **intf) { - struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; + struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; #if USE_3DLABS_FRONTEND - char **strings; - TBuiltInResource res; + char **strings; + TBuiltInResource res; #else - slang_unit_type type; - slang_info_log info_log; + 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; + 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)); + /* 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.code, type, &info_log)) + 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.code, 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 if (impl->_obj.compile_status) - impl->_obj._generic.info_log = _mesa_strdup ("Compile OK.\n"); + if (info_log.text != NULL) + impl->_obj._generic.info_log = _mesa_strdup(info_log.text); + else if (impl->_obj.compile_status) + impl->_obj._generic.info_log = _mesa_strdup("Compile OK.\n"); else - impl->_obj._generic.info_log = _mesa_strdup ("Compile failed.\n"); - slang_info_log_destruct (&info_log); + impl->_obj._generic.info_log = _mesa_strdup("Compile failed.\n"); + 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, + { + { + _unknown_AddRef, + _unknown_Release, + _shader_QueryInterface + }, + _generic_Delete, + _shader_GetType, + _generic_GetName, + _generic_GetDeleteStatus, _shader_GetInfoLog, _shader_GetInfoLogLength - }, - NULL, /* abstract GetSubType */ - _shader_GetCompileStatus, - _shader_SetSource, - _shader_GetSource, - _shader_Compile + }, + NULL, /* abstract GetSubType */ + _shader_GetCompileStatus, + _shader_SetSource, + _shader_GetSource, + _shader_Compile }; static void -_shader_constructor (struct gl2_shader_impl *impl) +_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; - _slang_code_object_ctr (&impl->_obj.code); + _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; + _slang_code_object_ctr(&impl->_obj.code); } struct gl2_program_obj { - struct gl2_container_obj _container; - GLboolean link_status; - GLboolean validate_status; + struct gl2_container_obj _container; + GLboolean link_status; + GLboolean validate_status; #if USE_3DLABS_FRONTEND - ShHandle linker; - ShHandle uniforms; + ShHandle linker; + ShHandle uniforms; #endif - slang_program prog; + slang_program prog; }; struct gl2_program_impl { - struct gl2_program_intf *_vftbl; - struct gl2_program_obj _obj; + struct gl2_program_intf *_vftbl; + struct gl2_program_obj _obj; }; static void -_program_destructor (struct gl2_unknown_intf **intf) +_program_destructor(struct gl2_unknown_intf **intf) { - struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; + struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; #if USE_3DLABS_FRONTEND - ShDestruct (impl->_obj.linker); - ShDestruct (impl->_obj.uniforms); + ShDestruct(impl->_obj.linker); + ShDestruct(impl->_obj.uniforms); #endif - _container_destructor (intf); - _slang_program_dtr (&impl->_obj.prog); + _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) +_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); + if (uiid == UIID_PROGRAM) { + (**intf).AddRef(intf); + return intf; + } + return _container_QueryInterface(intf, uiid); } static GLenum -_program_GetType (struct gl2_generic_intf **intf) +_program_GetType(struct gl2_generic_intf **intf) { - return GL_PROGRAM_OBJECT_ARB; + 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; - } +_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); + (**sha).Release(sha); + return _container_Attach(intf, att); } static GLboolean -_program_GetLinkStatus (struct gl2_program_intf **intf) +_program_GetLinkStatus(struct gl2_program_intf **intf) { - struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; + struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; - return impl->_obj.link_status; + return impl->_obj.link_status; } static GLboolean -_program_GetValidateStatus (struct gl2_program_intf **intf) +_program_GetValidateStatus(struct gl2_program_intf **intf) { - struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; + struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; - return impl->_obj.validate_status; + return impl->_obj.validate_status; } static GLvoid -_program_Link (struct gl2_program_intf **intf) +_program_Link(struct gl2_program_intf **intf) { - struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; + struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; #if USE_3DLABS_FRONTEND - ShHandle *handles; + ShHandle *handles; #endif - GLuint i, count; + GLuint i, count; slang_code_object *code[2]; GLboolean all_compiled = GL_TRUE; - impl->_obj.link_status = GL_FALSE; - _mesa_free ((void *) impl->_obj._container._generic.info_log); - impl->_obj._container._generic.info_log = NULL; - _slang_program_rst (&impl->_obj.prog); + impl->_obj.link_status = GL_FALSE; + _mesa_free((void *) impl->_obj._container._generic.info_log); + impl->_obj._container._generic.info_log = NULL; + _slang_program_rst(&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)); + 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 > 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); - if (unk == NULL) - return; - sha = (struct gl2_shader_impl *) unk; + + 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); + if (unk == NULL) + return; + sha = (struct gl2_shader_impl *) unk; code[i] = &sha->_obj.code; all_compiled = all_compiled && sha->_obj.compile_status; - (**unk).Release (unk); + (**unk).Release(unk); } impl->_obj.link_status = all_compiled; - if (!impl->_obj.link_status) - { - impl->_obj._container._generic.info_log = _mesa_strdup ( - "Error: One or more shaders has not successfully compiled.\n"); + if (!impl->_obj.link_status) { + impl->_obj._container._generic.info_log = + _mesa_strdup + ("Error: One or more shaders has not successfully compiled.\n"); return; } - impl->_obj.link_status = _slang_link (&impl->_obj.prog, code, count); - if (!impl->_obj.link_status) - { - impl->_obj._container._generic.info_log = _mesa_strdup ("Link failed.\n"); + impl->_obj.link_status = _slang_link(&impl->_obj.prog, code, count); + if (!impl->_obj.link_status) { + impl->_obj._container._generic.info_log = + _mesa_strdup("Link failed.\n"); return; } - impl->_obj._container._generic.info_log = _mesa_strdup ("Link OK.\n"); + impl->_obj._container._generic.info_log = _mesa_strdup("Link OK.\n"); #endif } static GLvoid -_program_Validate (struct gl2_program_intf **intf) +_program_Validate(struct gl2_program_intf **intf) { - struct gl2_program_impl *impl = (struct gl2_program_impl *) 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; + impl->_obj.validate_status = GL_FALSE; + _mesa_free((void *) impl->_obj._container._generic.info_log); + impl->_obj._container._generic.info_log = NULL; - /* TODO validate */ + /* TODO validate */ } static GLvoid -write_common_fixed (slang_program *pro, GLuint index, const GLvoid *src, GLuint off, GLuint size) +write_common_fixed(slang_program * pro, GLuint index, const GLvoid * src, + GLuint off, GLuint size) { - GLuint i; + GLuint i; - for (i = 0; i < SLANG_SHADER_MAX; i++) - { - GLuint addr; + for (i = 0; i < SLANG_SHADER_MAX; i++) { + GLuint addr; - addr = pro->common_fixed_entries[i][index]; - if (addr != ~0) - { - GLubyte *dst; + 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); - } - } + 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) +write_common_fixed_mat4(slang_program * pro, GLmatrix * matrix, GLuint off, + GLuint i, GLuint ii, GLuint it, GLuint iit) { - GLfloat mat[16]; + 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); + /* 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)); + write_common_fixed(pro, i, matrix->m, off, 16 * sizeof(GLfloat)); - /* inverse */ - write_common_fixed (pro, ii, matrix->inv, 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)); + /* 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)); + /* 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) +write_common_fixed_material(GLcontext * ctx, slang_program * pro, GLuint i, + GLuint e, GLuint a, GLuint d, GLuint sp, + GLuint sh) { - GLfloat v[17]; + 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)); + 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) +write_common_fixed_light_model_product(GLcontext * ctx, slang_program * pro, + GLuint i, GLuint e, GLuint a) { - GLfloat v[4]; + 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)); + 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) +write_common_fixed_light_product(GLcontext * ctx, slang_program * pro, + GLuint off, GLuint i, GLuint a, GLuint d, + GLuint s) { - GLfloat v[12]; + 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)); + 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)); +_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_UpdateFixedAttrib (struct gl2_program_intf **intf, GLuint index, GLvoid *data, - GLuint offset, GLuint size, GLboolean write) +_program_UpdateFixedAttrib(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); - } + 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); + } } @@ -1199,594 +1224,711 @@ _program_UpdateFixedAttrib (struct gl2_program_intf **intf, GLuint index, GLvoid */ static GLvoid _program_UpdateFixedVarying(struct gl2_program_intf **intf, GLuint index, - GLvoid *data, + 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); - } + 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 */ +_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) +_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; + 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; - } + 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) +get_active_variable(slang_active_variable * var, GLsizei maxLength, + GLsizei * length, GLint * size, GLenum * type, + GLchar * name) { - GLsizei len; + 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'; + 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) +get_active_variable_max_length(slang_active_variables * vars) { - GLuint i, len = 0; + 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; + 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) +_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]; + 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); + get_active_variable(u, maxLength, length, size, type, name); } static GLuint -_program_GetActiveUniformMaxLength (struct gl2_program_intf **intf) +_program_GetActiveUniformMaxLength(struct gl2_program_intf **intf) { - struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); + struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); - return get_active_variable_max_length (&impl->_obj.prog.active_uniforms); + return get_active_variable_max_length(&impl->_obj.prog.active_uniforms); } static GLuint -_program_GetActiveUniformCount (struct gl2_program_intf **intf) +_program_GetActiveUniformCount(struct gl2_program_intf **intf) { - struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); + struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); - return impl->_obj.prog.active_uniforms.count; + return impl->_obj.prog.active_uniforms.count; } static GLint -_program_GetUniformLocation (struct gl2_program_intf **intf, const GLchar *name) +_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; +} + +/** + * Write a uniform variable into program's memory. + * \return GL_TRUE for success, GL_FALSE if error + */ +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 *bind = &impl->_obj.prog.uniforms; - GLuint i; + 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 < 0 || 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; - for (i = 0; i < bind->count; i++) - if (_mesa_strcmp (bind->table[i].name, name) == 0) - return i; - return -1; + 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; + } + + for (i = 0; i < SLANG_SHADER_MAX; i++) { + if (uniform->address[i] != ~0) { + void *dest + = &impl->_obj.prog.machines[i]->mem[uniform->address[i] / 4]; + /* total number of values to copy */ + GLuint total + = count * slang_export_data_quant_components(uniform->quant); + GLuint j; + if (convert_float_to_bool) { + const GLfloat *src = (GLfloat *) (data); + GLfloat *dst = (GLfloat *) dest; + for (j = 0; j < total; j++) + dst[j] = src[j] != 0.0f ? 1.0f : 0.0f; + break; + } + else if (convert_int_to_bool) { + const GLint *src = (GLint *) (data); + GLfloat *dst = (GLfloat *) dest; + for (j = 0; j < total; j++) + dst[j] = src[j] ? 1.0f : 0.0f; + break; + } + else if (convert_int_to_float) { + const GLint *src = (GLint *) (data); + GLfloat *dst = (GLfloat *) dest; + for (j = 0; j < total; j++) + dst[j] = (GLfloat) src[j]; + break; + } + else { + _mesa_memcpy(dest, data, total * sizeof(GLfloat)); + break; + } + break; + } + } + return GL_TRUE; } +/** + * Read a uniform variable from program's memory. + * \return GL_TRUE for success, GL_FALSE if error + */ 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; +_program_ReadUniform(struct gl2_program_intf **intf, GLint loc, + GLsizei count, GLvoid *data, GLenum type) +{ + struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); + const slang_uniform_bindings *uniforms = &impl->_obj.prog.uniforms; + const slang_uniform_binding *uniform; + GLuint i; + GLboolean convert_bool_to_float = GL_FALSE; + GLboolean convert_bool_to_int = GL_FALSE; + GLboolean convert_float_to_int = GL_FALSE; + GLboolean types_match = GL_FALSE; + + if (loc < 0 || loc >= uniforms->count) + return GL_FALSE; + + uniform = &uniforms->table[loc]; + + 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_bool_to_float = GL_TRUE; + else + convert_bool_to_int = 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_bool_to_float = GL_TRUE; + else + convert_bool_to_int = 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_bool_to_float = GL_TRUE; + else + convert_bool_to_int = 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_bool_to_float = GL_TRUE; + else + convert_bool_to_int = 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: + /* uniform is a float type */ + types_match = (type == GL_FLOAT); + 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_float_to_int = GL_TRUE; + break; + } + + for (i = 0; i < SLANG_SHADER_MAX; i++) { + if (uniform->address[i] != ~0) { + /* XXX if bools are really implemented as floats, some of this + * could probably be culled out. + */ + const void *source + = &impl->_obj.prog.machines[i]->mem[uniform->address[i] / 4]; + /* total number of values to copy */ + const GLuint total + = count * slang_export_data_quant_components(uniform->quant); + GLuint j; + if (convert_bool_to_float) { + GLfloat *dst = (GLfloat *) (data); + const GLfloat *src = (GLfloat *) source; + for (j = 0; j < total; j++) + dst[j] = src[j] == 0.0 ? 0.0 : 1.0; + } + else if (convert_bool_to_int) { + GLint *dst = (GLint *) (data); + const GLfloat *src = (GLfloat *) source; + for (j = 0; j < total; j++) + dst[j] = src[j] == 0.0 ? 0 : 1; + } + else if (convert_float_to_int) { + GLint *dst = (GLint *) (data); + const GLfloat *src = (GLfloat *) source; + for (j = 0; j < total; j++) + dst[j] = (GLint) src[j]; + } + else { + /* no type conversion needed */ + _mesa_memcpy(data, source, total * sizeof(GLfloat)); + } + break; + } /* if */ + } /* for */ + + return GL_TRUE; } + static GLvoid -_program_GetActiveAttrib (struct gl2_program_intf **intf, GLuint index, GLsizei maxLength, - GLsizei *length, GLint *size, GLenum *type, GLchar *name) +_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]; + 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); + get_active_variable(a, maxLength, length, size, type, name); } static GLuint -_program_GetActiveAttribMaxLength (struct gl2_program_intf **intf) +_program_GetActiveAttribMaxLength(struct gl2_program_intf **intf) { - struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); + struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); - return get_active_variable_max_length (&impl->_obj.prog.active_attribs); + return get_active_variable_max_length(&impl->_obj.prog.active_attribs); } static GLuint -_program_GetActiveAttribCount (struct gl2_program_intf **intf) +_program_GetActiveAttribCount(struct gl2_program_intf **intf) { - struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); + struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); - return impl->_obj.prog.active_attribs.count; + return impl->_obj.prog.active_attribs.count; } static GLint -_program_GetAttribLocation (struct gl2_program_intf **intf, const GLchar *name) +_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; + 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; + 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) +_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; + 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"); + if (!_slang_attrib_overrides_add(&pro->attrib_overrides, index, name)) + _mesa_error(ctx, GL_OUT_OF_MEMORY, "_program_OverrideAttribBinding"); } static GLvoid -_program_WriteAttrib (struct gl2_program_intf **intf, GLuint index, const GLfloat *value) +_program_WriteAttrib(struct gl2_program_intf **intf, GLuint index, + const GLfloat * value) { struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); slang_program *pro = &impl->_obj.prog; slang_attrib_slot *slot = &pro->attribs.slots[index]; /* - * Generic attributes can be allocated in a shader with scalar, vec or mat type. - * For scalar and vec types (specifically float, vec2 and vec3) this is simple - just - * ignore the extra components. For mat type this is more complicated - the vertex_shader - * spec requires to store every column of a matrix in a separate attrib slot. - * To prvent from overwriting data from neighbouring matrix columns, the "fill" information - * is kept to know how many components to copy. + * Generic attributes can be allocated in a shader with scalar, vec + * or mat type. For scalar and vec types (specifically float, vec2 + * and vec3) this is simple - just ignore the extra components. For + * mat type this is more complicated - the vertex_shader spec + * requires to store every column of a matrix in a separate attrib + * slot. To prvent from overwriting data from neighbouring matrix + * columns, the "fill" information is kept to know how many + * components to copy. */ if (slot->addr != ~0) - _mesa_memcpy (&pro->machines[SLANG_SHADER_VERTEX]->mem[slot->addr / 4]._float, value, - slot->fill * sizeof (GLfloat)); + _mesa_memcpy(&pro->machines[SLANG_SHADER_VERTEX]->mem[slot->addr / 4]. + _float, value, slot->fill * sizeof(GLfloat)); } 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; - } +_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, + { + { + { + _unknown_AddRef, + _unknown_Release, + _program_QueryInterface + }, + _generic_Delete, + _program_GetType, + _generic_GetName, + _generic_GetDeleteStatus, _generic_GetInfoLog, _generic_GetInfoLogLength - }, - _program_Attach, - _container_Detach, - _container_GetAttachedCount, - _container_GetAttached - }, - _program_GetLinkStatus, - _program_GetValidateStatus, - _program_Link, - _program_Validate, - _program_UpdateFixedUniforms, - _program_UpdateFixedAttrib, - _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_Attach, + _container_Detach, + _container_GetAttachedCount, + _container_GetAttached + }, + _program_GetLinkStatus, + _program_GetValidateStatus, + _program_Link, + _program_Validate, + _program_UpdateFixedUniforms, + _program_UpdateFixedAttrib, + _program_UpdateFixedVarying, + _program_GetTextureImageUsage, + _program_IsShaderPresent, + _program_GetActiveUniform, + _program_GetActiveUniformMaxLength, + _program_GetActiveUniformCount, + _program_GetUniformLocation, + _program_WriteUniform, + _program_ReadUniform, + _program_GetActiveAttrib, + _program_GetActiveAttribMaxLength, + _program_GetActiveAttribCount, + _program_GetAttribLocation, + _program_OverrideAttribBinding, _program_WriteAttrib, - _program_UpdateVarying + _program_UpdateVarying }; static void -_program_constructor (struct gl2_program_impl *impl) +_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; + _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 (); + impl->_obj.linker = ShConstructLinker(EShExVertexFragment, 0); + impl->_obj.uniforms = ShConstructUniformMap(); #endif - _slang_program_ctr (&impl->_obj.prog); + _slang_program_ctr(&impl->_obj.prog); } struct gl2_fragment_shader_obj { - struct gl2_shader_obj _shader; + struct gl2_shader_obj _shader; }; struct gl2_fragment_shader_impl { - struct gl2_fragment_shader_intf *_vftbl; - struct gl2_fragment_shader_obj _obj; + struct gl2_fragment_shader_intf *_vftbl; + struct gl2_fragment_shader_obj _obj; }; static void -_fragment_shader_destructor (struct gl2_unknown_intf **intf) +_fragment_shader_destructor(struct gl2_unknown_intf **intf) { - struct gl2_fragment_shader_impl *impl = (struct gl2_fragment_shader_impl *) intf; + struct gl2_fragment_shader_impl *impl = + (struct gl2_fragment_shader_impl *) intf; - (void) impl; - /* TODO free fragment shader data */ + (void) impl; + /* TODO free fragment shader data */ - _shader_destructor (intf); + _shader_destructor(intf); } static struct gl2_unknown_intf ** -_fragment_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) +_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); + 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) +_fragment_shader_GetSubType(struct gl2_shader_intf **intf) { - return GL_FRAGMENT_SHADER_ARB; + 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, + { + { + { + _unknown_AddRef, + _unknown_Release, + _fragment_shader_QueryInterface + }, + _generic_Delete, + _shader_GetType, + _generic_GetName, + _generic_GetDeleteStatus, _shader_GetInfoLog, _shader_GetInfoLogLength - }, - _fragment_shader_GetSubType, - _shader_GetCompileStatus, - _shader_SetSource, - _shader_GetSource, - _shader_Compile - } + }, + _fragment_shader_GetSubType, + _shader_GetCompileStatus, + _shader_SetSource, + _shader_GetSource, + _shader_Compile + } }; static void -_fragment_shader_constructor (struct gl2_fragment_shader_impl *impl) +_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; + _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); + impl->_obj._shader._3dlabs_shhandle._obj.handle = + ShConstructCompiler(EShLangFragment, 0); #endif } struct gl2_vertex_shader_obj { - struct gl2_shader_obj _shader; + struct gl2_shader_obj _shader; }; struct gl2_vertex_shader_impl { - struct gl2_vertex_shader_intf *_vftbl; - struct gl2_vertex_shader_obj _obj; + struct gl2_vertex_shader_intf *_vftbl; + struct gl2_vertex_shader_obj _obj; }; static void -_vertex_shader_destructor (struct gl2_unknown_intf **intf) +_vertex_shader_destructor(struct gl2_unknown_intf **intf) { - struct gl2_vertex_shader_impl *impl = (struct gl2_vertex_shader_impl *) intf; + struct gl2_vertex_shader_impl *impl = + (struct gl2_vertex_shader_impl *) intf; - (void) impl; - /* TODO free vertex shader data */ + (void) impl; + /* TODO free vertex shader data */ - _shader_destructor (intf); + _shader_destructor(intf); } static struct gl2_unknown_intf ** -_vertex_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) +_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); + 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) +_vertex_shader_GetSubType(struct gl2_shader_intf **intf) { - return GL_VERTEX_SHADER_ARB; + 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, + { + { + { + _unknown_AddRef, + _unknown_Release, + _vertex_shader_QueryInterface + }, + _generic_Delete, + _shader_GetType, + _generic_GetName, + _generic_GetDeleteStatus, _shader_GetInfoLog, _shader_GetInfoLogLength - }, - _vertex_shader_GetSubType, - _shader_GetCompileStatus, - _shader_SetSource, - _shader_GetSource, - _shader_Compile - } + }, + _vertex_shader_GetSubType, + _shader_GetCompileStatus, + _shader_SetSource, + _shader_GetSource, + _shader_Compile + } }; static void -_vertex_shader_constructor (struct gl2_vertex_shader_impl *impl) +_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; + _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); + impl->_obj._shader._3dlabs_shhandle._obj.handle = + ShConstructCompiler(EShLangVertex, 0); #endif } @@ -1802,34 +1944,35 @@ struct gl2_debug_impl }; static GLvoid -_debug_destructor (struct gl2_unknown_intf **intf) +_debug_destructor(struct gl2_unknown_intf **intf) { struct gl2_debug_impl *impl = (struct gl2_debug_impl *) (intf); (void) (impl); /* TODO */ - _generic_destructor (intf); + _generic_destructor(intf); } static struct gl2_unknown_intf ** -_debug_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) +_debug_QueryInterface(struct gl2_unknown_intf **intf, enum gl2_uiid uiid) { if (uiid == UIID_DEBUG) { - (**intf).AddRef (intf); + (**intf).AddRef(intf); return intf; } - return _generic_QueryInterface (intf, uiid); + return _generic_QueryInterface(intf, uiid); } static GLenum -_debug_GetType (struct gl2_generic_intf **intf) +_debug_GetType(struct gl2_generic_intf **intf) { - return /*GL_DEBUG_OBJECT_MESA*/0; + return /*GL_DEBUG_OBJECT_MESA */ 0; } static GLvoid -_debug_ClearDebugLog (struct gl2_debug_intf **intf, GLenum logType, GLenum shaderType) +_debug_ClearDebugLog(struct gl2_debug_intf **intf, GLenum logType, + GLenum shaderType) { struct gl2_debug_impl *impl = (struct gl2_debug_impl *) (intf); @@ -1838,8 +1981,9 @@ _debug_ClearDebugLog (struct gl2_debug_intf **intf, GLenum logType, GLenum shade } static GLvoid -_debug_GetDebugLog (struct gl2_debug_intf **intf, GLenum logType, GLenum shaderType, - GLsizei maxLength, GLsizei *length, GLcharARB *infoLog) +_debug_GetDebugLog(struct gl2_debug_intf **intf, GLenum logType, + GLenum shaderType, GLsizei maxLength, GLsizei * length, + GLcharARB * infoLog) { struct gl2_debug_impl *impl = (struct gl2_debug_impl *) (intf); @@ -1848,7 +1992,8 @@ _debug_GetDebugLog (struct gl2_debug_intf **intf, GLenum logType, GLenum shaderT } static GLsizei -_debug_GetDebugLogLength (struct gl2_debug_intf **intf, GLenum logType, GLenum shaderType) +_debug_GetDebugLogLength(struct gl2_debug_intf **intf, GLenum logType, + GLenum shaderType) { struct gl2_debug_impl *impl = (struct gl2_debug_impl *) (intf); @@ -1878,70 +2023,68 @@ static struct gl2_debug_intf _debug_vftbl = { }; static GLvoid -_debug_constructor (struct gl2_debug_impl *impl) +_debug_constructor(struct gl2_debug_impl *impl) { - _generic_constructor ((struct gl2_generic_impl *) (impl)); + _generic_constructor((struct gl2_generic_impl *) (impl)); impl->_vftbl = &_debug_vftbl; impl->_obj._generic._unknown._destructor = _debug_destructor; } 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; +_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) +_mesa_3dlabs_create_program_object(void) { - struct gl2_program_impl *x = (struct gl2_program_impl *) - _mesa_malloc (sizeof (struct gl2_program_impl)); + 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; - } + if (x != NULL) { + _program_constructor(x); + return x->_obj._container._generic.name; + } - return 0; + return 0; } GLhandleARB -_mesa_3dlabs_create_debug_object (GLvoid) +_mesa_3dlabs_create_debug_object(GLvoid) { struct gl2_debug_impl *obj; - obj = (struct gl2_debug_impl *) (_mesa_malloc (sizeof (struct gl2_debug_impl))); + obj = + (struct gl2_debug_impl *) (_mesa_malloc(sizeof(struct gl2_debug_impl))); if (obj != NULL) { - _debug_constructor (obj); + _debug_constructor(obj); return obj->_obj._generic.name; } return 0; @@ -1950,47 +2093,52 @@ _mesa_3dlabs_create_debug_object (GLvoid) #include "slang_assemble.h" #include "slang_execute.h" -int _slang_fetch_discard (struct gl2_program_intf **pro, GLboolean *val) +int +_slang_fetch_discard(struct gl2_program_intf **pro, GLboolean * val) { - struct gl2_program_impl *impl; + 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; + 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) +static GLvoid +exec_shader(struct gl2_program_intf **pro, GLuint i) { - struct gl2_program_impl *impl; - slang_program *p; + struct gl2_program_impl *impl; + slang_program *p; - impl = (struct gl2_program_impl *) pro; - p = &impl->_obj.prog; + 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_machine_init(p->machines[i]); + p->machines[i]->ip = p->code[i][SLANG_COMMON_CODE_MAIN]; - _slang_execute2 (p->assemblies[i], p->machines[i]); + _slang_execute2(p->assemblies[i], p->machines[i]); } -GLvoid _slang_exec_fragment_shader (struct gl2_program_intf **pro) +GLvoid +_slang_exec_fragment_shader(struct gl2_program_intf **pro) { - exec_shader (pro, SLANG_SHADER_FRAGMENT); + exec_shader(pro, SLANG_SHADER_FRAGMENT); } -GLvoid _slang_exec_vertex_shader (struct gl2_program_intf **pro) +GLvoid +_slang_exec_vertex_shader(struct gl2_program_intf **pro) { - exec_shader (pro, SLANG_SHADER_VERTEX); + exec_shader(pro, SLANG_SHADER_VERTEX); } #endif void -_mesa_init_shaderobjects_3dlabs (GLcontext *ctx) +_mesa_init_shaderobjects_3dlabs(GLcontext * ctx) { #if USE_3DLABS_FRONTEND - _glslang_3dlabs_InitProcess (); - _glslang_3dlabs_ShInitialize (); + _glslang_3dlabs_InitProcess(); + _glslang_3dlabs_ShInitialize(); #endif } - diff --git a/src/mesa/shader/slang/slang_assemble.c b/src/mesa/shader/slang/slang_assemble.c index 36fb2305f68..0cba5d5d007 100644 --- a/src/mesa/shader/slang/slang_assemble.c +++ b/src/mesa/shader/slang/slang_assemble.c @@ -35,13 +35,15 @@ /* slang_assembly */ -static GLboolean slang_assembly_construct (slang_assembly *assem) +static GLboolean +slang_assembly_construct(slang_assembly * assem) { - assem->type = slang_asm_none; - return GL_TRUE; + assem->type = slang_asm_none; + return GL_TRUE; } -static GLvoid slang_assembly_destruct (slang_assembly *assem) +static GLvoid +slang_assembly_destruct(slang_assembly * assem) { } @@ -50,80 +52,89 @@ static GLvoid slang_assembly_destruct (slang_assembly *assem) */ GLvoid -_slang_assembly_file_ctr (slang_assembly_file *self) +_slang_assembly_file_ctr(slang_assembly_file * self) { self->code = NULL; self->count = 0; self->capacity = 0; } -GLvoid slang_assembly_file_destruct (slang_assembly_file *file) +GLvoid +slang_assembly_file_destruct(slang_assembly_file * file) { - GLuint i; + GLuint i; - for (i = 0; i < file->count; i++) - slang_assembly_destruct (&file->code[i]); - slang_alloc_free (file->code); + for (i = 0; i < file->count; i++) + slang_assembly_destruct(&file->code[i]); + slang_alloc_free(file->code); } -static GLboolean push_new (slang_assembly_file *file) +static GLboolean +push_new(slang_assembly_file * file) { - if (file->count == file->capacity) - { - GLuint n; - - if (file->capacity == 0) - n = 256; - else - n = file->capacity * 2; - file->code = (slang_assembly *) slang_alloc_realloc (file->code, - file->capacity * sizeof (slang_assembly), n * sizeof (slang_assembly)); - if (file->code == NULL) - return GL_FALSE; - file->capacity = n; - } - if (!slang_assembly_construct (&file->code[file->count])) - return GL_FALSE; - file->count++; - return GL_TRUE; + if (file->count == file->capacity) { + GLuint n; + + if (file->capacity == 0) + n = 256; + else + n = file->capacity * 2; + file->code = (slang_assembly *) + slang_alloc_realloc(file->code, + file->capacity * sizeof(slang_assembly), + n * sizeof(slang_assembly)); + if (file->code == NULL) + return GL_FALSE; + file->capacity = n; + } + if (!slang_assembly_construct(&file->code[file->count])) + return GL_FALSE; + file->count++; + return GL_TRUE; } -static GLboolean push_gen (slang_assembly_file *file, slang_assembly_type type, GLfloat literal, - GLuint label, GLuint size) +static GLboolean +push_gen(slang_assembly_file * file, slang_assembly_type type, + GLfloat literal, GLuint label, GLuint size) { - slang_assembly *assem; - - if (!push_new (file)) - return GL_FALSE; - assem = &file->code[file->count - 1]; - assem->type = type; - assem->literal = literal; - assem->param[0] = label; - assem->param[1] = size; - return GL_TRUE; + slang_assembly *assem; + + if (!push_new(file)) + return GL_FALSE; + assem = &file->code[file->count - 1]; + assem->type = type; + assem->literal = literal; + assem->param[0] = label; + assem->param[1] = size; + return GL_TRUE; } -GLboolean slang_assembly_file_push (slang_assembly_file *file, slang_assembly_type type) +GLboolean +slang_assembly_file_push(slang_assembly_file * file, slang_assembly_type type) { - return push_gen (file, type, (GLfloat) 0, 0, 0); + return push_gen(file, type, (GLfloat) 0, 0, 0); } -GLboolean slang_assembly_file_push_label (slang_assembly_file *file, slang_assembly_type type, - GLuint label) +GLboolean +slang_assembly_file_push_label(slang_assembly_file * file, + slang_assembly_type type, GLuint label) { - return push_gen (file, type, (GLfloat) 0, label, 0); + return push_gen(file, type, (GLfloat) 0, label, 0); } -GLboolean slang_assembly_file_push_label2 (slang_assembly_file *file, slang_assembly_type type, - GLuint label1, GLuint label2) +GLboolean +slang_assembly_file_push_label2(slang_assembly_file * file, + slang_assembly_type type, GLuint label1, + GLuint label2) { - return push_gen (file, type, (GLfloat) 0, label1, label2); + return push_gen(file, type, (GLfloat) 0, label1, label2); } -GLboolean slang_assembly_file_push_literal (slang_assembly_file *file, slang_assembly_type type, - GLfloat literal) +GLboolean +slang_assembly_file_push_literal(slang_assembly_file * file, + slang_assembly_type type, GLfloat literal) { - return push_gen (file, type, literal, 0, 0); + return push_gen(file, type, literal, 0, 0); } #define PUSH slang_assembly_file_push @@ -133,284 +144,296 @@ GLboolean slang_assembly_file_push_literal (slang_assembly_file *file, slang_ass /* slang_assembly_file_restore_point */ -GLboolean slang_assembly_file_restore_point_save (slang_assembly_file *file, - slang_assembly_file_restore_point *point) +GLboolean +slang_assembly_file_restore_point_save(slang_assembly_file * file, + slang_assembly_file_restore_point * + point) { - point->count = file->count; - return GL_TRUE; + point->count = file->count; + return GL_TRUE; } -GLboolean slang_assembly_file_restore_point_load (slang_assembly_file *file, - slang_assembly_file_restore_point *point) +GLboolean +slang_assembly_file_restore_point_load(slang_assembly_file * file, + slang_assembly_file_restore_point * + point) { - GLuint i; + GLuint i; - for (i = point->count; i < file->count; i++) - slang_assembly_destruct (&file->code[i]); - file->count = point->count; - return GL_TRUE; + for (i = point->count; i < file->count; i++) + slang_assembly_destruct(&file->code[i]); + file->count = point->count; + return GL_TRUE; } /* utility functions */ -static GLboolean sizeof_variable (slang_assemble_ctx *A, slang_type_specifier *spec, - slang_type_qualifier qual, GLuint array_len, GLuint *size) +static GLboolean +sizeof_variable(slang_assemble_ctx * A, slang_type_specifier * spec, + slang_type_qualifier qual, GLuint array_len, GLuint * size) { - slang_storage_aggregate agg; - - /* calculate the size of the variable's aggregate */ - if (!slang_storage_aggregate_construct (&agg)) - return GL_FALSE; - if (!_slang_aggregate_variable (&agg, spec, array_len, A->space.funcs, A->space.structs, - A->space.vars, A->mach, A->file, A->atoms)) - { - slang_storage_aggregate_destruct (&agg); - return GL_FALSE; - } - *size += _slang_sizeof_aggregate (&agg); - slang_storage_aggregate_destruct (&agg); - - /* for reference variables consider the additional address overhead */ - if (qual == slang_qual_out || qual == slang_qual_inout) - *size += 4; - - return GL_TRUE; + slang_storage_aggregate agg; + + /* calculate the size of the variable's aggregate */ + if (!slang_storage_aggregate_construct(&agg)) + return GL_FALSE; + if (!_slang_aggregate_variable + (&agg, spec, array_len, A->space.funcs, A->space.structs, + A->space.vars, A->mach, A->file, A->atoms)) { + slang_storage_aggregate_destruct(&agg); + return GL_FALSE; + } + *size += _slang_sizeof_aggregate(&agg); + slang_storage_aggregate_destruct(&agg); + + /* for reference variables consider the additional address overhead */ + if (qual == slang_qual_out || qual == slang_qual_inout) + *size += 4; + + return GL_TRUE; } -static GLboolean sizeof_variable2 (slang_assemble_ctx *A, slang_variable *var, GLuint *size) +static GLboolean +sizeof_variable2(slang_assemble_ctx * A, slang_variable * var, GLuint * size) { - var->address = *size; - if (var->type.qualifier == slang_qual_out || var->type.qualifier == slang_qual_inout) - var->address += 4; - return sizeof_variable (A, &var->type.specifier, var->type.qualifier, var->array_len, size); + var->address = *size; + if (var->type.qualifier == slang_qual_out + || var->type.qualifier == slang_qual_inout) + var->address += 4; + return sizeof_variable(A, &var->type.specifier, var->type.qualifier, + var->array_len, size); } -static GLboolean sizeof_variables (slang_assemble_ctx *A, slang_variable_scope *vars, GLuint start, - GLuint stop, GLuint *size) +static GLboolean +sizeof_variables(slang_assemble_ctx * A, slang_variable_scope * vars, + GLuint start, GLuint stop, GLuint * size) { - GLuint i; + GLuint i; - for (i = start; i < stop; i++) - if (!sizeof_variable2 (A, &vars->variables[i], size)) - return GL_FALSE; - return GL_TRUE; + for (i = start; i < stop; i++) + if (!sizeof_variable2(A, &vars->variables[i], size)) + return GL_FALSE; + return GL_TRUE; } -static GLboolean collect_locals (slang_assemble_ctx *A, slang_operation *op, GLuint *size) +static GLboolean +collect_locals(slang_assemble_ctx * A, slang_operation * op, GLuint * size) { - GLuint i; - - if (!sizeof_variables (A, op->locals, 0, op->locals->num_variables, size)) - return GL_FALSE; - for (i = 0; i < op->num_children; i++) - if (!collect_locals (A, &op->children[i], size)) - return GL_FALSE; - return GL_TRUE; + GLuint i; + + if (!sizeof_variables(A, op->locals, 0, op->locals->num_variables, size)) + return GL_FALSE; + for (i = 0; i < op->num_children; i++) + if (!collect_locals(A, &op->children[i], size)) + return GL_FALSE; + return GL_TRUE; } /* _slang_locate_function() */ -slang_function *_slang_locate_function (slang_function_scope *funcs, slang_atom a_name, - slang_operation *params, GLuint num_params, slang_assembly_name_space *space, - slang_atom_pool *atoms) +slang_function * +_slang_locate_function(const slang_function_scope * funcs, slang_atom a_name, + const slang_operation * params, GLuint num_params, + const slang_assembly_name_space * space, + slang_atom_pool * atoms) { - GLuint i; - - for (i = 0; i < funcs->num_functions; i++) - { - GLuint j; - slang_function *f = &funcs->functions[i]; - - if (a_name != f->header.a_name) - continue; - if (f->param_count != num_params) - continue; - for (j = 0; j < num_params; j++) - { - slang_assembly_typeinfo ti; - - if (!slang_assembly_typeinfo_construct (&ti)) - return NULL; - if (!_slang_typeof_operation_ (¶ms[j], space, &ti, atoms)) - { - slang_assembly_typeinfo_destruct (&ti); - return NULL; - } - if (!slang_type_specifier_equal (&ti.spec, &f->parameters->variables[j].type.specifier)) - { - slang_assembly_typeinfo_destruct (&ti); - break; - } - slang_assembly_typeinfo_destruct (&ti); - - /* "out" and "inout" formal parameter requires the actual parameter to be l-value */ - if (!ti.can_be_referenced && - (f->parameters->variables[j].type.qualifier == slang_qual_out || - f->parameters->variables[j].type.qualifier == slang_qual_inout)) - break; - } - if (j == num_params) - return f; - } - if (funcs->outer_scope != NULL) - return _slang_locate_function (funcs->outer_scope, a_name, params, num_params, space, atoms); - return NULL; + GLuint i; + + for (i = 0; i < funcs->num_functions; i++) { + GLuint j; + slang_function *f = &funcs->functions[i]; + + if (a_name != f->header.a_name) + continue; + if (f->param_count != num_params) + continue; + for (j = 0; j < num_params; j++) { + slang_assembly_typeinfo ti; + + if (!slang_assembly_typeinfo_construct(&ti)) + return NULL; + if (!_slang_typeof_operation_(¶ms[j], space, &ti, atoms)) { + slang_assembly_typeinfo_destruct(&ti); + return NULL; + } + if (!slang_type_specifier_equal + (&ti.spec, &f->parameters->variables[j].type.specifier)) { + slang_assembly_typeinfo_destruct(&ti); + break; + } + slang_assembly_typeinfo_destruct(&ti); + + /* "out" and "inout" formal parameter requires the actual parameter to be l-value */ + if (!ti.can_be_referenced && + (f->parameters->variables[j].type.qualifier == slang_qual_out || + f->parameters->variables[j].type.qualifier == slang_qual_inout)) + break; + } + if (j == num_params) + return f; + } + if (funcs->outer_scope != NULL) + return _slang_locate_function(funcs->outer_scope, a_name, params, + num_params, space, atoms); + return NULL; } /* _slang_assemble_function() */ -GLboolean _slang_assemble_function (slang_assemble_ctx *A, slang_function *fun) +GLboolean +_slang_assemble_function(slang_assemble_ctx * A, slang_function * fun) { - GLuint param_size, local_size; - GLuint skip, cleanup; - - fun->address = A->file->count; - - if (fun->body == NULL) - { - /* jump to the actual function body - we do not know it, so add the instruction - * to fixup table */ - fun->fixups.table = (GLuint *) slang_alloc_realloc (fun->fixups.table, - fun->fixups.count * sizeof (GLuint), (fun->fixups.count + 1) * sizeof (GLuint)); - if (fun->fixups.table == NULL) - return GL_FALSE; - fun->fixups.table[fun->fixups.count] = fun->address; - fun->fixups.count++; - if (!PUSH (A->file, slang_asm_jump)) - return GL_FALSE; - return GL_TRUE; - } - else - { - GLuint i; - - /* resolve all fixup table entries and delete it */ - for (i = 0; i < fun->fixups.count; i++) - A->file->code[fun->fixups.table[i]].param[0] = fun->address; - slang_fixup_table_free (&fun->fixups); - } - - /* At this point traverse function formal parameters and code to calculate - * total memory size to be allocated on the stack. - * During this process the variables will be assigned local addresses to - * reference them in the code. - * No storage optimizations are performed so exclusive scopes are not detected and shared. */ - - /* calculate return value size */ - param_size = 0; - if (fun->header.type.specifier.type != slang_spec_void) - if (!sizeof_variable (A, &fun->header.type.specifier, slang_qual_none, 0, ¶m_size)) - return GL_FALSE; - A->local.ret_size = param_size; - - /* calculate formal parameter list size */ - if (!sizeof_variables (A, fun->parameters, 0, fun->param_count, ¶m_size)) - return GL_FALSE; - - /* calculate local variables size - take into account the four-byte return address and - * temporaries for various tasks (4 for addr and 16 for swizzle temporaries). - * these include variables from the formal parameter scope and from the code */ - A->local.addr_tmp = param_size + 4; - A->local.swizzle_tmp = param_size + 4 + 4; - local_size = param_size + 4 + 4 + 16; - if (!sizeof_variables (A, fun->parameters, fun->param_count, fun->parameters->num_variables, - &local_size)) - return GL_FALSE; - if (!collect_locals (A, fun->body, &local_size)) - return GL_FALSE; - - /* allocate local variable storage */ - if (!PLAB (A->file, slang_asm_local_alloc, local_size - param_size - 4)) - return GL_FALSE; - - /* mark a new frame for function variable storage */ - if (!PLAB (A->file, slang_asm_enter, local_size)) - return GL_FALSE; - - /* jump directly to the actual code */ - skip = A->file->count; - if (!push_new (A->file)) - return GL_FALSE; - A->file->code[skip].type = slang_asm_jump; - - /* all "return" statements will be directed here */ - A->flow.function_end = A->file->count; - cleanup = A->file->count; - if (!push_new (A->file)) - return GL_FALSE; - A->file->code[cleanup].type = slang_asm_jump; - - /* execute the function body */ - A->file->code[skip].param[0] = A->file->count; - if (!_slang_assemble_operation (A, fun->body, /*slang_ref_freelance*/slang_ref_forbid)) - return GL_FALSE; - - /* this is the end of the function - restore the old function frame */ - A->file->code[cleanup].param[0] = A->file->count; - if (!PUSH (A->file, slang_asm_leave)) - return GL_FALSE; - - /* free local variable storage */ - if (!PLAB (A->file, slang_asm_local_free, local_size - param_size - 4)) - return GL_FALSE; - - /* return from the function */ - if (!PUSH (A->file, slang_asm_return)) - return GL_FALSE; - - return GL_TRUE; + GLuint param_size, local_size; + GLuint skip, cleanup; + + fun->address = A->file->count; + + if (fun->body == NULL) { + /* jump to the actual function body - we do not know it, so add + * the instruction to fixup table + */ + if (!slang_fixup_save(&fun->fixups, fun->address)) + return GL_FALSE; + if (!PUSH(A->file, slang_asm_jump)) + return GL_FALSE; + return GL_TRUE; + } + else { + /* resolve all fixup table entries and delete it */ + GLuint i; + for (i = 0; i < fun->fixups.count; i++) + A->file->code[fun->fixups.table[i]].param[0] = fun->address; + slang_fixup_table_free(&fun->fixups); + } + + /* At this point traverse function formal parameters and code to calculate + * total memory size to be allocated on the stack. + * During this process the variables will be assigned local addresses to + * reference them in the code. + * No storage optimizations are performed so exclusive scopes are not + * detected and shared. + */ + + /* calculate return value size */ + param_size = 0; + if (fun->header.type.specifier.type != slang_spec_void) + if (!sizeof_variable + (A, &fun->header.type.specifier, slang_qual_none, 0, ¶m_size)) + return GL_FALSE; + A->local.ret_size = param_size; + + /* calculate formal parameter list size */ + if (!sizeof_variables + (A, fun->parameters, 0, fun->param_count, ¶m_size)) + return GL_FALSE; + + /* calculate local variables size - take into account the four-byte + * return address and temporaries for various tasks (4 for addr and + * 16 for swizzle temporaries). these include variables from the + * formal parameter scope and from the code + */ + A->local.addr_tmp = param_size + 4; + A->local.swizzle_tmp = param_size + 4 + 4; + local_size = param_size + 4 + 4 + 16; + if (!sizeof_variables + (A, fun->parameters, fun->param_count, fun->parameters->num_variables, + &local_size)) + return GL_FALSE; + if (!collect_locals(A, fun->body, &local_size)) + return GL_FALSE; + + /* allocate local variable storage */ + if (!PLAB(A->file, slang_asm_local_alloc, local_size - param_size - 4)) + return GL_FALSE; + + /* mark a new frame for function variable storage */ + if (!PLAB(A->file, slang_asm_enter, local_size)) + return GL_FALSE; + + /* jump directly to the actual code */ + skip = A->file->count; + if (!push_new(A->file)) + return GL_FALSE; + A->file->code[skip].type = slang_asm_jump; + + /* all "return" statements will be directed here */ + A->flow.function_end = A->file->count; + cleanup = A->file->count; + if (!push_new(A->file)) + return GL_FALSE; + A->file->code[cleanup].type = slang_asm_jump; + + /* execute the function body */ + A->file->code[skip].param[0] = A->file->count; + if (!_slang_assemble_operation + (A, fun->body, /*slang_ref_freelance */ slang_ref_forbid)) + return GL_FALSE; + + /* this is the end of the function - restore the old function frame */ + A->file->code[cleanup].param[0] = A->file->count; + if (!PUSH(A->file, slang_asm_leave)) + return GL_FALSE; + + /* free local variable storage */ + if (!PLAB(A->file, slang_asm_local_free, local_size - param_size - 4)) + return GL_FALSE; + + /* return from the function */ + if (!PUSH(A->file, slang_asm_return)) + return GL_FALSE; + + return GL_TRUE; } -GLboolean _slang_cleanup_stack (slang_assemble_ctx *A, slang_operation *op) +GLboolean +_slang_cleanup_stack(slang_assemble_ctx * A, slang_operation * op) { - slang_assembly_typeinfo ti; - GLuint size = 0; - - /* get type info of the operation and calculate its size */ - if (!slang_assembly_typeinfo_construct (&ti)) - return GL_FALSE; - if (!_slang_typeof_operation (A, op, &ti)) - { - slang_assembly_typeinfo_destruct (&ti); - return GL_FALSE; - } - if (ti.spec.type != slang_spec_void) { - if (A->ref == slang_ref_force) { - size = 4; - } - else if (!sizeof_variable (A, &ti.spec, slang_qual_none, 0, &size)) - { - slang_assembly_typeinfo_destruct (&ti); - return GL_FALSE; - } - } - slang_assembly_typeinfo_destruct (&ti); - - /* if nonzero, free it from the stack */ - if (size != 0) - { - if (!PLAB (A->file, slang_asm_local_free, size)) - return GL_FALSE; - } - - return GL_TRUE; + slang_assembly_typeinfo ti; + GLuint size = 0; + + /* get type info of the operation and calculate its size */ + if (!slang_assembly_typeinfo_construct(&ti)) + return GL_FALSE; + if (!_slang_typeof_operation(A, op, &ti)) { + slang_assembly_typeinfo_destruct(&ti); + return GL_FALSE; + } + if (ti.spec.type != slang_spec_void) { + if (A->ref == slang_ref_force) { + size = 4; + } + else if (!sizeof_variable(A, &ti.spec, slang_qual_none, 0, &size)) { + slang_assembly_typeinfo_destruct(&ti); + return GL_FALSE; + } + } + slang_assembly_typeinfo_destruct(&ti); + + /* if nonzero, free it from the stack */ + if (size != 0) { + if (!PLAB(A->file, slang_asm_local_free, size)) + return GL_FALSE; + } + + return GL_TRUE; } /* _slang_assemble_operation() */ static GLboolean -dereference_basic (slang_assemble_ctx *A, slang_storage_type type, GLuint *size, slang_swizzle *swz, - GLboolean is_swizzled) +dereference_basic(slang_assemble_ctx * A, slang_storage_type type, + GLuint * size, slang_swizzle * swz, GLboolean is_swizzled) { GLuint src_offset; slang_assembly_type ty; - *size -= _slang_sizeof_type (type); + *size -= _slang_sizeof_type(type); - /* If swizzling is taking place, we are forced to use scalar operations, even if we have - * vec4 instructions enabled (this should be actually done with special vec4 shuffle - * instructions). - * Adjust the size and calculate the offset within source variable to read. + /* If swizzling is taking place, we are forced to use scalar + * operations, even if we have vec4 instructions enabled (this + * should be actually done with special vec4 shuffle instructions). + * Adjust the size and calculate the offset within source variable + * to read. */ if (is_swizzled) src_offset = swz->swizzle[*size / 4] * 4; @@ -418,14 +441,14 @@ dereference_basic (slang_assemble_ctx *A, slang_storage_type type, GLuint *size, src_offset = *size; /* dereference data slot of a basic type */ - if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4)) + if (!PLAB2(A->file, slang_asm_local_addr, A->local.addr_tmp, 4)) return GL_FALSE; - if (!PUSH (A->file, slang_asm_addr_deref)) + if (!PUSH(A->file, slang_asm_addr_deref)) return GL_FALSE; if (src_offset != 0) { - if (!PLAB (A->file, slang_asm_addr_push, src_offset)) + if (!PLAB(A->file, slang_asm_addr_push, src_offset)) return GL_FALSE; - if (!PUSH (A->file, slang_asm_addr_add)) + if (!PUSH(A->file, slang_asm_addr_add)) return GL_FALSE; } @@ -449,12 +472,13 @@ dereference_basic (slang_assemble_ctx *A, slang_storage_type type, GLuint *size, ty = slang_asm_none; } - return PUSH (A->file, ty); + return PUSH(A->file, ty); } static GLboolean -dereference_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg, GLuint *size, - slang_swizzle *swz, GLboolean is_swizzled) +dereference_aggregate(slang_assemble_ctx * A, + const slang_storage_aggregate * agg, GLuint * size, + slang_swizzle * swz, GLboolean is_swizzled) { GLuint i; @@ -464,22 +488,27 @@ dereference_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg for (j = arr->length; j > 0; j--) { if (arr->type == slang_stor_aggregate) { - if (!dereference_aggregate (A, arr->aggregate, size, swz, is_swizzled)) + if (!dereference_aggregate + (A, arr->aggregate, size, swz, is_swizzled)) return GL_FALSE; } else { if (is_swizzled && arr->type == slang_stor_vec4) { - if (!dereference_basic (A, slang_stor_float, size, swz, is_swizzled)) + if (!dereference_basic + (A, slang_stor_float, size, swz, is_swizzled)) return GL_FALSE; - if (!dereference_basic (A, slang_stor_float, size, swz, is_swizzled)) + if (!dereference_basic + (A, slang_stor_float, size, swz, is_swizzled)) return GL_FALSE; - if (!dereference_basic (A, slang_stor_float, size, swz, is_swizzled)) + if (!dereference_basic + (A, slang_stor_float, size, swz, is_swizzled)) return GL_FALSE; - if (!dereference_basic (A, slang_stor_float, size, swz, is_swizzled)) + if (!dereference_basic + (A, slang_stor_float, size, swz, is_swizzled)) return GL_FALSE; } else { - if (!dereference_basic (A, arr->type, size, swz, is_swizzled)) + if (!dereference_basic(A, arr->type, size, swz, is_swizzled)) return GL_FALSE; } } @@ -489,235 +518,240 @@ dereference_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg return GL_TRUE; } -GLboolean _slang_dereference (slang_assemble_ctx *A, slang_operation *op) +GLboolean +_slang_dereference(slang_assemble_ctx * A, slang_operation * op) { - slang_assembly_typeinfo ti; - GLboolean result = GL_FALSE; - slang_storage_aggregate agg; - GLuint size; - - /* get type information of the given operation */ - if (!slang_assembly_typeinfo_construct (&ti)) - return GL_FALSE; - if (!_slang_typeof_operation (A, op, &ti)) - goto end1; - - /* construct aggregate from the type info */ - if (!slang_storage_aggregate_construct (&agg)) - goto end1; - if (!_slang_aggregate_variable (&agg, &ti.spec, ti.array_len, A->space.funcs, A->space.structs, - A->space.vars, A->mach, A->file, A->atoms)) - goto end; - - /* dereference the resulting aggregate */ - size = _slang_sizeof_aggregate (&agg); - result = dereference_aggregate (A, &agg, &size, &ti.swz, ti.is_swizzled); - -end: - slang_storage_aggregate_destruct (&agg); -end1: - slang_assembly_typeinfo_destruct (&ti); - return result; + slang_assembly_typeinfo ti; + GLboolean result = GL_FALSE; + slang_storage_aggregate agg; + GLuint size; + + /* get type information of the given operation */ + if (!slang_assembly_typeinfo_construct(&ti)) + return GL_FALSE; + if (!_slang_typeof_operation(A, op, &ti)) + goto end1; + + /* construct aggregate from the type info */ + if (!slang_storage_aggregate_construct(&agg)) + goto end1; + if (!_slang_aggregate_variable + (&agg, &ti.spec, ti.array_len, A->space.funcs, A->space.structs, + A->space.vars, A->mach, A->file, A->atoms)) + goto end; + + /* dereference the resulting aggregate */ + size = _slang_sizeof_aggregate(&agg); + result = dereference_aggregate(A, &agg, &size, &ti.swz, ti.is_swizzled); + + end: + slang_storage_aggregate_destruct(&agg); + end1: + slang_assembly_typeinfo_destruct(&ti); + return result; } -GLboolean _slang_assemble_function_call (slang_assemble_ctx *A, slang_function *fun, - slang_operation *params, GLuint param_count, GLboolean assignment) +GLboolean +_slang_assemble_function_call(slang_assemble_ctx * A, slang_function * fun, + slang_operation * params, GLuint param_count, + GLboolean assignment) { - GLuint i; - slang_swizzle p_swz[64]; - slang_ref_type p_ref[64]; - - /* TODO: fix this, allocate dynamically */ - if (param_count > 64) - return GL_FALSE; - - /* make room for the return value, if any */ - if (fun->header.type.specifier.type != slang_spec_void) - { - GLuint ret_size = 0; - - if (!sizeof_variable (A, &fun->header.type.specifier, slang_qual_none, 0, &ret_size)) - return GL_FALSE; - if (!PLAB (A->file, slang_asm_local_alloc, ret_size)) - return GL_FALSE; - } - - /* push the actual parameters on the stack */ - for (i = 0; i < param_count; i++) - { - if (fun->parameters->variables[i].type.qualifier == slang_qual_inout || - fun->parameters->variables[i].type.qualifier == slang_qual_out) - { - if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4)) - return GL_FALSE; - /* TODO: optimize the "out" parameter case */ - if (!_slang_assemble_operation (A, ¶ms[i], slang_ref_force)) - return GL_FALSE; - p_swz[i] = A->swz; - p_ref[i] = A->ref; - if (!PUSH (A->file, slang_asm_addr_copy)) - return GL_FALSE; - if (!PUSH (A->file, slang_asm_addr_deref)) - return GL_FALSE; - if (i == 0 && assignment) - { - /* duplicate the resulting address */ - if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4)) - return GL_FALSE; - if (!PUSH (A->file, slang_asm_addr_deref)) - return GL_FALSE; - } - if (!_slang_dereference (A, ¶ms[i])) - return GL_FALSE; - } - else - { - if (!_slang_assemble_operation (A, ¶ms[i], slang_ref_forbid)) - return GL_FALSE; - p_swz[i] = A->swz; - p_ref[i] = A->ref; - } - } - - /* call the function */ - if (!PLAB (A->file, slang_asm_call, fun->address)) - return GL_FALSE; - - /* pop the parameters from the stack */ - for (i = param_count; i > 0; i--) - { - GLuint j = i - 1; - - A->swz = p_swz[j]; - A->ref = p_ref[j]; - if (fun->parameters->variables[j].type.qualifier == slang_qual_inout || - fun->parameters->variables[j].type.qualifier == slang_qual_out) - { - /* for output parameter copy the contents of the formal parameter - * back to the original actual parameter */ - if (!_slang_assemble_assignment (A, ¶ms[j])) - return GL_FALSE; - /* pop the actual parameter's address */ - if (!PLAB (A->file, slang_asm_local_free, 4)) - return GL_FALSE; - } - else - { - /* pop the value of the parameter */ - if (!_slang_cleanup_stack (A, ¶ms[j])) - return GL_FALSE; - } - } - - return GL_TRUE; + GLuint i; + slang_swizzle p_swz[64]; + slang_ref_type p_ref[64]; + + /* TODO: fix this, allocate dynamically */ + if (param_count > 64) + return GL_FALSE; + + /* make room for the return value, if any */ + if (fun->header.type.specifier.type != slang_spec_void) { + GLuint ret_size = 0; + + if (!sizeof_variable + (A, &fun->header.type.specifier, slang_qual_none, 0, &ret_size)) + return GL_FALSE; + if (!PLAB(A->file, slang_asm_local_alloc, ret_size)) + return GL_FALSE; + } + + /* push the actual parameters on the stack */ + for (i = 0; i < param_count; i++) { + if (fun->parameters->variables[i].type.qualifier == slang_qual_inout || + fun->parameters->variables[i].type.qualifier == slang_qual_out) { + if (!PLAB2(A->file, slang_asm_local_addr, A->local.addr_tmp, 4)) + return GL_FALSE; + /* TODO: optimize the "out" parameter case */ + if (!_slang_assemble_operation(A, ¶ms[i], slang_ref_force)) + return GL_FALSE; + p_swz[i] = A->swz; + p_ref[i] = A->ref; + if (!PUSH(A->file, slang_asm_addr_copy)) + return GL_FALSE; + if (!PUSH(A->file, slang_asm_addr_deref)) + return GL_FALSE; + if (i == 0 && assignment) { + /* duplicate the resulting address */ + if (!PLAB2(A->file, slang_asm_local_addr, A->local.addr_tmp, 4)) + return GL_FALSE; + if (!PUSH(A->file, slang_asm_addr_deref)) + return GL_FALSE; + } + if (!_slang_dereference(A, ¶ms[i])) + return GL_FALSE; + } + else { + if (!_slang_assemble_operation(A, ¶ms[i], slang_ref_forbid)) + return GL_FALSE; + p_swz[i] = A->swz; + p_ref[i] = A->ref; + } + } + + /* call the function */ + if (!PLAB(A->file, slang_asm_call, fun->address)) + return GL_FALSE; + + /* pop the parameters from the stack */ + for (i = param_count; i > 0; i--) { + GLuint j = i - 1; + + A->swz = p_swz[j]; + A->ref = p_ref[j]; + if (fun->parameters->variables[j].type.qualifier == slang_qual_inout || + fun->parameters->variables[j].type.qualifier == slang_qual_out) { + /* for output parameter copy the contents of the formal parameter + * back to the original actual parameter + */ + if (!_slang_assemble_assignment(A, ¶ms[j])) + return GL_FALSE; + /* pop the actual parameter's address */ + if (!PLAB(A->file, slang_asm_local_free, 4)) + return GL_FALSE; + } + else { + /* pop the value of the parameter */ + if (!_slang_cleanup_stack(A, ¶ms[j])) + return GL_FALSE; + } + } + + return GL_TRUE; } -GLboolean _slang_assemble_function_call_name (slang_assemble_ctx *A, const char *name, - slang_operation *params, GLuint param_count, GLboolean assignment) +GLboolean +_slang_assemble_function_call_name(slang_assemble_ctx * A, const char *name, + slang_operation * params, + GLuint param_count, GLboolean assignment) { - slang_atom atom; - slang_function *fun; - - atom = slang_atom_pool_atom (A->atoms, name); - if (atom == SLANG_ATOM_NULL) - return GL_FALSE; - fun = _slang_locate_function (A->space.funcs, atom, params, param_count, &A->space, A->atoms); - if (fun == NULL) - return GL_FALSE; - return _slang_assemble_function_call (A, fun, params, param_count, assignment); + slang_atom atom; + slang_function *fun; + + atom = slang_atom_pool_atom(A->atoms, name); + if (atom == SLANG_ATOM_NULL) + return GL_FALSE; + fun = + _slang_locate_function(A->space.funcs, atom, params, param_count, + &A->space, A->atoms); + if (fun == NULL) + return GL_FALSE; + return _slang_assemble_function_call(A, fun, params, param_count, + assignment); } -static GLboolean assemble_function_call_name_dummyint (slang_assemble_ctx *A, const char *name, - slang_operation *params) +static GLboolean +assemble_function_call_name_dummyint(slang_assemble_ctx * A, const char *name, + slang_operation * params) { - slang_operation p[2]; - GLboolean result; - - p[0] = params[0]; - if (!slang_operation_construct (&p[1])) - return GL_FALSE; - p[1].type = slang_oper_literal_int; - result = _slang_assemble_function_call_name (A, name, p, 2, GL_FALSE); - slang_operation_destruct (&p[1]); - return result; + slang_operation p[2]; + GLboolean result; + + p[0] = params[0]; + if (!slang_operation_construct(&p[1])) + return GL_FALSE; + p[1].type = slang_oper_literal_int; + result = _slang_assemble_function_call_name(A, name, p, 2, GL_FALSE); + slang_operation_destruct(&p[1]); + return result; } static const struct { - const char *name; - slang_assembly_type code1, code2; + const char *name; + slang_assembly_type code1, code2; } inst[] = { - /* core */ - { "float_add", slang_asm_float_add, slang_asm_float_copy }, - { "float_multiply", slang_asm_float_multiply, slang_asm_float_copy }, - { "float_divide", slang_asm_float_divide, slang_asm_float_copy }, - { "float_negate", slang_asm_float_negate, slang_asm_float_copy }, - { "float_less", slang_asm_float_less, slang_asm_bool_copy }, - { "float_equal", slang_asm_float_equal_exp,slang_asm_bool_copy }, - { "float_to_int", slang_asm_float_to_int, slang_asm_int_copy }, - { "float_sine", slang_asm_float_sine, slang_asm_float_copy }, - { "float_arcsine", slang_asm_float_arcsine, slang_asm_float_copy }, - { "float_arctan", slang_asm_float_arctan, slang_asm_float_copy }, - { "float_power", slang_asm_float_power, slang_asm_float_copy }, - { "float_log2", slang_asm_float_log2, slang_asm_float_copy }, - { "float_floor", slang_asm_float_floor, slang_asm_float_copy }, - { "float_ceil", slang_asm_float_ceil, slang_asm_float_copy }, - { "float_noise1", slang_asm_float_noise1, slang_asm_float_copy }, - { "float_noise2", slang_asm_float_noise2, slang_asm_float_copy }, - { "float_noise3", slang_asm_float_noise3, slang_asm_float_copy }, - { "float_noise4", slang_asm_float_noise4, slang_asm_float_copy }, - { "int_to_float", slang_asm_int_to_float, slang_asm_float_copy }, - { "vec4_tex1d", slang_asm_vec4_tex1d, slang_asm_none }, - { "vec4_tex2d", slang_asm_vec4_tex2d, slang_asm_none }, - { "vec4_tex3d", slang_asm_vec4_tex3d, slang_asm_none }, - { "vec4_texcube", slang_asm_vec4_texcube, slang_asm_none }, - { "vec4_shad1d", slang_asm_vec4_shad1d, slang_asm_none }, - { "vec4_shad2d", slang_asm_vec4_shad2d, slang_asm_none }, - /* GL_MESA_shader_debug */ - { "float_print", slang_asm_float_deref, slang_asm_float_print }, - { "int_print", slang_asm_int_deref, slang_asm_int_print }, - { "bool_print", slang_asm_bool_deref, slang_asm_bool_print }, + /* core */ + {"float_add", slang_asm_float_add, slang_asm_float_copy}, + {"float_multiply", slang_asm_float_multiply, slang_asm_float_copy}, + {"float_divide", slang_asm_float_divide, slang_asm_float_copy}, + {"float_negate", slang_asm_float_negate, slang_asm_float_copy}, + {"float_less", slang_asm_float_less, slang_asm_bool_copy}, + {"float_equal", slang_asm_float_equal_exp, slang_asm_bool_copy}, + {"float_to_int", slang_asm_float_to_int, slang_asm_int_copy}, + {"float_sine", slang_asm_float_sine, slang_asm_float_copy}, + {"float_arcsine", slang_asm_float_arcsine, slang_asm_float_copy}, + {"float_arctan", slang_asm_float_arctan, slang_asm_float_copy}, + {"float_power", slang_asm_float_power, slang_asm_float_copy}, + {"float_log2", slang_asm_float_log2, slang_asm_float_copy}, + {"float_floor", slang_asm_float_floor, slang_asm_float_copy}, + {"float_ceil", slang_asm_float_ceil, slang_asm_float_copy}, + {"float_noise1", slang_asm_float_noise1, slang_asm_float_copy}, + {"float_noise2", slang_asm_float_noise2, slang_asm_float_copy}, + {"float_noise3", slang_asm_float_noise3, slang_asm_float_copy}, + {"float_noise4", slang_asm_float_noise4, slang_asm_float_copy}, + {"int_to_float", slang_asm_int_to_float, slang_asm_float_copy}, + {"vec4_tex1d", slang_asm_vec4_tex1d, slang_asm_none}, + {"vec4_tex2d", slang_asm_vec4_tex2d, slang_asm_none}, + {"vec4_tex3d", slang_asm_vec4_tex3d, slang_asm_none}, + {"vec4_texcube", slang_asm_vec4_texcube, slang_asm_none}, + {"vec4_shad1d", slang_asm_vec4_shad1d, slang_asm_none}, + {"vec4_shad2d", slang_asm_vec4_shad2d, slang_asm_none}, + /* GL_MESA_shader_debug */ + {"float_print", slang_asm_float_deref, slang_asm_float_print}, + {"int_print", slang_asm_int_deref, slang_asm_int_print}, + {"bool_print", slang_asm_bool_deref, slang_asm_bool_print}, /* vec4 */ - { "float_to_vec4", slang_asm_float_to_vec4, slang_asm_none }, - { "vec4_add", slang_asm_vec4_add, slang_asm_none }, - { "vec4_subtract", slang_asm_vec4_subtract, slang_asm_none }, - { "vec4_multiply", slang_asm_vec4_multiply, slang_asm_none }, - { "vec4_divide", slang_asm_vec4_divide, slang_asm_none }, - { "vec4_negate", slang_asm_vec4_negate, slang_asm_none }, - { "vec4_dot", slang_asm_vec4_dot, slang_asm_none }, - - { NULL, slang_asm_none, slang_asm_none } + {"float_to_vec4", slang_asm_float_to_vec4, slang_asm_none}, + {"vec4_add", slang_asm_vec4_add, slang_asm_none}, + {"vec4_subtract", slang_asm_vec4_subtract, slang_asm_none}, + {"vec4_multiply", slang_asm_vec4_multiply, slang_asm_none}, + {"vec4_divide", slang_asm_vec4_divide, slang_asm_none}, + {"vec4_negate", slang_asm_vec4_negate, slang_asm_none}, + {"vec4_dot", slang_asm_vec4_dot, slang_asm_none}, + {NULL, slang_asm_none, slang_asm_none} }; -static GLboolean call_asm_instruction (slang_assemble_ctx *A, slang_atom a_name) +static GLboolean +call_asm_instruction(slang_assemble_ctx * A, slang_atom a_name) { - const char *id; - GLuint i; + const char *id; + GLuint i; - id = slang_atom_pool_id (A->atoms, a_name); + id = slang_atom_pool_id(A->atoms, a_name); - for (i = 0; inst[i].name != NULL; i++) - if (slang_string_compare (id, inst[i].name) == 0) - break; - if (inst[i].name == NULL) - return GL_FALSE; + for (i = 0; inst[i].name != NULL; i++) + if (slang_string_compare(id, inst[i].name) == 0) + break; + if (inst[i].name == NULL) + return GL_FALSE; - if (!PLAB2 (A->file, inst[i].code1, 4, 0)) - return GL_FALSE; - if (inst[i].code2 != slang_asm_none) - if (!PLAB2 (A->file, inst[i].code2, 4, 0)) - return GL_FALSE; + if (!PLAB2(A->file, inst[i].code1, 4, 0)) + return GL_FALSE; + if (inst[i].code2 != slang_asm_none) + if (!PLAB2(A->file, inst[i].code2, 4, 0)) + return GL_FALSE; - /* clean-up the stack from the remaining dst address */ - if (!PLAB (A->file, slang_asm_local_free, 4)) - return GL_FALSE; + /* clean-up the stack from the remaining dst address */ + if (!PLAB(A->file, slang_asm_local_free, 4)) + return GL_FALSE; - return GL_TRUE; + return GL_TRUE; } static GLboolean -equality_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg, GLuint *index, - GLuint size, GLuint z_label) +equality_aggregate(slang_assemble_ctx * A, + const slang_storage_aggregate * agg, GLuint * index, + GLuint size, GLuint z_label) { GLuint i; @@ -727,22 +761,25 @@ equality_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg, G for (j = 0; j < arr->length; j++) { if (arr->type == slang_stor_aggregate) { - if (!equality_aggregate (A, arr->aggregate, index, size, z_label)) + if (!equality_aggregate(A, arr->aggregate, index, size, z_label)) return GL_FALSE; } else { #if defined(USE_X86_ASM) || defined(SLANG_X86) if (arr->type == slang_stor_vec4) { - if (!PLAB2 (A->file, slang_asm_vec4_equal_int, size + *index, *index)) + if (!PLAB2 + (A->file, slang_asm_vec4_equal_int, size + *index, *index)) return GL_FALSE; } else #endif - if (!PLAB2 (A->file, slang_asm_float_equal_int, size + *index, *index)) - return GL_FALSE; + if (!PLAB2 + (A->file, slang_asm_float_equal_int, size + *index, + *index)) + return GL_FALSE; - *index += _slang_sizeof_type (arr->type); - if (!PLAB (A->file, slang_asm_jump_if_zero, z_label)) + *index += _slang_sizeof_type(arr->type); + if (!PLAB(A->file, slang_asm_jump_if_zero, z_label)) return GL_FALSE; } } @@ -751,753 +788,755 @@ equality_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg, G return GL_TRUE; } -static GLboolean equality (slang_assemble_ctx *A, slang_operation *op, GLboolean equal) +static GLboolean +equality(slang_assemble_ctx * A, slang_operation * op, GLboolean equal) { - slang_assembly_typeinfo ti; - GLboolean result = GL_FALSE; - slang_storage_aggregate agg; - GLuint index, size; - GLuint skip_jump, true_label, true_jump, false_label, false_jump; - - /* get type of operation */ - if (!slang_assembly_typeinfo_construct (&ti)) - return GL_FALSE; - if (!_slang_typeof_operation (A, op, &ti)) - goto end1; - - /* convert it to an aggregate */ - if (!slang_storage_aggregate_construct (&agg)) - goto end1; - if (!_slang_aggregate_variable (&agg, &ti.spec, 0, A->space.funcs, A->space.structs, - A->space.vars, A->mach, A->file, A->atoms)) - goto end; - - /* compute the size of the agregate - there are two such aggregates on the stack */ - size = _slang_sizeof_aggregate (&agg); - - /* jump to the actual data-comparison code */ - skip_jump = A->file->count; - if (!PUSH (A->file, slang_asm_jump)) - goto end; - - /* pop off the stack the compared data and push 1 */ - true_label = A->file->count; - if (!PLAB (A->file, slang_asm_local_free, size * 2)) - goto end; - if (!PLIT (A->file, slang_asm_bool_push, (GLfloat) 1)) - goto end; - true_jump = A->file->count; - if (!PUSH (A->file, slang_asm_jump)) - goto end; - - false_label = A->file->count; - if (!PLAB (A->file, slang_asm_local_free, size * 2)) - goto end; - if (!PLIT (A->file, slang_asm_bool_push, (GLfloat) 0)) - goto end; - false_jump = A->file->count; - if (!PUSH (A->file, slang_asm_jump)) - goto end; - - A->file->code[skip_jump].param[0] = A->file->count; - - /* compare the data on stack, it will eventually jump either to true or false label */ - index = 0; - if (!equality_aggregate (A, &agg, &index, size, equal ? false_label : true_label)) - goto end; - if (!PLAB (A->file, slang_asm_jump, equal ? true_label : false_label)) - goto end; - - A->file->code[true_jump].param[0] = A->file->count; - A->file->code[false_jump].param[0] = A->file->count; - - result = GL_TRUE; -end: - slang_storage_aggregate_destruct (&agg); -end1: - slang_assembly_typeinfo_destruct (&ti); - return result; + slang_assembly_typeinfo ti; + GLboolean result = GL_FALSE; + slang_storage_aggregate agg; + GLuint index, size; + GLuint skip_jump, true_label, true_jump, false_label, false_jump; + + /* get type of operation */ + if (!slang_assembly_typeinfo_construct(&ti)) + return GL_FALSE; + if (!_slang_typeof_operation(A, op, &ti)) + goto end1; + + /* convert it to an aggregate */ + if (!slang_storage_aggregate_construct(&agg)) + goto end1; + if (!_slang_aggregate_variable + (&agg, &ti.spec, 0, A->space.funcs, A->space.structs, A->space.vars, + A->mach, A->file, A->atoms)) + goto end; + + /* compute the size of the agregate - there are two such aggregates on the stack */ + size = _slang_sizeof_aggregate(&agg); + + /* jump to the actual data-comparison code */ + skip_jump = A->file->count; + if (!PUSH(A->file, slang_asm_jump)) + goto end; + + /* pop off the stack the compared data and push 1 */ + true_label = A->file->count; + if (!PLAB(A->file, slang_asm_local_free, size * 2)) + goto end; + if (!PLIT(A->file, slang_asm_bool_push, (GLfloat) 1)) + goto end; + true_jump = A->file->count; + if (!PUSH(A->file, slang_asm_jump)) + goto end; + + false_label = A->file->count; + if (!PLAB(A->file, slang_asm_local_free, size * 2)) + goto end; + if (!PLIT(A->file, slang_asm_bool_push, (GLfloat) 0)) + goto end; + false_jump = A->file->count; + if (!PUSH(A->file, slang_asm_jump)) + goto end; + + A->file->code[skip_jump].param[0] = A->file->count; + + /* compare the data on stack, it will eventually jump either to true or false label */ + index = 0; + if (!equality_aggregate + (A, &agg, &index, size, equal ? false_label : true_label)) + goto end; + if (!PLAB(A->file, slang_asm_jump, equal ? true_label : false_label)) + goto end; + + A->file->code[true_jump].param[0] = A->file->count; + A->file->code[false_jump].param[0] = A->file->count; + + result = GL_TRUE; + end: + slang_storage_aggregate_destruct(&agg); + end1: + slang_assembly_typeinfo_destruct(&ti); + return result; } -static GLboolean handle_subscript (slang_assemble_ctx *A, slang_assembly_typeinfo *tie, - slang_assembly_typeinfo *tia, slang_operation *op, slang_ref_type ref) +static GLboolean +handle_subscript(slang_assemble_ctx * A, slang_assembly_typeinfo * tie, + slang_assembly_typeinfo * tia, slang_operation * op, + slang_ref_type ref) { - GLuint asize = 0, esize = 0; - - /* get type info of the master expression (matrix, vector or an array */ - if (!_slang_typeof_operation (A, &op->children[0], tia)) - return GL_FALSE; - if (!sizeof_variable (A, &tia->spec, slang_qual_none, tia->array_len, &asize)) - return GL_FALSE; - - /* get type info of the result (matrix column, vector row or array element) */ - if (!_slang_typeof_operation (A, op, tie)) - return GL_FALSE; - if (!sizeof_variable (A, &tie->spec, slang_qual_none, 0, &esize)) - return GL_FALSE; - - /* assemble the master expression */ - if (!_slang_assemble_operation (A, &op->children[0], ref)) - return GL_FALSE; - - /* when indexing an l-value swizzle, push the swizzle_tmp */ - if (ref == slang_ref_force && tia->is_swizzled) - if (!PLAB2 (A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16)) - return GL_FALSE; - - /* assemble the subscript expression */ - if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid)) - return GL_FALSE; - - if (ref == slang_ref_force && tia->is_swizzled) - { - GLuint i; - - /* copy the swizzle indexes to the swizzle_tmp */ - for (i = 0; i < tia->swz.num_components; i++) - { - if (!PLAB2 (A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16)) - return GL_FALSE; - if (!PLAB (A->file, slang_asm_addr_push, i * 4)) - return GL_FALSE; - if (!PUSH (A->file, slang_asm_addr_add)) - return GL_FALSE; - if (!PLAB (A->file, slang_asm_addr_push, tia->swz.swizzle[i])) - return GL_FALSE; - if (!PUSH (A->file, slang_asm_addr_copy)) - return GL_FALSE; - if (!PLAB (A->file, slang_asm_local_free, 4)) - return GL_FALSE; - } - - /* offset the pushed swizzle_tmp address and dereference it */ - if (!PUSH (A->file, slang_asm_int_to_addr)) - return GL_FALSE; - if (!PLAB (A->file, slang_asm_addr_push, 4)) - return GL_FALSE; - if (!PUSH (A->file, slang_asm_addr_multiply)) - return GL_FALSE; - if (!PUSH (A->file, slang_asm_addr_add)) - return GL_FALSE; - if (!PUSH (A->file, slang_asm_addr_deref)) - return GL_FALSE; - } - else - { - /* convert the integer subscript to a relative address */ - if (!PUSH (A->file, slang_asm_int_to_addr)) - return GL_FALSE; - } - - if (!PLAB (A->file, slang_asm_addr_push, esize)) - return GL_FALSE; - if (!PUSH (A->file, slang_asm_addr_multiply)) - return GL_FALSE; - - if (ref == slang_ref_force) - { - /* offset the base address with the relative address */ - if (!PUSH (A->file, slang_asm_addr_add)) - return GL_FALSE; - } - else - { - GLuint i; - - /* move the selected element to the beginning of the master expression */ - for (i = 0; i < esize; i += 4) - if (!PLAB2 (A->file, slang_asm_float_move, asize - esize + i + 4, i + 4)) - return GL_FALSE; - if (!PLAB (A->file, slang_asm_local_free, 4)) - return GL_FALSE; - - /* free the rest of the master expression */ - if (!PLAB (A->file, slang_asm_local_free, asize - esize)) - return GL_FALSE; - } - - return GL_TRUE; + GLuint asize = 0, esize = 0; + + /* get type info of the master expression (matrix, vector or an array */ + if (!_slang_typeof_operation(A, &op->children[0], tia)) + return GL_FALSE; + if (!sizeof_variable + (A, &tia->spec, slang_qual_none, tia->array_len, &asize)) + return GL_FALSE; + + /* get type info of the result (matrix column, vector row or array element) */ + if (!_slang_typeof_operation(A, op, tie)) + return GL_FALSE; + if (!sizeof_variable(A, &tie->spec, slang_qual_none, 0, &esize)) + return GL_FALSE; + + /* assemble the master expression */ + if (!_slang_assemble_operation(A, &op->children[0], ref)) + return GL_FALSE; + + /* when indexing an l-value swizzle, push the swizzle_tmp */ + if (ref == slang_ref_force && tia->is_swizzled) + if (!PLAB2(A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16)) + return GL_FALSE; + + /* assemble the subscript expression */ + if (!_slang_assemble_operation(A, &op->children[1], slang_ref_forbid)) + return GL_FALSE; + + if (ref == slang_ref_force && tia->is_swizzled) { + GLuint i; + + /* copy the swizzle indexes to the swizzle_tmp */ + for (i = 0; i < tia->swz.num_components; i++) { + if (!PLAB2(A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16)) + return GL_FALSE; + if (!PLAB(A->file, slang_asm_addr_push, i * 4)) + return GL_FALSE; + if (!PUSH(A->file, slang_asm_addr_add)) + return GL_FALSE; + if (!PLAB(A->file, slang_asm_addr_push, tia->swz.swizzle[i])) + return GL_FALSE; + if (!PUSH(A->file, slang_asm_addr_copy)) + return GL_FALSE; + if (!PLAB(A->file, slang_asm_local_free, 4)) + return GL_FALSE; + } + + /* offset the pushed swizzle_tmp address and dereference it */ + if (!PUSH(A->file, slang_asm_int_to_addr)) + return GL_FALSE; + if (!PLAB(A->file, slang_asm_addr_push, 4)) + return GL_FALSE; + if (!PUSH(A->file, slang_asm_addr_multiply)) + return GL_FALSE; + if (!PUSH(A->file, slang_asm_addr_add)) + return GL_FALSE; + if (!PUSH(A->file, slang_asm_addr_deref)) + return GL_FALSE; + } + else { + /* convert the integer subscript to a relative address */ + if (!PUSH(A->file, slang_asm_int_to_addr)) + return GL_FALSE; + } + + if (!PLAB(A->file, slang_asm_addr_push, esize)) + return GL_FALSE; + if (!PUSH(A->file, slang_asm_addr_multiply)) + return GL_FALSE; + + if (ref == slang_ref_force) { + /* offset the base address with the relative address */ + if (!PUSH(A->file, slang_asm_addr_add)) + return GL_FALSE; + } + else { + GLuint i; + + /* move the selected element to the beginning of the master expression */ + for (i = 0; i < esize; i += 4) + if (!PLAB2 + (A->file, slang_asm_float_move, asize - esize + i + 4, i + 4)) + return GL_FALSE; + if (!PLAB(A->file, slang_asm_local_free, 4)) + return GL_FALSE; + + /* free the rest of the master expression */ + if (!PLAB(A->file, slang_asm_local_free, asize - esize)) + return GL_FALSE; + } + + return GL_TRUE; } -static GLboolean handle_field (slang_assemble_ctx *A, slang_assembly_typeinfo *tia, - slang_assembly_typeinfo *tib, slang_operation *op, slang_ref_type ref) +static GLboolean +handle_field(slang_assemble_ctx * A, slang_assembly_typeinfo * tia, + slang_assembly_typeinfo * tib, slang_operation * op, + slang_ref_type ref) { - /* get type info of the result (field or swizzle) */ - if (!_slang_typeof_operation (A, op, tia)) - return GL_FALSE; - - /* get type info of the master expression being accessed (struct or vector) */ - if (!_slang_typeof_operation (A, &op->children[0], tib)) - return GL_FALSE; - - /* if swizzling a vector in-place, the swizzle temporary is needed */ - if (ref == slang_ref_forbid && tia->is_swizzled) - if (!PLAB2 (A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16)) - return GL_FALSE; - - /* assemble the master expression */ - if (!_slang_assemble_operation (A, &op->children[0], ref)) - return GL_FALSE; - - /* assemble the field expression */ - if (tia->is_swizzled) - { - if (ref == slang_ref_force) - { + /* get type info of the result (field or swizzle) */ + if (!_slang_typeof_operation(A, op, tia)) + return GL_FALSE; + + /* get type info of the master expression being accessed (struct or vector) */ + if (!_slang_typeof_operation(A, &op->children[0], tib)) + return GL_FALSE; + + /* if swizzling a vector in-place, the swizzle temporary is needed */ + if (ref == slang_ref_forbid && tia->is_swizzled) + if (!PLAB2(A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16)) + return GL_FALSE; + + /* assemble the master expression */ + if (!_slang_assemble_operation(A, &op->children[0], ref)) + return GL_FALSE; + + /* assemble the field expression */ + if (tia->is_swizzled) { + if (ref == slang_ref_force) { #if 0 - if (tia->swz.num_components == 1) - { - /* simple case - adjust the vector's address to point to the selected component */ - if (!PLAB (file, slang_asm_addr_push, tia->swz.swizzle[0] * 4)) - return 0; - if (!PUSH (file, slang_asm_addr_add)) - return 0; - } - else + if (tia->swz.num_components == 1) { + /* simple case - adjust the vector's address to point to + * the selected component + */ + if (!PLAB(file, slang_asm_addr_push, tia->swz.swizzle[0] * 4)) + return 0; + if (!PUSH(file, slang_asm_addr_add)) + return 0; + } + else #endif - { - /* two or more vector components are being referenced - the so-called write mask - * must be passed to the upper operations and applied when assigning value - * to this swizzle */ - A->swz = tia->swz; - } - } - else - { - /* swizzle the vector in-place using the swizzle temporary */ - if (!_slang_assemble_constructor_from_swizzle (A, &tia->swz, &tia->spec, &tib->spec)) - return GL_FALSE; - } - } - else - { - GLuint i, struct_size = 0, field_offset = 0, field_size = 0; + { + /* two or more vector components are being referenced - + * the so-called write mask must be passed to the upper + * operations and applied when assigning value to this swizzle + */ + A->swz = tia->swz; + } + } + else { + /* swizzle the vector in-place using the swizzle temporary */ + if (!_slang_assemble_constructor_from_swizzle + (A, &tia->swz, &tia->spec, &tib->spec)) + return GL_FALSE; + } + } + else { + GLuint i, struct_size = 0, field_offset = 0, field_size = 0; /* * Calculate struct size, field offset and field size. */ - for (i = 0; i < tib->spec._struct->fields->num_variables; i++) - { - slang_variable *field; - slang_storage_aggregate agg; - GLuint size; - - field = &tib->spec._struct->fields->variables[i]; - if (!slang_storage_aggregate_construct (&agg)) - return GL_FALSE; - if (!_slang_aggregate_variable (&agg, &field->type.specifier, field->array_len, - A->space.funcs, A->space.structs, A->space.vars, A->mach, A->file, A->atoms)) - { - slang_storage_aggregate_destruct (&agg); - return GL_FALSE; - } - size = _slang_sizeof_aggregate (&agg); - slang_storage_aggregate_destruct (&agg); + for (i = 0; i < tib->spec._struct->fields->num_variables; i++) { + slang_variable *field; + slang_storage_aggregate agg; + GLuint size; + + field = &tib->spec._struct->fields->variables[i]; + if (!slang_storage_aggregate_construct(&agg)) + return GL_FALSE; + if (!_slang_aggregate_variable + (&agg, &field->type.specifier, field->array_len, A->space.funcs, + A->space.structs, A->space.vars, A->mach, A->file, A->atoms)) { + slang_storage_aggregate_destruct(&agg); + return GL_FALSE; + } + size = _slang_sizeof_aggregate(&agg); + slang_storage_aggregate_destruct(&agg); if (op->a_id == field->a_name) { field_size = size; field_offset = struct_size; } struct_size += size; - } + } - if (ref == slang_ref_force) - { + if (ref == slang_ref_force) { GLboolean shift; /* - * OPTIMIZATION: If selecting first field, no address shifting is needed. - */ + * OPTIMIZATION: If selecting first field, no address shifting + * is needed. + */ shift = (field_offset != 0); if (shift) { - if (!PLAB (A->file, slang_asm_addr_push, field_offset)) + if (!PLAB(A->file, slang_asm_addr_push, field_offset)) + return GL_FALSE; + if (!PUSH(A->file, slang_asm_addr_add)) return GL_FALSE; - if (!PUSH (A->file, slang_asm_addr_add)) - return GL_FALSE; - } - } - else - { + } + } + else { GLboolean relocate, shrink; - GLuint free_b = 0; + GLuint free_b = 0; /* - * OPTIMIZATION: If selecting last field, no relocation is needed. - */ + * OPTIMIZATION: If selecting last field, no relocation is needed. + */ relocate = (field_offset != (struct_size - field_size)); /* - * OPTIMIZATION: If field and struct sizes are equal, no partial free is needed. - */ + * OPTIMIZATION: If field and struct sizes are equal, no partial + * free is needed. + */ shrink = (field_size != struct_size); - if (relocate) - { - GLuint i; + if (relocate) { + GLuint i; + + /* + * Move the selected element to the end of the master expression. + * Do it in reverse order to avoid overwriting itself. + */ + if (!PLAB(A->file, slang_asm_addr_push, field_offset)) + return GL_FALSE; + for (i = field_size; i > 0; i -= 4) + if (!PLAB2 + (A->file, slang_asm_float_move, + struct_size - field_size + i, i)) + return GL_FALSE; + free_b += 4; + } + + if (shrink) { + /* free the rest of the master expression */ + free_b += struct_size - field_size; + } - /* - * Move the selected element to the end of the master expression. - * Do it in reverse order to avoid overwriting itself. - */ - if (!PLAB (A->file, slang_asm_addr_push, field_offset)) + if (free_b) { + if (!PLAB(A->file, slang_asm_local_free, free_b)) return GL_FALSE; - for (i = field_size; i > 0; i -= 4) - if (!PLAB2 (A->file, slang_asm_float_move, struct_size - field_size + i, i)) - return GL_FALSE; - free_b += 4; - } - - if (shrink) - { - /* free the rest of the master expression */ - free_b += struct_size - field_size; - } - - if (free_b) - { - if (!PLAB (A->file, slang_asm_local_free, free_b)) - return GL_FALSE; - } - } - } - - return GL_TRUE; + } + } + } + + return GL_TRUE; } -GLboolean _slang_assemble_operation (slang_assemble_ctx *A, slang_operation *op, slang_ref_type ref) +GLboolean +_slang_assemble_operation(slang_assemble_ctx * A, slang_operation * op, + slang_ref_type ref) { - /* set default results */ - A->ref = /*(ref == slang_ref_freelance) ? slang_ref_force : */ref; - A->swz.num_components = 0; - - switch (op->type) - { - case slang_oper_block_no_new_scope: - case slang_oper_block_new_scope: - { - GLuint i; - - for (i = 0; i < op->num_children; i++) - { - if (!_slang_assemble_operation (A, &op->children[i], slang_ref_forbid/*slang_ref_freelance*/)) - return GL_FALSE; - if (!_slang_cleanup_stack (A, &op->children[i])) - return GL_FALSE; - } - } - break; - case slang_oper_variable_decl: - { - GLuint i; - slang_operation assign; - GLboolean result; - - /* Construct assignment expression placeholder. */ - if (!slang_operation_construct (&assign)) - return GL_FALSE; - assign.type = slang_oper_assign; - assign.children = (slang_operation *) slang_alloc_malloc (2 * sizeof (slang_operation)); - if (assign.children == NULL) - { - slang_operation_destruct (&assign); - return GL_FALSE; - } - for (assign.num_children = 0; assign.num_children < 2; assign.num_children++) - if (!slang_operation_construct (&assign.children[assign.num_children])) - { - slang_operation_destruct (&assign); - return GL_FALSE; - } - - result = GL_TRUE; - for (i = 0; i < op->num_children; i++) - { - slang_variable *var; - - var = _slang_locate_variable (op->children[i].locals, op->children[i].a_id, GL_TRUE); - if (var == NULL) - { - result = GL_FALSE; - break; - } - if (var->initializer == NULL) - continue; - - if (!slang_operation_copy (&assign.children[0], &op->children[i]) || - !slang_operation_copy (&assign.children[1], var->initializer) || - !_slang_assemble_assign (A, &assign, "=", slang_ref_forbid) || - !_slang_cleanup_stack (A, &assign)) - { - result = GL_FALSE; - break; - } - } - slang_operation_destruct (&assign); - if (!result) - return GL_FALSE; - } - break; - case slang_oper_asm: - { - GLuint i; - - if (!_slang_assemble_operation (A, &op->children[0], slang_ref_force)) - return GL_FALSE; - for (i = 1; i < op->num_children; i++) - if (!_slang_assemble_operation (A, &op->children[i], slang_ref_forbid)) - return GL_FALSE; - if (!call_asm_instruction (A, op->a_id)) - return GL_FALSE; - } - break; - case slang_oper_break: - if (!PLAB (A->file, slang_asm_jump, A->flow.loop_end)) - return GL_FALSE; - break; - case slang_oper_continue: - if (!PLAB (A->file, slang_asm_jump, A->flow.loop_start)) - return GL_FALSE; - break; - case slang_oper_discard: - if (!PUSH (A->file, slang_asm_discard)) - return GL_FALSE; - if (!PUSH (A->file, slang_asm_exit)) - return GL_FALSE; - break; - case slang_oper_return: - if (A->local.ret_size != 0) - { - /* push the result's address */ - if (!PLAB2 (A->file, slang_asm_local_addr, 0, A->local.ret_size)) - return GL_FALSE; - if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid)) - return GL_FALSE; - - A->swz.num_components = 0; - /* assign the operation to the function result (it was reserved on the stack) */ - if (!_slang_assemble_assignment (A, op->children)) - return GL_FALSE; - - if (!PLAB (A->file, slang_asm_local_free, 4)) - return GL_FALSE; - } - if (!PLAB (A->file, slang_asm_jump, A->flow.function_end)) - return GL_FALSE; - break; - case slang_oper_expression: - if (ref == slang_ref_force) - return GL_FALSE; - if (!_slang_assemble_operation (A, &op->children[0], ref)) - return GL_FALSE; - break; - case slang_oper_if: - if (!_slang_assemble_if (A, op)) - return GL_FALSE; - break; - case slang_oper_while: - if (!_slang_assemble_while (A, op)) - return GL_FALSE; - break; - case slang_oper_do: - if (!_slang_assemble_do (A, op)) - return GL_FALSE; - break; - case slang_oper_for: - if (!_slang_assemble_for (A, op)) - return GL_FALSE; - break; - case slang_oper_void: - break; - case slang_oper_literal_bool: - if (ref == slang_ref_force) - return GL_FALSE; - if (!PLIT (A->file, slang_asm_bool_push, op->literal)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_literal_int: - if (ref == slang_ref_force) - return GL_FALSE; - if (!PLIT (A->file, slang_asm_int_push, op->literal)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_literal_float: - if (ref == slang_ref_force) - return GL_FALSE; - if (!PLIT (A->file, slang_asm_float_push, op->literal)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_identifier: - { - slang_variable *var; - GLuint size; - - /* find the variable and calculate its size */ - var = _slang_locate_variable (op->locals, op->a_id, GL_TRUE); - if (var == NULL) - return GL_FALSE; - size = 0; - if (!sizeof_variable (A, &var->type.specifier, slang_qual_none, var->array_len, &size)) - return GL_FALSE; - - /* prepare stack for dereferencing */ - if (ref == slang_ref_forbid) - if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4)) - return GL_FALSE; - - /* push the variable's address */ - if (var->global) - { - if (!PLAB (A->file, slang_asm_global_addr, var->address)) - return GL_FALSE; - } - else - { - if (!PLAB2 (A->file, slang_asm_local_addr, var->address, size)) - return GL_FALSE; - } - - /* perform the dereference */ - if (ref == slang_ref_forbid) - { - if (!PUSH (A->file, slang_asm_addr_copy)) - return GL_FALSE; - if (!PLAB (A->file, slang_asm_local_free, 4)) - return GL_FALSE; - if (!_slang_dereference (A, op)) - return GL_FALSE; - } - } - break; - case slang_oper_sequence: - if (ref == slang_ref_force) - return GL_FALSE; - if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid/*slang_ref_freelance*/)) - return GL_FALSE; - if (!_slang_cleanup_stack (A, &op->children[0])) - return GL_FALSE; - if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_assign: - if (!_slang_assemble_assign (A, op, "=", ref)) - return GL_FALSE; - break; - case slang_oper_addassign: - if (!_slang_assemble_assign (A, op, "+=", ref)) - return GL_FALSE; - A->ref = ref; - break; - case slang_oper_subassign: - if (!_slang_assemble_assign (A, op, "-=", ref)) - return GL_FALSE; - A->ref = ref; - break; - case slang_oper_mulassign: - if (!_slang_assemble_assign (A, op, "*=", ref)) - return GL_FALSE; - A->ref = ref; - break; - /*case slang_oper_modassign:*/ - /*case slang_oper_lshassign:*/ - /*case slang_oper_rshassign:*/ - /*case slang_oper_orassign:*/ - /*case slang_oper_xorassign:*/ - /*case slang_oper_andassign:*/ - case slang_oper_divassign: - if (!_slang_assemble_assign (A, op, "/=", ref)) - return GL_FALSE; - A->ref = ref; - break; - case slang_oper_select: - if (!_slang_assemble_select (A, op)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_logicalor: - if (!_slang_assemble_logicalor (A, op)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_logicaland: - if (!_slang_assemble_logicaland (A, op)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_logicalxor: - if (!_slang_assemble_function_call_name (A, "^^", op->children, 2, GL_FALSE)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - /*case slang_oper_bitor:*/ - /*case slang_oper_bitxor:*/ - /*case slang_oper_bitand:*/ - case slang_oper_less: - if (!_slang_assemble_function_call_name (A, "<", op->children, 2, GL_FALSE)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_greater: - if (!_slang_assemble_function_call_name (A, ">", op->children, 2, GL_FALSE)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_lessequal: - if (!_slang_assemble_function_call_name (A, "<=", op->children, 2, GL_FALSE)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_greaterequal: - if (!_slang_assemble_function_call_name (A, ">=", op->children, 2, GL_FALSE)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - /*case slang_oper_lshift:*/ - /*case slang_oper_rshift:*/ - case slang_oper_add: - if (!_slang_assemble_function_call_name (A, "+", op->children, 2, GL_FALSE)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_subtract: - if (!_slang_assemble_function_call_name (A, "-", op->children, 2, GL_FALSE)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_multiply: - if (!_slang_assemble_function_call_name (A, "*", op->children, 2, GL_FALSE)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - /*case slang_oper_modulus:*/ - case slang_oper_divide: - if (!_slang_assemble_function_call_name (A, "/", op->children, 2, GL_FALSE)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_equal: - if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid)) - return GL_FALSE; - if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid)) - return GL_FALSE; - if (!equality (A, op->children, GL_TRUE)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_notequal: - if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid)) - return GL_FALSE; - if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid)) - return GL_FALSE; - if (!equality (A, op->children, GL_FALSE)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_preincrement: - if (!_slang_assemble_assign (A, op, "++", ref)) - return GL_FALSE; - A->ref = ref; - break; - case slang_oper_predecrement: - if (!_slang_assemble_assign (A, op, "--", ref)) - return GL_FALSE; - A->ref = ref; - break; - case slang_oper_plus: - if (!_slang_dereference (A, op)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_minus: - if (!_slang_assemble_function_call_name (A, "-", op->children, 1, GL_FALSE)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - /*case slang_oper_complement:*/ - case slang_oper_not: - if (!_slang_assemble_function_call_name (A, "!", op->children, 1, GL_FALSE)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_subscript: - { - slang_assembly_typeinfo ti_arr, ti_elem; - - if (!slang_assembly_typeinfo_construct (&ti_arr)) - return GL_FALSE; - if (!slang_assembly_typeinfo_construct (&ti_elem)) - { - slang_assembly_typeinfo_destruct (&ti_arr); - return GL_FALSE; - } - if (!handle_subscript (A, &ti_elem, &ti_arr, op, ref)) - { - slang_assembly_typeinfo_destruct (&ti_arr); - slang_assembly_typeinfo_destruct (&ti_elem); - return GL_FALSE; - } - slang_assembly_typeinfo_destruct (&ti_arr); - slang_assembly_typeinfo_destruct (&ti_elem); - } - break; - case slang_oper_call: - { - slang_function *fun; - - fun = _slang_locate_function (A->space.funcs, op->a_id, op->children, op->num_children, - &A->space, A->atoms); - if (fun == NULL) - { - if (!_slang_assemble_constructor (A, op)) - return GL_FALSE; - } - else - { - if (!_slang_assemble_function_call (A, fun, op->children, op->num_children, GL_FALSE)) - return GL_FALSE; - } - A->ref = slang_ref_forbid; - } - break; - case slang_oper_field: - { - slang_assembly_typeinfo ti_after, ti_before; - - if (!slang_assembly_typeinfo_construct (&ti_after)) - return GL_FALSE; - if (!slang_assembly_typeinfo_construct (&ti_before)) - { - slang_assembly_typeinfo_destruct (&ti_after); - return GL_FALSE; - } - if (!handle_field (A, &ti_after, &ti_before, op, ref)) - { - slang_assembly_typeinfo_destruct (&ti_after); - slang_assembly_typeinfo_destruct (&ti_before); - return GL_FALSE; - } - slang_assembly_typeinfo_destruct (&ti_after); - slang_assembly_typeinfo_destruct (&ti_before); - } - break; - case slang_oper_postincrement: - if (!assemble_function_call_name_dummyint (A, "++", op->children)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_postdecrement: - if (!assemble_function_call_name_dummyint (A, "--", op->children)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - default: - return GL_FALSE; - } - - return GL_TRUE; -} + /* set default results */ + A->ref = /*(ref == slang_ref_freelance) ? slang_ref_force : */ ref; + A->swz.num_components = 0; + + switch (op->type) { + case slang_oper_block_no_new_scope: + case slang_oper_block_new_scope: + { + GLuint i; + + for (i = 0; i < op->num_children; i++) { + if (!_slang_assemble_operation + (A, &op->children[i], + slang_ref_forbid /*slang_ref_freelance */ )) + return GL_FALSE; + if (!_slang_cleanup_stack(A, &op->children[i])) + return GL_FALSE; + } + } + break; + case slang_oper_variable_decl: + { + GLuint i; + slang_operation assign; + GLboolean result; + + /* Construct assignment expression placeholder. */ + if (!slang_operation_construct(&assign)) + return GL_FALSE; + assign.type = slang_oper_assign; + assign.children = + (slang_operation *) slang_alloc_malloc(2 * + sizeof(slang_operation)); + if (assign.children == NULL) { + slang_operation_destruct(&assign); + return GL_FALSE; + } + for (assign.num_children = 0; assign.num_children < 2; + assign.num_children++) + if (!slang_operation_construct + (&assign.children[assign.num_children])) { + slang_operation_destruct(&assign); + return GL_FALSE; + } + + result = GL_TRUE; + for (i = 0; i < op->num_children; i++) { + slang_variable *var; + + var = + _slang_locate_variable(op->children[i].locals, + op->children[i].a_id, GL_TRUE); + if (var == NULL) { + result = GL_FALSE; + break; + } + if (var->initializer == NULL) + continue; + + if (!slang_operation_copy(&assign.children[0], &op->children[i]) + || !slang_operation_copy(&assign.children[1], + var->initializer) + || !_slang_assemble_assign(A, &assign, "=", slang_ref_forbid) + || !_slang_cleanup_stack(A, &assign)) { + result = GL_FALSE; + break; + } + } + slang_operation_destruct(&assign); + if (!result) + return GL_FALSE; + } + break; + case slang_oper_asm: + { + GLuint i; + if (!_slang_assemble_operation(A, &op->children[0], slang_ref_force)) + return GL_FALSE; + for (i = 1; i < op->num_children; i++) + if (!_slang_assemble_operation + (A, &op->children[i], slang_ref_forbid)) + return GL_FALSE; + if (!call_asm_instruction(A, op->a_id)) + return GL_FALSE; + } + break; + case slang_oper_break: + if (!PLAB(A->file, slang_asm_jump, A->flow.loop_end)) + return GL_FALSE; + break; + case slang_oper_continue: + if (!PLAB(A->file, slang_asm_jump, A->flow.loop_start)) + return GL_FALSE; + break; + case slang_oper_discard: + if (!PUSH(A->file, slang_asm_discard)) + return GL_FALSE; + if (!PUSH(A->file, slang_asm_exit)) + return GL_FALSE; + break; + case slang_oper_return: + if (A->local.ret_size != 0) { + /* push the result's address */ + if (!PLAB2(A->file, slang_asm_local_addr, 0, A->local.ret_size)) + return GL_FALSE; + if (!_slang_assemble_operation + (A, &op->children[0], slang_ref_forbid)) + return GL_FALSE; + + A->swz.num_components = 0; + /* assign the operation to the function result (it was reserved on the stack) */ + if (!_slang_assemble_assignment(A, op->children)) + return GL_FALSE; + + if (!PLAB(A->file, slang_asm_local_free, 4)) + return GL_FALSE; + } + if (!PLAB(A->file, slang_asm_jump, A->flow.function_end)) + return GL_FALSE; + break; + case slang_oper_expression: + if (ref == slang_ref_force) + return GL_FALSE; + if (!_slang_assemble_operation(A, &op->children[0], ref)) + return GL_FALSE; + break; + case slang_oper_if: + if (!_slang_assemble_if(A, op)) + return GL_FALSE; + break; + case slang_oper_while: + if (!_slang_assemble_while(A, op)) + return GL_FALSE; + break; + case slang_oper_do: + if (!_slang_assemble_do(A, op)) + return GL_FALSE; + break; + case slang_oper_for: + if (!_slang_assemble_for(A, op)) + return GL_FALSE; + break; + case slang_oper_void: + break; + case slang_oper_literal_bool: + if (ref == slang_ref_force) + return GL_FALSE; + if (!PLIT(A->file, slang_asm_bool_push, op->literal)) + return GL_FALSE; + A->ref = slang_ref_forbid; + break; + case slang_oper_literal_int: + if (ref == slang_ref_force) + return GL_FALSE; + if (!PLIT(A->file, slang_asm_int_push, op->literal)) + return GL_FALSE; + A->ref = slang_ref_forbid; + break; + case slang_oper_literal_float: + if (ref == slang_ref_force) + return GL_FALSE; + if (!PLIT(A->file, slang_asm_float_push, op->literal)) + return GL_FALSE; + A->ref = slang_ref_forbid; + break; + case slang_oper_identifier: + { + slang_variable *var; + GLuint size; + + /* find the variable and calculate its size */ + var = _slang_locate_variable(op->locals, op->a_id, GL_TRUE); + if (var == NULL) + return GL_FALSE; + size = 0; + if (!sizeof_variable + (A, &var->type.specifier, slang_qual_none, var->array_len, + &size)) + return GL_FALSE; + + /* prepare stack for dereferencing */ + if (ref == slang_ref_forbid) + if (!PLAB2(A->file, slang_asm_local_addr, A->local.addr_tmp, 4)) + return GL_FALSE; + + /* push the variable's address */ + if (var->global) { + if (!PLAB(A->file, slang_asm_global_addr, var->address)) + return GL_FALSE; + } + else { + if (!PLAB2(A->file, slang_asm_local_addr, var->address, size)) + return GL_FALSE; + } + + /* perform the dereference */ + if (ref == slang_ref_forbid) { + if (!PUSH(A->file, slang_asm_addr_copy)) + return GL_FALSE; + if (!PLAB(A->file, slang_asm_local_free, 4)) + return GL_FALSE; + if (!_slang_dereference(A, op)) + return GL_FALSE; + } + } + break; + case slang_oper_sequence: + if (ref == slang_ref_force) + return GL_FALSE; + if (!_slang_assemble_operation(A, &op->children[0], + slang_ref_forbid /*slang_ref_freelance */ )) + return GL_FALSE; + if (!_slang_cleanup_stack(A, &op->children[0])) + return GL_FALSE; + if (!_slang_assemble_operation(A, &op->children[1], slang_ref_forbid)) + return GL_FALSE; + A->ref = slang_ref_forbid; + break; + case slang_oper_assign: + if (!_slang_assemble_assign(A, op, "=", ref)) + return GL_FALSE; + break; + case slang_oper_addassign: + if (!_slang_assemble_assign(A, op, "+=", ref)) + return GL_FALSE; + A->ref = ref; + break; + case slang_oper_subassign: + if (!_slang_assemble_assign(A, op, "-=", ref)) + return GL_FALSE; + A->ref = ref; + break; + case slang_oper_mulassign: + if (!_slang_assemble_assign(A, op, "*=", ref)) + return GL_FALSE; + A->ref = ref; + break; + /*case slang_oper_modassign: */ + /*case slang_oper_lshassign: */ + /*case slang_oper_rshassign: */ + /*case slang_oper_orassign: */ + /*case slang_oper_xorassign: */ + /*case slang_oper_andassign: */ + case slang_oper_divassign: + if (!_slang_assemble_assign(A, op, "/=", ref)) + return GL_FALSE; + A->ref = ref; + break; + case slang_oper_select: + if (!_slang_assemble_select(A, op)) + return GL_FALSE; + A->ref = slang_ref_forbid; + break; + case slang_oper_logicalor: + if (!_slang_assemble_logicalor(A, op)) + return GL_FALSE; + A->ref = slang_ref_forbid; + break; + case slang_oper_logicaland: + if (!_slang_assemble_logicaland(A, op)) + return GL_FALSE; + A->ref = slang_ref_forbid; + break; + case slang_oper_logicalxor: + if (!_slang_assemble_function_call_name(A, "^^", op->children, 2, GL_FALSE)) + return GL_FALSE; + A->ref = slang_ref_forbid; + break; + /*case slang_oper_bitor: */ + /*case slang_oper_bitxor: */ + /*case slang_oper_bitand: */ + case slang_oper_less: + if (!_slang_assemble_function_call_name(A, "<", op->children, 2, GL_FALSE)) + return GL_FALSE; + A->ref = slang_ref_forbid; + break; + case slang_oper_greater: + if (!_slang_assemble_function_call_name(A, ">", op->children, 2, GL_FALSE)) + return GL_FALSE; + A->ref = slang_ref_forbid; + break; + case slang_oper_lessequal: + if (!_slang_assemble_function_call_name(A, "<=", op->children, 2, GL_FALSE)) + return GL_FALSE; + A->ref = slang_ref_forbid; + break; + case slang_oper_greaterequal: + if (!_slang_assemble_function_call_name(A, ">=", op->children, 2, GL_FALSE)) + return GL_FALSE; + A->ref = slang_ref_forbid; + break; + /*case slang_oper_lshift: */ + /*case slang_oper_rshift: */ + case slang_oper_add: + if (!_slang_assemble_function_call_name(A, "+", op->children, 2, GL_FALSE)) + return GL_FALSE; + A->ref = slang_ref_forbid; + break; + case slang_oper_subtract: + if (!_slang_assemble_function_call_name(A, "-", op->children, 2, GL_FALSE)) + return GL_FALSE; + A->ref = slang_ref_forbid; + break; + case slang_oper_multiply: + if (!_slang_assemble_function_call_name(A, "*", op->children, 2, GL_FALSE)) + return GL_FALSE; + A->ref = slang_ref_forbid; + break; + /*case slang_oper_modulus: */ + case slang_oper_divide: + if (!_slang_assemble_function_call_name(A, "/", op->children, 2, GL_FALSE)) + return GL_FALSE; + A->ref = slang_ref_forbid; + break; + case slang_oper_equal: + if (!_slang_assemble_operation(A, &op->children[0], slang_ref_forbid)) + return GL_FALSE; + if (!_slang_assemble_operation(A, &op->children[1], slang_ref_forbid)) + return GL_FALSE; + if (!equality(A, op->children, GL_TRUE)) + return GL_FALSE; + A->ref = slang_ref_forbid; + break; + case slang_oper_notequal: + if (!_slang_assemble_operation(A, &op->children[0], slang_ref_forbid)) + return GL_FALSE; + if (!_slang_assemble_operation(A, &op->children[1], slang_ref_forbid)) + return GL_FALSE; + if (!equality(A, op->children, GL_FALSE)) + return GL_FALSE; + A->ref = slang_ref_forbid; + break; + case slang_oper_preincrement: + if (!_slang_assemble_assign(A, op, "++", ref)) + return GL_FALSE; + A->ref = ref; + break; + case slang_oper_predecrement: + if (!_slang_assemble_assign(A, op, "--", ref)) + return GL_FALSE; + A->ref = ref; + break; + case slang_oper_plus: + if (!_slang_dereference(A, op)) + return GL_FALSE; + A->ref = slang_ref_forbid; + break; + case slang_oper_minus: + if (!_slang_assemble_function_call_name + (A, "-", op->children, 1, GL_FALSE)) + return GL_FALSE; + A->ref = slang_ref_forbid; + break; + /*case slang_oper_complement: */ + case slang_oper_not: + if (!_slang_assemble_function_call_name + (A, "!", op->children, 1, GL_FALSE)) + return GL_FALSE; + A->ref = slang_ref_forbid; + break; + case slang_oper_subscript: + { + slang_assembly_typeinfo ti_arr, ti_elem; + + if (!slang_assembly_typeinfo_construct(&ti_arr)) + return GL_FALSE; + if (!slang_assembly_typeinfo_construct(&ti_elem)) { + slang_assembly_typeinfo_destruct(&ti_arr); + return GL_FALSE; + } + if (!handle_subscript(A, &ti_elem, &ti_arr, op, ref)) { + slang_assembly_typeinfo_destruct(&ti_arr); + slang_assembly_typeinfo_destruct(&ti_elem); + return GL_FALSE; + } + slang_assembly_typeinfo_destruct(&ti_arr); + slang_assembly_typeinfo_destruct(&ti_elem); + } + break; + case slang_oper_call: + { + slang_function *fun; + + fun = + _slang_locate_function(A->space.funcs, op->a_id, op->children, + op->num_children, &A->space, A->atoms); + if (fun == NULL) { + if (!_slang_assemble_constructor(A, op)) + return GL_FALSE; + } + else { + if (!_slang_assemble_function_call + (A, fun, op->children, op->num_children, GL_FALSE)) + return GL_FALSE; + } + A->ref = slang_ref_forbid; + } + break; + case slang_oper_field: + { + slang_assembly_typeinfo ti_after, ti_before; + + if (!slang_assembly_typeinfo_construct(&ti_after)) + return GL_FALSE; + if (!slang_assembly_typeinfo_construct(&ti_before)) { + slang_assembly_typeinfo_destruct(&ti_after); + return GL_FALSE; + } + if (!handle_field(A, &ti_after, &ti_before, op, ref)) { + slang_assembly_typeinfo_destruct(&ti_after); + slang_assembly_typeinfo_destruct(&ti_before); + return GL_FALSE; + } + slang_assembly_typeinfo_destruct(&ti_after); + slang_assembly_typeinfo_destruct(&ti_before); + } + break; + case slang_oper_postincrement: + if (!assemble_function_call_name_dummyint(A, "++", op->children)) + return GL_FALSE; + A->ref = slang_ref_forbid; + break; + case slang_oper_postdecrement: + if (!assemble_function_call_name_dummyint(A, "--", op->children)) + return GL_FALSE; + A->ref = slang_ref_forbid; + break; + default: + return GL_FALSE; + } + return GL_TRUE; +} diff --git a/src/mesa/shader/slang/slang_assemble.h b/src/mesa/shader/slang/slang_assemble.h index 95e4fa263a3..d004e665003 100644 --- a/src/mesa/shader/slang/slang_assemble.h +++ b/src/mesa/shader/slang/slang_assemble.h @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.2 * * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. * @@ -22,7 +22,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if !defined SLANG_ASSEMBLE_H +#ifndef SLANG_ASSEMBLE_H #define SLANG_ASSEMBLE_H #include "slang_utility.h" @@ -31,72 +31,82 @@ extern "C" { #endif + struct slang_operation_; typedef enum slang_assembly_type_ { - /* core */ - slang_asm_none, - slang_asm_float_copy, - slang_asm_float_move, - slang_asm_float_push, - slang_asm_float_deref, - slang_asm_float_add, - slang_asm_float_multiply, - slang_asm_float_divide, - slang_asm_float_negate, - slang_asm_float_less, - slang_asm_float_equal_exp, - slang_asm_float_equal_int, - slang_asm_float_to_int, - slang_asm_float_sine, - slang_asm_float_arcsine, - slang_asm_float_arctan, - slang_asm_float_power, - slang_asm_float_log2, - slang_asm_float_floor, - slang_asm_float_ceil, - slang_asm_float_noise1, - slang_asm_float_noise2, - slang_asm_float_noise3, - slang_asm_float_noise4, - slang_asm_int_copy, - slang_asm_int_move, - slang_asm_int_push, - slang_asm_int_deref, - slang_asm_int_to_float, - slang_asm_int_to_addr, - slang_asm_bool_copy, - slang_asm_bool_move, - slang_asm_bool_push, - slang_asm_bool_deref, - slang_asm_addr_copy, - slang_asm_addr_push, - slang_asm_addr_deref, - slang_asm_addr_add, - slang_asm_addr_multiply, - slang_asm_vec4_tex1d, - slang_asm_vec4_tex2d, - slang_asm_vec4_tex3d, - slang_asm_vec4_texcube, - slang_asm_vec4_shad1d, - slang_asm_vec4_shad2d, - slang_asm_jump, - slang_asm_jump_if_zero, - slang_asm_enter, - slang_asm_leave, - slang_asm_local_alloc, - slang_asm_local_free, - slang_asm_local_addr, - slang_asm_global_addr, - slang_asm_call, - slang_asm_return, - slang_asm_discard, - slang_asm_exit, + /* core */ + slang_asm_none, + slang_asm_float_copy, + slang_asm_float_move, + slang_asm_float_push, + slang_asm_float_deref, + slang_asm_float_add, /* a = pop(); b = pop(); push(a + b); */ + slang_asm_float_multiply, + slang_asm_float_divide, + slang_asm_float_negate, /* push(-pop()) */ + slang_asm_float_less, /* a = pop(); b = pop(); push(a < b); */ + slang_asm_float_equal_exp, + slang_asm_float_equal_int, + slang_asm_float_to_int, /* push(floatToInt(pop())) */ + slang_asm_float_sine, /* push(sin(pop()) */ + slang_asm_float_arcsine, + slang_asm_float_arctan, + slang_asm_float_power, /* push(pow(pop(), pop())) */ + slang_asm_float_log2, + slang_asm_float_floor, + slang_asm_float_ceil, + slang_asm_float_noise1, /* push(noise1(pop()) */ + slang_asm_float_noise2, /* push(noise2(pop(), pop())) */ + slang_asm_float_noise3, + slang_asm_float_noise4, + + slang_asm_int_copy, + slang_asm_int_move, + slang_asm_int_push, + slang_asm_int_deref, + slang_asm_int_to_float, + slang_asm_int_to_addr, + + slang_asm_bool_copy, + slang_asm_bool_move, + slang_asm_bool_push, + slang_asm_bool_deref, + + slang_asm_addr_copy, + slang_asm_addr_push, + slang_asm_addr_deref, + slang_asm_addr_add, + slang_asm_addr_multiply, + + slang_asm_vec4_tex1d, + slang_asm_vec4_tex2d, + slang_asm_vec4_tex3d, + slang_asm_vec4_texcube, + slang_asm_vec4_shad1d, + slang_asm_vec4_shad2d, + + slang_asm_jump, + slang_asm_jump_if_zero, + + slang_asm_enter, + slang_asm_leave, + + slang_asm_local_alloc, + slang_asm_local_free, + slang_asm_local_addr, + slang_asm_global_addr, + + slang_asm_call, /* push(ip); jump(inst->param[0]); */ + slang_asm_return, + + slang_asm_discard, + slang_asm_exit, /* GL_MESA_shader_debug */ - slang_asm_float_print, - slang_asm_int_print, - slang_asm_bool_print, + slang_asm_float_print, + slang_asm_int_print, + slang_asm_bool_print, /* vec4 */ slang_asm_float_to_vec4, slang_asm_vec4_add, @@ -109,111 +119,152 @@ typedef enum slang_assembly_type_ slang_asm_vec4_deref, slang_asm_vec4_equal_int, /* not a real assembly instruction */ - slang_asm__last + slang_asm__last } slang_assembly_type; + +/** + * An assembly-level shader instruction. + */ typedef struct slang_assembly_ { - slang_assembly_type type; - GLfloat literal; - GLuint param[2]; + slang_assembly_type type; /**< The instruction opcode */ + GLfloat literal; /**< float literal */ + GLuint param[2]; /**< Two integer/address parameters */ } slang_assembly; + +/** + * A list of slang_assembly instructions + */ typedef struct slang_assembly_file_ { - slang_assembly *code; - GLuint count; - GLuint capacity; + slang_assembly *code; + GLuint count; + GLuint capacity; } slang_assembly_file; + +extern GLvoid +_slang_assembly_file_ctr(slang_assembly_file *); + extern GLvoid -_slang_assembly_file_ctr (slang_assembly_file *); +slang_assembly_file_destruct(slang_assembly_file *); + +extern GLboolean +slang_assembly_file_push(slang_assembly_file *, slang_assembly_type); + +extern GLboolean +slang_assembly_file_push_label(slang_assembly_file *, + slang_assembly_type, GLuint); + +extern GLboolean +slang_assembly_file_push_label2(slang_assembly_file *, slang_assembly_type, + GLuint, GLuint); + +extern GLboolean +slang_assembly_file_push_literal(slang_assembly_file *, + slang_assembly_type, GLfloat); -GLvoid slang_assembly_file_destruct (slang_assembly_file *); -GLboolean slang_assembly_file_push (slang_assembly_file *, slang_assembly_type); -GLboolean slang_assembly_file_push_label (slang_assembly_file *, slang_assembly_type, GLuint); -GLboolean slang_assembly_file_push_label2 (slang_assembly_file *, slang_assembly_type, GLuint, GLuint); -GLboolean slang_assembly_file_push_literal (slang_assembly_file *, slang_assembly_type, GLfloat); typedef struct slang_assembly_file_restore_point_ { - GLuint count; + GLuint count; } slang_assembly_file_restore_point; -GLboolean slang_assembly_file_restore_point_save (slang_assembly_file *, - slang_assembly_file_restore_point *); -GLboolean slang_assembly_file_restore_point_load (slang_assembly_file *, - slang_assembly_file_restore_point *); + +extern GLboolean +slang_assembly_file_restore_point_save(slang_assembly_file *, + slang_assembly_file_restore_point *); + +extern GLboolean +slang_assembly_file_restore_point_load(slang_assembly_file *, + slang_assembly_file_restore_point *); + typedef struct slang_assembly_flow_control_ { - GLuint loop_start; /* for "continue" statement */ - GLuint loop_end; /* for "break" statement */ - GLuint function_end; /* for "return" statement */ + GLuint loop_start; /**< for "continue" statement */ + GLuint loop_end; /**< for "break" statement */ + GLuint function_end; /**< for "return" statement */ } slang_assembly_flow_control; typedef struct slang_assembly_local_info_ { - GLuint ret_size; - GLuint addr_tmp; - GLuint swizzle_tmp; + GLuint ret_size; + GLuint addr_tmp; + GLuint swizzle_tmp; } slang_assembly_local_info; typedef enum { - slang_ref_force, - slang_ref_forbid/*, - slang_ref_freelance*/ + slang_ref_force, + slang_ref_forbid /**< slang_ref_freelance */ } slang_ref_type; -/* - * Holds a complete information about vector swizzle - the <swizzle> array contains - * vector component source indices, where 0 is "x", 1 is "y", 2 is "z" and 3 is "w". +/** + * Holds complete information about vector swizzle - the <swizzle> + * array contains vector component source indices, where 0 is "x", 1 + * is "y", 2 is "z" and 3 is "w". * Example: "xwz" --> { 3, { 0, 3, 2, not used } }. */ typedef struct slang_swizzle_ { - GLuint num_components; - GLuint swizzle[4]; + GLuint num_components; + GLuint swizzle[4]; } slang_swizzle; typedef struct slang_assembly_name_space_ { - struct slang_function_scope_ *funcs; - struct slang_struct_scope_ *structs; - struct slang_variable_scope_ *vars; + struct slang_function_scope_ *funcs; + struct slang_struct_scope_ *structs; + struct slang_variable_scope_ *vars; } slang_assembly_name_space; typedef struct slang_assemble_ctx_ { - slang_assembly_file *file; - struct slang_machine_ *mach; - slang_atom_pool *atoms; - slang_assembly_name_space space; - slang_assembly_flow_control flow; - slang_assembly_local_info local; - slang_ref_type ref; - slang_swizzle swz; + slang_assembly_file *file; + struct slang_machine_ *mach; + slang_atom_pool *atoms; + slang_assembly_name_space space; + slang_assembly_flow_control flow; + slang_assembly_local_info local; + slang_ref_type ref; + slang_swizzle swz; } slang_assemble_ctx; -struct slang_function_ *_slang_locate_function (struct slang_function_scope_ *funcs, slang_atom name, - struct slang_operation_ *params, GLuint num_params, slang_assembly_name_space *space, - slang_atom_pool *); +extern struct slang_function_ * +_slang_locate_function(const struct slang_function_scope_ *funcs, + slang_atom name, const struct slang_operation_ *params, + GLuint num_params, + const slang_assembly_name_space *space, + slang_atom_pool *); -GLboolean _slang_assemble_function (slang_assemble_ctx *, struct slang_function_ *); +extern GLboolean +_slang_assemble_function(slang_assemble_ctx *, struct slang_function_ *); -GLboolean _slang_cleanup_stack (slang_assemble_ctx *, struct slang_operation_ *); +extern GLboolean +_slang_assemble_function2(slang_assemble_ctx * , struct slang_function_ *); -GLboolean _slang_dereference (slang_assemble_ctx *, struct slang_operation_ *); +extern GLboolean +_slang_cleanup_stack(slang_assemble_ctx *, struct slang_operation_ *); -GLboolean _slang_assemble_function_call (slang_assemble_ctx *, struct slang_function_ *, - struct slang_operation_ *, GLuint, GLboolean); +extern GLboolean +_slang_dereference(slang_assemble_ctx *, struct slang_operation_ *); -GLboolean _slang_assemble_function_call_name (slang_assemble_ctx *, const char *, - struct slang_operation_ *, GLuint, GLboolean); +extern GLboolean +_slang_assemble_function_call(slang_assemble_ctx *, struct slang_function_ *, + struct slang_operation_ *, GLuint, GLboolean); + +extern GLboolean +_slang_assemble_function_call_name(slang_assemble_ctx *, const char *, + struct slang_operation_ *, GLuint, + GLboolean); + +extern GLboolean +_slang_assemble_operation(slang_assemble_ctx *, struct slang_operation_ *, + slang_ref_type); -GLboolean _slang_assemble_operation (slang_assemble_ctx *, struct slang_operation_ *, - slang_ref_type); #ifdef __cplusplus } @@ -225,4 +276,3 @@ GLboolean _slang_assemble_operation (slang_assemble_ctx *, struct slang_operatio #include "slang_assemble_conditional.h" #endif - diff --git a/src/mesa/shader/slang/slang_assemble_assignment.c b/src/mesa/shader/slang/slang_assemble_assignment.c index d894a8db18c..a1038671c41 100644 --- a/src/mesa/shader/slang/slang_assemble_assignment.c +++ b/src/mesa/shader/slang/slang_assemble_assignment.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.2 * * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. * @@ -53,8 +53,11 @@ * +------------------+ */ + + static GLboolean -assign_basic (slang_assemble_ctx *A, slang_storage_type type, GLuint *index, GLuint size) +assign_basic(slang_assemble_ctx * A, slang_storage_type type, GLuint * index, + GLuint size) { GLuint dst_offset, dst_addr_loc; slang_assembly_type ty; @@ -85,22 +88,25 @@ assign_basic (slang_assemble_ctx *A, slang_storage_type type, GLuint *index, GLu ty = slang_asm_none; } - /* Calculate the distance from top of the stack to the destination address. As the - * copy operation progresses, components of the source are being successively popped - * off the stack by the amount of *index increase step. - */ + /* Calculate the distance from top of the stack to the destination + * address. As the copy operation progresses, components of the + * source are being successively popped off the stack by the amount + * of *index increase step. + */ dst_addr_loc = size - *index; - if (!slang_assembly_file_push_label2 (A->file, ty, dst_addr_loc, dst_offset)) + if (!slang_assembly_file_push_label2 + (A->file, ty, dst_addr_loc, dst_offset)) return GL_FALSE; - *index += _slang_sizeof_type (type); + *index += _slang_sizeof_type(type); return GL_TRUE; } + static GLboolean -assign_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg, GLuint *index, - GLuint size) +assign_aggregate(slang_assemble_ctx * A, const slang_storage_aggregate * agg, + GLuint * index, GLuint size) { GLuint i; @@ -110,25 +116,26 @@ assign_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg, GLu for (j = 0; j < arr->length; j++) { if (arr->type == slang_stor_aggregate) { - if (!assign_aggregate (A, arr->aggregate, index, size)) + if (!assign_aggregate(A, arr->aggregate, index, size)) return GL_FALSE; } else { - /* When the destination is swizzled, we are forced to do float_copy, even if - * vec4 extension is enabled with vec4_copy operation. + /* When the destination is swizzled, we are forced to do + * float_copy, even if vec4 extension is enabled with + * vec4_copy operation. */ if (A->swz.num_components != 0 && arr->type == slang_stor_vec4) { - if (!assign_basic (A, slang_stor_float, index, size)) + if (!assign_basic(A, slang_stor_float, index, size)) return GL_FALSE; - if (!assign_basic (A, slang_stor_float, index, size)) + if (!assign_basic(A, slang_stor_float, index, size)) return GL_FALSE; - if (!assign_basic (A, slang_stor_float, index, size)) + if (!assign_basic(A, slang_stor_float, index, size)) return GL_FALSE; - if (!assign_basic (A, slang_stor_float, index, size)) + if (!assign_basic(A, slang_stor_float, index, size)) return GL_FALSE; } else { - if (!assign_basic (A, arr->type, index, size)) + if (!assign_basic(A, arr->type, index, size)) return GL_FALSE; } } @@ -138,80 +145,79 @@ assign_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *agg, GLu return GL_TRUE; } -GLboolean _slang_assemble_assignment (slang_assemble_ctx *A, slang_operation *op) + +GLboolean +_slang_assemble_assignment(slang_assemble_ctx * A, const slang_operation * op) { - slang_assembly_typeinfo ti; - GLboolean result = GL_FALSE; - slang_storage_aggregate agg; - GLuint index, size; - - if (!slang_assembly_typeinfo_construct (&ti)) - return GL_FALSE; - if (!_slang_typeof_operation (A, op, &ti)) - goto end1; - - if (!slang_storage_aggregate_construct (&agg)) - goto end1; - if (!_slang_aggregate_variable (&agg, &ti.spec, 0, A->space.funcs, A->space.structs, - A->space.vars, A->mach, A->file, A->atoms)) - goto end; - - index = 0; - size = _slang_sizeof_aggregate (&agg); - result = assign_aggregate (A, &agg, &index, size); - -end1: - slang_storage_aggregate_destruct (&agg); -end: - slang_assembly_typeinfo_destruct (&ti); - return result; + slang_assembly_typeinfo ti; + GLboolean result = GL_FALSE; + slang_storage_aggregate agg; + GLuint index, size; + + if (!slang_assembly_typeinfo_construct(&ti)) + return GL_FALSE; + if (!_slang_typeof_operation(A, op, &ti)) + goto end1; + + if (!slang_storage_aggregate_construct(&agg)) + goto end1; + if (!_slang_aggregate_variable(&agg, &ti.spec, 0, A->space.funcs, + A->space.structs, A->space.vars, + A->mach, A->file, A->atoms)) + goto end; + + index = 0; + size = _slang_sizeof_aggregate(&agg); + result = assign_aggregate(A, &agg, &index, size); + + end1: + slang_storage_aggregate_destruct(&agg); + end: + slang_assembly_typeinfo_destruct(&ti); + return result; } -/* - * _slang_assemble_assign() - * - * Performs unary (pre ++ and --) or binary (=, +=, -=, *=, /=) assignment on the operation's - * children. - */ -GLboolean _slang_assemble_assign (slang_assemble_ctx *A, slang_operation *op, const char *oper, - slang_ref_type ref) +/** + * Performs unary (pre ++ and --) or binary (=, +=, -=, *=, /=) + * assignment on the operation's children. + */ +GLboolean +_slang_assemble_assign(slang_assemble_ctx * A, slang_operation * op, + const char *oper, slang_ref_type ref) { - slang_swizzle swz; - - if (ref == slang_ref_forbid) - { - if (!slang_assembly_file_push_label2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4)) - return GL_FALSE; - } - - if (slang_string_compare ("=", oper) == 0) - { - if (!_slang_assemble_operation (A, &op->children[0], slang_ref_force)) - return GL_FALSE; - swz = A->swz; - if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid)) - return GL_FALSE; - A->swz = swz; - if (!_slang_assemble_assignment (A, op->children)) - return GL_FALSE; - } - else - { - if (!_slang_assemble_function_call_name (A, oper, op->children, op->num_children, GL_TRUE)) - return GL_FALSE; - } - - if (ref == slang_ref_forbid) - { - if (!slang_assembly_file_push (A->file, slang_asm_addr_copy)) - return GL_FALSE; - if (!slang_assembly_file_push_label (A->file, slang_asm_local_free, 4)) - return GL_FALSE; - if (!_slang_dereference (A, op->children)) - return GL_FALSE; - } - - return GL_TRUE; -} + slang_swizzle swz; + + if (ref == slang_ref_forbid) { + if (!slang_assembly_file_push_label2 + (A->file, slang_asm_local_addr, A->local.addr_tmp, 4)) + return GL_FALSE; + } + + if (slang_string_compare("=", oper) == 0) { + if (!_slang_assemble_operation(A, &op->children[0], slang_ref_force)) + return GL_FALSE; + swz = A->swz; + if (!_slang_assemble_operation(A, &op->children[1], slang_ref_forbid)) + return GL_FALSE; + A->swz = swz; + if (!_slang_assemble_assignment(A, op->children)) + return GL_FALSE; + } + else { + if (!_slang_assemble_function_call_name + (A, oper, op->children, op->num_children, GL_TRUE)) + return GL_FALSE; + } + + if (ref == slang_ref_forbid) { + if (!slang_assembly_file_push(A->file, slang_asm_addr_copy)) + return GL_FALSE; + if (!slang_assembly_file_push_label(A->file, slang_asm_local_free, 4)) + return GL_FALSE; + if (!_slang_dereference(A, op->children)) + return GL_FALSE; + } + return GL_TRUE; +} diff --git a/src/mesa/shader/slang/slang_assemble_assignment.h b/src/mesa/shader/slang/slang_assemble_assignment.h index 7b993b543b1..3c1ecdedab8 100644 --- a/src/mesa/shader/slang/slang_assemble_assignment.h +++ b/src/mesa/shader/slang/slang_assemble_assignment.h @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.2 * * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. * @@ -22,21 +22,24 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if !defined SLANG_ASSEMBLE_ASSIGNMENT_H +#ifndef SLANG_ASSEMBLE_ASSIGNMENT_H #define SLANG_ASSEMBLE_ASSIGNMENT_H #if defined __cplusplus extern "C" { #endif -GLboolean _slang_assemble_assignment (slang_assemble_ctx *, struct slang_operation_ *); -GLboolean _slang_assemble_assign (slang_assemble_ctx *, struct slang_operation_ *, const char *, - slang_ref_type); +extern GLboolean +_slang_assemble_assignment(slang_assemble_ctx *, const struct slang_operation_ *); + +extern GLboolean +_slang_assemble_assign(slang_assemble_ctx *, struct slang_operation_ *, + const char *, slang_ref_type); + #ifdef __cplusplus } #endif -#endif - +#endif /* SLANG_ASSEMBLE_ASSIGNMENT_H */ diff --git a/src/mesa/shader/slang/slang_assemble_constructor.c b/src/mesa/shader/slang/slang_assemble_constructor.c index 9d1aa707182..6cd320d4466 100644 --- a/src/mesa/shader/slang/slang_assemble_constructor.c +++ b/src/mesa/shader/slang/slang_assemble_constructor.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.2 * * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. * @@ -32,348 +32,370 @@ #include "slang_assemble.h" #include "slang_storage.h" -/* _slang_is_swizzle() */ -GLboolean _slang_is_swizzle (const char *field, GLuint rows, slang_swizzle *swz) + +/** + * Checks if a field selector is a general swizzle (an r-value swizzle + * with replicated components or an l-value swizzle mask) for a + * vector. Returns GL_TRUE if this is the case, <swz> is filled with + * swizzle information. Returns GL_FALSE otherwise. + */ +GLboolean +_slang_is_swizzle(const char *field, GLuint rows, slang_swizzle * swz) { - GLuint i; - GLboolean xyzw = GL_FALSE, rgba = GL_FALSE, stpq = GL_FALSE; - - /* the swizzle can be at most 4-component long */ - swz->num_components = slang_string_length (field); - if (swz->num_components > 4) - return GL_FALSE; - - for (i = 0; i < swz->num_components; i++) - { - /* mark which swizzle group is used */ - switch (field[i]) - { - case 'x': - case 'y': - case 'z': - case 'w': - xyzw = GL_TRUE; - break; - case 'r': - case 'g': - case 'b': - case 'a': - rgba = GL_TRUE; - break; - case 's': - case 't': - case 'p': - case 'q': - stpq = GL_TRUE; - break; - default: - return GL_FALSE; - } - - /* collect swizzle component */ - switch (field[i]) - { - case 'x': - case 'r': - case 's': - swz->swizzle[i] = 0; - break; - case 'y': - case 'g': - case 't': - swz->swizzle[i] = 1; - break; - case 'z': - case 'b': - case 'p': - swz->swizzle[i] = 2; - break; - case 'w': - case 'a': - case 'q': - swz->swizzle[i] = 3; - break; - } - - /* check if the component is valid for given vector's row count */ - if (rows <= swz->swizzle[i]) - return GL_FALSE; - } - - /* only one swizzle group can be used */ - if ((xyzw && rgba) || (xyzw && stpq) || (rgba && stpq)) - return GL_FALSE; - - return GL_TRUE; + GLuint i; + GLboolean xyzw = GL_FALSE, rgba = GL_FALSE, stpq = GL_FALSE; + + /* the swizzle can be at most 4-component long */ + swz->num_components = slang_string_length(field); + if (swz->num_components > 4) + return GL_FALSE; + + for (i = 0; i < swz->num_components; i++) { + /* mark which swizzle group is used */ + switch (field[i]) { + case 'x': + case 'y': + case 'z': + case 'w': + xyzw = GL_TRUE; + break; + case 'r': + case 'g': + case 'b': + case 'a': + rgba = GL_TRUE; + break; + case 's': + case 't': + case 'p': + case 'q': + stpq = GL_TRUE; + break; + default: + return GL_FALSE; + } + + /* collect swizzle component */ + switch (field[i]) { + case 'x': + case 'r': + case 's': + swz->swizzle[i] = 0; + break; + case 'y': + case 'g': + case 't': + swz->swizzle[i] = 1; + break; + case 'z': + case 'b': + case 'p': + swz->swizzle[i] = 2; + break; + case 'w': + case 'a': + case 'q': + swz->swizzle[i] = 3; + break; + } + + /* check if the component is valid for given vector's row count */ + if (rows <= swz->swizzle[i]) + return GL_FALSE; + } + + /* only one swizzle group can be used */ + if ((xyzw && rgba) || (xyzw && stpq) || (rgba && stpq)) + return GL_FALSE; + + return GL_TRUE; } -/* _slang_is_swizzle_mask() */ -GLboolean _slang_is_swizzle_mask (const slang_swizzle *swz, GLuint rows) + +/** + * Checks if a general swizzle is an l-value swizzle - these swizzles + * do not have duplicated fields. Returns GL_TRUE if this is a + * swizzle mask. Returns GL_FALSE otherwise + */ +GLboolean +_slang_is_swizzle_mask(const slang_swizzle * swz, GLuint rows) { - GLuint i, c = 0; + GLuint i, c = 0; - /* the swizzle may not be longer than the vector dim */ - if (swz->num_components > rows) - return GL_FALSE; + /* the swizzle may not be longer than the vector dim */ + if (swz->num_components > rows) + return GL_FALSE; - /* the swizzle components cannot be duplicated */ - for (i = 0; i < swz->num_components; i++) - { - if ((c & (1 << swz->swizzle[i])) != 0) - return GL_FALSE; - c |= 1 << swz->swizzle[i]; - } + /* the swizzle components cannot be duplicated */ + for (i = 0; i < swz->num_components; i++) { + if ((c & (1 << swz->swizzle[i])) != 0) + return GL_FALSE; + c |= 1 << swz->swizzle[i]; + } - return GL_TRUE; + return GL_TRUE; } -/* _slang_multiply_swizzles() */ -GLvoid _slang_multiply_swizzles (slang_swizzle *dst, const slang_swizzle *left, - const slang_swizzle *right) + +/** + * Combines (multiplies) two swizzles to form single swizzle. + * Example: "vec.wzyx.yx" --> "vec.zw". + */ +GLvoid +_slang_multiply_swizzles(slang_swizzle * dst, const slang_swizzle * left, + const slang_swizzle * right) { - GLuint i; + GLuint i; - dst->num_components = right->num_components; - for (i = 0; i < right->num_components; i++) - dst->swizzle[i] = left->swizzle[right->swizzle[i]]; + dst->num_components = right->num_components; + for (i = 0; i < right->num_components; i++) + dst->swizzle[i] = left->swizzle[right->swizzle[i]]; } -/* _slang_assemble_constructor() */ + static GLboolean -sizeof_argument (slang_assemble_ctx *A, GLuint *size, slang_operation *op) +sizeof_argument(slang_assemble_ctx * A, GLuint * size, slang_operation * op) { slang_assembly_typeinfo ti; GLboolean result = GL_FALSE; slang_storage_aggregate agg; - if (!slang_assembly_typeinfo_construct (&ti)) + if (!slang_assembly_typeinfo_construct(&ti)) return GL_FALSE; - if (!_slang_typeof_operation (A, op, &ti)) + if (!_slang_typeof_operation(A, op, &ti)) goto end1; - if (!slang_storage_aggregate_construct (&agg)) + if (!slang_storage_aggregate_construct(&agg)) goto end1; - if (!_slang_aggregate_variable (&agg, &ti.spec, 0, A->space.funcs, A->space.structs, - A->space.vars, A->mach, A->file, A->atoms)) + if (!_slang_aggregate_variable(&agg, &ti.spec, 0, A->space.funcs, + A->space.structs, A->space.vars, + A->mach, A->file, A->atoms)) goto end; - *size = _slang_sizeof_aggregate (&agg); + *size = _slang_sizeof_aggregate(&agg); result = GL_TRUE; -end: - slang_storage_aggregate_destruct (&agg); -end1: - slang_assembly_typeinfo_destruct (&ti); + end: + slang_storage_aggregate_destruct(&agg); + end1: + slang_assembly_typeinfo_destruct(&ti); return result; } -static GLboolean constructor_aggregate (slang_assemble_ctx *A, const slang_storage_aggregate *flat, - slang_operation *op, GLuint garbage_size) + +static GLboolean +constructor_aggregate(slang_assemble_ctx * A, + const slang_storage_aggregate * flat, + slang_operation * op, GLuint garbage_size) { - slang_assembly_typeinfo ti; - GLboolean result = GL_FALSE; - slang_storage_aggregate agg, flat_agg; - - if (!slang_assembly_typeinfo_construct (&ti)) - return GL_FALSE; - if (!_slang_typeof_operation (A, op, &ti)) - goto end1; - - if (!slang_storage_aggregate_construct (&agg)) - goto end1; - if (!_slang_aggregate_variable (&agg, &ti.spec, 0, A->space.funcs, A->space.structs, - A->space.vars, A->mach, A->file, A->atoms)) - goto end2; - - if (!slang_storage_aggregate_construct (&flat_agg)) - goto end2; - if (!_slang_flatten_aggregate (&flat_agg, &agg)) - goto end; - - if (!_slang_assemble_operation (A, op, slang_ref_forbid)) - goto end; - - /* TODO: convert (generic) elements */ - - /* free the garbage */ - if (garbage_size != 0) - { - GLuint i; - - /* move the non-garbage part to the end of the argument */ - if (!slang_assembly_file_push_label (A->file, slang_asm_addr_push, 0)) - goto end; - for (i = flat_agg.count * 4 - garbage_size; i > 0; i -= 4) - { - if (!slang_assembly_file_push_label2 (A->file, slang_asm_float_move, - garbage_size + i, i)) - { - goto end; - } - } - if (!slang_assembly_file_push_label (A->file, slang_asm_local_free, garbage_size + 4)) - goto end; - } - - result = GL_TRUE; -end: - slang_storage_aggregate_destruct (&flat_agg); -end2: - slang_storage_aggregate_destruct (&agg); -end1: - slang_assembly_typeinfo_destruct (&ti); - return result; + slang_assembly_typeinfo ti; + GLboolean result = GL_FALSE; + slang_storage_aggregate agg, flat_agg; + + if (!slang_assembly_typeinfo_construct(&ti)) + return GL_FALSE; + if (!_slang_typeof_operation(A, op, &ti)) + goto end1; + + if (!slang_storage_aggregate_construct(&agg)) + goto end1; + if (!_slang_aggregate_variable(&agg, &ti.spec, 0, A->space.funcs, + A->space.structs, A->space.vars, + A->mach, A->file, A->atoms)) + goto end2; + + if (!slang_storage_aggregate_construct(&flat_agg)) + goto end2; + if (!_slang_flatten_aggregate(&flat_agg, &agg)) + goto end; + + if (!_slang_assemble_operation(A, op, slang_ref_forbid)) + goto end; + + /* TODO: convert (generic) elements */ + + /* free the garbage */ + if (garbage_size != 0) { + GLuint i; + + /* move the non-garbage part to the end of the argument */ + if (!slang_assembly_file_push_label(A->file, slang_asm_addr_push, 0)) + goto end; + for (i = flat_agg.count * 4 - garbage_size; i > 0; i -= 4) { + if (!slang_assembly_file_push_label2(A->file, slang_asm_float_move, + garbage_size + i, i)) { + goto end; + } + } + if (!slang_assembly_file_push_label + (A->file, slang_asm_local_free, garbage_size + 4)) + goto end; + } + + result = GL_TRUE; + end: + slang_storage_aggregate_destruct(&flat_agg); + end2: + slang_storage_aggregate_destruct(&agg); + end1: + slang_assembly_typeinfo_destruct(&ti); + return result; } -GLboolean _slang_assemble_constructor (slang_assemble_ctx *A, slang_operation *op) + +GLboolean +_slang_assemble_constructor(slang_assemble_ctx * A, const slang_operation * op) { - slang_assembly_typeinfo ti; - GLboolean result = GL_FALSE; - slang_storage_aggregate agg, flat; - GLuint size, i; - GLuint arg_sums[2]; - - /* get typeinfo of the constructor (the result of constructor expression) */ - if (!slang_assembly_typeinfo_construct (&ti)) - return GL_FALSE; - if (!_slang_typeof_operation (A, op, &ti)) - goto end1; - - /* create an aggregate of the constructor */ - if (!slang_storage_aggregate_construct (&agg)) - goto end1; - if (!_slang_aggregate_variable (&agg, &ti.spec, 0, A->space.funcs, A->space.structs, - A->space.vars, A->mach, A->file, A->atoms)) - goto end2; - - /* calculate size of the constructor */ - size = _slang_sizeof_aggregate (&agg); - - /* flatten the constructor */ - if (!slang_storage_aggregate_construct (&flat)) - goto end2; - if (!_slang_flatten_aggregate (&flat, &agg)) - goto end; - - /* collect the last two constructor's argument size sums */ - arg_sums[0] = 0; /* will hold all but the last argument's size sum */ - arg_sums[1] = 0; /* will hold all argument's size sum */ - for (i = 0; i < op->num_children; i++) - { - GLuint arg_size = 0; - - if (!sizeof_argument (A, &arg_size, &op->children[i])) - goto end; - if (i > 0) - arg_sums[0] = arg_sums[1]; - arg_sums[1] += arg_size; - } - - /* check if there are too many arguments */ - if (arg_sums[0] >= size) - { - /* TODO: info log: too many arguments in constructor list */ - goto end; - } - - /* check if there are too few arguments */ - if (arg_sums[1] < size) - { - /* TODO: info log: too few arguments in constructor list */ - goto end; - } - - /* traverse the children that form the constructor expression */ - for (i = op->num_children; i > 0; i--) - { - GLuint garbage_size; - - /* the last argument may be too big - calculate the unnecessary data size */ - if (i == op->num_children) - garbage_size = arg_sums[1] - size; - else - garbage_size = 0; - - if (!constructor_aggregate (A, &flat, &op->children[i - 1], garbage_size)) - goto end; - } - - result = GL_TRUE; -end: - slang_storage_aggregate_destruct (&flat); -end2: - slang_storage_aggregate_destruct (&agg); -end1: - slang_assembly_typeinfo_destruct (&ti); - return result; + slang_assembly_typeinfo ti; + GLboolean result = GL_FALSE; + slang_storage_aggregate agg, flat; + GLuint size, i; + GLuint arg_sums[2]; + + /* get typeinfo of the constructor (the result of constructor expression) */ + if (!slang_assembly_typeinfo_construct(&ti)) + return GL_FALSE; + if (!_slang_typeof_operation(A, op, &ti)) + goto end1; + + /* create an aggregate of the constructor */ + if (!slang_storage_aggregate_construct(&agg)) + goto end1; + if (!_slang_aggregate_variable(&agg, &ti.spec, 0, A->space.funcs, + A->space.structs, A->space.vars, + A->mach, A->file, A->atoms)) + goto end2; + + /* calculate size of the constructor */ + size = _slang_sizeof_aggregate(&agg); + + /* flatten the constructor */ + if (!slang_storage_aggregate_construct(&flat)) + goto end2; + if (!_slang_flatten_aggregate(&flat, &agg)) + goto end; + + /* collect the last two constructor's argument size sums */ + arg_sums[0] = 0; /* will hold all but the last argument's size sum */ + arg_sums[1] = 0; /* will hold all argument's size sum */ + for (i = 0; i < op->num_children; i++) { + GLuint arg_size = 0; + + if (!sizeof_argument(A, &arg_size, &op->children[i])) + goto end; + if (i > 0) + arg_sums[0] = arg_sums[1]; + arg_sums[1] += arg_size; + } + + /* check if there are too many arguments */ + if (arg_sums[0] >= size) { + /* TODO: info log: too many arguments in constructor list */ + goto end; + } + + /* check if there are too few arguments */ + if (arg_sums[1] < size) { + /* TODO: info log: too few arguments in constructor list */ + goto end; + } + + /* traverse the children that form the constructor expression */ + for (i = op->num_children; i > 0; i--) { + GLuint garbage_size; + + /* the last argument may be too big - calculate the unnecessary + * data size + */ + if (i == op->num_children) + garbage_size = arg_sums[1] - size; + else + garbage_size = 0; + + if (!constructor_aggregate + (A, &flat, &op->children[i - 1], garbage_size)) + goto end; + } + + result = GL_TRUE; + end: + slang_storage_aggregate_destruct(&flat); + end2: + slang_storage_aggregate_destruct(&agg); + end1: + slang_assembly_typeinfo_destruct(&ti); + return result; } -/* _slang_assemble_constructor_from_swizzle() */ -GLboolean _slang_assemble_constructor_from_swizzle (slang_assemble_ctx *A, const slang_swizzle *swz, - slang_type_specifier *spec, slang_type_specifier *master_spec) + +GLboolean +_slang_assemble_constructor_from_swizzle(slang_assemble_ctx * A, + const slang_swizzle * swz, + const slang_type_specifier * spec, + const slang_type_specifier * master_spec) { - GLuint master_rows, i; - - master_rows = _slang_type_dim (master_spec->type); - for (i = 0; i < master_rows; i++) - { - switch (_slang_type_base (master_spec->type)) - { - case slang_spec_bool: - if (!slang_assembly_file_push_label2 (A->file, slang_asm_bool_copy, - (master_rows - i) * 4, i * 4)) - return GL_FALSE; - break; - case slang_spec_int: - if (!slang_assembly_file_push_label2 (A->file, slang_asm_int_copy, - (master_rows - i) * 4, i * 4)) - return GL_FALSE; - break; - case slang_spec_float: - if (!slang_assembly_file_push_label2 (A->file, slang_asm_float_copy, - (master_rows - i) * 4, i * 4)) - return GL_FALSE; - break; - default: - break; - } - } - if (!slang_assembly_file_push_label (A->file, slang_asm_local_free, 4)) - return GL_FALSE; - for (i = swz->num_components; i > 0; i--) - { - GLuint n = i - 1; - - if (!slang_assembly_file_push_label2 (A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16)) - return GL_FALSE; - if (!slang_assembly_file_push_label (A->file, slang_asm_addr_push, swz->swizzle[n] * 4)) - return GL_FALSE; - if (!slang_assembly_file_push (A->file, slang_asm_addr_add)) - return GL_FALSE; - switch (_slang_type_base (master_spec->type)) - { - case slang_spec_bool: - if (!slang_assembly_file_push (A->file, slang_asm_bool_deref)) - return GL_FALSE; - break; - case slang_spec_int: - if (!slang_assembly_file_push (A->file, slang_asm_int_deref)) - return GL_FALSE; - break; - case slang_spec_float: - if (!slang_assembly_file_push (A->file, slang_asm_float_deref)) - return GL_FALSE; - break; - default: - break; - } - } - - return GL_TRUE; -} + const GLuint master_rows = _slang_type_dim(master_spec->type); + GLuint i; + + for (i = 0; i < master_rows; i++) { + switch (_slang_type_base(master_spec->type)) { + case slang_spec_bool: + if (!slang_assembly_file_push_label2(A->file, slang_asm_bool_copy, + (master_rows - i) * 4, i * 4)) + return GL_FALSE; + break; + case slang_spec_int: + if (!slang_assembly_file_push_label2(A->file, slang_asm_int_copy, + (master_rows - i) * 4, i * 4)) + return GL_FALSE; + break; + case slang_spec_float: + if (!slang_assembly_file_push_label2(A->file, slang_asm_float_copy, + (master_rows - i) * 4, i * 4)) + return GL_FALSE; + break; + default: + break; + } + } + + if (!slang_assembly_file_push_label(A->file, slang_asm_local_free, 4)) + return GL_FALSE; + for (i = swz->num_components; i > 0; i--) { + const GLuint n = i - 1; + + if (!slang_assembly_file_push_label2(A->file, slang_asm_local_addr, + A->local.swizzle_tmp, 16)) + return GL_FALSE; + if (!slang_assembly_file_push_label(A->file, slang_asm_addr_push, + swz->swizzle[n] * 4)) + return GL_FALSE; + if (!slang_assembly_file_push(A->file, slang_asm_addr_add)) + return GL_FALSE; + + switch (_slang_type_base(master_spec->type)) { + case slang_spec_bool: + if (!slang_assembly_file_push(A->file, slang_asm_bool_deref)) + return GL_FALSE; + break; + case slang_spec_int: + if (!slang_assembly_file_push(A->file, slang_asm_int_deref)) + return GL_FALSE; + break; + case slang_spec_float: + if (!slang_assembly_file_push(A->file, slang_asm_float_deref)) + return GL_FALSE; + break; + default: + break; + } + } + + return GL_TRUE; +} diff --git a/src/mesa/shader/slang/slang_assemble_constructor.h b/src/mesa/shader/slang/slang_assemble_constructor.h index 41a03943cf5..c0deb913448 100644 --- a/src/mesa/shader/slang/slang_assemble_constructor.h +++ b/src/mesa/shader/slang/slang_assemble_constructor.h @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.2 * * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. * @@ -22,43 +22,36 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if !defined SLANG_ASSEMBLE_CONSTRUCTOR_H +#ifndef SLANG_ASSEMBLE_CONSTRUCTOR_H #define SLANG_ASSEMBLE_CONSTRUCTOR_H #if defined __cplusplus extern "C" { #endif -/* - * Checks if a field selector is a general swizzle (an r-value swizzle with replicated - * components or an l-value swizzle mask) for a vector. - * Returns GL_TRUE if this is the case, <swz> is filled with swizzle information. - * Returns GL_FALSE otherwise. - */ -GLboolean _slang_is_swizzle (const char *field, GLuint rows, slang_swizzle *swz); -/* - * Checks if a general swizzle is an l-value swizzle - these swizzles do not have - * duplicated fields. - * Returns GL_TRUE if this is a swizzle mask. - * Returns GL_FALSE otherwise - */ -GLboolean _slang_is_swizzle_mask (const slang_swizzle *swz, GLuint rows); +extern GLboolean +_slang_is_swizzle(const char *field, GLuint rows, slang_swizzle *swz); -/* - * Combines (multiplies) two swizzles to form single swizzle. - * Example: "vec.wzyx.yx" --> "vec.zw". - */ -GLvoid _slang_multiply_swizzles (slang_swizzle *, const slang_swizzle *, const slang_swizzle *); +extern GLboolean +_slang_is_swizzle_mask(const slang_swizzle *swz, GLuint rows); + +extern GLvoid +_slang_multiply_swizzles(slang_swizzle *, const slang_swizzle *, + const slang_swizzle *); -GLboolean _slang_assemble_constructor (slang_assemble_ctx *, struct slang_operation_ *); +extern GLboolean +_slang_assemble_constructor(slang_assemble_ctx *, + const struct slang_operation_ *); -GLboolean _slang_assemble_constructor_from_swizzle (slang_assemble_ctx *, const slang_swizzle *, - slang_type_specifier *, slang_type_specifier *); +extern GLboolean +_slang_assemble_constructor_from_swizzle(slang_assemble_ctx *, + const slang_swizzle *, + const slang_type_specifier *, + const slang_type_specifier *); #ifdef __cplusplus } #endif -#endif - +#endif /* SLANG_ASSEMBLE_CONSTRUCTOR_H */ diff --git a/src/mesa/shader/slang/slang_assemble_typeinfo.c b/src/mesa/shader/slang/slang_assemble_typeinfo.c index 58f4e24f256..265e417dadd 100644 --- a/src/mesa/shader/slang/slang_assemble_typeinfo.c +++ b/src/mesa/shader/slang/slang_assemble_typeinfo.c @@ -36,552 +36,590 @@ * slang_type_specifier */ -GLvoid slang_type_specifier_ctr (slang_type_specifier *self) +GLvoid +slang_type_specifier_ctr(slang_type_specifier * self) { - self->type = slang_spec_void; - self->_struct = NULL; - self->_array = NULL; + self->type = slang_spec_void; + self->_struct = NULL; + self->_array = NULL; } -GLvoid slang_type_specifier_dtr (slang_type_specifier *self) +GLvoid +slang_type_specifier_dtr(slang_type_specifier * self) { - if (self->_struct != NULL) - { - slang_struct_destruct (self->_struct); - slang_alloc_free (self->_struct); - } - if (self->_array != NULL) - { - slang_type_specifier_dtr (self->_array); - slang_alloc_free (self->_array); - } + if (self->_struct != NULL) { + slang_struct_destruct(self->_struct); + slang_alloc_free(self->_struct); + } + if (self->_array != NULL) { + slang_type_specifier_dtr(self->_array); + slang_alloc_free(self->_array); + } } -GLboolean slang_type_specifier_copy (slang_type_specifier *x, const slang_type_specifier *y) +GLboolean +slang_type_specifier_copy(slang_type_specifier * x, + const slang_type_specifier * y) { - slang_type_specifier z; - - slang_type_specifier_ctr (&z); - z.type = y->type; - if (z.type == slang_spec_struct) - { - z._struct = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct)); - if (z._struct == NULL) - { - slang_type_specifier_dtr (&z); - return GL_FALSE; - } - if (!slang_struct_construct (z._struct)) - { - slang_alloc_free (z._struct); - slang_type_specifier_dtr (&z); - return GL_FALSE; - } - if (!slang_struct_copy (z._struct, y->_struct)) - { - slang_type_specifier_dtr (&z); - return GL_FALSE; - } - } - else if (z.type == slang_spec_array) - { - z._array = (slang_type_specifier *) slang_alloc_malloc (sizeof (slang_type_specifier)); - if (z._array == NULL) - { - slang_type_specifier_dtr (&z); - return GL_FALSE; - } - slang_type_specifier_ctr (z._array); - if (!slang_type_specifier_copy (z._array, y->_array)) - { - slang_type_specifier_dtr (&z); - return GL_FALSE; - } - } - slang_type_specifier_dtr (x); - *x = z; - return GL_TRUE; + slang_type_specifier z; + + slang_type_specifier_ctr(&z); + z.type = y->type; + if (z.type == slang_spec_struct) { + z._struct = (slang_struct *) slang_alloc_malloc(sizeof(slang_struct)); + if (z._struct == NULL) { + slang_type_specifier_dtr(&z); + return GL_FALSE; + } + if (!slang_struct_construct(z._struct)) { + slang_alloc_free(z._struct); + slang_type_specifier_dtr(&z); + return GL_FALSE; + } + if (!slang_struct_copy(z._struct, y->_struct)) { + slang_type_specifier_dtr(&z); + return GL_FALSE; + } + } + else if (z.type == slang_spec_array) { + z._array = + (slang_type_specifier *) + slang_alloc_malloc(sizeof(slang_type_specifier)); + if (z._array == NULL) { + slang_type_specifier_dtr(&z); + return GL_FALSE; + } + slang_type_specifier_ctr(z._array); + if (!slang_type_specifier_copy(z._array, y->_array)) { + slang_type_specifier_dtr(&z); + return GL_FALSE; + } + } + slang_type_specifier_dtr(x); + *x = z; + return GL_TRUE; } -GLboolean slang_type_specifier_equal (const slang_type_specifier *x, const slang_type_specifier *y) +GLboolean +slang_type_specifier_equal(const slang_type_specifier * x, + const slang_type_specifier * y) { - if (x->type != y->type) - return 0; - if (x->type == slang_spec_struct) - return slang_struct_equal (x->_struct, y->_struct); - if (x->type == slang_spec_array) - return slang_type_specifier_equal (x->_array, y->_array); - return 1; + if (x->type != y->type) + return 0; + if (x->type == slang_spec_struct) + return slang_struct_equal(x->_struct, y->_struct); + if (x->type == slang_spec_array) + return slang_type_specifier_equal(x->_array, y->_array); + return 1; } /* slang_assembly_typeinfo */ -GLboolean slang_assembly_typeinfo_construct (slang_assembly_typeinfo *ti) +GLboolean +slang_assembly_typeinfo_construct(slang_assembly_typeinfo * ti) { - slang_type_specifier_ctr (&ti->spec); - ti->array_len = 0; - return GL_TRUE; + slang_type_specifier_ctr(&ti->spec); + ti->array_len = 0; + return GL_TRUE; } -GLvoid slang_assembly_typeinfo_destruct (slang_assembly_typeinfo *ti) +GLvoid +slang_assembly_typeinfo_destruct(slang_assembly_typeinfo * ti) { - slang_type_specifier_dtr (&ti->spec); + slang_type_specifier_dtr(&ti->spec); } /* _slang_typeof_operation() */ -static GLboolean typeof_existing_function (const char *name, slang_operation *params, - GLuint num_params, slang_assembly_name_space *space, slang_type_specifier *spec, - slang_atom_pool *atoms) +/** + * Determine the return type of a function. + * \param name name of the function + * \param params array of function parameters + * \param num_params number of parameters + * \param space namespace to use + * \param spec returns the function's type + * \param atoms atom pool + * \return GL_TRUE for success, GL_FALSE if failure + */ +static GLboolean +typeof_existing_function(const char *name, const slang_operation * params, + GLuint num_params, + const slang_assembly_name_space * space, + slang_type_specifier * spec, + slang_atom_pool * atoms) { - slang_atom atom; - GLboolean exists; - - atom = slang_atom_pool_atom (atoms, name); - if (!_slang_typeof_function (atom, params, num_params, space, spec, &exists, atoms)) - return GL_FALSE; - return exists; + slang_atom atom; + GLboolean exists; + + atom = slang_atom_pool_atom(atoms, name); + if (!_slang_typeof_function(atom, params, num_params, space, spec, + &exists, atoms)) + return GL_FALSE; + return exists; } -GLboolean _slang_typeof_operation (slang_assemble_ctx *A, slang_operation *op, - slang_assembly_typeinfo *ti) +GLboolean +_slang_typeof_operation(const slang_assemble_ctx * A, + const slang_operation * op, + slang_assembly_typeinfo * ti) { - return _slang_typeof_operation_ (op, &A->space, ti, A->atoms); + return _slang_typeof_operation_(op, &A->space, ti, A->atoms); } -GLboolean _slang_typeof_operation_ (slang_operation *op, slang_assembly_name_space *space, - slang_assembly_typeinfo *ti, slang_atom_pool *atoms) + +/** + * Determine the return type of an operation. + * \param op the operation node + * \param space the namespace to use + * \param ti the returned type + * \param atoms atom pool + * \return GL_TRUE for success, GL_FALSE if failure + */ +GLboolean +_slang_typeof_operation_(const slang_operation * op, + const slang_assembly_name_space * space, + slang_assembly_typeinfo * ti, + slang_atom_pool * atoms) { - ti->can_be_referenced = GL_FALSE; - ti->is_swizzled = GL_FALSE; - - switch (op->type) - { - case slang_oper_block_no_new_scope: - case slang_oper_block_new_scope: - case slang_oper_variable_decl: - case slang_oper_asm: - case slang_oper_break: - case slang_oper_continue: - case slang_oper_discard: - case slang_oper_return: - case slang_oper_if: - case slang_oper_while: - case slang_oper_do: - case slang_oper_for: - case slang_oper_void: - ti->spec.type = slang_spec_void; - break; - case slang_oper_expression: - case slang_oper_assign: - case slang_oper_addassign: - case slang_oper_subassign: - case slang_oper_mulassign: - case slang_oper_divassign: - case slang_oper_preincrement: - case slang_oper_predecrement: - if (!_slang_typeof_operation_ (op->children, space, ti, atoms)) - return 0; - break; - case slang_oper_literal_bool: - case slang_oper_logicalor: - case slang_oper_logicalxor: - case slang_oper_logicaland: - case slang_oper_equal: - case slang_oper_notequal: - case slang_oper_less: - case slang_oper_greater: - case slang_oper_lessequal: - case slang_oper_greaterequal: - case slang_oper_not: - ti->spec.type = slang_spec_bool; - break; - case slang_oper_literal_int: - ti->spec.type = slang_spec_int; - break; - case slang_oper_literal_float: - ti->spec.type = slang_spec_float; - break; - case slang_oper_identifier: - { - slang_variable *var; - - var = _slang_locate_variable (op->locals, op->a_id, GL_TRUE); - if (var == NULL) - return GL_FALSE; - if (!slang_type_specifier_copy (&ti->spec, &var->type.specifier)) - return GL_FALSE; - ti->can_be_referenced = GL_TRUE; - ti->array_len = var->array_len; - } - break; - case slang_oper_sequence: - /* TODO: check [0] and [1] if they match */ - if (!_slang_typeof_operation_ (&op->children[1], space, ti, atoms)) - return GL_FALSE; - ti->can_be_referenced = GL_FALSE; - ti->is_swizzled = GL_FALSE; - break; - /*case slang_oper_modassign:*/ - /*case slang_oper_lshassign:*/ - /*case slang_oper_rshassign:*/ - /*case slang_oper_orassign:*/ - /*case slang_oper_xorassign:*/ - /*case slang_oper_andassign:*/ - case slang_oper_select: - /* TODO: check [1] and [2] if they match */ - if (!_slang_typeof_operation_ (&op->children[1], space, ti, atoms)) - return GL_FALSE; - ti->can_be_referenced = GL_FALSE; - ti->is_swizzled = GL_FALSE; - break; - /*case slang_oper_bitor:*/ - /*case slang_oper_bitxor:*/ - /*case slang_oper_bitand:*/ - /*case slang_oper_lshift:*/ - /*case slang_oper_rshift:*/ - case slang_oper_add: - if (!typeof_existing_function ("+", op->children, 2, space, &ti->spec, atoms)) - return GL_FALSE; - break; - case slang_oper_subtract: - if (!typeof_existing_function ("-", op->children, 2, space, &ti->spec, atoms)) - return GL_FALSE; - break; - case slang_oper_multiply: - if (!typeof_existing_function ("*", op->children, 2, space, &ti->spec, atoms)) - return GL_FALSE; - break; - case slang_oper_divide: - if (!typeof_existing_function ("/", op->children, 2, space, &ti->spec, atoms)) - return GL_FALSE; - break; - /*case slang_oper_modulus:*/ - case slang_oper_plus: - if (!_slang_typeof_operation_ (op->children, space, ti, atoms)) - return GL_FALSE; - ti->can_be_referenced = GL_FALSE; - ti->is_swizzled = GL_FALSE; - break; - case slang_oper_minus: - if (!typeof_existing_function ("-", op->children, 1, space, &ti->spec, atoms)) - return GL_FALSE; - break; - /*case slang_oper_complement:*/ - case slang_oper_subscript: - { - slang_assembly_typeinfo _ti; - - if (!slang_assembly_typeinfo_construct (&_ti)) - return GL_FALSE; - if (!_slang_typeof_operation_ (op->children, space, &_ti, atoms)) - { - slang_assembly_typeinfo_destruct (&_ti); - return GL_FALSE; - } - ti->can_be_referenced = _ti.can_be_referenced; - if (_ti.spec.type == slang_spec_array) - { - if (!slang_type_specifier_copy (&ti->spec, _ti.spec._array)) - { - slang_assembly_typeinfo_destruct (&_ti); - return GL_FALSE; - } - } - else - { - if (!_slang_type_is_vector (_ti.spec.type) && !_slang_type_is_matrix (_ti.spec.type)) - { - slang_assembly_typeinfo_destruct (&_ti); - return GL_FALSE; - } - ti->spec.type = _slang_type_base (_ti.spec.type); - } - slang_assembly_typeinfo_destruct (&_ti); - } - break; - case slang_oper_call: - { - GLboolean exists; - - if (!_slang_typeof_function (op->a_id, op->children, op->num_children, space, &ti->spec, - &exists, atoms)) - return GL_FALSE; - if (!exists) - { - slang_struct *s = slang_struct_scope_find (space->structs, op->a_id, GL_TRUE); - if (s != NULL) - { - ti->spec.type = slang_spec_struct; - ti->spec._struct = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct)); - if (ti->spec._struct == NULL) - return GL_FALSE; - if (!slang_struct_construct (ti->spec._struct)) - { - slang_alloc_free (ti->spec._struct); - ti->spec._struct = NULL; - return GL_FALSE; - } - if (!slang_struct_copy (ti->spec._struct, s)) - return GL_FALSE; - } - else - { - const char *name; - slang_type_specifier_type type; - - name = slang_atom_pool_id (atoms, op->a_id); - type = slang_type_specifier_type_from_string (name); - if (type == slang_spec_void) - return GL_FALSE; - ti->spec.type = type; - } - } - } - break; - case slang_oper_field: - { - slang_assembly_typeinfo _ti; - - if (!slang_assembly_typeinfo_construct (&_ti)) - return GL_FALSE; - if (!_slang_typeof_operation_ (op->children, space, &_ti, atoms)) - { - slang_assembly_typeinfo_destruct (&_ti); - return GL_FALSE; - } - if (_ti.spec.type == slang_spec_struct) - { - slang_variable *field; - - field = _slang_locate_variable (_ti.spec._struct->fields, op->a_id, GL_FALSE); - if (field == NULL) - { - slang_assembly_typeinfo_destruct (&_ti); - return GL_FALSE; - } - if (!slang_type_specifier_copy (&ti->spec, &field->type.specifier)) - { - slang_assembly_typeinfo_destruct (&_ti); - return GL_FALSE; - } - ti->can_be_referenced = _ti.can_be_referenced; - } - else - { - GLuint rows; - const char *swizzle; - slang_type_specifier_type base; - - /* determine the swizzle of the field expression */ - if (!_slang_type_is_vector (_ti.spec.type)) - { - slang_assembly_typeinfo_destruct (&_ti); - return GL_FALSE; - } - rows = _slang_type_dim (_ti.spec.type); - swizzle = slang_atom_pool_id (atoms, op->a_id); - if (!_slang_is_swizzle (swizzle, rows, &ti->swz)) - { - slang_assembly_typeinfo_destruct (&_ti); - return GL_FALSE; - } - ti->is_swizzled = GL_TRUE; - ti->can_be_referenced = _ti.can_be_referenced && _slang_is_swizzle_mask (&ti->swz, - rows); - if (_ti.is_swizzled) - { - slang_swizzle swz; - - /* swizzle the swizzle */ - _slang_multiply_swizzles (&swz, &_ti.swz, &ti->swz); - ti->swz = swz; - } - base = _slang_type_base (_ti.spec.type); - switch (ti->swz.num_components) - { - case 1: - ti->spec.type = base; - break; - case 2: - switch (base) - { - case slang_spec_float: - ti->spec.type = slang_spec_vec2; - break; - case slang_spec_int: - ti->spec.type = slang_spec_ivec2; - break; - case slang_spec_bool: - ti->spec.type = slang_spec_bvec2; - break; - default: - break; - } - break; - case 3: - switch (base) - { - case slang_spec_float: - ti->spec.type = slang_spec_vec3; - break; - case slang_spec_int: - ti->spec.type = slang_spec_ivec3; - break; - case slang_spec_bool: - ti->spec.type = slang_spec_bvec3; - break; - default: - break; - } - break; - case 4: - switch (base) - { - case slang_spec_float: - ti->spec.type = slang_spec_vec4; - break; - case slang_spec_int: - ti->spec.type = slang_spec_ivec4; - break; - case slang_spec_bool: - ti->spec.type = slang_spec_bvec4; - break; - default: - break; - } - break; - default: - break; - } - } - slang_assembly_typeinfo_destruct (&_ti); - } - break; - case slang_oper_postincrement: - case slang_oper_postdecrement: - if (!_slang_typeof_operation_ (op->children, space, ti, atoms)) - return GL_FALSE; - ti->can_be_referenced = GL_FALSE; - ti->is_swizzled = GL_FALSE; - break; - default: - return GL_FALSE; - } - - return GL_TRUE; + ti->can_be_referenced = GL_FALSE; + ti->is_swizzled = GL_FALSE; + + switch (op->type) { + case slang_oper_block_no_new_scope: + case slang_oper_block_new_scope: + case slang_oper_variable_decl: + case slang_oper_asm: + case slang_oper_break: + case slang_oper_continue: + case slang_oper_discard: + case slang_oper_return: + case slang_oper_if: + case slang_oper_while: + case slang_oper_do: + case slang_oper_for: + case slang_oper_void: + ti->spec.type = slang_spec_void; + break; + case slang_oper_expression: + case slang_oper_assign: + case slang_oper_addassign: + case slang_oper_subassign: + case slang_oper_mulassign: + case slang_oper_divassign: + case slang_oper_preincrement: + case slang_oper_predecrement: + if (!_slang_typeof_operation_(op->children, space, ti, atoms)) + return 0; + break; + case slang_oper_literal_bool: + case slang_oper_logicalor: + case slang_oper_logicalxor: + case slang_oper_logicaland: + case slang_oper_equal: + case slang_oper_notequal: + case slang_oper_less: + case slang_oper_greater: + case slang_oper_lessequal: + case slang_oper_greaterequal: + case slang_oper_not: + ti->spec.type = slang_spec_bool; + break; + case slang_oper_literal_int: + ti->spec.type = slang_spec_int; + break; + case slang_oper_literal_float: + ti->spec.type = slang_spec_float; + break; + case slang_oper_identifier: + { + slang_variable *var; + + var = _slang_locate_variable(op->locals, op->a_id, GL_TRUE); + if (var == NULL) + return GL_FALSE; + if (!slang_type_specifier_copy(&ti->spec, &var->type.specifier)) + return GL_FALSE; + ti->can_be_referenced = GL_TRUE; + ti->array_len = var->array_len; + } + break; + case slang_oper_sequence: + /* TODO: check [0] and [1] if they match */ + if (!_slang_typeof_operation_(&op->children[1], space, ti, atoms)) + return GL_FALSE; + ti->can_be_referenced = GL_FALSE; + ti->is_swizzled = GL_FALSE; + break; + /*case slang_oper_modassign: */ + /*case slang_oper_lshassign: */ + /*case slang_oper_rshassign: */ + /*case slang_oper_orassign: */ + /*case slang_oper_xorassign: */ + /*case slang_oper_andassign: */ + case slang_oper_select: + /* TODO: check [1] and [2] if they match */ + if (!_slang_typeof_operation_(&op->children[1], space, ti, atoms)) + return GL_FALSE; + ti->can_be_referenced = GL_FALSE; + ti->is_swizzled = GL_FALSE; + break; + /*case slang_oper_bitor: */ + /*case slang_oper_bitxor: */ + /*case slang_oper_bitand: */ + /*case slang_oper_lshift: */ + /*case slang_oper_rshift: */ + case slang_oper_add: + if (!typeof_existing_function("+", op->children, 2, space, + &ti->spec, atoms)) + return GL_FALSE; + break; + case slang_oper_subtract: + if (!typeof_existing_function("-", op->children, 2, space, + &ti->spec, atoms)) + return GL_FALSE; + break; + case slang_oper_multiply: + if (!typeof_existing_function("*", op->children, 2, space, + &ti->spec, atoms)) + return GL_FALSE; + break; + case slang_oper_divide: + if (!typeof_existing_function("/", op->children, 2, space, + &ti->spec, atoms)) + return GL_FALSE; + break; + /*case slang_oper_modulus: */ + case slang_oper_plus: + if (!_slang_typeof_operation_(op->children, space, ti, atoms)) + return GL_FALSE; + ti->can_be_referenced = GL_FALSE; + ti->is_swizzled = GL_FALSE; + break; + case slang_oper_minus: + if (!typeof_existing_function + ("-", op->children, 1, space, &ti->spec, atoms)) + return GL_FALSE; + break; + /*case slang_oper_complement: */ + case slang_oper_subscript: + { + slang_assembly_typeinfo _ti; + + if (!slang_assembly_typeinfo_construct(&_ti)) + return GL_FALSE; + if (!_slang_typeof_operation_(op->children, space, &_ti, atoms)) { + slang_assembly_typeinfo_destruct(&_ti); + return GL_FALSE; + } + ti->can_be_referenced = _ti.can_be_referenced; + if (_ti.spec.type == slang_spec_array) { + if (!slang_type_specifier_copy(&ti->spec, _ti.spec._array)) { + slang_assembly_typeinfo_destruct(&_ti); + return GL_FALSE; + } + } + else { + if (!_slang_type_is_vector(_ti.spec.type) + && !_slang_type_is_matrix(_ti.spec.type)) { + slang_assembly_typeinfo_destruct(&_ti); + return GL_FALSE; + } + ti->spec.type = _slang_type_base(_ti.spec.type); + } + slang_assembly_typeinfo_destruct(&_ti); + } + break; + case slang_oper_call: + { + GLboolean exists; + + if (!_slang_typeof_function(op->a_id, op->children, op->num_children, + space, &ti->spec, &exists, atoms)) + return GL_FALSE; + if (!exists) { + slang_struct *s = + slang_struct_scope_find(space->structs, op->a_id, GL_TRUE); + if (s != NULL) { + ti->spec.type = slang_spec_struct; + ti->spec._struct = + (slang_struct *) slang_alloc_malloc(sizeof(slang_struct)); + if (ti->spec._struct == NULL) + return GL_FALSE; + if (!slang_struct_construct(ti->spec._struct)) { + slang_alloc_free(ti->spec._struct); + ti->spec._struct = NULL; + return GL_FALSE; + } + if (!slang_struct_copy(ti->spec._struct, s)) + return GL_FALSE; + } + else { + const char *name; + slang_type_specifier_type type; + + name = slang_atom_pool_id(atoms, op->a_id); + type = slang_type_specifier_type_from_string(name); + if (type == slang_spec_void) + return GL_FALSE; + ti->spec.type = type; + } + } + } + break; + case slang_oper_field: + { + slang_assembly_typeinfo _ti; + + if (!slang_assembly_typeinfo_construct(&_ti)) + return GL_FALSE; + if (!_slang_typeof_operation_(op->children, space, &_ti, atoms)) { + slang_assembly_typeinfo_destruct(&_ti); + return GL_FALSE; + } + if (_ti.spec.type == slang_spec_struct) { + slang_variable *field; + + field = + _slang_locate_variable(_ti.spec._struct->fields, op->a_id, + GL_FALSE); + if (field == NULL) { + slang_assembly_typeinfo_destruct(&_ti); + return GL_FALSE; + } + if (!slang_type_specifier_copy(&ti->spec, &field->type.specifier)) { + slang_assembly_typeinfo_destruct(&_ti); + return GL_FALSE; + } + ti->can_be_referenced = _ti.can_be_referenced; + } + else { + GLuint rows; + const char *swizzle; + slang_type_specifier_type base; + + /* determine the swizzle of the field expression */ + if (!_slang_type_is_vector(_ti.spec.type)) { + slang_assembly_typeinfo_destruct(&_ti); + return GL_FALSE; + } + rows = _slang_type_dim(_ti.spec.type); + swizzle = slang_atom_pool_id(atoms, op->a_id); + if (!_slang_is_swizzle(swizzle, rows, &ti->swz)) { + slang_assembly_typeinfo_destruct(&_ti); + return GL_FALSE; + } + ti->is_swizzled = GL_TRUE; + ti->can_be_referenced = _ti.can_be_referenced + && _slang_is_swizzle_mask(&ti->swz, rows); + if (_ti.is_swizzled) { + slang_swizzle swz; + + /* swizzle the swizzle */ + _slang_multiply_swizzles(&swz, &_ti.swz, &ti->swz); + ti->swz = swz; + } + base = _slang_type_base(_ti.spec.type); + switch (ti->swz.num_components) { + case 1: + ti->spec.type = base; + break; + case 2: + switch (base) { + case slang_spec_float: + ti->spec.type = slang_spec_vec2; + break; + case slang_spec_int: + ti->spec.type = slang_spec_ivec2; + break; + case slang_spec_bool: + ti->spec.type = slang_spec_bvec2; + break; + default: + break; + } + break; + case 3: + switch (base) { + case slang_spec_float: + ti->spec.type = slang_spec_vec3; + break; + case slang_spec_int: + ti->spec.type = slang_spec_ivec3; + break; + case slang_spec_bool: + ti->spec.type = slang_spec_bvec3; + break; + default: + break; + } + break; + case 4: + switch (base) { + case slang_spec_float: + ti->spec.type = slang_spec_vec4; + break; + case slang_spec_int: + ti->spec.type = slang_spec_ivec4; + break; + case slang_spec_bool: + ti->spec.type = slang_spec_bvec4; + break; + default: + break; + } + break; + default: + break; + } + } + slang_assembly_typeinfo_destruct(&_ti); + } + break; + case slang_oper_postincrement: + case slang_oper_postdecrement: + if (!_slang_typeof_operation_(op->children, space, ti, atoms)) + return GL_FALSE; + ti->can_be_referenced = GL_FALSE; + ti->is_swizzled = GL_FALSE; + break; + default: + return GL_FALSE; + } + + return GL_TRUE; } -/* _slang_typeof_function() */ -GLboolean _slang_typeof_function (slang_atom a_name, slang_operation *params, GLuint num_params, - slang_assembly_name_space *space, slang_type_specifier *spec, GLboolean *exists, - slang_atom_pool *atoms) + +/** + * Determine the return type of a function. + * \param a_name the function name + * \param param function parameters (overloading) + * \param num_params number of parameters to function + * \param space namespace to search + * \param exists returns GL_TRUE or GL_FALSE to indicate existance of function + * \return GL_TRUE for success, GL_FALSE if failure (bad function name) + */ +GLboolean +_slang_typeof_function(slang_atom a_name, const slang_operation * params, + GLuint num_params, + const slang_assembly_name_space * space, + slang_type_specifier * spec, GLboolean * exists, + slang_atom_pool * atoms) { - slang_function *fun; - - fun = _slang_locate_function (space->funcs, a_name, params, num_params, space, atoms); - *exists = fun != NULL; - if (fun == NULL) - return GL_TRUE; - return slang_type_specifier_copy (spec, &fun->header.type.specifier); + slang_function *fun = _slang_locate_function(space->funcs, a_name, params, + num_params, space, atoms); + *exists = fun != NULL; + if (!fun) + return GL_TRUE; /* yes, not false */ + return slang_type_specifier_copy(spec, &fun->header.type.specifier); } -/* _slang_type_is_matrix() */ -GLboolean _slang_type_is_matrix (slang_type_specifier_type ty) + +/** + * Determine if a type is a matrix. + * \return GL_TRUE if is a matrix, GL_FALSE otherwise. + */ +GLboolean +_slang_type_is_matrix(slang_type_specifier_type ty) { - switch (ty) - { - case slang_spec_mat2: - case slang_spec_mat3: - case slang_spec_mat4: - return GL_TRUE; - default: - return GL_FALSE; - } + switch (ty) { + case slang_spec_mat2: + case slang_spec_mat3: + case slang_spec_mat4: + return GL_TRUE; + default: + return GL_FALSE; + } } -/* _slang_type_is_vector() */ -GLboolean _slang_type_is_vector (slang_type_specifier_type ty) +/** + * Determine if a type is a vector. + * \return GL_TRUE if is a vector, GL_FALSE otherwise. + */ +GLboolean +_slang_type_is_vector(slang_type_specifier_type ty) { - switch (ty) - { - case slang_spec_vec2: - case slang_spec_vec3: - case slang_spec_vec4: - case slang_spec_ivec2: - case slang_spec_ivec3: - case slang_spec_ivec4: - case slang_spec_bvec2: - case slang_spec_bvec3: - case slang_spec_bvec4: - return GL_TRUE; - default: - return GL_FALSE; - } + switch (ty) { + case slang_spec_vec2: + case slang_spec_vec3: + case slang_spec_vec4: + case slang_spec_ivec2: + case slang_spec_ivec3: + case slang_spec_ivec4: + case slang_spec_bvec2: + case slang_spec_bvec3: + case slang_spec_bvec4: + return GL_TRUE; + default: + return GL_FALSE; + } } -/* _slang_type_base_of_vector() */ -slang_type_specifier_type _slang_type_base (slang_type_specifier_type ty) +/** + * Given a vector type, return the type of the vector's elements + */ +slang_type_specifier_type +_slang_type_base(slang_type_specifier_type ty) { - switch (ty) - { - case slang_spec_float: - case slang_spec_vec2: - case slang_spec_vec3: - case slang_spec_vec4: - return slang_spec_float; - case slang_spec_int: - case slang_spec_ivec2: - case slang_spec_ivec3: - case slang_spec_ivec4: - return slang_spec_int; - case slang_spec_bool: - case slang_spec_bvec2: - case slang_spec_bvec3: - case slang_spec_bvec4: - return slang_spec_bool; - case slang_spec_mat2: - return slang_spec_vec2; - case slang_spec_mat3: - return slang_spec_vec3; - case slang_spec_mat4: - return slang_spec_vec4; - default: - return slang_spec_void; - } + switch (ty) { + case slang_spec_float: + case slang_spec_vec2: + case slang_spec_vec3: + case slang_spec_vec4: + return slang_spec_float; + case slang_spec_int: + case slang_spec_ivec2: + case slang_spec_ivec3: + case slang_spec_ivec4: + return slang_spec_int; + case slang_spec_bool: + case slang_spec_bvec2: + case slang_spec_bvec3: + case slang_spec_bvec4: + return slang_spec_bool; + case slang_spec_mat2: + return slang_spec_vec2; + case slang_spec_mat3: + return slang_spec_vec3; + case slang_spec_mat4: + return slang_spec_vec4; + default: + return slang_spec_void; + } } -/* _slang_type_dim */ -GLuint _slang_type_dim (slang_type_specifier_type ty) +/** + * Return the dimensionality of a vector or matrix type. + */ +GLuint +_slang_type_dim(slang_type_specifier_type ty) { - switch (ty) - { - case slang_spec_float: - case slang_spec_int: - case slang_spec_bool: - return 1; - case slang_spec_vec2: - case slang_spec_ivec2: - case slang_spec_bvec2: - case slang_spec_mat2: - return 2; - case slang_spec_vec3: - case slang_spec_ivec3: - case slang_spec_bvec3: - case slang_spec_mat3: - return 3; - case slang_spec_vec4: - case slang_spec_ivec4: - case slang_spec_bvec4: - case slang_spec_mat4: - return 4; - default: - return 0; - } + switch (ty) { + case slang_spec_float: + case slang_spec_int: + case slang_spec_bool: + return 1; + case slang_spec_vec2: + case slang_spec_ivec2: + case slang_spec_bvec2: + case slang_spec_mat2: + return 2; + case slang_spec_vec3: + case slang_spec_ivec3: + case slang_spec_bvec3: + case slang_spec_mat3: + return 3; + case slang_spec_vec4: + case slang_spec_ivec4: + case slang_spec_bvec4: + case slang_spec_mat4: + return 4; + default: + return 0; + } } - diff --git a/src/mesa/shader/slang/slang_assemble_typeinfo.h b/src/mesa/shader/slang/slang_assemble_typeinfo.h index 7e8af96915b..777dc21f3a7 100644 --- a/src/mesa/shader/slang/slang_assemble_typeinfo.h +++ b/src/mesa/shader/slang/slang_assemble_typeinfo.h @@ -29,84 +29,120 @@ extern "C" { #endif + +/** + * The basic shading language types (float, vec4, mat3, etc) + */ typedef enum slang_type_specifier_type_ { - slang_spec_void, - slang_spec_bool, - slang_spec_bvec2, - slang_spec_bvec3, - slang_spec_bvec4, - slang_spec_int, - slang_spec_ivec2, - slang_spec_ivec3, - slang_spec_ivec4, - slang_spec_float, - slang_spec_vec2, - slang_spec_vec3, - slang_spec_vec4, - slang_spec_mat2, - slang_spec_mat3, - slang_spec_mat4, - slang_spec_sampler1D, - slang_spec_sampler2D, - slang_spec_sampler3D, - slang_spec_samplerCube, - slang_spec_sampler1DShadow, - slang_spec_sampler2DShadow, - slang_spec_struct, - slang_spec_array + slang_spec_void, + slang_spec_bool, + slang_spec_bvec2, + slang_spec_bvec3, + slang_spec_bvec4, + slang_spec_int, + slang_spec_ivec2, + slang_spec_ivec3, + slang_spec_ivec4, + slang_spec_float, + slang_spec_vec2, + slang_spec_vec3, + slang_spec_vec4, + slang_spec_mat2, + slang_spec_mat3, + slang_spec_mat4, + slang_spec_sampler1D, + slang_spec_sampler2D, + slang_spec_sampler3D, + slang_spec_samplerCube, + slang_spec_sampler1DShadow, + slang_spec_sampler2DShadow, + slang_spec_struct, + slang_spec_array } slang_type_specifier_type; + +/** + * Describes more sophisticated types, like structs and arrays. + */ typedef struct slang_type_specifier_ { - slang_type_specifier_type type; - struct slang_struct_ *_struct; /* type: spec_struct */ - struct slang_type_specifier_ *_array; /* type: spec_array */ + slang_type_specifier_type type; + struct slang_struct_ *_struct; /**< used if type == spec_struct */ + struct slang_type_specifier_ *_array; /**< used if type == spec_array */ } slang_type_specifier; -GLvoid slang_type_specifier_ctr (slang_type_specifier *); -GLvoid slang_type_specifier_dtr (slang_type_specifier *); -GLboolean slang_type_specifier_copy (slang_type_specifier *, const slang_type_specifier *); -GLboolean slang_type_specifier_equal (const slang_type_specifier *, const slang_type_specifier *); + +extern GLvoid +slang_type_specifier_ctr(slang_type_specifier *); + +extern GLvoid +slang_type_specifier_dtr(slang_type_specifier *); + +extern GLboolean +slang_type_specifier_copy(slang_type_specifier *, const slang_type_specifier *); + +extern GLboolean +slang_type_specifier_equal(const slang_type_specifier *, + const slang_type_specifier *); + typedef struct slang_assembly_typeinfo_ { - GLboolean can_be_referenced; - GLboolean is_swizzled; - slang_swizzle swz; - slang_type_specifier spec; - GLuint array_len; + GLboolean can_be_referenced; + GLboolean is_swizzled; + slang_swizzle swz; + slang_type_specifier spec; + GLuint array_len; } slang_assembly_typeinfo; -GLboolean slang_assembly_typeinfo_construct (slang_assembly_typeinfo *); -GLvoid slang_assembly_typeinfo_destruct (slang_assembly_typeinfo *); +extern GLboolean +slang_assembly_typeinfo_construct(slang_assembly_typeinfo *); -/* +extern GLvoid +slang_assembly_typeinfo_destruct(slang_assembly_typeinfo *); + + +/** * Retrieves type information about an operation. * Returns GL_TRUE on success. * Returns GL_FALSE otherwise. */ -GLboolean _slang_typeof_operation (slang_assemble_ctx *, struct slang_operation_ *, - slang_assembly_typeinfo *); -GLboolean _slang_typeof_operation_ (struct slang_operation_ *, slang_assembly_name_space *, - slang_assembly_typeinfo *, slang_atom_pool *); +extern GLboolean +_slang_typeof_operation(const slang_assemble_ctx *, + const struct slang_operation_ *, + slang_assembly_typeinfo *); -/* +extern GLboolean +_slang_typeof_operation_(const struct slang_operation_ *, + const slang_assembly_name_space *, + slang_assembly_typeinfo *, slang_atom_pool *); + +/** * Retrieves type of a function prototype, if one exists. * Returns GL_TRUE on success, even if the function was not found. * Returns GL_FALSE otherwise. */ -GLboolean _slang_typeof_function (slang_atom a_name, struct slang_operation_ *params, - GLuint num_params, slang_assembly_name_space *, slang_type_specifier *spec, GLboolean *exists, - slang_atom_pool *); +extern GLboolean +_slang_typeof_function(slang_atom a_name, + const struct slang_operation_ *params, + GLuint num_params, const slang_assembly_name_space *, + slang_type_specifier *spec, GLboolean *exists, + slang_atom_pool *); + +extern GLboolean +_slang_type_is_matrix(slang_type_specifier_type); + +extern GLboolean +_slang_type_is_vector(slang_type_specifier_type); -GLboolean _slang_type_is_matrix (slang_type_specifier_type); +extern slang_type_specifier_type +_slang_type_base(slang_type_specifier_type); -GLboolean _slang_type_is_vector (slang_type_specifier_type); +extern GLuint +_slang_type_dim(slang_type_specifier_type); -slang_type_specifier_type _slang_type_base (slang_type_specifier_type); -GLuint _slang_type_dim (slang_type_specifier_type); #ifdef __cplusplus } diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c index 357d61b246a..c49ab4a68dc 100644 --- a/src/mesa/shader/slang/slang_compile.c +++ b/src/mesa/shader/slang/slang_compile.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.6 + * Version: 6.5.2 * * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. * @@ -35,21 +35,25 @@ #include "slang_storage.h" /* - * This is a straightforward implementation of the slang front-end compiler. - * Lots of error-checking functionality is missing but every well-formed shader source should - * compile successfully and execute as expected. However, some semantically ill-formed shaders + * This is a straightforward implementation of the slang front-end + * compiler. Lots of error-checking functionality is missing but + * every well-formed shader source should compile successfully and + * execute as expected. However, some semantically ill-formed shaders * may be accepted resulting in undefined behaviour. */ -/* slang_var_pool */ -static GLuint slang_var_pool_alloc (slang_var_pool *pool, unsigned int size) -{ - GLuint addr; - addr = pool->next_addr; - pool->next_addr += size; - return addr; +/** + * Allocate storage for a variable of 'size' bytes from given pool. + * Return the allocated address for the variable. + */ +static GLuint +slang_var_pool_alloc(slang_var_pool * pool, unsigned int size) +{ + const GLuint addr = pool->next_addr; + pool->next_addr += size; + return addr; } /* @@ -57,20 +61,21 @@ static GLuint slang_var_pool_alloc (slang_var_pool *pool, unsigned int size) */ GLvoid -_slang_code_unit_ctr (slang_code_unit *self, struct slang_code_object_ *object) +_slang_code_unit_ctr(slang_code_unit * self, + struct slang_code_object_ * object) { - _slang_variable_scope_ctr (&self->vars); - _slang_function_scope_ctr (&self->funs); - _slang_struct_scope_ctr (&self->structs); + _slang_variable_scope_ctr(&self->vars); + _slang_function_scope_ctr(&self->funs); + _slang_struct_scope_ctr(&self->structs); self->object = object; } GLvoid -_slang_code_unit_dtr (slang_code_unit *self) +_slang_code_unit_dtr(slang_code_unit * self) { - slang_variable_scope_destruct (&self->vars); - slang_function_scope_destruct (&self->funs); - slang_struct_scope_destruct (&self->structs); + slang_variable_scope_destruct(&self->vars); + slang_function_scope_destruct(&self->funs); + slang_struct_scope_destruct(&self->structs); } /* @@ -78,296 +83,313 @@ _slang_code_unit_dtr (slang_code_unit *self) */ GLvoid -_slang_code_object_ctr (slang_code_object *self) +_slang_code_object_ctr(slang_code_object * self) { GLuint i; for (i = 0; i < SLANG_BUILTIN_TOTAL; i++) - _slang_code_unit_ctr (&self->builtin[i], self); - _slang_code_unit_ctr (&self->unit, self); - _slang_assembly_file_ctr (&self->assembly); - slang_machine_ctr (&self->machine); + _slang_code_unit_ctr(&self->builtin[i], self); + _slang_code_unit_ctr(&self->unit, self); + _slang_assembly_file_ctr(&self->assembly); + slang_machine_ctr(&self->machine); self->varpool.next_addr = 0; - slang_atom_pool_construct (&self->atompool); - slang_export_data_table_ctr (&self->expdata); + slang_atom_pool_construct(&self->atompool); + slang_export_data_table_ctr(&self->expdata); self->expdata.atoms = &self->atompool; - slang_export_code_table_ctr (&self->expcode); + slang_export_code_table_ctr(&self->expcode); self->expcode.atoms = &self->atompool; } GLvoid -_slang_code_object_dtr (slang_code_object *self) +_slang_code_object_dtr(slang_code_object * self) { GLuint i; for (i = 0; i < SLANG_BUILTIN_TOTAL; i++) - _slang_code_unit_dtr (&self->builtin[i]); - _slang_code_unit_dtr (&self->unit); - slang_assembly_file_destruct (&self->assembly); - slang_machine_dtr (&self->machine); - slang_atom_pool_destruct (&self->atompool); - slang_export_data_table_dtr (&self->expdata); - slang_export_code_table_ctr (&self->expcode); + _slang_code_unit_dtr(&self->builtin[i]); + _slang_code_unit_dtr(&self->unit); + slang_assembly_file_destruct(&self->assembly); + slang_machine_dtr(&self->machine); + slang_atom_pool_destruct(&self->atompool); + slang_export_data_table_dtr(&self->expdata); + slang_export_code_table_ctr(&self->expcode); } /* slang_info_log */ static char *out_of_memory = "Error: Out of memory.\n"; -void slang_info_log_construct (slang_info_log *log) +void +slang_info_log_construct(slang_info_log * log) { - log->text = NULL; - log->dont_free_text = 0; + log->text = NULL; + log->dont_free_text = 0; } -void slang_info_log_destruct (slang_info_log *log) +void +slang_info_log_destruct(slang_info_log * log) { - if (!log->dont_free_text) - slang_alloc_free (log->text); + if (!log->dont_free_text) + slang_alloc_free(log->text); } -static int slang_info_log_message (slang_info_log *log, const char *prefix, const char *msg) +static int +slang_info_log_message(slang_info_log * log, const char *prefix, + const char *msg) { GLuint size; - if (log->dont_free_text) - return 0; - size = slang_string_length (msg) + 2; + if (log->dont_free_text) + return 0; + size = slang_string_length(msg) + 2; if (prefix != NULL) - size += slang_string_length (prefix) + 2; + size += slang_string_length(prefix) + 2; if (log->text != NULL) { - GLuint old_len = slang_string_length (log->text); - log->text = (char *) (slang_alloc_realloc (log->text, old_len + 1, old_len + size)); + GLuint old_len = slang_string_length(log->text); + log->text = (char *) + slang_alloc_realloc(log->text, old_len + 1, old_len + size); } else { - log->text = (char *) (slang_alloc_malloc (size)); + log->text = (char *) (slang_alloc_malloc(size)); if (log->text != NULL) log->text[0] = '\0'; } - if (log->text == NULL) - return 0; + if (log->text == NULL) + return 0; if (prefix != NULL) { - slang_string_concat (log->text, prefix); - slang_string_concat (log->text, ": "); + slang_string_concat(log->text, prefix); + slang_string_concat(log->text, ": "); } - slang_string_concat (log->text, msg); - slang_string_concat (log->text, "\n"); - return 1; + slang_string_concat(log->text, msg); + slang_string_concat(log->text, "\n"); + return 1; } -int slang_info_log_print (slang_info_log *log, const char *msg, ...) +int +slang_info_log_print(slang_info_log * log, const char *msg, ...) { va_list va; char buf[1024]; - va_start (va, msg); - _mesa_vsprintf (buf, msg, va); - va_end (va); - return slang_info_log_message (log, NULL, buf); + va_start(va, msg); + _mesa_vsprintf(buf, msg, va); + va_end(va); + return slang_info_log_message(log, NULL, buf); } -int slang_info_log_error (slang_info_log *log, const char *msg, ...) +int +slang_info_log_error(slang_info_log * log, const char *msg, ...) { - va_list va; - char buf[1024]; - - va_start (va, msg); - _mesa_vsprintf (buf, msg, va); - va_end (va); - if (slang_info_log_message (log, "Error", buf)) - return 1; - slang_info_log_memory (log); - return 0; + va_list va; + char buf[1024]; + + va_start(va, msg); + _mesa_vsprintf(buf, msg, va); + va_end(va); + if (slang_info_log_message(log, "Error", buf)) + return 1; + slang_info_log_memory(log); + return 0; } -int slang_info_log_warning (slang_info_log *log, const char *msg, ...) +int +slang_info_log_warning(slang_info_log * log, const char *msg, ...) { - va_list va; - char buf[1024]; - - va_start (va, msg); - _mesa_vsprintf (buf, msg, va); - va_end (va); - if (slang_info_log_message (log, "Warning", buf)) - return 1; - slang_info_log_memory (log); - return 0; + va_list va; + char buf[1024]; + + va_start(va, msg); + _mesa_vsprintf(buf, msg, va); + va_end(va); + if (slang_info_log_message(log, "Warning", buf)) + return 1; + slang_info_log_memory(log); + return 0; } -void slang_info_log_memory (slang_info_log *log) +void +slang_info_log_memory(slang_info_log * log) { - if (!slang_info_log_message (log, "Error", "Out of memory.")) - { - log->dont_free_text = 1; - log->text = out_of_memory; - } + if (!slang_info_log_message(log, "Error", "Out of memory.")) { + log->dont_free_text = 1; + log->text = out_of_memory; + } } /* slang_parse_ctx */ typedef struct slang_parse_ctx_ { - const byte *I; - slang_info_log *L; - int parsing_builtin; - int global_scope; - slang_atom_pool *atoms; + const byte *I; + slang_info_log *L; + int parsing_builtin; + GLboolean global_scope; /**< Is object being declared a global? */ + slang_atom_pool *atoms; } slang_parse_ctx; /* slang_output_ctx */ typedef struct slang_output_ctx_ { - slang_variable_scope *vars; - slang_function_scope *funs; - slang_struct_scope *structs; - slang_assembly_file *assembly; - slang_var_pool *global_pool; - slang_machine *machine; + slang_variable_scope *vars; + slang_function_scope *funs; + slang_struct_scope *structs; + slang_assembly_file *assembly; + slang_var_pool *global_pool; + slang_machine *machine; } slang_output_ctx; /* _slang_compile() */ -static void parse_identifier_str (slang_parse_ctx *C, char **id) +static void +parse_identifier_str(slang_parse_ctx * C, char **id) { - *id = (char *) C->I; - C->I += _mesa_strlen (*id) + 1; + *id = (char *) C->I; + C->I += _mesa_strlen(*id) + 1; } -static slang_atom parse_identifier (slang_parse_ctx *C) +static slang_atom +parse_identifier(slang_parse_ctx * C) { - const char *id; - - id = (const char *) C->I; - C->I += _mesa_strlen (id) + 1; - return slang_atom_pool_atom (C->atoms, id); + const char *id; + + id = (const char *) C->I; + C->I += _mesa_strlen(id) + 1; + return slang_atom_pool_atom(C->atoms, id); } -static int parse_number (slang_parse_ctx *C, int *number) +static int +parse_number(slang_parse_ctx * C, int *number) { - const int radix = (int) (*C->I++); - *number = 0; - while (*C->I != '\0') - { - int digit; - if (*C->I >= '0' && *C->I <= '9') - digit = (int) (*C->I - '0'); - else if (*C->I >= 'A' && *C->I <= 'Z') - digit = (int) (*C->I - 'A') + 10; - else - digit = (int) (*C->I - 'a') + 10; - *number = *number * radix + digit; - C->I++; - } - C->I++; - if (*number > 65535) - slang_info_log_warning (C->L, "%d: literal integer overflow.", *number); - return 1; + const int radix = (int) (*C->I++); + *number = 0; + while (*C->I != '\0') { + int digit; + if (*C->I >= '0' && *C->I <= '9') + digit = (int) (*C->I - '0'); + else if (*C->I >= 'A' && *C->I <= 'Z') + digit = (int) (*C->I - 'A') + 10; + else + digit = (int) (*C->I - 'a') + 10; + *number = *number * radix + digit; + C->I++; + } + C->I++; + if (*number > 65535) + slang_info_log_warning(C->L, "%d: literal integer overflow.", *number); + return 1; } -static int parse_float (slang_parse_ctx *C, float *number) +static int +parse_float(slang_parse_ctx * C, float *number) { - char *integral = NULL; - char *fractional = NULL; - char *exponent = NULL; - char *whole = NULL; - - parse_identifier_str (C, &integral); - parse_identifier_str (C, &fractional); - parse_identifier_str (C, &exponent); - - whole = (char *) (slang_alloc_malloc ((_mesa_strlen (integral) + _mesa_strlen (fractional) + - _mesa_strlen (exponent) + 3) * sizeof (char))); - if (whole == NULL) - { - slang_info_log_memory (C->L); - return 0; - } - - slang_string_copy (whole, integral); - slang_string_concat (whole, "."); - slang_string_concat (whole, fractional); - slang_string_concat (whole, "E"); - slang_string_concat (whole, exponent); - - *number = (float) (_mesa_strtod(whole, (char **)NULL)); - - slang_alloc_free (whole); - return 1; + char *integral = NULL; + char *fractional = NULL; + char *exponent = NULL; + char *whole = NULL; + + parse_identifier_str(C, &integral); + parse_identifier_str(C, &fractional); + parse_identifier_str(C, &exponent); + + whole = (char *) (slang_alloc_malloc((_mesa_strlen(integral) + + _mesa_strlen(fractional) + + _mesa_strlen(exponent) + 3) * sizeof(char))); + if (whole == NULL) { + slang_info_log_memory(C->L); + return 0; + } + + slang_string_copy(whole, integral); + slang_string_concat(whole, "."); + slang_string_concat(whole, fractional); + slang_string_concat(whole, "E"); + slang_string_concat(whole, exponent); + + *number = (float) (_mesa_strtod(whole, (char **) NULL)); + + slang_alloc_free(whole); + return 1; } /* revision number - increment after each change affecting emitted output */ #define REVISION 3 -static int check_revision (slang_parse_ctx *C) +static int +check_revision(slang_parse_ctx * C) { - if (*C->I != REVISION) - { - slang_info_log_error (C->L, "Internal compiler error."); - return 0; - } - C->I++; - return 1; + if (*C->I != REVISION) { + slang_info_log_error(C->L, "Internal compiler error."); + return 0; + } + C->I++; + return 1; } -static int parse_statement (slang_parse_ctx *, slang_output_ctx *, slang_operation *); -static int parse_expression (slang_parse_ctx *, slang_output_ctx *, slang_operation *); -static int parse_type_specifier (slang_parse_ctx *, slang_output_ctx *, slang_type_specifier *); +static int parse_statement(slang_parse_ctx *, slang_output_ctx *, + slang_operation *); +static int parse_expression(slang_parse_ctx *, slang_output_ctx *, + slang_operation *); +static int parse_type_specifier(slang_parse_ctx *, slang_output_ctx *, + slang_type_specifier *); -static GLboolean parse_array_len (slang_parse_ctx *C, slang_output_ctx *O, GLuint *len) +static GLboolean +parse_array_len(slang_parse_ctx * C, slang_output_ctx * O, GLuint * len) { - slang_operation array_size; - slang_assembly_name_space space; - GLboolean result; - - if (!slang_operation_construct (&array_size)) - return GL_FALSE; - if (!parse_expression (C, O, &array_size)) - { - slang_operation_destruct (&array_size); - return GL_FALSE; - } - - space.funcs = O->funs; - space.structs = O->structs; - space.vars = O->vars; - result = _slang_evaluate_int (O->assembly, O->machine, &space, &array_size, len, C->atoms); - slang_operation_destruct (&array_size); - return result; + slang_operation array_size; + slang_assembly_name_space space; + GLboolean result; + + if (!slang_operation_construct(&array_size)) + return GL_FALSE; + if (!parse_expression(C, O, &array_size)) { + slang_operation_destruct(&array_size); + return GL_FALSE; + } + + space.funcs = O->funs; + space.structs = O->structs; + space.vars = O->vars; + result = _slang_evaluate_int(O->assembly, O->machine, &space, + &array_size, len, C->atoms); + slang_operation_destruct(&array_size); + return result; } -static GLboolean calculate_var_size (slang_parse_ctx *C, slang_output_ctx *O, slang_variable *var) +static GLboolean +calculate_var_size(slang_parse_ctx * C, slang_output_ctx * O, + slang_variable * var) { - slang_storage_aggregate agg; - - if (!slang_storage_aggregate_construct (&agg)) - return GL_FALSE; - if (!_slang_aggregate_variable (&agg, &var->type.specifier, var->array_len, O->funs, O->structs, - O->vars, O->machine, O->assembly, C->atoms)) - { - slang_storage_aggregate_destruct (&agg); - return GL_FALSE; - } - var->size = _slang_sizeof_aggregate (&agg); - slang_storage_aggregate_destruct (&agg); - return GL_TRUE; + slang_storage_aggregate agg; + + if (!slang_storage_aggregate_construct(&agg)) + return GL_FALSE; + if (!_slang_aggregate_variable(&agg, &var->type.specifier, var->array_len, + O->funs, O->structs, O->vars, O->machine, + O->assembly, C->atoms)) { + slang_storage_aggregate_destruct(&agg); + return GL_FALSE; + } + var->size = _slang_sizeof_aggregate(&agg); + slang_storage_aggregate_destruct(&agg); + return GL_TRUE; } -static GLboolean convert_to_array (slang_parse_ctx *C, slang_variable *var, - const slang_type_specifier *sp) +static GLboolean +convert_to_array(slang_parse_ctx * C, slang_variable * var, + const slang_type_specifier * sp) { - /* sized array - mark it as array, copy the specifier to the array element and - * parse the expression */ - var->type.specifier.type = slang_spec_array; - var->type.specifier._array = (slang_type_specifier *) slang_alloc_malloc (sizeof ( - slang_type_specifier)); - if (var->type.specifier._array == NULL) - { - slang_info_log_memory (C->L); - return GL_FALSE; - } - slang_type_specifier_ctr (var->type.specifier._array); - return slang_type_specifier_copy (var->type.specifier._array, sp); + /* sized array - mark it as array, copy the specifier to the array element and + * parse the expression */ + var->type.specifier.type = slang_spec_array; + var->type.specifier._array = (slang_type_specifier *) + slang_alloc_malloc(sizeof(slang_type_specifier)); + if (var->type.specifier._array == NULL) { + slang_info_log_memory(C->L); + return GL_FALSE; + } + slang_type_specifier_ctr(var->type.specifier._array); + return slang_type_specifier_copy(var->type.specifier._array, sp); } /* structure field */ @@ -375,136 +397,128 @@ static GLboolean convert_to_array (slang_parse_ctx *C, slang_variable *var, #define FIELD_NEXT 1 #define FIELD_ARRAY 2 -static GLboolean parse_struct_field_var (slang_parse_ctx *C, slang_output_ctx *O, slang_variable *var, - const slang_type_specifier *sp) +static GLboolean +parse_struct_field_var(slang_parse_ctx * C, slang_output_ctx * O, + slang_variable * var, const slang_type_specifier * sp) { - var->a_name = parse_identifier (C); - if (var->a_name == SLANG_ATOM_NULL) - return GL_FALSE; - - switch (*C->I++) - { - case FIELD_NONE: - if (!slang_type_specifier_copy (&var->type.specifier, sp)) - return GL_FALSE; - break; - case FIELD_ARRAY: - if (!convert_to_array (C, var, sp)) - return GL_FALSE; - if (!parse_array_len (C, O, &var->array_len)) - return GL_FALSE; - break; - default: - return GL_FALSE; - } - - return calculate_var_size (C, O, var); + var->a_name = parse_identifier(C); + if (var->a_name == SLANG_ATOM_NULL) + return GL_FALSE; + + switch (*C->I++) { + case FIELD_NONE: + if (!slang_type_specifier_copy(&var->type.specifier, sp)) + return GL_FALSE; + break; + case FIELD_ARRAY: + if (!convert_to_array(C, var, sp)) + return GL_FALSE; + if (!parse_array_len(C, O, &var->array_len)) + return GL_FALSE; + break; + default: + return GL_FALSE; + } + + return calculate_var_size(C, O, var); } -static int parse_struct_field (slang_parse_ctx *C, slang_output_ctx *O, slang_struct *st, - slang_type_specifier *sp) +static int +parse_struct_field(slang_parse_ctx * C, slang_output_ctx * O, + slang_struct * st, slang_type_specifier * sp) { - slang_output_ctx o = *O; - - o.structs = st->structs; - if (!parse_type_specifier (C, &o, sp)) - return 0; - do - { - slang_variable *var; - - st->fields->variables = (slang_variable *) slang_alloc_realloc (st->fields->variables, - st->fields->num_variables * sizeof (slang_variable), - (st->fields->num_variables + 1) * sizeof (slang_variable)); - if (st->fields->variables == NULL) - { - slang_info_log_memory (C->L); - return 0; - } - var = &st->fields->variables[st->fields->num_variables]; - if (!slang_variable_construct (var)) - return 0; - st->fields->num_variables++; - if (!parse_struct_field_var (C, &o, var, sp)) - return 0; - } - while (*C->I++ != FIELD_NONE); - - return 1; + slang_output_ctx o = *O; + + o.structs = st->structs; + if (!parse_type_specifier(C, &o, sp)) + return 0; + + do { + slang_variable *var = slang_variable_scope_grow(st->fields); + if (!var) { + slang_info_log_memory(C->L); + return 0; + } + if (!parse_struct_field_var(C, &o, var, sp)) + return 0; + } + while (*C->I++ != FIELD_NONE); + + return 1; } -static int parse_struct (slang_parse_ctx *C, slang_output_ctx *O, slang_struct **st) +static int +parse_struct(slang_parse_ctx * C, slang_output_ctx * O, slang_struct ** st) { - slang_atom a_name; - const char *name; - - /* parse struct name (if any) and make sure it is unique in current scope */ - a_name = parse_identifier (C); - if (a_name == SLANG_ATOM_NULL) - return 0; - name = slang_atom_pool_id (C->atoms, a_name); - if (name[0] != '\0' && slang_struct_scope_find (O->structs, a_name, 0) != NULL) - { - slang_info_log_error (C->L, "%s: duplicate type name.", name); - return 0; - } - - /* set-up a new struct */ - *st = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct)); - if (*st == NULL) - { - slang_info_log_memory (C->L); - return 0; - } - if (!slang_struct_construct (*st)) - { - slang_alloc_free (*st); - *st = NULL; - slang_info_log_memory (C->L); - return 0; - } - (**st).a_name = a_name; - (**st).structs->outer_scope = O->structs; - - /* parse individual struct fields */ - do - { - slang_type_specifier sp; - - slang_type_specifier_ctr (&sp); - if (!parse_struct_field (C, O, *st, &sp)) - { - slang_type_specifier_dtr (&sp); - return 0; - } - slang_type_specifier_dtr (&sp); - } - while (*C->I++ != FIELD_NONE); - - /* if named struct, copy it to current scope */ - if (name[0] != '\0') - { - slang_struct *s; - - O->structs->structs = (slang_struct *) slang_alloc_realloc (O->structs->structs, - O->structs->num_structs * sizeof (slang_struct), - (O->structs->num_structs + 1) * sizeof (slang_struct)); - if (O->structs->structs == NULL) - { - slang_info_log_memory (C->L); - return 0; - } - s = &O->structs->structs[O->structs->num_structs]; - if (!slang_struct_construct (s)) - return 0; - O->structs->num_structs++; - if (!slang_struct_copy (s, *st)) - return 0; - } - - return 1; + slang_atom a_name; + const char *name; + + /* parse struct name (if any) and make sure it is unique in current scope */ + a_name = parse_identifier(C); + if (a_name == SLANG_ATOM_NULL) + return 0; + + name = slang_atom_pool_id(C->atoms, a_name); + if (name[0] != '\0' + && slang_struct_scope_find(O->structs, a_name, 0) != NULL) { + slang_info_log_error(C->L, "%s: duplicate type name.", name); + return 0; + } + + /* set-up a new struct */ + *st = (slang_struct *) slang_alloc_malloc(sizeof(slang_struct)); + if (*st == NULL) { + slang_info_log_memory(C->L); + return 0; + } + if (!slang_struct_construct(*st)) { + slang_alloc_free(*st); + *st = NULL; + slang_info_log_memory(C->L); + return 0; + } + (**st).a_name = a_name; + (**st).structs->outer_scope = O->structs; + + /* parse individual struct fields */ + do { + slang_type_specifier sp; + + slang_type_specifier_ctr(&sp); + if (!parse_struct_field(C, O, *st, &sp)) { + slang_type_specifier_dtr(&sp); + return 0; + } + slang_type_specifier_dtr(&sp); + } + while (*C->I++ != FIELD_NONE); + + /* if named struct, copy it to current scope */ + if (name[0] != '\0') { + slang_struct *s; + + O->structs->structs = + (slang_struct *) slang_alloc_realloc(O->structs->structs, + O->structs->num_structs * + sizeof(slang_struct), + (O->structs->num_structs + + 1) * sizeof(slang_struct)); + if (O->structs->structs == NULL) { + slang_info_log_memory(C->L); + return 0; + } + s = &O->structs->structs[O->structs->num_structs]; + if (!slang_struct_construct(s)) + return 0; + O->structs->num_structs++; + if (!slang_struct_copy(s, *st)) + return 0; + } + + return 1; } + /* type qualifier */ #define TYPE_QUALIFIER_NONE 0 #define TYPE_QUALIFIER_CONST 1 @@ -514,35 +528,35 @@ static int parse_struct (slang_parse_ctx *C, slang_output_ctx *O, slang_struct * #define TYPE_QUALIFIER_FIXEDOUTPUT 5 #define TYPE_QUALIFIER_FIXEDINPUT 6 -static int parse_type_qualifier (slang_parse_ctx *C, slang_type_qualifier *qual) +static int +parse_type_qualifier(slang_parse_ctx * C, slang_type_qualifier * qual) { - switch (*C->I++) - { - case TYPE_QUALIFIER_NONE: - *qual = slang_qual_none; - break; - case TYPE_QUALIFIER_CONST: - *qual = slang_qual_const; - break; - case TYPE_QUALIFIER_ATTRIBUTE: - *qual = slang_qual_attribute; - break; - case TYPE_QUALIFIER_VARYING: - *qual = slang_qual_varying; - break; - case TYPE_QUALIFIER_UNIFORM: - *qual = slang_qual_uniform; - break; - case TYPE_QUALIFIER_FIXEDOUTPUT: - *qual = slang_qual_fixedoutput; - break; - case TYPE_QUALIFIER_FIXEDINPUT: - *qual = slang_qual_fixedinput; - break; - default: - return 0; - } - return 1; + switch (*C->I++) { + case TYPE_QUALIFIER_NONE: + *qual = slang_qual_none; + break; + case TYPE_QUALIFIER_CONST: + *qual = slang_qual_const; + break; + case TYPE_QUALIFIER_ATTRIBUTE: + *qual = slang_qual_attribute; + break; + case TYPE_QUALIFIER_VARYING: + *qual = slang_qual_varying; + break; + case TYPE_QUALIFIER_UNIFORM: + *qual = slang_qual_uniform; + break; + case TYPE_QUALIFIER_FIXEDOUTPUT: + *qual = slang_qual_fixedoutput; + break; + case TYPE_QUALIFIER_FIXEDINPUT: + *qual = slang_qual_fixedinput; + break; + default: + return 0; + } + return 1; } /* type specifier */ @@ -571,127 +585,127 @@ static int parse_type_qualifier (slang_parse_ctx *C, slang_type_qualifier *qual) #define TYPE_SPECIFIER_STRUCT 22 #define TYPE_SPECIFIER_TYPENAME 23 -static int parse_type_specifier (slang_parse_ctx *C, slang_output_ctx *O, slang_type_specifier *spec) +static int +parse_type_specifier(slang_parse_ctx * C, slang_output_ctx * O, + slang_type_specifier * spec) { - switch (*C->I++) - { - case TYPE_SPECIFIER_VOID: - spec->type = slang_spec_void; - break; - case TYPE_SPECIFIER_BOOL: - spec->type = slang_spec_bool; - break; - case TYPE_SPECIFIER_BVEC2: - spec->type = slang_spec_bvec2; - break; - case TYPE_SPECIFIER_BVEC3: - spec->type = slang_spec_bvec3; - break; - case TYPE_SPECIFIER_BVEC4: - spec->type = slang_spec_bvec4; - break; - case TYPE_SPECIFIER_INT: - spec->type = slang_spec_int; - break; - case TYPE_SPECIFIER_IVEC2: - spec->type = slang_spec_ivec2; - break; - case TYPE_SPECIFIER_IVEC3: - spec->type = slang_spec_ivec3; - break; - case TYPE_SPECIFIER_IVEC4: - spec->type = slang_spec_ivec4; - break; - case TYPE_SPECIFIER_FLOAT: - spec->type = slang_spec_float; - break; - case TYPE_SPECIFIER_VEC2: - spec->type = slang_spec_vec2; - break; - case TYPE_SPECIFIER_VEC3: - spec->type = slang_spec_vec3; - break; - case TYPE_SPECIFIER_VEC4: - spec->type = slang_spec_vec4; - break; - case TYPE_SPECIFIER_MAT2: - spec->type = slang_spec_mat2; - break; - case TYPE_SPECIFIER_MAT3: - spec->type = slang_spec_mat3; - break; - case TYPE_SPECIFIER_MAT4: - spec->type = slang_spec_mat4; - break; - case TYPE_SPECIFIER_SAMPLER1D: - spec->type = slang_spec_sampler1D; - break; - case TYPE_SPECIFIER_SAMPLER2D: - spec->type = slang_spec_sampler2D; - break; - case TYPE_SPECIFIER_SAMPLER3D: - spec->type = slang_spec_sampler3D; - break; - case TYPE_SPECIFIER_SAMPLERCUBE: - spec->type = slang_spec_samplerCube; - break; - case TYPE_SPECIFIER_SAMPLER1DSHADOW: - spec->type = slang_spec_sampler1DShadow; - break; - case TYPE_SPECIFIER_SAMPLER2DSHADOW: - spec->type = slang_spec_sampler2DShadow; - break; - case TYPE_SPECIFIER_STRUCT: - spec->type = slang_spec_struct; - if (!parse_struct (C, O, &spec->_struct)) - return 0; - break; - case TYPE_SPECIFIER_TYPENAME: - spec->type = slang_spec_struct; - { - slang_atom a_name; - slang_struct *stru; - - a_name = parse_identifier (C); - if (a_name == NULL) - return 0; - - stru = slang_struct_scope_find (O->structs, a_name, 1); - if (stru == NULL) - { - slang_info_log_error (C->L, "%s: undeclared type name.", - slang_atom_pool_id (C->atoms, a_name)); - return 0; - } - - spec->_struct = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct)); - if (spec->_struct == NULL) - { - slang_info_log_memory (C->L); - return 0; - } - if (!slang_struct_construct (spec->_struct)) - { - slang_alloc_free (spec->_struct); - spec->_struct = NULL; - return 0; - } - if (!slang_struct_copy (spec->_struct, stru)) - return 0; - } - break; - default: - return 0; - } - return 1; + switch (*C->I++) { + case TYPE_SPECIFIER_VOID: + spec->type = slang_spec_void; + break; + case TYPE_SPECIFIER_BOOL: + spec->type = slang_spec_bool; + break; + case TYPE_SPECIFIER_BVEC2: + spec->type = slang_spec_bvec2; + break; + case TYPE_SPECIFIER_BVEC3: + spec->type = slang_spec_bvec3; + break; + case TYPE_SPECIFIER_BVEC4: + spec->type = slang_spec_bvec4; + break; + case TYPE_SPECIFIER_INT: + spec->type = slang_spec_int; + break; + case TYPE_SPECIFIER_IVEC2: + spec->type = slang_spec_ivec2; + break; + case TYPE_SPECIFIER_IVEC3: + spec->type = slang_spec_ivec3; + break; + case TYPE_SPECIFIER_IVEC4: + spec->type = slang_spec_ivec4; + break; + case TYPE_SPECIFIER_FLOAT: + spec->type = slang_spec_float; + break; + case TYPE_SPECIFIER_VEC2: + spec->type = slang_spec_vec2; + break; + case TYPE_SPECIFIER_VEC3: + spec->type = slang_spec_vec3; + break; + case TYPE_SPECIFIER_VEC4: + spec->type = slang_spec_vec4; + break; + case TYPE_SPECIFIER_MAT2: + spec->type = slang_spec_mat2; + break; + case TYPE_SPECIFIER_MAT3: + spec->type = slang_spec_mat3; + break; + case TYPE_SPECIFIER_MAT4: + spec->type = slang_spec_mat4; + break; + case TYPE_SPECIFIER_SAMPLER1D: + spec->type = slang_spec_sampler1D; + break; + case TYPE_SPECIFIER_SAMPLER2D: + spec->type = slang_spec_sampler2D; + break; + case TYPE_SPECIFIER_SAMPLER3D: + spec->type = slang_spec_sampler3D; + break; + case TYPE_SPECIFIER_SAMPLERCUBE: + spec->type = slang_spec_samplerCube; + break; + case TYPE_SPECIFIER_SAMPLER1DSHADOW: + spec->type = slang_spec_sampler1DShadow; + break; + case TYPE_SPECIFIER_SAMPLER2DSHADOW: + spec->type = slang_spec_sampler2DShadow; + break; + case TYPE_SPECIFIER_STRUCT: + spec->type = slang_spec_struct; + if (!parse_struct(C, O, &spec->_struct)) + return 0; + break; + case TYPE_SPECIFIER_TYPENAME: + spec->type = slang_spec_struct; + { + slang_atom a_name; + slang_struct *stru; + + a_name = parse_identifier(C); + if (a_name == NULL) + return 0; + + stru = slang_struct_scope_find(O->structs, a_name, 1); + if (stru == NULL) { + slang_info_log_error(C->L, "%s: undeclared type name.", + slang_atom_pool_id(C->atoms, a_name)); + return 0; + } + + spec->_struct = + (slang_struct *) slang_alloc_malloc(sizeof(slang_struct)); + if (spec->_struct == NULL) { + slang_info_log_memory(C->L); + return 0; + } + if (!slang_struct_construct(spec->_struct)) { + slang_alloc_free(spec->_struct); + spec->_struct = NULL; + return 0; + } + if (!slang_struct_copy(spec->_struct, stru)) + return 0; + } + break; + default: + return 0; + } + return 1; } -static int parse_fully_specified_type (slang_parse_ctx *C, slang_output_ctx *O, - slang_fully_specified_type *type) +static int +parse_fully_specified_type(slang_parse_ctx * C, slang_output_ctx * O, + slang_fully_specified_type * type) { - if (!parse_type_qualifier (C, &type->qualifier)) - return 0; - return parse_type_specifier (C, O, &type->specifier); + if (!parse_type_qualifier(C, &type->qualifier)) + return 0; + return parse_type_specifier(C, O, &type->specifier); } /* operation */ @@ -758,459 +772,487 @@ static int parse_fully_specified_type (slang_parse_ctx *C, slang_output_ctx *O, #define OP_POSTINCREMENT 60 #define OP_POSTDECREMENT 61 -static int parse_child_operation (slang_parse_ctx *C, slang_output_ctx *O, slang_operation *oper, - int statement) + +/** + * When parsing a compound production, this function is used to parse the + * children. + * For example, a a while-loop compound will have two children, the + * while condition expression and the loop body. So, this function will + * be called twice to parse those two sub-expressions. + * \param C the parsing context + * \param O the output context + * \param oper the operation we're parsing + * \param statment which child of the operation is being parsed + * \return 1 if success, 0 if error + */ +static int +parse_child_operation(slang_parse_ctx * C, slang_output_ctx * O, + slang_operation * oper, unsigned int statement) { - slang_operation *ch; - - oper->children = (slang_operation *) slang_alloc_realloc (oper->children, - oper->num_children * sizeof (slang_operation), - (oper->num_children + 1) * sizeof (slang_operation)); - if (oper->children == NULL) - { - slang_info_log_memory (C->L); - return 0; - } - ch = &oper->children[oper->num_children]; - if (!slang_operation_construct (ch)) - { - slang_info_log_memory (C->L); - return 0; - } - oper->num_children++; - if (statement) - return parse_statement (C, O, ch); - return parse_expression (C, O, ch); + slang_operation *ch; + + /* grow child array */ + oper->children = (slang_operation *) + slang_alloc_realloc(oper->children, + oper->num_children * sizeof(slang_operation), + (oper->num_children + 1) * sizeof(slang_operation)); + if (oper->children == NULL) { + slang_info_log_memory(C->L); + return 0; + } + + ch = &oper->children[oper->num_children]; + if (!slang_operation_construct(ch)) { + slang_info_log_memory(C->L); + return 0; + } + oper->num_children++; + /* XXX I guess the 0th "statement" is not really a statement? */ + if (statement) + return parse_statement(C, O, ch); + return parse_expression(C, O, ch); } -static int parse_declaration (slang_parse_ctx *C, slang_output_ctx *O); +static int parse_declaration(slang_parse_ctx * C, slang_output_ctx * O); -static int parse_statement (slang_parse_ctx *C, slang_output_ctx *O, slang_operation *oper) +static int +parse_statement(slang_parse_ctx * C, slang_output_ctx * O, + slang_operation * oper) { - oper->locals->outer_scope = O->vars; - switch (*C->I++) - { - case OP_BLOCK_BEGIN_NO_NEW_SCOPE: - /* parse child statements, do not create new variable scope */ - oper->type = slang_oper_block_no_new_scope; - while (*C->I != OP_END) - if (!parse_child_operation (C, O, oper, 1)) - return 0; - C->I++; - break; - case OP_BLOCK_BEGIN_NEW_SCOPE: - /* parse child statements, create new variable scope */ - { - slang_output_ctx o = *O; - - oper->type = slang_oper_block_new_scope; - o.vars = oper->locals; - while (*C->I != OP_END) - if (!parse_child_operation (C, &o, oper, 1)) - return 0; - C->I++; - } - break; - case OP_DECLARE: - /* local variable declaration, individual declarators are stored as children identifiers */ - oper->type = slang_oper_variable_decl; - { - const unsigned int first_var = O->vars->num_variables; - - /* parse the declaration, note that there can be zero or more than one declarators */ - if (!parse_declaration (C, O)) - return 0; - if (first_var < O->vars->num_variables) - { - const unsigned int num_vars = O->vars->num_variables - first_var; - unsigned int i; - - oper->children = (slang_operation *) slang_alloc_malloc (num_vars * sizeof ( - slang_operation)); - if (oper->children == NULL) - { - slang_info_log_memory (C->L); - return 0; - } - for (oper->num_children = 0; oper->num_children < num_vars; oper->num_children++) - if (!slang_operation_construct (&oper->children[oper->num_children])) - { - slang_info_log_memory (C->L); - return 0; - } - for (i = first_var; i < O->vars->num_variables; i++) - { - slang_operation *o = &oper->children[i - first_var]; - - o->type = slang_oper_identifier; - o->locals->outer_scope = O->vars; - o->a_id = O->vars->variables[i].a_name; - } - } - } - break; - case OP_ASM: - /* the __asm statement, parse the mnemonic and all its arguments as expressions */ - oper->type = slang_oper_asm; - oper->a_id = parse_identifier (C); - if (oper->a_id == SLANG_ATOM_NULL) - return 0; - while (*C->I != OP_END) - if (!parse_child_operation (C, O, oper, 0)) - return 0; - C->I++; - break; - case OP_BREAK: - oper->type = slang_oper_break; - break; - case OP_CONTINUE: - oper->type = slang_oper_continue; - break; - case OP_DISCARD: - oper->type = slang_oper_discard; - break; - case OP_RETURN: - oper->type = slang_oper_return; - if (!parse_child_operation (C, O, oper, 0)) - return 0; - break; - case OP_EXPRESSION: - oper->type = slang_oper_expression; - if (!parse_child_operation (C, O, oper, 0)) - return 0; - break; - case OP_IF: - oper->type = slang_oper_if; - if (!parse_child_operation (C, O, oper, 0)) - return 0; - if (!parse_child_operation (C, O, oper, 1)) - return 0; - if (!parse_child_operation (C, O, oper, 1)) - return 0; - break; - case OP_WHILE: - { - slang_output_ctx o = *O; - - oper->type = slang_oper_while; - o.vars = oper->locals; - if (!parse_child_operation (C, &o, oper, 1)) - return 0; - if (!parse_child_operation (C, &o, oper, 1)) - return 0; - } - break; - case OP_DO: - oper->type = slang_oper_do; - if (!parse_child_operation (C, O, oper, 1)) - return 0; - if (!parse_child_operation (C, O, oper, 0)) - return 0; - break; - case OP_FOR: - { - slang_output_ctx o = *O; - - oper->type = slang_oper_for; - o.vars = oper->locals; - if (!parse_child_operation (C, &o, oper, 1)) - return 0; - if (!parse_child_operation (C, &o, oper, 1)) - return 0; - if (!parse_child_operation (C, &o, oper, 0)) - return 0; - if (!parse_child_operation (C, &o, oper, 1)) - return 0; - } - break; - default: - return 0; - } - return 1; + oper->locals->outer_scope = O->vars; + switch (*C->I++) { + case OP_BLOCK_BEGIN_NO_NEW_SCOPE: + /* parse child statements, do not create new variable scope */ + oper->type = slang_oper_block_no_new_scope; + while (*C->I != OP_END) + if (!parse_child_operation(C, O, oper, 1)) + return 0; + C->I++; + break; + case OP_BLOCK_BEGIN_NEW_SCOPE: + /* parse child statements, create new variable scope */ + { + slang_output_ctx o = *O; + + oper->type = slang_oper_block_new_scope; + o.vars = oper->locals; + while (*C->I != OP_END) + if (!parse_child_operation(C, &o, oper, 1)) + return 0; + C->I++; + } + break; + case OP_DECLARE: + /* local variable declaration, individual declarators are stored as + * children identifiers + */ + oper->type = slang_oper_variable_decl; + { + const unsigned int first_var = O->vars->num_variables; + + /* parse the declaration, note that there can be zero or more + * than one declarators + */ + if (!parse_declaration(C, O)) + return 0; + if (first_var < O->vars->num_variables) { + const unsigned int num_vars = O->vars->num_variables - first_var; + unsigned int i; + + oper->children = (slang_operation *) + slang_alloc_malloc(num_vars * sizeof(slang_operation)); + if (oper->children == NULL) { + slang_info_log_memory(C->L); + return 0; + } + for (oper->num_children = 0; oper->num_children < num_vars; + oper->num_children++) { + if (!slang_operation_construct + (&oper->children[oper->num_children])) { + slang_info_log_memory(C->L); + return 0; + } + } + for (i = first_var; i < O->vars->num_variables; i++) { + slang_operation *o = &oper->children[i - first_var]; + o->type = slang_oper_identifier; + o->locals->outer_scope = O->vars; + o->a_id = O->vars->variables[i].a_name; + } + } + } + break; + case OP_ASM: + /* the __asm statement, parse the mnemonic and all its arguments + * as expressions + */ + oper->type = slang_oper_asm; + oper->a_id = parse_identifier(C); + if (oper->a_id == SLANG_ATOM_NULL) + return 0; + while (*C->I != OP_END) { + if (!parse_child_operation(C, O, oper, 0)) + return 0; + } + C->I++; + break; + case OP_BREAK: + oper->type = slang_oper_break; + break; + case OP_CONTINUE: + oper->type = slang_oper_continue; + break; + case OP_DISCARD: + oper->type = slang_oper_discard; + break; + case OP_RETURN: + oper->type = slang_oper_return; + if (!parse_child_operation(C, O, oper, 0)) + return 0; + break; + case OP_EXPRESSION: + oper->type = slang_oper_expression; + if (!parse_child_operation(C, O, oper, 0)) + return 0; + break; + case OP_IF: + oper->type = slang_oper_if; + if (!parse_child_operation(C, O, oper, 0)) + return 0; + if (!parse_child_operation(C, O, oper, 1)) + return 0; + if (!parse_child_operation(C, O, oper, 1)) + return 0; + break; + case OP_WHILE: + { + slang_output_ctx o = *O; + + oper->type = slang_oper_while; + o.vars = oper->locals; + if (!parse_child_operation(C, &o, oper, 1)) + return 0; + if (!parse_child_operation(C, &o, oper, 1)) + return 0; + } + break; + case OP_DO: + oper->type = slang_oper_do; + if (!parse_child_operation(C, O, oper, 1)) + return 0; + if (!parse_child_operation(C, O, oper, 0)) + return 0; + break; + case OP_FOR: + { + slang_output_ctx o = *O; + + oper->type = slang_oper_for; + o.vars = oper->locals; + if (!parse_child_operation(C, &o, oper, 1)) + return 0; + if (!parse_child_operation(C, &o, oper, 1)) + return 0; + if (!parse_child_operation(C, &o, oper, 0)) + return 0; + if (!parse_child_operation(C, &o, oper, 1)) + return 0; + } + break; + default: + return 0; + } + return 1; } -static int handle_nary_expression (slang_parse_ctx *C, slang_operation *op, slang_operation **ops, - unsigned int *total_ops, unsigned int n) +static int +handle_nary_expression(slang_parse_ctx * C, slang_operation * op, + slang_operation ** ops, unsigned int *total_ops, + unsigned int n) { - unsigned int i; - - op->children = (slang_operation *) slang_alloc_malloc (n * sizeof (slang_operation)); - if (op->children == NULL) - { - slang_info_log_memory (C->L); - return 0; - } - op->num_children = n; - - for (i = 0; i < n; i++) - op->children[i] = (*ops)[*total_ops - (n + 1 - i)]; - (*ops)[*total_ops - (n + 1)] = (*ops)[*total_ops - 1]; - *total_ops -= n; - - *ops = (slang_operation *) slang_alloc_realloc (*ops, (*total_ops + n) * sizeof (slang_operation), - *total_ops * sizeof (slang_operation)); - if (*ops == NULL) - { - slang_info_log_memory (C->L); - return 0; - } - return 1; + unsigned int i; + + op->children = + (slang_operation *) slang_alloc_malloc(n * sizeof(slang_operation)); + if (op->children == NULL) { + slang_info_log_memory(C->L); + return 0; + } + op->num_children = n; + + for (i = 0; i < n; i++) + op->children[i] = (*ops)[*total_ops - (n + 1 - i)]; + (*ops)[*total_ops - (n + 1)] = (*ops)[*total_ops - 1]; + *total_ops -= n; + + *ops = (slang_operation *) + slang_alloc_realloc(*ops, + (*total_ops + n) * sizeof(slang_operation), + *total_ops * sizeof(slang_operation)); + if (*ops == NULL) { + slang_info_log_memory(C->L); + return 0; + } + return 1; } -static int is_constructor_name (const char *name, slang_atom a_name, slang_struct_scope *structs) +static int +is_constructor_name(const char *name, slang_atom a_name, + slang_struct_scope * structs) { - if (slang_type_specifier_type_from_string (name) != slang_spec_void) - return 1; - return slang_struct_scope_find (structs, a_name, 1) != NULL; + if (slang_type_specifier_type_from_string(name) != slang_spec_void) + return 1; + return slang_struct_scope_find(structs, a_name, 1) != NULL; } -static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_operation *oper) +static int +parse_expression(slang_parse_ctx * C, slang_output_ctx * O, + slang_operation * oper) { - slang_operation *ops = NULL; - unsigned int num_ops = 0; - int number; - - while (*C->I != OP_END) - { - slang_operation *op; - const unsigned int op_code = *C->I++; - - /* allocate default operation, becomes a no-op if not used */ - ops = (slang_operation *) slang_alloc_realloc (ops, - num_ops * sizeof (slang_operation), (num_ops + 1) * sizeof (slang_operation)); - if (ops == NULL) - { - slang_info_log_memory (C->L); - return 0; - } - op = &ops[num_ops]; - if (!slang_operation_construct (op)) - { - slang_info_log_memory (C->L); - return 0; - } - num_ops++; - op->locals->outer_scope = O->vars; - - switch (op_code) - { - case OP_PUSH_VOID: - op->type = slang_oper_void; - break; - case OP_PUSH_BOOL: - op->type = slang_oper_literal_bool; - if (!parse_number (C, &number)) - return 0; - op->literal = (GLfloat) number; - break; - case OP_PUSH_INT: - op->type = slang_oper_literal_int; - if (!parse_number (C, &number)) - return 0; - op->literal = (GLfloat) number; - break; - case OP_PUSH_FLOAT: - op->type = slang_oper_literal_float; - if (!parse_float (C, &op->literal)) - return 0; - break; - case OP_PUSH_IDENTIFIER: - op->type = slang_oper_identifier; - op->a_id = parse_identifier (C); - if (op->a_id == SLANG_ATOM_NULL) - return 0; - break; - case OP_SEQUENCE: - op->type = slang_oper_sequence; - if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) - return 0; - break; - case OP_ASSIGN: - op->type = slang_oper_assign; - if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) - return 0; - break; - case OP_ADDASSIGN: - op->type = slang_oper_addassign; - if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) - return 0; - break; - case OP_SUBASSIGN: - op->type = slang_oper_subassign; - if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) - return 0; - break; - case OP_MULASSIGN: - op->type = slang_oper_mulassign; - if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) - return 0; - break; - case OP_DIVASSIGN: - op->type = slang_oper_divassign; - if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) - return 0; - break; - /*case OP_MODASSIGN:*/ - /*case OP_LSHASSIGN:*/ - /*case OP_RSHASSIGN:*/ - /*case OP_ORASSIGN:*/ - /*case OP_XORASSIGN:*/ - /*case OP_ANDASSIGN:*/ - case OP_SELECT: - op->type = slang_oper_select; - if (!handle_nary_expression (C, op, &ops, &num_ops, 3)) - return 0; - break; - case OP_LOGICALOR: - op->type = slang_oper_logicalor; - if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) - return 0; - break; - case OP_LOGICALXOR: - op->type = slang_oper_logicalxor; - if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) - return 0; - break; - case OP_LOGICALAND: - op->type = slang_oper_logicaland; - if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) - return 0; - break; - /*case OP_BITOR:*/ - /*case OP_BITXOR:*/ - /*case OP_BITAND:*/ - case OP_EQUAL: - op->type = slang_oper_equal; - if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) - return 0; - break; - case OP_NOTEQUAL: - op->type = slang_oper_notequal; - if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) - return 0; - break; - case OP_LESS: - op->type = slang_oper_less; - if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) - return 0; - break; - case OP_GREATER: - op->type = slang_oper_greater; - if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) - return 0; - break; - case OP_LESSEQUAL: - op->type = slang_oper_lessequal; - if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) - return 0; - break; - case OP_GREATEREQUAL: - op->type = slang_oper_greaterequal; - if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) - return 0; - break; - /*case OP_LSHIFT:*/ - /*case OP_RSHIFT:*/ - case OP_ADD: - op->type = slang_oper_add; - if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) - return 0; - break; - case OP_SUBTRACT: - op->type = slang_oper_subtract; - if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) - return 0; - break; - case OP_MULTIPLY: - op->type = slang_oper_multiply; - if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) - return 0; - break; - case OP_DIVIDE: - op->type = slang_oper_divide; - if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) - return 0; - break; - /*case OP_MODULUS:*/ - case OP_PREINCREMENT: - op->type = slang_oper_preincrement; - if (!handle_nary_expression (C, op, &ops, &num_ops, 1)) - return 0; - break; - case OP_PREDECREMENT: - op->type = slang_oper_predecrement; - if (!handle_nary_expression (C, op, &ops, &num_ops, 1)) - return 0; - break; - case OP_PLUS: - op->type = slang_oper_plus; - if (!handle_nary_expression (C, op, &ops, &num_ops, 1)) - return 0; - break; - case OP_MINUS: - op->type = slang_oper_minus; - if (!handle_nary_expression (C, op, &ops, &num_ops, 1)) - return 0; - break; - case OP_NOT: - op->type = slang_oper_not; - if (!handle_nary_expression (C, op, &ops, &num_ops, 1)) - return 0; - break; - /*case OP_COMPLEMENT:*/ - case OP_SUBSCRIPT: - op->type = slang_oper_subscript; - if (!handle_nary_expression (C, op, &ops, &num_ops, 2)) - return 0; - break; - case OP_CALL: - op->type = slang_oper_call; - op->a_id = parse_identifier (C); - if (op->a_id == SLANG_ATOM_NULL) - return 0; - while (*C->I != OP_END) - if (!parse_child_operation (C, O, op, 0)) - return 0; - C->I++; - if (!C->parsing_builtin && !slang_function_scope_find_by_name (O->funs, op->a_id, 1)) - { - const char *id; - - id = slang_atom_pool_id (C->atoms, op->a_id); - if (!is_constructor_name (id, op->a_id, O->structs)) - { - slang_info_log_error (C->L, "%s: undeclared function name.", id); - return 0; - } - } - break; - case OP_FIELD: - op->type = slang_oper_field; - op->a_id = parse_identifier (C); - if (op->a_id == SLANG_ATOM_NULL) - return 0; - if (!handle_nary_expression (C, op, &ops, &num_ops, 1)) - return 0; - break; - case OP_POSTINCREMENT: - op->type = slang_oper_postincrement; - if (!handle_nary_expression (C, op, &ops, &num_ops, 1)) - return 0; - break; - case OP_POSTDECREMENT: - op->type = slang_oper_postdecrement; - if (!handle_nary_expression (C, op, &ops, &num_ops, 1)) - return 0; - break; - default: - return 0; - } - } - C->I++; - - *oper = *ops; - slang_alloc_free (ops); - return 1; + slang_operation *ops = NULL; + unsigned int num_ops = 0; + int number; + + while (*C->I != OP_END) { + slang_operation *op; + const unsigned int op_code = *C->I++; + + /* allocate default operation, becomes a no-op if not used */ + ops = (slang_operation *) + slang_alloc_realloc(ops, + num_ops * sizeof(slang_operation), + (num_ops + 1) * sizeof(slang_operation)); + if (ops == NULL) { + slang_info_log_memory(C->L); + return 0; + } + op = &ops[num_ops]; + if (!slang_operation_construct(op)) { + slang_info_log_memory(C->L); + return 0; + } + num_ops++; + op->locals->outer_scope = O->vars; + + switch (op_code) { + case OP_PUSH_VOID: + op->type = slang_oper_void; + break; + case OP_PUSH_BOOL: + op->type = slang_oper_literal_bool; + if (!parse_number(C, &number)) + return 0; + op->literal = (GLfloat) number; + break; + case OP_PUSH_INT: + op->type = slang_oper_literal_int; + if (!parse_number(C, &number)) + return 0; + op->literal = (GLfloat) number; + break; + case OP_PUSH_FLOAT: + op->type = slang_oper_literal_float; + if (!parse_float(C, &op->literal)) + return 0; + break; + case OP_PUSH_IDENTIFIER: + op->type = slang_oper_identifier; + op->a_id = parse_identifier(C); + if (op->a_id == SLANG_ATOM_NULL) + return 0; + break; + case OP_SEQUENCE: + op->type = slang_oper_sequence; + if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) + return 0; + break; + case OP_ASSIGN: + op->type = slang_oper_assign; + if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) + return 0; + break; + case OP_ADDASSIGN: + op->type = slang_oper_addassign; + if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) + return 0; + break; + case OP_SUBASSIGN: + op->type = slang_oper_subassign; + if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) + return 0; + break; + case OP_MULASSIGN: + op->type = slang_oper_mulassign; + if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) + return 0; + break; + case OP_DIVASSIGN: + op->type = slang_oper_divassign; + if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) + return 0; + break; + /*case OP_MODASSIGN: */ + /*case OP_LSHASSIGN: */ + /*case OP_RSHASSIGN: */ + /*case OP_ORASSIGN: */ + /*case OP_XORASSIGN: */ + /*case OP_ANDASSIGN: */ + case OP_SELECT: + op->type = slang_oper_select; + if (!handle_nary_expression(C, op, &ops, &num_ops, 3)) + return 0; + break; + case OP_LOGICALOR: + op->type = slang_oper_logicalor; + if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) + return 0; + break; + case OP_LOGICALXOR: + op->type = slang_oper_logicalxor; + if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) + return 0; + break; + case OP_LOGICALAND: + op->type = slang_oper_logicaland; + if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) + return 0; + break; + /*case OP_BITOR: */ + /*case OP_BITXOR: */ + /*case OP_BITAND: */ + case OP_EQUAL: + op->type = slang_oper_equal; + if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) + return 0; + break; + case OP_NOTEQUAL: + op->type = slang_oper_notequal; + if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) + return 0; + break; + case OP_LESS: + op->type = slang_oper_less; + if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) + return 0; + break; + case OP_GREATER: + op->type = slang_oper_greater; + if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) + return 0; + break; + case OP_LESSEQUAL: + op->type = slang_oper_lessequal; + if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) + return 0; + break; + case OP_GREATEREQUAL: + op->type = slang_oper_greaterequal; + if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) + return 0; + break; + /*case OP_LSHIFT: */ + /*case OP_RSHIFT: */ + case OP_ADD: + op->type = slang_oper_add; + if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) + return 0; + break; + case OP_SUBTRACT: + op->type = slang_oper_subtract; + if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) + return 0; + break; + case OP_MULTIPLY: + op->type = slang_oper_multiply; + if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) + return 0; + break; + case OP_DIVIDE: + op->type = slang_oper_divide; + if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) + return 0; + break; + /*case OP_MODULUS: */ + case OP_PREINCREMENT: + op->type = slang_oper_preincrement; + if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) + return 0; + break; + case OP_PREDECREMENT: + op->type = slang_oper_predecrement; + if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) + return 0; + break; + case OP_PLUS: + op->type = slang_oper_plus; + if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) + return 0; + break; + case OP_MINUS: + op->type = slang_oper_minus; + if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) + return 0; + break; + case OP_NOT: + op->type = slang_oper_not; + if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) + return 0; + break; + /*case OP_COMPLEMENT: */ + case OP_SUBSCRIPT: + op->type = slang_oper_subscript; + if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) + return 0; + break; + case OP_CALL: + op->type = slang_oper_call; + op->a_id = parse_identifier(C); + if (op->a_id == SLANG_ATOM_NULL) + return 0; + while (*C->I != OP_END) + if (!parse_child_operation(C, O, op, 0)) + return 0; + C->I++; + + if (!C->parsing_builtin + && !slang_function_scope_find_by_name(O->funs, op->a_id, 1)) { + const char *id; + + id = slang_atom_pool_id(C->atoms, op->a_id); + if (!is_constructor_name(id, op->a_id, O->structs)) { + slang_info_log_error(C->L, "%s: undeclared function name.", id); + return 0; + } + } + break; + case OP_FIELD: + op->type = slang_oper_field; + op->a_id = parse_identifier(C); + if (op->a_id == SLANG_ATOM_NULL) + return 0; + if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) + return 0; + break; + case OP_POSTINCREMENT: + op->type = slang_oper_postincrement; + if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) + return 0; + break; + case OP_POSTDECREMENT: + op->type = slang_oper_postdecrement; + if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) + return 0; + break; + default: + return 0; + } + } + C->I++; + + *oper = *ops; + slang_alloc_free(ops); + + return 1; } /* parameter qualifier */ @@ -1222,78 +1264,76 @@ static int parse_expression (slang_parse_ctx *C, slang_output_ctx *O, slang_oper #define PARAMETER_ARRAY_NOT_PRESENT 0 #define PARAMETER_ARRAY_PRESENT 1 -static int parse_parameter_declaration (slang_parse_ctx *C, slang_output_ctx *O, - slang_variable *param) +static int +parse_parameter_declaration(slang_parse_ctx * C, slang_output_ctx * O, + slang_variable * param) { - /* parse and validate the parameter's type qualifiers (there can be two at most) because - * not all combinations are valid */ - if (!parse_type_qualifier (C, ¶m->type.qualifier)) - return 0; - switch (*C->I++) - { - case PARAM_QUALIFIER_IN: - if (param->type.qualifier != slang_qual_const && param->type.qualifier != slang_qual_none) - { - slang_info_log_error (C->L, "Invalid type qualifier."); - return 0; - } - break; - case PARAM_QUALIFIER_OUT: - if (param->type.qualifier == slang_qual_none) - param->type.qualifier = slang_qual_out; - else - { - slang_info_log_error (C->L, "Invalid type qualifier."); - return 0; - } - break; - case PARAM_QUALIFIER_INOUT: - if (param->type.qualifier == slang_qual_none) - param->type.qualifier = slang_qual_inout; - else - { - slang_info_log_error (C->L, "Invalid type qualifier."); - return 0; - } - break; - default: - return 0; - } - - /* parse parameter's type specifier and name */ - if (!parse_type_specifier (C, O, ¶m->type.specifier)) - return 0; - param->a_name = parse_identifier (C); - if (param->a_name == SLANG_ATOM_NULL) - return 0; - - /* if the parameter is an array, parse its size (the size must be explicitly defined */ - if (*C->I++ == PARAMETER_ARRAY_PRESENT) - { - slang_type_specifier p; - - slang_type_specifier_ctr (&p); - if (!slang_type_specifier_copy (&p, ¶m->type.specifier)) - { - slang_type_specifier_dtr (&p); - return GL_FALSE; - } - if (!convert_to_array (C, param, &p)) - { - slang_type_specifier_dtr (&p); - return GL_FALSE; - } - slang_type_specifier_dtr (&p); - if (!parse_array_len (C, O, ¶m->array_len)) - return GL_FALSE; - } - - /* calculate the parameter size */ - if (!calculate_var_size (C, O, param)) - return GL_FALSE; - - /* TODO: allocate the local address here? */ - return 1; + /* parse and validate the parameter's type qualifiers (there can be + * two at most) because not all combinations are valid + */ + if (!parse_type_qualifier(C, ¶m->type.qualifier)) + return 0; + switch (*C->I++) { + case PARAM_QUALIFIER_IN: + if (param->type.qualifier != slang_qual_const + && param->type.qualifier != slang_qual_none) { + slang_info_log_error(C->L, "Invalid type qualifier."); + return 0; + } + break; + case PARAM_QUALIFIER_OUT: + if (param->type.qualifier == slang_qual_none) + param->type.qualifier = slang_qual_out; + else { + slang_info_log_error(C->L, "Invalid type qualifier."); + return 0; + } + break; + case PARAM_QUALIFIER_INOUT: + if (param->type.qualifier == slang_qual_none) + param->type.qualifier = slang_qual_inout; + else { + slang_info_log_error(C->L, "Invalid type qualifier."); + return 0; + } + break; + default: + return 0; + } + + /* parse parameter's type specifier and name */ + if (!parse_type_specifier(C, O, ¶m->type.specifier)) + return 0; + param->a_name = parse_identifier(C); + if (param->a_name == SLANG_ATOM_NULL) + return 0; + + /* if the parameter is an array, parse its size (the size must be + * explicitly defined + */ + if (*C->I++ == PARAMETER_ARRAY_PRESENT) { + slang_type_specifier p; + + slang_type_specifier_ctr(&p); + if (!slang_type_specifier_copy(&p, ¶m->type.specifier)) { + slang_type_specifier_dtr(&p); + return GL_FALSE; + } + if (!convert_to_array(C, param, &p)) { + slang_type_specifier_dtr(&p); + return GL_FALSE; + } + slang_type_specifier_dtr(&p); + if (!parse_array_len(C, O, ¶m->array_len)) + return GL_FALSE; + } + + /* calculate the parameter size */ + if (!calculate_var_size(C, O, param)) + return GL_FALSE; + + /* TODO: allocate the local address here? */ + return 1; } /* function type */ @@ -1336,251 +1376,247 @@ static int parse_parameter_declaration (slang_parse_ctx *C, slang_output_ctx *O, /*#define OPERATOR_COMPLEMENT 28*/ #define OPERATOR_NOT 29 -static const struct { - unsigned int o_code; - const char *o_name; +static const struct +{ + unsigned int o_code; + const char *o_name; } operator_names[] = { - { OPERATOR_INCREMENT, "++" }, - { OPERATOR_ADDASSIGN, "+=" }, - { OPERATOR_PLUS, "+" }, - { OPERATOR_DECREMENT, "--" }, - { OPERATOR_SUBASSIGN, "-=" }, - { OPERATOR_MINUS, "-" }, - { OPERATOR_NOT, "!" }, - { OPERATOR_MULASSIGN, "*=" }, - { OPERATOR_MULTIPLY, "*" }, - { OPERATOR_DIVASSIGN, "/=" }, - { OPERATOR_DIVIDE, "/" }, - { OPERATOR_LESSEQUAL, "<=" }, - /*{ OPERATOR_LSHASSIGN, "<<=" },*/ - /*{ OPERATOR_LSHIFT, "<<" },*/ - { OPERATOR_LESS, "<" }, - { OPERATOR_GREATEREQUAL, ">=" }, - /*{ OPERATOR_RSHASSIGN, ">>=" },*/ - /*{ OPERATOR_RSHIFT, ">>" },*/ - { OPERATOR_GREATER, ">" }, - /*{ OPERATOR_MODASSIGN, "%=" },*/ - /*{ OPERATOR_MODULUS, "%" },*/ - /*{ OPERATOR_ANDASSIGN, "&=" },*/ - /*{ OPERATOR_BITAND, "&" },*/ - /*{ OPERATOR_ORASSIGN, "|=" },*/ - /*{ OPERATOR_BITOR, "|" },*/ - /*{ OPERATOR_COMPLEMENT, "~" },*/ - /*{ OPERATOR_XORASSIGN, "^=" },*/ - { OPERATOR_LOGICALXOR, "^^" }, - /*{ OPERATOR_BITXOR, "^" }*/ + {OPERATOR_INCREMENT, "++"}, + {OPERATOR_ADDASSIGN, "+="}, + {OPERATOR_PLUS, "+"}, + {OPERATOR_DECREMENT, "--"}, + {OPERATOR_SUBASSIGN, "-="}, + {OPERATOR_MINUS, "-"}, + {OPERATOR_NOT, "!"}, + {OPERATOR_MULASSIGN, "*="}, + {OPERATOR_MULTIPLY, "*"}, + {OPERATOR_DIVASSIGN, "/="}, + {OPERATOR_DIVIDE, "/"}, + {OPERATOR_LESSEQUAL, "<="}, + /*{ OPERATOR_LSHASSIGN, "<<=" }, */ + /*{ OPERATOR_LSHIFT, "<<" }, */ + {OPERATOR_LESS, "<"}, + {OPERATOR_GREATEREQUAL, ">="}, + /*{ OPERATOR_RSHASSIGN, ">>=" }, */ + /*{ OPERATOR_RSHIFT, ">>" }, */ + {OPERATOR_GREATER, ">"}, + /*{ OPERATOR_MODASSIGN, "%=" }, */ + /*{ OPERATOR_MODULUS, "%" }, */ + /*{ OPERATOR_ANDASSIGN, "&=" }, */ + /*{ OPERATOR_BITAND, "&" }, */ + /*{ OPERATOR_ORASSIGN, "|=" }, */ + /*{ OPERATOR_BITOR, "|" }, */ + /*{ OPERATOR_COMPLEMENT, "~" }, */ + /*{ OPERATOR_XORASSIGN, "^=" }, */ + {OPERATOR_LOGICALXOR, "^^"}, + /*{ OPERATOR_BITXOR, "^" } */ }; -static slang_atom parse_operator_name (slang_parse_ctx *C) +static slang_atom +parse_operator_name(slang_parse_ctx * C) { - unsigned int i; - - for (i = 0; i < sizeof (operator_names) / sizeof (*operator_names); i++) - { - if (operator_names[i].o_code == (unsigned int) (*C->I)) - { - slang_atom atom = slang_atom_pool_atom (C->atoms, operator_names[i].o_name); - if (atom == SLANG_ATOM_NULL) - { - slang_info_log_memory (C->L); - return 0; - } - C->I++; - return atom; - } - } - return 0; + unsigned int i; + + for (i = 0; i < sizeof(operator_names) / sizeof(*operator_names); i++) { + if (operator_names[i].o_code == (unsigned int) (*C->I)) { + slang_atom atom = + slang_atom_pool_atom(C->atoms, operator_names[i].o_name); + if (atom == SLANG_ATOM_NULL) { + slang_info_log_memory(C->L); + return 0; + } + C->I++; + return atom; + } + } + return 0; } -static int parse_function_prototype (slang_parse_ctx *C, slang_output_ctx *O, slang_function *func) +static int +parse_function_prototype(slang_parse_ctx * C, slang_output_ctx * O, + slang_function * func) { - /* parse function type and name */ - if (!parse_fully_specified_type (C, O, &func->header.type)) - return 0; - switch (*C->I++) - { - case FUNCTION_ORDINARY: - func->kind = slang_func_ordinary; - func->header.a_name = parse_identifier (C); - if (func->header.a_name == SLANG_ATOM_NULL) - return 0; - break; - case FUNCTION_CONSTRUCTOR: - func->kind = slang_func_constructor; - if (func->header.type.specifier.type == slang_spec_struct) - return 0; - func->header.a_name = slang_atom_pool_atom (C->atoms, - slang_type_specifier_type_to_string (func->header.type.specifier.type)); - if (func->header.a_name == SLANG_ATOM_NULL) - { - slang_info_log_memory (C->L); - return 0; - } - break; - case FUNCTION_OPERATOR: - func->kind = slang_func_operator; - func->header.a_name = parse_operator_name (C); - if (func->header.a_name == SLANG_ATOM_NULL) - return 0; - break; - default: - return 0; - } - - /* parse function parameters */ - while (*C->I++ == PARAMETER_NEXT) - { - slang_variable *p; - - func->parameters->variables = (slang_variable *) slang_alloc_realloc ( - func->parameters->variables, - func->parameters->num_variables * sizeof (slang_variable), - (func->parameters->num_variables + 1) * sizeof (slang_variable)); - if (func->parameters->variables == NULL) - { - slang_info_log_memory (C->L); - return 0; - } - p = &func->parameters->variables[func->parameters->num_variables]; - if (!slang_variable_construct (p)) - return 0; - func->parameters->num_variables++; - if (!parse_parameter_declaration (C, O, p)) - return 0; - } - - /* function formal parameters and local variables share the same scope, so save - * the information about param count in a seperate place - * also link the scope to the global variable scope so when a given identifier is not - * found here, the search process continues in the global space */ - func->param_count = func->parameters->num_variables; - func->parameters->outer_scope = O->vars; - return 1; + /* parse function type and name */ + if (!parse_fully_specified_type(C, O, &func->header.type)) + return 0; + switch (*C->I++) { + case FUNCTION_ORDINARY: + func->kind = slang_func_ordinary; + func->header.a_name = parse_identifier(C); + if (func->header.a_name == SLANG_ATOM_NULL) + return 0; + break; + case FUNCTION_CONSTRUCTOR: + func->kind = slang_func_constructor; + if (func->header.type.specifier.type == slang_spec_struct) + return 0; + func->header.a_name = + slang_atom_pool_atom(C->atoms, + slang_type_specifier_type_to_string + (func->header.type.specifier.type)); + if (func->header.a_name == SLANG_ATOM_NULL) { + slang_info_log_memory(C->L); + return 0; + } + break; + case FUNCTION_OPERATOR: + func->kind = slang_func_operator; + func->header.a_name = parse_operator_name(C); + if (func->header.a_name == SLANG_ATOM_NULL) + return 0; + break; + default: + return 0; + } + + /* parse function parameters */ + while (*C->I++ == PARAMETER_NEXT) { + slang_variable *p = slang_variable_scope_grow(func->parameters); + if (!p) { + slang_info_log_memory(C->L); + return 0; + } + if (!parse_parameter_declaration(C, O, p)) + return 0; + } + + /* function formal parameters and local variables share the same + * scope, so save the information about param count in a seperate + * place also link the scope to the global variable scope so when a + * given identifier is not found here, the search process continues + * in the global space + */ + func->param_count = func->parameters->num_variables; + func->parameters->outer_scope = O->vars; + return 1; } -static int parse_function_definition (slang_parse_ctx *C, slang_output_ctx *O, slang_function *func) +static int +parse_function_definition(slang_parse_ctx * C, slang_output_ctx * O, + slang_function * func) { - slang_output_ctx o = *O; - - if (!parse_function_prototype (C, O, func)) - return 0; - - /* create function's body operation */ - func->body = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation)); - if (func->body == NULL) - { - slang_info_log_memory (C->L); - return 0; - } - if (!slang_operation_construct (func->body)) - { - slang_alloc_free (func->body); - func->body = NULL; - slang_info_log_memory (C->L); - return 0; - } - - /* to parse the body the parse context is modified in order to capture parsed variables - * into function's local variable scope */ - C->global_scope = 0; - o.vars = func->parameters; - if (!parse_statement (C, &o, func->body)) - return 0; - C->global_scope = 1; - return 1; + slang_output_ctx o = *O; + + if (!parse_function_prototype(C, O, func)) + return 0; + + /* create function's body operation */ + func->body = + (slang_operation *) slang_alloc_malloc(sizeof(slang_operation)); + if (func->body == NULL) { + slang_info_log_memory(C->L); + return 0; + } + if (!slang_operation_construct(func->body)) { + slang_alloc_free(func->body); + func->body = NULL; + slang_info_log_memory(C->L); + return 0; + } + + /* to parse the body the parse context is modified in order to + * capture parsed variables into function's local variable scope + */ + C->global_scope = GL_FALSE; + o.vars = func->parameters; + if (!parse_statement(C, &o, func->body)) + return 0; + + C->global_scope = GL_TRUE; + return 1; } -static GLboolean initialize_global (slang_assemble_ctx *A, slang_variable *var) +static GLboolean +initialize_global(slang_assemble_ctx * A, slang_variable * var) { - slang_assembly_file_restore_point point; - slang_machine mach; - slang_assembly_local_info save_local = A->local; - slang_operation op_id, op_assign; - GLboolean result; - - /* save the current assembly */ - if (!slang_assembly_file_restore_point_save (A->file, &point)) - return GL_FALSE; - - /* setup the machine */ - mach = *A->mach; - mach.ip = A->file->count; - - /* allocate local storage for expression */ - A->local.ret_size = 0; - A->local.addr_tmp = 0; - A->local.swizzle_tmp = 4; - if (!slang_assembly_file_push_label (A->file, slang_asm_local_alloc, 20)) - return GL_FALSE; - if (!slang_assembly_file_push_label (A->file, slang_asm_enter, 20)) - return GL_FALSE; - - /* construct the left side of assignment */ - if (!slang_operation_construct (&op_id)) - return GL_FALSE; - op_id.type = slang_oper_identifier; - op_id.a_id = var->a_name; - - /* put the variable into operation's scope */ - op_id.locals->variables = (slang_variable *) slang_alloc_malloc (sizeof (slang_variable)); - if (op_id.locals->variables == NULL) - { - slang_operation_destruct (&op_id); - return GL_FALSE; - } - op_id.locals->num_variables = 1; - op_id.locals->variables[0] = *var; - - /* construct the assignment expression */ - if (!slang_operation_construct (&op_assign)) - { - op_id.locals->num_variables = 0; - slang_operation_destruct (&op_id); - return GL_FALSE; - } - op_assign.type = slang_oper_assign; - op_assign.children = (slang_operation *) slang_alloc_malloc (2 * sizeof (slang_operation)); - if (op_assign.children == NULL) - { - slang_operation_destruct (&op_assign); - op_id.locals->num_variables = 0; - slang_operation_destruct (&op_id); - return GL_FALSE; - } - op_assign.num_children = 2; - op_assign.children[0] = op_id; - op_assign.children[1] = *var->initializer; - - /* insert the actual expression */ - result = _slang_assemble_operation (A, &op_assign, slang_ref_forbid); - - /* carefully destroy the operations */ - op_assign.num_children = 0; - slang_alloc_free (op_assign.children); - op_assign.children = NULL; - slang_operation_destruct (&op_assign); - op_id.locals->num_variables = 0; - slang_operation_destruct (&op_id); - - if (!result) - return GL_FALSE; - if (!slang_assembly_file_push (A->file, slang_asm_exit)) - return GL_FALSE; - - /* execute the expression */ - if (!_slang_execute2 (A->file, &mach)) - return GL_FALSE; - - /* restore the old assembly */ - if (!slang_assembly_file_restore_point_load (A->file, &point)) - return GL_FALSE; - A->local = save_local; - - /* now we copy the contents of the initialized variable back to the original machine */ - _mesa_memcpy ((GLubyte *) A->mach->mem + var->address, (GLubyte *) mach.mem + var->address, - var->size); - - return GL_TRUE; + slang_assembly_file_restore_point point; + slang_machine mach; + slang_assembly_local_info save_local = A->local; + slang_operation op_id, op_assign; + GLboolean result; + + /* save the current assembly */ + if (!slang_assembly_file_restore_point_save(A->file, &point)) + return GL_FALSE; + + /* setup the machine */ + mach = *A->mach; + mach.ip = A->file->count; + + /* allocate local storage for expression */ + A->local.ret_size = 0; + A->local.addr_tmp = 0; + A->local.swizzle_tmp = 4; + if (!slang_assembly_file_push_label(A->file, slang_asm_local_alloc, 20)) + return GL_FALSE; + if (!slang_assembly_file_push_label(A->file, slang_asm_enter, 20)) + return GL_FALSE; + + /* construct the left side of assignment */ + if (!slang_operation_construct(&op_id)) + return GL_FALSE; + op_id.type = slang_oper_identifier; + op_id.a_id = var->a_name; + + /* put the variable into operation's scope */ + op_id.locals->variables = + (slang_variable *) slang_alloc_malloc(sizeof(slang_variable)); + if (op_id.locals->variables == NULL) { + slang_operation_destruct(&op_id); + return GL_FALSE; + } + op_id.locals->num_variables = 1; + op_id.locals->variables[0] = *var; + + /* construct the assignment expression */ + if (!slang_operation_construct(&op_assign)) { + op_id.locals->num_variables = 0; + slang_operation_destruct(&op_id); + return GL_FALSE; + } + op_assign.type = slang_oper_assign; + op_assign.children = + (slang_operation *) slang_alloc_malloc(2 * sizeof(slang_operation)); + if (op_assign.children == NULL) { + slang_operation_destruct(&op_assign); + op_id.locals->num_variables = 0; + slang_operation_destruct(&op_id); + return GL_FALSE; + } + op_assign.num_children = 2; + op_assign.children[0] = op_id; + op_assign.children[1] = *var->initializer; + + /* insert the actual expression */ + result = _slang_assemble_operation(A, &op_assign, slang_ref_forbid); + + /* carefully destroy the operations */ + op_assign.num_children = 0; + slang_alloc_free(op_assign.children); + op_assign.children = NULL; + slang_operation_destruct(&op_assign); + op_id.locals->num_variables = 0; + slang_operation_destruct(&op_id); + + if (!result) + return GL_FALSE; + if (!slang_assembly_file_push(A->file, slang_asm_exit)) + return GL_FALSE; + + /* execute the expression */ + if (!_slang_execute2(A->file, &mach)) + return GL_FALSE; + + /* restore the old assembly */ + if (!slang_assembly_file_restore_point_load(A->file, &point)) + return GL_FALSE; + A->local = save_local; + + /* now we copy the contents of the initialized variable back to the original machine */ + _mesa_memcpy((GLubyte *) A->mach->mem + var->address, + (GLubyte *) mach.mem + var->address, var->size); + + return GL_TRUE; } /* init declarator list */ @@ -1594,89 +1630,88 @@ static GLboolean initialize_global (slang_assemble_ctx *A, slang_variable *var) #define VARIABLE_ARRAY_EXPLICIT 3 #define VARIABLE_ARRAY_UNKNOWN 4 -static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O, - const slang_fully_specified_type *type) + +/** + * Parse the initializer for a variable declaration. + */ +static int +parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, + const slang_fully_specified_type * type) { - slang_variable *var; - - /* empty init declatator (without name, e.g. "float ;") */ - if (*C->I++ == VARIABLE_NONE) - return 1; - - /* make room for the new variable and initialize it */ - O->vars->variables = (slang_variable *) slang_alloc_realloc (O->vars->variables, - O->vars->num_variables * sizeof (slang_variable), - (O->vars->num_variables + 1) * sizeof (slang_variable)); - if (O->vars->variables == NULL) - { - slang_info_log_memory (C->L); - return 0; - } - var = &O->vars->variables[O->vars->num_variables]; - if (!slang_variable_construct (var)) - return 0; - O->vars->num_variables++; - - /* copy the declarator qualifier type, parse the identifier */ - var->global = C->global_scope; - var->type.qualifier = type->qualifier; - var->a_name = parse_identifier (C); - if (var->a_name == SLANG_ATOM_NULL) - return 0; - - switch (*C->I++) - { - case VARIABLE_NONE: - /* simple variable declarator - just copy the specifier */ - if (!slang_type_specifier_copy (&var->type.specifier, &type->specifier)) - return 0; - break; - case VARIABLE_INITIALIZER: - /* initialized variable - copy the specifier and parse the expression */ - if (!slang_type_specifier_copy (&var->type.specifier, &type->specifier)) - return 0; - var->initializer = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation)); - if (var->initializer == NULL) - { - slang_info_log_memory (C->L); - return 0; - } - if (!slang_operation_construct (var->initializer)) - { - slang_alloc_free (var->initializer); - var->initializer = NULL; - slang_info_log_memory (C->L); - return 0; - } - if (!parse_expression (C, O, var->initializer)) - return 0; - break; + slang_variable *var; + + /* empty init declatator (without name, e.g. "float ;") */ + if (*C->I++ == VARIABLE_NONE) + return 1; + + /* make room for the new variable and initialize it */ + var = slang_variable_scope_grow(O->vars); + if (!var) { + slang_info_log_memory(C->L); + return 0; + } + + /* copy the declarator qualifier type, parse the identifier */ + var->global = C->global_scope; + var->type.qualifier = type->qualifier; + var->a_name = parse_identifier(C); + if (var->a_name == SLANG_ATOM_NULL) + return 0; + + switch (*C->I++) { + case VARIABLE_NONE: + /* simple variable declarator - just copy the specifier */ + if (!slang_type_specifier_copy(&var->type.specifier, &type->specifier)) + return 0; + break; + case VARIABLE_INITIALIZER: + /* initialized variable - copy the specifier and parse the expression */ + if (!slang_type_specifier_copy(&var->type.specifier, &type->specifier)) + return 0; + var->initializer = + (slang_operation *) slang_alloc_malloc(sizeof(slang_operation)); + if (var->initializer == NULL) { + slang_info_log_memory(C->L); + return 0; + } + if (!slang_operation_construct(var->initializer)) { + slang_alloc_free(var->initializer); + var->initializer = NULL; + slang_info_log_memory(C->L); + return 0; + } + if (!parse_expression(C, O, var->initializer)) + return 0; + break; #if 0 - case VARIABLE_ARRAY_UNKNOWN: - /* unsized array - mark it as array and copy the specifier to the array element */ - if (!convert_to_array (C, var, &type->specifier)) - return GL_FALSE; - break; + case VARIABLE_ARRAY_UNKNOWN: + /* unsized array - mark it as array and copy the specifier to + the array element + */ + if (!convert_to_array(C, var, &type->specifier)) + return GL_FALSE; + break; #endif - case VARIABLE_ARRAY_EXPLICIT: - if (!convert_to_array (C, var, &type->specifier)) - return GL_FALSE; - if (!parse_array_len (C, O, &var->array_len)) - return GL_FALSE; - break; - default: - return 0; - } - - /* allocate global address space for a variable with a known size */ - if (C->global_scope && !(var->type.specifier.type == slang_spec_array && var->array_len == 0)) - { - if (!calculate_var_size (C, O, var)) - return GL_FALSE; - var->address = slang_var_pool_alloc (O->global_pool, var->size); - } - - /* initialize global variable */ + case VARIABLE_ARRAY_EXPLICIT: + if (!convert_to_array(C, var, &type->specifier)) + return GL_FALSE; + if (!parse_array_len(C, O, &var->array_len)) + return GL_FALSE; + break; + default: + return 0; + } + + /* allocate global address space for a variable with a known size */ + if (C->global_scope + && !(var->type.specifier.type == slang_spec_array + && var->array_len == 0)) { + if (!calculate_var_size(C, O, var)) + return GL_FALSE; + var->address = slang_var_pool_alloc(O->global_pool, var->size); + } + + /* initialize global variable */ if (C->global_scope) { if (var->initializer != NULL) { slang_assemble_ctx A; @@ -1687,160 +1722,171 @@ static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O, A.space.funcs = O->funs; A.space.structs = O->structs; A.space.vars = O->vars; - if (!initialize_global (&A, var)) + if (!initialize_global(&A, var)) return 0; } else { - _mesa_memset ((GLubyte *) (O->machine->mem) + var->address, 0, var->size); + _mesa_memset((GLubyte *) (O->machine->mem) + var->address, 0, + var->size); } - } - return 1; + } + return 1; } -static int parse_init_declarator_list (slang_parse_ctx *C, slang_output_ctx *O) +/** + * Parse a list of variable declarations. Each variable may have an + * initializer. + */ +static int +parse_init_declarator_list(slang_parse_ctx * C, slang_output_ctx * O) { - slang_fully_specified_type type; - - /* parse the fully specified type, common to all declarators */ - if (!slang_fully_specified_type_construct (&type)) - return 0; - if (!parse_fully_specified_type (C, O, &type)) - { - slang_fully_specified_type_destruct (&type); - return 0; - } - - /* parse declarators, pass-in the parsed type */ - do - { - if (!parse_init_declarator (C, O, &type)) - { - slang_fully_specified_type_destruct (&type); - return 0; - } - } - while (*C->I++ == DECLARATOR_NEXT); - - slang_fully_specified_type_destruct (&type); - return 1; + slang_fully_specified_type type; + + /* parse the fully specified type, common to all declarators */ + if (!slang_fully_specified_type_construct(&type)) + return 0; + if (!parse_fully_specified_type(C, O, &type)) { + slang_fully_specified_type_destruct(&type); + return 0; + } + + /* parse declarators, pass-in the parsed type */ + do { + if (!parse_init_declarator(C, O, &type)) { + slang_fully_specified_type_destruct(&type); + return 0; + } + } + while (*C->I++ == DECLARATOR_NEXT); + + slang_fully_specified_type_destruct(&type); + return 1; } -static int parse_function (slang_parse_ctx *C, slang_output_ctx *O, int definition, - slang_function **parsed_func_ret) + +/** + * Parse a function definition or declaration. + * \param C parsing context + * \param O output context + * \param definition if non-zero expect a definition, else a declaration + * \param parsed_func_ret returns the parsed function + * \return 1 if success, 0 if failure + */ +static int +parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition, + slang_function ** parsed_func_ret) { - slang_function parsed_func, *found_func; - - /* parse function definition/declaration */ - if (!slang_function_construct (&parsed_func)) - return 0; - if (definition) - { - if (!parse_function_definition (C, O, &parsed_func)) - { - slang_function_destruct (&parsed_func); - return 0; - } - } - else - { - if (!parse_function_prototype (C, O, &parsed_func)) - { - slang_function_destruct (&parsed_func); - return 0; - } - } - - /* find a function with a prototype matching the parsed one - only the current scope - * is being searched to allow built-in function overriding */ - found_func = slang_function_scope_find (O->funs, &parsed_func, 0); - if (found_func == NULL) - { - /* add the parsed function to the function list */ - O->funs->functions = (slang_function *) slang_alloc_realloc (O->funs->functions, - O->funs->num_functions * sizeof (slang_function), - (O->funs->num_functions + 1) * sizeof (slang_function)); - if (O->funs->functions == NULL) - { - slang_info_log_memory (C->L); - slang_function_destruct (&parsed_func); - return 0; - } - O->funs->functions[O->funs->num_functions] = parsed_func; - O->funs->num_functions++; - - /* return the newly parsed function */ - *parsed_func_ret = &O->funs->functions[O->funs->num_functions - 1]; - } - else - { - /* TODO: check function return type qualifiers and specifiers */ - if (definition) - { - if (found_func->body != NULL) - { - slang_info_log_error (C->L, "%s: function already has a body.", - slang_atom_pool_id (C->atoms, parsed_func.header.a_name)); - slang_function_destruct (&parsed_func); - return 0; - } - - /* destroy the existing function declaration and replace it with the new one, - * remember to save the fixup table */ - parsed_func.fixups = found_func->fixups; - slang_fixup_table_init (&found_func->fixups); - slang_function_destruct (found_func); - *found_func = parsed_func; - } - else - { - /* another declaration of the same function prototype - ignore it */ - slang_function_destruct (&parsed_func); - } - - /* return the found function */ - *parsed_func_ret = found_func; - } - - /* assemble the parsed function */ - { - slang_assemble_ctx A; - - A.file = O->assembly; - A.mach = O->machine; - A.atoms = C->atoms; - A.space.funcs = O->funs; - A.space.structs = O->structs; - A.space.vars = O->vars; - if (!_slang_assemble_function (&A, *parsed_func_ret)) - return 0; - } - return 1; + slang_function parsed_func, *found_func; + + /* parse function definition/declaration */ + if (!slang_function_construct(&parsed_func)) + return 0; + if (definition) { + if (!parse_function_definition(C, O, &parsed_func)) { + slang_function_destruct(&parsed_func); + return 0; + } + } + else { + if (!parse_function_prototype(C, O, &parsed_func)) { + slang_function_destruct(&parsed_func); + return 0; + } + } + + /* find a function with a prototype matching the parsed one - only + * the current scope is being searched to allow built-in function + * overriding + */ + found_func = slang_function_scope_find(O->funs, &parsed_func, 0); + if (found_func == NULL) { + /* add the parsed function to the function list */ + O->funs->functions = + (slang_function *) slang_alloc_realloc(O->funs->functions, + O->funs->num_functions * + sizeof(slang_function), + (O->funs->num_functions + + 1) * sizeof(slang_function)); + if (O->funs->functions == NULL) { + slang_info_log_memory(C->L); + slang_function_destruct(&parsed_func); + return 0; + } + O->funs->functions[O->funs->num_functions] = parsed_func; + O->funs->num_functions++; + + /* return the newly parsed function */ + *parsed_func_ret = &O->funs->functions[O->funs->num_functions - 1]; + } + else { + /* TODO: check function return type qualifiers and specifiers */ + if (definition) { + if (found_func->body != NULL) { + slang_info_log_error(C->L, "%s: function already has a body.", + slang_atom_pool_id(C->atoms, + parsed_func.header. + a_name)); + slang_function_destruct(&parsed_func); + return 0; + } + + /* destroy the existing function declaration and replace it + * with the new one, remember to save the fixup table + */ + parsed_func.fixups = found_func->fixups; + slang_fixup_table_init(&found_func->fixups); + slang_function_destruct(found_func); + *found_func = parsed_func; + } + else { + /* another declaration of the same function prototype - ignore it */ + slang_function_destruct(&parsed_func); + } + + /* return the found function */ + *parsed_func_ret = found_func; + } + + /* assemble the parsed function */ + { + slang_assemble_ctx A; + + A.file = O->assembly; + A.mach = O->machine; + A.atoms = C->atoms; + A.space.funcs = O->funs; + A.space.structs = O->structs; + A.space.vars = O->vars; + if (!_slang_assemble_function(&A, *parsed_func_ret)) + return 0; + } + return 1; } /* declaration */ #define DECLARATION_FUNCTION_PROTOTYPE 1 #define DECLARATION_INIT_DECLARATOR_LIST 2 -static int parse_declaration (slang_parse_ctx *C, slang_output_ctx *O) +static int +parse_declaration(slang_parse_ctx * C, slang_output_ctx * O) { - switch (*C->I++) - { - case DECLARATION_INIT_DECLARATOR_LIST: - if (!parse_init_declarator_list (C, O)) - return 0; - break; - case DECLARATION_FUNCTION_PROTOTYPE: - { - slang_function *dummy_func; - - if (!parse_function (C, O, 0, &dummy_func)) - return 0; - } - break; - default: - return 0; - } - return 1; + switch (*C->I++) { + case DECLARATION_INIT_DECLARATOR_LIST: + if (!parse_init_declarator_list(C, O)) + return 0; + break; + case DECLARATION_FUNCTION_PROTOTYPE: + { + slang_function *dummy_func; + + if (!parse_function(C, O, 0, &dummy_func)) + return 0; + } + break; + default: + return 0; + } + return 1; } /* external declaration */ @@ -1849,9 +1895,9 @@ static int parse_declaration (slang_parse_ctx *C, slang_output_ctx *O) #define EXTERNAL_DECLARATION 2 static GLboolean -parse_code_unit (slang_parse_ctx *C, slang_code_unit *unit) +parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit) { - slang_output_ctx o; + slang_output_ctx o; /* setup output context */ o.funs = &unit->funs; @@ -1861,34 +1907,33 @@ parse_code_unit (slang_parse_ctx *C, slang_code_unit *unit) o.global_pool = &unit->object->varpool; o.machine = &unit->object->machine; - /* parse individual functions and declarations */ - while (*C->I != EXTERNAL_NULL) - { - switch (*C->I++) - { - case EXTERNAL_FUNCTION_DEFINITION: - { - slang_function *func; - - if (!parse_function (C, &o, 1, &func)) - return 0; - } - break; - case EXTERNAL_DECLARATION: - if (!parse_declaration (C, &o)) - return 0; - break; - default: - return 0; - } - } - C->I++; - return 1; + /* parse individual functions and declarations */ + while (*C->I != EXTERNAL_NULL) { + switch (*C->I++) { + case EXTERNAL_FUNCTION_DEFINITION: + { + slang_function *func; + + if (!parse_function(C, &o, 1, &func)) + return 0; + } + break; + case EXTERNAL_DECLARATION: + if (!parse_declaration(C, &o)) + return 0; + break; + default: + return 0; + } + } + C->I++; + return 1; } static GLboolean -compile_binary (const byte *prod, slang_code_unit *unit, slang_unit_type type, - slang_info_log *infolog, slang_code_unit *builtin, slang_code_unit *downlink) +compile_binary(const byte * prod, slang_code_unit * unit, + slang_unit_type type, slang_info_log * infolog, + slang_code_unit * builtin, slang_code_unit * downlink) { slang_parse_ctx C; @@ -1901,7 +1946,7 @@ compile_binary (const byte *prod, slang_code_unit *unit, slang_unit_type type, C.global_scope = GL_TRUE; C.atoms = &unit->object->atompool; - if (!check_revision (&C)) + if (!check_revision(&C)) return GL_FALSE; if (downlink != NULL) { @@ -1911,58 +1956,64 @@ compile_binary (const byte *prod, slang_code_unit *unit, slang_unit_type type, } /* parse translation unit */ - return parse_code_unit (&C, unit); + return parse_code_unit(&C, unit); } static GLboolean -compile_with_grammar (grammar id, const char *source, slang_code_unit *unit, slang_unit_type type, - slang_info_log *infolog, slang_code_unit *builtin) +compile_with_grammar(grammar id, const char *source, slang_code_unit * unit, + slang_unit_type type, slang_info_log * infolog, + slang_code_unit * builtin) { byte *prod; GLuint size, start, version; slang_string preprocessed; /* First retrieve the version number. */ - if (!_slang_preprocess_version (source, &version, &start, infolog)) + if (!_slang_preprocess_version(source, &version, &start, infolog)) return GL_FALSE; if (version > 110) { - slang_info_log_error (infolog, "language version specified is not supported."); + slang_info_log_error(infolog, + "language version specified is not supported."); return GL_FALSE; } /* Now preprocess the source string. */ - slang_string_init (&preprocessed); - if (!_slang_preprocess_directives (&preprocessed, &source[start], infolog)) { - slang_string_free (&preprocessed); - slang_info_log_error (infolog, "failed to preprocess the source."); + slang_string_init(&preprocessed); + if (!_slang_preprocess_directives(&preprocessed, &source[start], infolog)) { + slang_string_free(&preprocessed); + slang_info_log_error(infolog, "failed to preprocess the source."); return GL_FALSE; } /* Finally check the syntax and generate its binary representation. */ - if (!grammar_fast_check (id, (const byte *) (slang_string_cstr (&preprocessed)), &prod, &size, 65536)) { + if (!grammar_fast_check + (id, (const byte *) (slang_string_cstr(&preprocessed)), &prod, &size, + 65536)) { char buf[1024]; GLint pos; - slang_string_free (&preprocessed); - grammar_get_last_error ((byte *) (buf), sizeof (buf), &pos); - slang_info_log_error (infolog, buf); + slang_string_free(&preprocessed); + grammar_get_last_error((byte *) (buf), sizeof(buf), &pos); + slang_info_log_error(infolog, buf); return GL_FALSE; } - slang_string_free (&preprocessed); + slang_string_free(&preprocessed); /* Syntax is okay - translate it to internal representation. */ - if (!compile_binary (prod, unit, type, infolog, builtin, &builtin[SLANG_BUILTIN_TOTAL - 1])) { - grammar_alloc_free (prod); + if (!compile_binary + (prod, unit, type, infolog, builtin, + &builtin[SLANG_BUILTIN_TOTAL - 1])) { + grammar_alloc_free(prod); return GL_FALSE; } - grammar_alloc_free (prod); + grammar_alloc_free(prod); return GL_TRUE; } -static const char *slang_shader_syn = +LONGSTRING static const char *slang_shader_syn = #include "library/slang_shader_syn.h" -; + ; static const byte slang_core_gc[] = { #include "library/slang_core_gc.h" @@ -1987,106 +2038,111 @@ static const byte slang_builtin_vec4_gc[] = { #endif static GLboolean -compile_object (grammar *id, const char *source, slang_code_object *object, slang_unit_type type, - slang_info_log *infolog) +compile_object(grammar * id, const char *source, slang_code_object * object, + slang_unit_type type, slang_info_log * infolog) { slang_code_unit *builtins = NULL; /* load GLSL grammar */ - *id = grammar_load_from_text ((const byte *) (slang_shader_syn)); - if (*id == 0) - { - byte buf[1024]; - int pos; - - grammar_get_last_error (buf, 1024, &pos); - slang_info_log_error (infolog, (const char *) (buf)); + *id = grammar_load_from_text((const byte *) (slang_shader_syn)); + if (*id == 0) { + byte buf[1024]; + int pos; + + grammar_get_last_error(buf, 1024, &pos); + slang_info_log_error(infolog, (const char *) (buf)); return GL_FALSE; - } - - /* set shader type - the syntax is slightly different for different shaders */ - if (type == slang_unit_fragment_shader || type == slang_unit_fragment_builtin) - grammar_set_reg8 (*id, (const byte *) "shader_type", 1); - else - grammar_set_reg8 (*id, (const byte *) "shader_type", 2); - - /* enable language extensions */ - grammar_set_reg8 (*id, (const byte *) "parsing_builtin", 1); - - /* if parsing user-specified shader, load built-in library */ - if (type == slang_unit_fragment_shader || type == slang_unit_vertex_shader) - { - /* compile core functionality first */ - if (!compile_binary (slang_core_gc, &object->builtin[SLANG_BUILTIN_CORE], - slang_unit_fragment_builtin, infolog, NULL, NULL)) + } + + /* set shader type - the syntax is slightly different for different shaders */ + if (type == slang_unit_fragment_shader + || type == slang_unit_fragment_builtin) + grammar_set_reg8(*id, (const byte *) "shader_type", 1); + else + grammar_set_reg8(*id, (const byte *) "shader_type", 2); + + /* enable language extensions */ + grammar_set_reg8(*id, (const byte *) "parsing_builtin", 1); + + /* if parsing user-specified shader, load built-in library */ + if (type == slang_unit_fragment_shader || type == slang_unit_vertex_shader) { + /* compile core functionality first */ + if (!compile_binary(slang_core_gc, &object->builtin[SLANG_BUILTIN_CORE], + slang_unit_fragment_builtin, infolog, NULL, NULL)) return GL_FALSE; - /* compile common functions and variables, link to core */ - if (!compile_binary (slang_common_builtin_gc, &object->builtin[SLANG_BUILTIN_COMMON], - slang_unit_fragment_builtin, infolog, NULL, - &object->builtin[SLANG_BUILTIN_CORE])) + /* compile common functions and variables, link to core */ + if (!compile_binary + (slang_common_builtin_gc, &object->builtin[SLANG_BUILTIN_COMMON], + slang_unit_fragment_builtin, infolog, NULL, + &object->builtin[SLANG_BUILTIN_CORE])) return GL_FALSE; - /* compile target-specific functions and variables, link to common */ - if (type == slang_unit_fragment_shader) - { - if (!compile_binary (slang_fragment_builtin_gc, &object->builtin[SLANG_BUILTIN_TARGET], - slang_unit_fragment_builtin, infolog, NULL, - &object->builtin[SLANG_BUILTIN_COMMON])) + /* compile target-specific functions and variables, link to common */ + if (type == slang_unit_fragment_shader) { + if (!compile_binary + (slang_fragment_builtin_gc, + &object->builtin[SLANG_BUILTIN_TARGET], + slang_unit_fragment_builtin, infolog, NULL, + &object->builtin[SLANG_BUILTIN_COMMON])) return GL_FALSE; - } - else if (type == slang_unit_vertex_shader) - { - if (!compile_binary (slang_vertex_builtin_gc, &object->builtin[SLANG_BUILTIN_TARGET], - slang_unit_vertex_builtin, infolog, NULL, - &object->builtin[SLANG_BUILTIN_COMMON])) + } + else if (type == slang_unit_vertex_shader) { + if (!compile_binary + (slang_vertex_builtin_gc, &object->builtin[SLANG_BUILTIN_TARGET], + slang_unit_vertex_builtin, infolog, NULL, + &object->builtin[SLANG_BUILTIN_COMMON])) return GL_FALSE; - } + } #if defined(USE_X86_ASM) || defined(SLANG_X86) /* compile x86 4-component vector overrides, link to target */ - if (!compile_binary (slang_builtin_vec4_gc, &object->builtin[SLANG_BUILTIN_VEC4], - slang_unit_fragment_builtin, infolog, NULL, - &object->builtin[SLANG_BUILTIN_TARGET])) + if (!compile_binary + (slang_builtin_vec4_gc, &object->builtin[SLANG_BUILTIN_VEC4], + slang_unit_fragment_builtin, infolog, NULL, + &object->builtin[SLANG_BUILTIN_TARGET])) return GL_FALSE; #endif - /* disable language extensions */ - grammar_set_reg8 (*id, (const byte *) "parsing_builtin", 0); + /* disable language extensions */ + grammar_set_reg8(*id, (const byte *) "parsing_builtin", 0); builtins = object->builtin; - } + } - /* compile the actual shader - pass-in built-in library for external shader */ - return compile_with_grammar (*id, source, &object->unit, type, infolog, builtins); + /* compile the actual shader - pass-in built-in library for external shader */ + return compile_with_grammar(*id, source, &object->unit, type, infolog, + builtins); } GLboolean -_slang_compile (const char *source, slang_code_object *object, slang_unit_type type, - slang_info_log *infolog) +_slang_compile(const char *source, slang_code_object * object, + slang_unit_type type, slang_info_log * infolog) { GLboolean success; grammar id = 0; - _slang_code_object_dtr (object); - _slang_code_object_ctr (object); + _slang_code_object_dtr(object); + _slang_code_object_ctr(object); - success = compile_object (&id, source, object, type, infolog); + success = compile_object(&id, source, object, type, infolog); if (id != 0) - grammar_destroy (id); + grammar_destroy(id); if (!success) return GL_FALSE; - if (!_slang_build_export_data_table (&object->expdata, &object->unit.vars)) + if (!_slang_build_export_data_table(&object->expdata, &object->unit.vars)) return GL_FALSE; - if (!_slang_build_export_code_table (&object->expcode, &object->unit.funs, &object->unit)) + if (!_slang_build_export_code_table + (&object->expcode, &object->unit.funs, &object->unit)) return GL_FALSE; #if defined(USE_X86_ASM) || defined(SLANG_X86) /* XXX: lookup the @main label */ - if (!_slang_x86_codegen (&object->machine, &object->assembly, object->expcode.entries[0].address)) + if (!_slang_x86_codegen + (&object->machine, &object->assembly, + object->expcode.entries[0].address)) return GL_FALSE; #endif return GL_TRUE; } - diff --git a/src/mesa/shader/slang/slang_compile_function.c b/src/mesa/shader/slang/slang_compile_function.c index eb8fd1bd40f..e6e0d89ddb6 100644 --- a/src/mesa/shader/slang/slang_compile_function.c +++ b/src/mesa/shader/slang/slang_compile_function.c @@ -33,50 +33,74 @@ /* slang_fixup_table */ -void slang_fixup_table_init (slang_fixup_table *fix) +void +slang_fixup_table_init(slang_fixup_table * fix) { - fix->table = NULL; - fix->count = 0; + fix->table = NULL; + fix->count = 0; } -void slang_fixup_table_free (slang_fixup_table *fix) +void +slang_fixup_table_free(slang_fixup_table * fix) { - slang_alloc_free (fix->table); - slang_fixup_table_init (fix); + slang_alloc_free(fix->table); + slang_fixup_table_init(fix); } +/** + * Add a new fixup address to the table. + */ +GLboolean +slang_fixup_save(slang_fixup_table *fixups, GLuint address) +{ + fixups->table = (GLuint *) + slang_alloc_realloc(fixups->table, + fixups->count * sizeof(GLuint), + (fixups->count + 1) * sizeof(GLuint)); + if (fixups->table == NULL) + return GL_FALSE; + fixups->table[fixups->count] = address; + fixups->count++; + return GL_TRUE; +} + + + /* slang_function */ -int slang_function_construct (slang_function *func) +int +slang_function_construct(slang_function * func) { - func->kind = slang_func_ordinary; - if (!slang_variable_construct (&func->header)) - return 0; - func->parameters = (slang_variable_scope *) slang_alloc_malloc (sizeof (slang_variable_scope)); - if (func->parameters == NULL) - { - slang_variable_destruct (&func->header); - return 0; - } - _slang_variable_scope_ctr (func->parameters); - func->param_count = 0; - func->body = NULL; - func->address = ~0; - slang_fixup_table_init (&func->fixups); - return 1; + func->kind = slang_func_ordinary; + if (!slang_variable_construct(&func->header)) + return 0; + + func->parameters = (slang_variable_scope *) + slang_alloc_malloc(sizeof(slang_variable_scope)); + if (func->parameters == NULL) { + slang_variable_destruct(&func->header); + return 0; + } + + _slang_variable_scope_ctr(func->parameters); + func->param_count = 0; + func->body = NULL; + func->address = ~0; + slang_fixup_table_init(&func->fixups); + return 1; } -void slang_function_destruct (slang_function *func) +void +slang_function_destruct(slang_function * func) { - slang_variable_destruct (&func->header); - slang_variable_scope_destruct (func->parameters); - slang_alloc_free (func->parameters); - if (func->body != NULL) - { - slang_operation_destruct (func->body); - slang_alloc_free (func->body); - } - slang_fixup_table_free (&func->fixups); + slang_variable_destruct(&func->header); + slang_variable_scope_destruct(func->parameters); + slang_alloc_free(func->parameters); + if (func->body != NULL) { + slang_operation_destruct(func->body); + slang_alloc_free(func->body); + } + slang_fixup_table_free(&func->fixups); } /* @@ -84,60 +108,82 @@ void slang_function_destruct (slang_function *func) */ GLvoid -_slang_function_scope_ctr (slang_function_scope *self) +_slang_function_scope_ctr(slang_function_scope * self) { self->functions = NULL; self->num_functions = 0; self->outer_scope = NULL; } -void slang_function_scope_destruct (slang_function_scope *scope) +void +slang_function_scope_destruct(slang_function_scope * scope) { - unsigned int i; + unsigned int i; - for (i = 0; i < scope->num_functions; i++) - slang_function_destruct (scope->functions + i); - slang_alloc_free (scope->functions); + for (i = 0; i < scope->num_functions; i++) + slang_function_destruct(scope->functions + i); + slang_alloc_free(scope->functions); } -int slang_function_scope_find_by_name (slang_function_scope *funcs, slang_atom a_name, int all_scopes) + +/** + * Search a list of functions for a particular function by name. + * \param funcs the list of functions to search + * \param a_name the name to search for + * \param all_scopes if non-zero, search containing scopes too. + * \return pointer to found function, or NULL. + */ +int +slang_function_scope_find_by_name(slang_function_scope * funcs, + slang_atom a_name, int all_scopes) { - unsigned int i; - - for (i = 0; i < funcs->num_functions; i++) - if (a_name == funcs->functions[i].header.a_name) - return 1; - if (all_scopes && funcs->outer_scope != NULL) - return slang_function_scope_find_by_name (funcs->outer_scope, a_name, 1); - return 0; + unsigned int i; + + for (i = 0; i < funcs->num_functions; i++) + if (a_name == funcs->functions[i].header.a_name) + return 1; + if (all_scopes && funcs->outer_scope != NULL) + return slang_function_scope_find_by_name(funcs->outer_scope, a_name, 1); + return 0; } -slang_function *slang_function_scope_find (slang_function_scope *funcs, slang_function *fun, - int all_scopes) + +/** + * Search a list of functions for a particular function (for implementing + * function calls. Matching is done by first comparing the function's name, + * then the function's parameter list. + * + * \param funcs the list of functions to search + * \param fun the function to search for + * \param all_scopes if non-zero, search containing scopes too. + * \return pointer to found function, or NULL. + */ +slang_function * +slang_function_scope_find(slang_function_scope * funcs, slang_function * fun, + int all_scopes) { - unsigned int i; - - for (i = 0; i < funcs->num_functions; i++) - { - slang_function *f = &funcs->functions[i]; - unsigned int j; - - if (fun->header.a_name != f->header.a_name) - continue; - if (fun->param_count != f->param_count) - continue; - for (j = 0; j < fun->param_count; j++) - { - if (!slang_type_specifier_equal (&fun->parameters->variables[j].type.specifier, - &f->parameters->variables[j].type.specifier)) - break; - } - if (j == fun->param_count) - return f; - } - if (all_scopes && funcs->outer_scope != NULL) - return slang_function_scope_find (funcs->outer_scope, fun, 1); - return NULL; + unsigned int i; + + for (i = 0; i < funcs->num_functions; i++) { + slang_function *f = &funcs->functions[i]; + unsigned int j; + + if (fun->header.a_name != f->header.a_name) + continue; + if (fun->param_count != f->param_count) + continue; + for (j = 0; j < fun->param_count; j++) { + if (!slang_type_specifier_equal + (&fun->parameters->variables[j].type.specifier, + &f->parameters->variables[j].type.specifier)) + break; + } + if (j == fun->param_count) + return f; + } + if (all_scopes && funcs->outer_scope != NULL) + return slang_function_scope_find(funcs->outer_scope, fun, 1); + return NULL; } /* @@ -145,31 +191,30 @@ slang_function *slang_function_scope_find (slang_function_scope *funcs, slang_fu */ GLboolean -_slang_build_export_code_table (slang_export_code_table *tbl, slang_function_scope *funs, - slang_code_unit *unit) +_slang_build_export_code_table(slang_export_code_table * tbl, + slang_function_scope * funs, + slang_code_unit * unit) { - slang_atom mainAtom; - GLuint i; - - mainAtom = slang_atom_pool_atom (tbl->atoms, "main"); - if (mainAtom == SLANG_ATOM_NULL) - return GL_FALSE; - - for (i = 0; i < funs->num_functions; i++) - { - if (funs->functions[i].header.a_name == mainAtom) - { - slang_function *fun = &funs->functions[i]; - slang_export_code_entry *e; - slang_assemble_ctx A; - - e = slang_export_code_table_add (tbl); - if (e == NULL) - return GL_FALSE; + slang_atom mainAtom; + GLuint i; + + mainAtom = slang_atom_pool_atom(tbl->atoms, "main"); + if (mainAtom == SLANG_ATOM_NULL) + return GL_FALSE; + + for (i = 0; i < funs->num_functions; i++) { + if (funs->functions[i].header.a_name == mainAtom) { + slang_function *fun = &funs->functions[i]; + slang_export_code_entry *e; + slang_assemble_ctx A; + + e = slang_export_code_table_add(tbl); + if (e == NULL) + return GL_FALSE; e->address = unit->object->assembly.count; - e->name = slang_atom_pool_atom (tbl->atoms, "@main"); - if (e->name == SLANG_ATOM_NULL) - return GL_FALSE; + e->name = slang_atom_pool_atom(tbl->atoms, "@main"); + if (e->name == SLANG_ATOM_NULL) + return GL_FALSE; A.file = &unit->object->assembly; A.mach = &unit->object->machine; @@ -177,12 +222,13 @@ _slang_build_export_code_table (slang_export_code_table *tbl, slang_function_sco A.space.funcs = &unit->funs; A.space.structs = &unit->structs; A.space.vars = &unit->vars; - slang_assembly_file_push_label (&unit->object->assembly, slang_asm_local_alloc, 20); - slang_assembly_file_push_label (&unit->object->assembly, slang_asm_enter, 20); - _slang_assemble_function_call (&A, fun, NULL, 0, GL_FALSE); - slang_assembly_file_push (&unit->object->assembly, slang_asm_exit); - } - } - return GL_TRUE; + slang_assembly_file_push_label(&unit->object->assembly, + slang_asm_local_alloc, 20); + slang_assembly_file_push_label(&unit->object->assembly, + slang_asm_enter, 20); + _slang_assemble_function_call(&A, fun, NULL, 0, GL_FALSE); + slang_assembly_file_push(&unit->object->assembly, slang_asm_exit); + } + } + return GL_TRUE; } - diff --git a/src/mesa/shader/slang/slang_compile_function.h b/src/mesa/shader/slang/slang_compile_function.h index 24bc0d6ffd1..c05c6f4d850 100644 --- a/src/mesa/shader/slang/slang_compile_function.h +++ b/src/mesa/shader/slang/slang_compile_function.h @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.2 * * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. * @@ -22,7 +22,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if !defined SLANG_COMPILE_FUNCTION_H +#ifndef SLANG_COMPILE_FUNCTION_H #define SLANG_COMPILE_FUNCTION_H #if defined __cplusplus @@ -31,57 +31,81 @@ extern "C" { struct slang_code_unit_; +/** + * Types of functions. + */ typedef enum slang_function_kind_ { - slang_func_ordinary, - slang_func_constructor, - slang_func_operator + slang_func_ordinary, + slang_func_constructor, + slang_func_operator } slang_function_kind; + +/** + * When we need to fill in addresses which we won't know until the future, + * we keep track of them with a fix-up table. + */ typedef struct slang_fixup_table_ { - GLuint *table; - GLuint count; + GLuint *table; /**< array[count] of addresses */ + GLuint count; } slang_fixup_table; -void slang_fixup_table_init (slang_fixup_table *); -void slang_fixup_table_free (slang_fixup_table *); +extern void slang_fixup_table_init(slang_fixup_table *); +extern void slang_fixup_table_free(slang_fixup_table *); +extern GLboolean slang_fixup_save(slang_fixup_table *fixups, GLuint address); + +/** + * Description of a compiled shader function. + */ typedef struct slang_function_ { - slang_function_kind kind; - slang_variable header; - slang_variable_scope *parameters; - unsigned int param_count; - slang_operation *body; - unsigned int address; - slang_fixup_table fixups; + slang_function_kind kind; + slang_variable header; /**< The function's name and return type */ + slang_variable_scope *parameters; /**< formal parameters AND local vars */ + unsigned int param_count; /**< number of formal params (no locals) */ + slang_operation *body; /**< The instruction tree */ + unsigned int address; /**< Address of this func in memory */ + slang_fixup_table fixups; /**< Mem locations which need func's address */ } slang_function; -int slang_function_construct (slang_function *); -void slang_function_destruct (slang_function *); +extern int slang_function_construct(slang_function *); +extern void slang_function_destruct(slang_function *); + +/** + * Basically, a list of compiled functions. + */ typedef struct slang_function_scope_ { - slang_function *functions; + slang_function *functions; GLuint num_functions; - struct slang_function_scope_ *outer_scope; + struct slang_function_scope_ *outer_scope; } slang_function_scope; + extern GLvoid -_slang_function_scope_ctr (slang_function_scope *); +_slang_function_scope_ctr(slang_function_scope *); + +extern void +slang_function_scope_destruct(slang_function_scope *); + +extern int +slang_function_scope_find_by_name(slang_function_scope *, slang_atom, int); -void slang_function_scope_destruct (slang_function_scope *); -int slang_function_scope_find_by_name (slang_function_scope *, slang_atom, int); -slang_function *slang_function_scope_find (slang_function_scope *, slang_function *, int); +extern slang_function * +slang_function_scope_find(slang_function_scope *, slang_function *, int); extern GLboolean -_slang_build_export_code_table (slang_export_code_table *, slang_function_scope *, - struct slang_code_unit_ *); +_slang_build_export_code_table(slang_export_code_table *, + slang_function_scope *, + struct slang_code_unit_ *); + #ifdef __cplusplus } #endif -#endif - +#endif /* SLANG_COMPILE_FUNCTION_H */ diff --git a/src/mesa/shader/slang/slang_compile_operation.c b/src/mesa/shader/slang/slang_compile_operation.c index 7e920135597..73f57bfb123 100644 --- a/src/mesa/shader/slang/slang_compile_operation.c +++ b/src/mesa/shader/slang/slang_compile_operation.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.2 * * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. * @@ -31,68 +31,85 @@ #include "imports.h" #include "slang_compile.h" -/* slang_operation */ -int slang_operation_construct (slang_operation *oper) +/** + * Init a slang_operation object + */ +GLboolean +slang_operation_construct(slang_operation * oper) { - oper->type = slang_oper_none; - oper->children = NULL; - oper->num_children = 0; - oper->literal = (float) 0; - oper->a_id = SLANG_ATOM_NULL; - oper->locals = (slang_variable_scope *) slang_alloc_malloc (sizeof (slang_variable_scope)); - if (oper->locals == NULL) - return 0; - _slang_variable_scope_ctr (oper->locals); - return 1; + oper->type = slang_oper_none; + oper->children = NULL; + oper->num_children = 0; + oper->literal = (float) 0; + oper->a_id = SLANG_ATOM_NULL; + oper->locals = + (slang_variable_scope *) + slang_alloc_malloc(sizeof(slang_variable_scope)); + if (oper->locals == NULL) + return GL_FALSE; + _slang_variable_scope_ctr(oper->locals); + return GL_TRUE; } -void slang_operation_destruct (slang_operation *oper) +void +slang_operation_destruct(slang_operation * oper) { - unsigned int i; + GLuint i; - for (i = 0; i < oper->num_children; i++) - slang_operation_destruct (oper->children + i); - slang_alloc_free (oper->children); - slang_variable_scope_destruct (oper->locals); - slang_alloc_free (oper->locals); + for (i = 0; i < oper->num_children; i++) + slang_operation_destruct(oper->children + i); + slang_alloc_free(oper->children); + slang_variable_scope_destruct(oper->locals); + slang_alloc_free(oper->locals); } -int slang_operation_copy (slang_operation *x, const slang_operation *y) +/** + * Recursively copy a slang_operation node. + * \return GL_TRUE for success, GL_FALSE if failure + */ +GLboolean +slang_operation_copy(slang_operation * x, const slang_operation * y) { - slang_operation z; - unsigned int i; + slang_operation z; + GLuint i; - if (!slang_operation_construct (&z)) - return 0; - z.type = y->type; - z.children = (slang_operation *) slang_alloc_malloc (y->num_children * sizeof (slang_operation)); - if (z.children == NULL) - { - slang_operation_destruct (&z); - return 0; - } - for (z.num_children = 0; z.num_children < y->num_children; z.num_children++) - if (!slang_operation_construct (&z.children[z.num_children])) - { - slang_operation_destruct (&z); - return 0; - } - for (i = 0; i < z.num_children; i++) - if (!slang_operation_copy (&z.children[i], &y->children[i])) - { - slang_operation_destruct (&z); - return 0; - } - z.literal = y->literal; - z.a_id = y->a_id; - if (!slang_variable_scope_copy (z.locals, y->locals)) - { - slang_operation_destruct (&z); - return 0; - } - slang_operation_destruct (x); - *x = z; - return 1; + if (!slang_operation_construct(&z)) + return GL_FALSE; + z.type = y->type; + z.children = (slang_operation *) + slang_alloc_malloc(y->num_children * sizeof(slang_operation)); + if (z.children == NULL) { + slang_operation_destruct(&z); + return GL_FALSE; + } + for (z.num_children = 0; z.num_children < y->num_children; + z.num_children++) { + if (!slang_operation_construct(&z.children[z.num_children])) { + slang_operation_destruct(&z); + return GL_FALSE; + } + } + for (i = 0; i < z.num_children; i++) { + if (!slang_operation_copy(&z.children[i], &y->children[i])) { + slang_operation_destruct(&z); + return GL_FALSE; + } + } + z.literal = y->literal; + z.a_id = y->a_id; + if (!slang_variable_scope_copy(z.locals, y->locals)) { + slang_operation_destruct(&z); + return GL_FALSE; + } + slang_operation_destruct(x); + *x = z; + return GL_TRUE; } + +slang_operation * +slang_operation_new(GLuint count) +{ + return (slang_operation *) _mesa_calloc(count * sizeof(slang_operation)); +} diff --git a/src/mesa/shader/slang/slang_compile_operation.h b/src/mesa/shader/slang/slang_compile_operation.h index d9bce36b9bd..a9376ec945f 100644 --- a/src/mesa/shader/slang/slang_compile_operation.h +++ b/src/mesa/shader/slang/slang_compile_operation.h @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.2 * * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. * @@ -22,96 +22,119 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if !defined SLANG_COMPILE_OPERATION_H +#ifndef SLANG_COMPILE_OPERATION_H #define SLANG_COMPILE_OPERATION_H #if defined __cplusplus extern "C" { #endif + +/** + * Types of slang operations. + * These are the types of the AST (abstract syntax tree) nodes. + * [foo] indicates a sub-tree or reference to another type of node + */ typedef enum slang_operation_type_ { - slang_oper_none, - slang_oper_block_no_new_scope, - slang_oper_block_new_scope, - slang_oper_variable_decl, - slang_oper_asm, - slang_oper_break, - slang_oper_continue, - slang_oper_discard, - slang_oper_return, - slang_oper_expression, - slang_oper_if, - slang_oper_while, - slang_oper_do, - slang_oper_for, - slang_oper_void, - slang_oper_literal_bool, - slang_oper_literal_int, - slang_oper_literal_float, - slang_oper_identifier, - slang_oper_sequence, - slang_oper_assign, - slang_oper_addassign, - slang_oper_subassign, - slang_oper_mulassign, - slang_oper_divassign, - /*slang_oper_modassign,*/ - /*slang_oper_lshassign,*/ - /*slang_oper_rshassign,*/ - /*slang_oper_orassign,*/ - /*slang_oper_xorassign,*/ - /*slang_oper_andassign,*/ - slang_oper_select, - slang_oper_logicalor, - slang_oper_logicalxor, - slang_oper_logicaland, - /*slang_oper_bitor,*/ - /*slang_oper_bitxor,*/ - /*slang_oper_bitand,*/ - slang_oper_equal, - slang_oper_notequal, - slang_oper_less, - slang_oper_greater, - slang_oper_lessequal, - slang_oper_greaterequal, - /*slang_oper_lshift,*/ - /*slang_oper_rshift,*/ - slang_oper_add, - slang_oper_subtract, - slang_oper_multiply, - slang_oper_divide, - /*slang_oper_modulus,*/ - slang_oper_preincrement, - slang_oper_predecrement, - slang_oper_plus, - slang_oper_minus, - /*slang_oper_complement,*/ - slang_oper_not, - slang_oper_subscript, - slang_oper_call, - slang_oper_field, - slang_oper_postincrement, - slang_oper_postdecrement + slang_oper_none, + slang_oper_block_no_new_scope, /* "{" sequence "}" */ + slang_oper_block_new_scope, /* "{" sequence "}" */ + slang_oper_variable_decl, /* [type] [var] or [var] = [expr] */ + slang_oper_asm, + slang_oper_break, /* "break" statement */ + slang_oper_continue, /* "continue" statement */ + slang_oper_discard, /* "discard" (kill fragment) statement */ + slang_oper_return, /* "return" [expr] */ + slang_oper_expression, /* [expr] */ + slang_oper_if, /* "if" [0] then [1] else [2] */ + slang_oper_while, /* "while" [cond] [body] */ + slang_oper_do, /* "do" [body] "while" [cond] */ + slang_oper_for, /* "for" [init] [while] [incr] [body] */ + slang_oper_void, /* nop */ + slang_oper_literal_bool, /* "true" or "false" */ + slang_oper_literal_int, /* integer literal */ + slang_oper_literal_float, /* float literal */ + slang_oper_identifier, /* var name, func name, etc */ + slang_oper_sequence, /* [expr] "," [expr] "," etc */ + slang_oper_assign, /* [var] "=" [expr] */ + slang_oper_addassign, /* [var] "+=" [expr] */ + slang_oper_subassign, /* [var] "-=" [expr] */ + slang_oper_mulassign, /* [var] "*=" [expr] */ + slang_oper_divassign, /* [var] "/=" [expr] */ + /*slang_oper_modassign, */ + /*slang_oper_lshassign, */ + /*slang_oper_rshassign, */ + /*slang_oper_orassign, */ + /*slang_oper_xorassign, */ + /*slang_oper_andassign, */ + slang_oper_select, /* [expr] "?" [expr] ":" [expr] */ + slang_oper_logicalor, /* [expr] "||" [expr] */ + slang_oper_logicalxor, /* [expr] "^^" [expr] */ + slang_oper_logicaland, /* [expr] "&&" [expr] */ + /*slang_oper_bitor, */ + /*slang_oper_bitxor, */ + /*slang_oper_bitand, */ + slang_oper_equal, /* [expr] "==" [expr] */ + slang_oper_notequal, /* [expr] "!=" [expr] */ + slang_oper_less, /* [expr] "<" [expr] */ + slang_oper_greater, /* [expr] ">" [expr] */ + slang_oper_lessequal, /* [expr] "<=" [expr] */ + slang_oper_greaterequal, /* [expr] ">=" [expr] */ + /*slang_oper_lshift, */ + /*slang_oper_rshift, */ + slang_oper_add, /* [expr] "+" [expr] */ + slang_oper_subtract, /* [expr] "-" [expr] */ + slang_oper_multiply, /* [expr] "*" [expr] */ + slang_oper_divide, /* [expr] "/" [expr] */ + /*slang_oper_modulus, */ + slang_oper_preincrement, /* "++" [var] */ + slang_oper_predecrement, /* "--" [var] */ + slang_oper_plus, /* "-" [expr] */ + slang_oper_minus, /* "+" [expr] */ + /*slang_oper_complement, */ + slang_oper_not, /* "!" [expr] */ + slang_oper_subscript, /* [expr] "[" [expr] "]" */ + slang_oper_call, /* [func name] [param] [param] [...] */ + slang_oper_field, /* i.e.: ".next" or ".xzy" or ".xxx" etc */ + slang_oper_postincrement, /* [var] "++" */ + slang_oper_postdecrement /* [var] "--" */ } slang_operation_type; + +/** + * A slang_operation is basically a compiled instruction (such as assignment, + * a while-loop, a conditional, a multiply, a function call, etc). + * The AST (abstract syntax tree) is built from these nodes. + * NOTE: This structure could have been implemented as a union of simpler + * structs which would correspond to the operation types above. + */ typedef struct slang_operation_ { - slang_operation_type type; - struct slang_operation_ *children; - unsigned int num_children; - float literal; /* type: bool, literal_int, literal_float */ - slang_atom a_id; /* type: asm, identifier, call, field */ - slang_variable_scope *locals; + slang_operation_type type; + struct slang_operation_ *children; + GLuint num_children; + GLfloat literal; /**< Used for float, int and bool values */ + slang_atom a_id; /**< type: asm, identifier, call, field */ + slang_variable_scope *locals; /**< local vars for scope */ } slang_operation; -int slang_operation_construct (slang_operation *); -void slang_operation_destruct (slang_operation *); -int slang_operation_copy (slang_operation *, const slang_operation *); + +extern GLboolean +slang_operation_construct(slang_operation *); + +extern void +slang_operation_destruct(slang_operation *); + +extern GLboolean +slang_operation_copy(slang_operation *, const slang_operation *); + +extern slang_operation * +slang_operation_new(GLuint count); + #ifdef __cplusplus } #endif -#endif - +#endif /* SLANG_COMPILE_OPERATION_H */ diff --git a/src/mesa/shader/slang/slang_compile_variable.c b/src/mesa/shader/slang/slang_compile_variable.c index b62743addb0..a8a2d6aa6a0 100644 --- a/src/mesa/shader/slang/slang_compile_variable.c +++ b/src/mesa/shader/slang/slang_compile_variable.c @@ -35,89 +35,92 @@ typedef struct { - const char *name; - slang_type_specifier_type type; + const char *name; + slang_type_specifier_type type; } type_specifier_type_name; -static type_specifier_type_name type_specifier_type_names[] = { - { "void", slang_spec_void }, - { "bool", slang_spec_bool }, - { "bvec2", slang_spec_bvec2 }, - { "bvec3", slang_spec_bvec3 }, - { "bvec4", slang_spec_bvec4 }, - { "int", slang_spec_int }, - { "ivec2", slang_spec_ivec2 }, - { "ivec3", slang_spec_ivec3 }, - { "ivec4", slang_spec_ivec4 }, - { "float", slang_spec_float }, - { "vec2", slang_spec_vec2 }, - { "vec3", slang_spec_vec3 }, - { "vec4", slang_spec_vec4 }, - { "mat2", slang_spec_mat2 }, - { "mat3", slang_spec_mat3 }, - { "mat4", slang_spec_mat4 }, - { "sampler1D", slang_spec_sampler1D }, - { "sampler2D", slang_spec_sampler2D }, - { "sampler3D", slang_spec_sampler3D }, - { "samplerCube", slang_spec_samplerCube }, - { "sampler1DShadow", slang_spec_sampler1DShadow }, - { "sampler2DShadow", slang_spec_sampler2DShadow }, - { NULL, slang_spec_void } +static const type_specifier_type_name type_specifier_type_names[] = { + {"void", slang_spec_void}, + {"bool", slang_spec_bool}, + {"bvec2", slang_spec_bvec2}, + {"bvec3", slang_spec_bvec3}, + {"bvec4", slang_spec_bvec4}, + {"int", slang_spec_int}, + {"ivec2", slang_spec_ivec2}, + {"ivec3", slang_spec_ivec3}, + {"ivec4", slang_spec_ivec4}, + {"float", slang_spec_float}, + {"vec2", slang_spec_vec2}, + {"vec3", slang_spec_vec3}, + {"vec4", slang_spec_vec4}, + {"mat2", slang_spec_mat2}, + {"mat3", slang_spec_mat3}, + {"mat4", slang_spec_mat4}, + {"sampler1D", slang_spec_sampler1D}, + {"sampler2D", slang_spec_sampler2D}, + {"sampler3D", slang_spec_sampler3D}, + {"samplerCube", slang_spec_samplerCube}, + {"sampler1DShadow", slang_spec_sampler1DShadow}, + {"sampler2DShadow", slang_spec_sampler2DShadow}, + {NULL, slang_spec_void} }; -slang_type_specifier_type slang_type_specifier_type_from_string (const char *name) +slang_type_specifier_type +slang_type_specifier_type_from_string(const char *name) { - type_specifier_type_name *p = type_specifier_type_names; - while (p->name != NULL) - { - if (slang_string_compare (p->name, name) == 0) - break; - p++; - } - return p->type; + const type_specifier_type_name *p = type_specifier_type_names; + while (p->name != NULL) { + if (slang_string_compare(p->name, name) == 0) + break; + p++; + } + return p->type; } -const char *slang_type_specifier_type_to_string (slang_type_specifier_type type) +const char * +slang_type_specifier_type_to_string(slang_type_specifier_type type) { - type_specifier_type_name *p = type_specifier_type_names; - while (p->name != NULL) - { - if (p->type == type) - break; - p++; - } - return p->name; + const type_specifier_type_name *p = type_specifier_type_names; + while (p->name != NULL) { + if (p->type == type) + break; + p++; + } + return p->name; } /* slang_fully_specified_type */ -int slang_fully_specified_type_construct (slang_fully_specified_type *type) +int +slang_fully_specified_type_construct(slang_fully_specified_type * type) { - type->qualifier = slang_qual_none; - slang_type_specifier_ctr (&type->specifier); - return 1; + type->qualifier = slang_qual_none; + slang_type_specifier_ctr(&type->specifier); + return 1; } -void slang_fully_specified_type_destruct (slang_fully_specified_type *type) +void +slang_fully_specified_type_destruct(slang_fully_specified_type * type) { - slang_type_specifier_dtr (&type->specifier); + slang_type_specifier_dtr(&type->specifier); } -int slang_fully_specified_type_copy (slang_fully_specified_type *x, const slang_fully_specified_type *y) +int +slang_fully_specified_type_copy(slang_fully_specified_type * x, + const slang_fully_specified_type * y) { - slang_fully_specified_type z; - - if (!slang_fully_specified_type_construct (&z)) - return 0; - z.qualifier = y->qualifier; - if (!slang_type_specifier_copy (&z.specifier, &y->specifier)) - { - slang_fully_specified_type_destruct (&z); - return 0; - } - slang_fully_specified_type_destruct (x); - *x = z; - return 1; + slang_fully_specified_type z; + + if (!slang_fully_specified_type_construct(&z)) + return 0; + z.qualifier = y->qualifier; + if (!slang_type_specifier_copy(&z.specifier, &y->specifier)) { + slang_fully_specified_type_destruct(&z); + return 0; + } + slang_fully_specified_type_destruct(x); + *x = z; + return 1; } /* @@ -125,246 +128,281 @@ int slang_fully_specified_type_copy (slang_fully_specified_type *x, const slang_ */ GLvoid -_slang_variable_scope_ctr (slang_variable_scope *self) +_slang_variable_scope_ctr(slang_variable_scope * self) { self->variables = NULL; self->num_variables = 0; self->outer_scope = NULL; } -void slang_variable_scope_destruct (slang_variable_scope *scope) +void +slang_variable_scope_destruct(slang_variable_scope * scope) { - unsigned int i; + unsigned int i; + + if (!scope) + return; + for (i = 0; i < scope->num_variables; i++) + slang_variable_destruct(scope->variables + i); + slang_alloc_free(scope->variables); + /* do not free scope->outer_scope */ +} - for (i = 0; i < scope->num_variables; i++) - slang_variable_destruct (scope->variables + i); - slang_alloc_free (scope->variables); - /* do not free scope->outer_scope */ +int +slang_variable_scope_copy(slang_variable_scope * x, + const slang_variable_scope * y) +{ + slang_variable_scope z; + unsigned int i; + + _slang_variable_scope_ctr(&z); + z.variables = (slang_variable *) + slang_alloc_malloc(y->num_variables * sizeof(slang_variable)); + if (z.variables == NULL) { + slang_variable_scope_destruct(&z); + return 0; + } + for (z.num_variables = 0; z.num_variables < y->num_variables; + z.num_variables++) { + if (!slang_variable_construct(&z.variables[z.num_variables])) { + slang_variable_scope_destruct(&z); + return 0; + } + } + for (i = 0; i < z.num_variables; i++) { + if (!slang_variable_copy(&z.variables[i], &y->variables[i])) { + slang_variable_scope_destruct(&z); + return 0; + } + } + z.outer_scope = y->outer_scope; + slang_variable_scope_destruct(x); + *x = z; + return 1; } -int slang_variable_scope_copy (slang_variable_scope *x, const slang_variable_scope *y) + +/** + * Grow the variable list by one. + * \return pointer to space for the new variable (will be initialized) + */ +slang_variable * +slang_variable_scope_grow(slang_variable_scope *scope) { - slang_variable_scope z; - unsigned int i; - - _slang_variable_scope_ctr (&z); - z.variables = (slang_variable *) slang_alloc_malloc (y->num_variables * sizeof (slang_variable)); - if (z.variables == NULL) - { - slang_variable_scope_destruct (&z); - return 0; - } - for (z.num_variables = 0; z.num_variables < y->num_variables; z.num_variables++) - if (!slang_variable_construct (&z.variables[z.num_variables])) - { - slang_variable_scope_destruct (&z); - return 0; - } - for (i = 0; i < z.num_variables; i++) - if (!slang_variable_copy (&z.variables[i], &y->variables[i])) - { - slang_variable_scope_destruct (&z); - return 0; - } - z.outer_scope = y->outer_scope; - slang_variable_scope_destruct (x); - *x = z; - return 1; + const int n = scope->num_variables; + scope->variables = (slang_variable *) + slang_alloc_realloc(scope->variables, + n * sizeof(slang_variable), + (n + 1) * sizeof(slang_variable)); + if (!scope->variables) + return NULL; + + scope->num_variables++; + + if (!slang_variable_construct(scope->variables + n)) + return NULL; + + return scope->variables + n; } + + /* slang_variable */ -int slang_variable_construct (slang_variable *var) +int +slang_variable_construct(slang_variable * var) { - if (!slang_fully_specified_type_construct (&var->type)) - return 0; - var->a_name = SLANG_ATOM_NULL; - var->array_len = 0; - var->initializer = NULL; - var->address = ~0; - var->size = 0; - var->global = 0; - return 1; + if (!slang_fully_specified_type_construct(&var->type)) + return 0; + var->a_name = SLANG_ATOM_NULL; + var->array_len = 0; + var->initializer = NULL; + var->address = ~0; + var->address2 = 0; + var->size = 0; + var->global = GL_FALSE; + return 1; } -void slang_variable_destruct (slang_variable *var) +void +slang_variable_destruct(slang_variable * var) { - slang_fully_specified_type_destruct (&var->type); - if (var->initializer != NULL) - { - slang_operation_destruct (var->initializer); - slang_alloc_free (var->initializer); - } + slang_fully_specified_type_destruct(&var->type); + if (var->initializer != NULL) { + slang_operation_destruct(var->initializer); + slang_alloc_free(var->initializer); + } } -int slang_variable_copy (slang_variable *x, const slang_variable *y) +int +slang_variable_copy(slang_variable * x, const slang_variable * y) { - slang_variable z; - - if (!slang_variable_construct (&z)) - return 0; - if (!slang_fully_specified_type_copy (&z.type, &y->type)) - { - slang_variable_destruct (&z); - return 0; - } - z.a_name = y->a_name; - z.array_len = y->array_len; - if (y->initializer != NULL) - { - z.initializer = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation)); - if (z.initializer == NULL) - { - slang_variable_destruct (&z); - return 0; - } - if (!slang_operation_construct (z.initializer)) - { - slang_alloc_free (z.initializer); - slang_variable_destruct (&z); - return 0; - } - if (!slang_operation_copy (z.initializer, y->initializer)) - { - slang_variable_destruct (&z); - return 0; - } - } - z.address = y->address; - z.size = y->size; - z.global = y->global; - slang_variable_destruct (x); - *x = z; - return 1; + slang_variable z; + + if (!slang_variable_construct(&z)) + return 0; + if (!slang_fully_specified_type_copy(&z.type, &y->type)) { + slang_variable_destruct(&z); + return 0; + } + z.a_name = y->a_name; + z.array_len = y->array_len; + if (y->initializer != NULL) { + z.initializer = + (slang_operation *) slang_alloc_malloc(sizeof(slang_operation)); + if (z.initializer == NULL) { + slang_variable_destruct(&z); + return 0; + } + if (!slang_operation_construct(z.initializer)) { + slang_alloc_free(z.initializer); + slang_variable_destruct(&z); + return 0; + } + if (!slang_operation_copy(z.initializer, y->initializer)) { + slang_variable_destruct(&z); + return 0; + } + } + z.address = y->address; + z.size = y->size; + z.global = y->global; + slang_variable_destruct(x); + *x = z; + return 1; } -slang_variable *_slang_locate_variable (slang_variable_scope *scope, slang_atom a_name, GLboolean all) +slang_variable * +_slang_locate_variable(const slang_variable_scope * scope, + const slang_atom a_name, GLboolean all) { - GLuint i; - - for (i = 0; i < scope->num_variables; i++) - if (a_name == scope->variables[i].a_name) - return &scope->variables[i]; - if (all && scope->outer_scope != NULL) - return _slang_locate_variable (scope->outer_scope, a_name, 1); - return NULL; + GLuint i; + + for (i = 0; i < scope->num_variables; i++) + if (a_name == scope->variables[i].a_name) + return &scope->variables[i]; + if (all && scope->outer_scope != NULL) + return _slang_locate_variable(scope->outer_scope, a_name, 1); + return NULL; } /* * _slang_build_export_data_table() */ -static GLenum gl_type_from_specifier (const slang_type_specifier *type) +static GLenum +gl_type_from_specifier(const slang_type_specifier * type) { - switch (type->type) - { - case slang_spec_bool: - return GL_BOOL_ARB; - case slang_spec_bvec2: - return GL_BOOL_VEC2_ARB; - case slang_spec_bvec3: - return GL_BOOL_VEC3_ARB; - case slang_spec_bvec4: - return GL_BOOL_VEC4_ARB; - case slang_spec_int: - return GL_INT; - case slang_spec_ivec2: - return GL_INT_VEC2_ARB; - case slang_spec_ivec3: - return GL_INT_VEC3_ARB; - case slang_spec_ivec4: - return GL_INT_VEC4_ARB; - case slang_spec_float: - return GL_FLOAT; - case slang_spec_vec2: - return GL_FLOAT_VEC2_ARB; - case slang_spec_vec3: - return GL_FLOAT_VEC3_ARB; - case slang_spec_vec4: - return GL_FLOAT_VEC4_ARB; - case slang_spec_mat2: - return GL_FLOAT_MAT2_ARB; - case slang_spec_mat3: - return GL_FLOAT_MAT3_ARB; - case slang_spec_mat4: - return GL_FLOAT_MAT4_ARB; - case slang_spec_sampler1D: - return GL_SAMPLER_1D_ARB; - case slang_spec_sampler2D: - return GL_SAMPLER_2D_ARB; - case slang_spec_sampler3D: - return GL_SAMPLER_3D_ARB; - case slang_spec_samplerCube: - return GL_SAMPLER_CUBE_ARB; - case slang_spec_sampler1DShadow: - return GL_SAMPLER_1D_SHADOW_ARB; - case slang_spec_sampler2DShadow: - return GL_SAMPLER_2D_SHADOW_ARB; - case slang_spec_array: - return gl_type_from_specifier (type->_array); - default: - return GL_FLOAT; - } + switch (type->type) { + case slang_spec_bool: + return GL_BOOL_ARB; + case slang_spec_bvec2: + return GL_BOOL_VEC2_ARB; + case slang_spec_bvec3: + return GL_BOOL_VEC3_ARB; + case slang_spec_bvec4: + return GL_BOOL_VEC4_ARB; + case slang_spec_int: + return GL_INT; + case slang_spec_ivec2: + return GL_INT_VEC2_ARB; + case slang_spec_ivec3: + return GL_INT_VEC3_ARB; + case slang_spec_ivec4: + return GL_INT_VEC4_ARB; + case slang_spec_float: + return GL_FLOAT; + case slang_spec_vec2: + return GL_FLOAT_VEC2_ARB; + case slang_spec_vec3: + return GL_FLOAT_VEC3_ARB; + case slang_spec_vec4: + return GL_FLOAT_VEC4_ARB; + case slang_spec_mat2: + return GL_FLOAT_MAT2_ARB; + case slang_spec_mat3: + return GL_FLOAT_MAT3_ARB; + case slang_spec_mat4: + return GL_FLOAT_MAT4_ARB; + case slang_spec_sampler1D: + return GL_SAMPLER_1D_ARB; + case slang_spec_sampler2D: + return GL_SAMPLER_2D_ARB; + case slang_spec_sampler3D: + return GL_SAMPLER_3D_ARB; + case slang_spec_samplerCube: + return GL_SAMPLER_CUBE_ARB; + case slang_spec_sampler1DShadow: + return GL_SAMPLER_1D_SHADOW_ARB; + case slang_spec_sampler2DShadow: + return GL_SAMPLER_2D_SHADOW_ARB; + case slang_spec_array: + return gl_type_from_specifier(type->_array); + default: + return GL_FLOAT; + } } -static GLboolean build_quant (slang_export_data_quant *q, slang_variable *var) +static GLboolean +build_quant(slang_export_data_quant * q, const slang_variable * var) { - slang_type_specifier *spec = &var->type.specifier; - - q->name = var->a_name; - q->size = var->size; - if (spec->type == slang_spec_array) - { - q->array_len = var->array_len; - q->size /= var->array_len; - spec = spec->_array; - } - if (spec->type == slang_spec_struct) - { - GLuint i; - - q->u.field_count = spec->_struct->fields->num_variables; - q->structure = (slang_export_data_quant *) slang_alloc_malloc ( - q->u.field_count * sizeof (slang_export_data_quant)); - if (q->structure == NULL) - return GL_FALSE; - - for (i = 0; i < q->u.field_count; i++) - slang_export_data_quant_ctr (&q->structure[i]); - for (i = 0; i < q->u.field_count; i++) - if (!build_quant (&q->structure[i], &spec->_struct->fields->variables[i])) - return GL_FALSE; - } - else - q->u.basic_type = gl_type_from_specifier (spec); - return GL_TRUE; + const slang_type_specifier *spec = &var->type.specifier; + + q->name = var->a_name; + q->size = var->size; + if (spec->type == slang_spec_array) { + q->array_len = var->array_len; + q->size /= var->array_len; + spec = spec->_array; + } + if (spec->type == slang_spec_struct) { + GLuint i; + + q->u.field_count = spec->_struct->fields->num_variables; + q->structure = (slang_export_data_quant *) + slang_alloc_malloc(q->u.field_count + * sizeof(slang_export_data_quant)); + if (q->structure == NULL) + return GL_FALSE; + + for (i = 0; i < q->u.field_count; i++) + slang_export_data_quant_ctr(&q->structure[i]); + for (i = 0; i < q->u.field_count; i++) { + if (!build_quant(&q->structure[i], + &spec->_struct->fields->variables[i])) + return GL_FALSE; + } + } + else + q->u.basic_type = gl_type_from_specifier(spec); + return GL_TRUE; } -GLboolean _slang_build_export_data_table (slang_export_data_table *tbl, slang_variable_scope *vars) +GLboolean +_slang_build_export_data_table(slang_export_data_table * tbl, + slang_variable_scope * vars) { - GLuint i; - - for (i = 0; i < vars->num_variables; i++) - { - slang_variable *var = &vars->variables[i]; - slang_export_data_entry *e; - - e = slang_export_data_table_add (tbl); - if (e == NULL) - return GL_FALSE; - if (!build_quant (&e->quant, var)) - return GL_FALSE; - if (var->type.qualifier == slang_qual_uniform) - e->access = slang_exp_uniform; - else if (var->type.qualifier == slang_qual_attribute) - e->access = slang_exp_attribute; - else - e->access = slang_exp_varying; - e->address = var->address; - } - - if (vars->outer_scope != NULL) - return _slang_build_export_data_table (tbl, vars->outer_scope); - return GL_TRUE; + GLuint i; + + for (i = 0; i < vars->num_variables; i++) { + const slang_variable *var = &vars->variables[i]; + slang_export_data_entry *e; + + e = slang_export_data_table_add(tbl); + if (e == NULL) + return GL_FALSE; + if (!build_quant(&e->quant, var)) + return GL_FALSE; + if (var->type.qualifier == slang_qual_uniform) + e->access = slang_exp_uniform; + else if (var->type.qualifier == slang_qual_attribute) + e->access = slang_exp_attribute; + else + e->access = slang_exp_varying; + e->address = var->address; + } + + if (vars->outer_scope != NULL) + return _slang_build_export_data_table(tbl, vars->outer_scope); + return GL_TRUE; } - diff --git a/src/mesa/shader/slang/slang_compile_variable.h b/src/mesa/shader/slang/slang_compile_variable.h index 6b9679a3b75..b0910e855ea 100644 --- a/src/mesa/shader/slang/slang_compile_variable.h +++ b/src/mesa/shader/slang/slang_compile_variable.h @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.2 * * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. * @@ -22,74 +22,113 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if !defined SLANG_COMPILE_VARIABLE_H +#ifndef SLANG_COMPILE_VARIABLE_H #define SLANG_COMPILE_VARIABLE_H #if defined __cplusplus extern "C" { #endif + typedef enum slang_type_qualifier_ { - slang_qual_none, - slang_qual_const, - slang_qual_attribute, - slang_qual_varying, - slang_qual_uniform, - slang_qual_out, - slang_qual_inout, - slang_qual_fixedoutput, /* internal */ - slang_qual_fixedinput /* internal */ + slang_qual_none, + slang_qual_const, + slang_qual_attribute, + slang_qual_varying, + slang_qual_uniform, + slang_qual_out, + slang_qual_inout, + slang_qual_fixedoutput, /* internal */ + slang_qual_fixedinput /* internal */ } slang_type_qualifier; -slang_type_specifier_type slang_type_specifier_type_from_string (const char *); -const char *slang_type_specifier_type_to_string (slang_type_specifier_type); +extern slang_type_specifier_type +slang_type_specifier_type_from_string(const char *); + +extern const char * +slang_type_specifier_type_to_string(slang_type_specifier_type); + + typedef struct slang_fully_specified_type_ { - slang_type_qualifier qualifier; - slang_type_specifier specifier; + slang_type_qualifier qualifier; + slang_type_specifier specifier; } slang_fully_specified_type; -int slang_fully_specified_type_construct (slang_fully_specified_type *); -void slang_fully_specified_type_destruct (slang_fully_specified_type *); -int slang_fully_specified_type_copy (slang_fully_specified_type *, const slang_fully_specified_type *); +extern int +slang_fully_specified_type_construct(slang_fully_specified_type *); + +extern void +slang_fully_specified_type_destruct(slang_fully_specified_type *); + +extern int +slang_fully_specified_type_copy(slang_fully_specified_type *, + const slang_fully_specified_type *); + + +/** + * A shading language program variable. + */ +typedef struct slang_variable_ +{ + slang_fully_specified_type type; /**< Variable's data type */ + slang_atom a_name; /**< The variable's name (char *) */ + GLuint array_len; /**< only if type == slang_spec_array */ + struct slang_operation_ *initializer; /**< Optional initializer code */ + GLuint address; /**< Storage location */ + GLuint address2; /**< Storage location */ + GLuint size; /**< Variable's size in bytes */ + GLboolean global; /**< A global var? */ + void *aux; /**< Used during code gen */ +} slang_variable; + +/** + * Basically a list of variables, with a pointer to the parent scope. + */ typedef struct slang_variable_scope_ { - struct slang_variable_ *variables; + slang_variable *variables; /**< Array [num_variables] */ GLuint num_variables; - struct slang_variable_scope_ *outer_scope; + struct slang_variable_scope_ *outer_scope; } slang_variable_scope; extern GLvoid -_slang_variable_scope_ctr (slang_variable_scope *); +_slang_variable_scope_ctr(slang_variable_scope *); -void slang_variable_scope_destruct (slang_variable_scope *); -int slang_variable_scope_copy (slang_variable_scope *, const slang_variable_scope *); +extern void +slang_variable_scope_destruct(slang_variable_scope *); -typedef struct slang_variable_ -{ - slang_fully_specified_type type; - slang_atom a_name; - GLuint array_len; /* type: spec_array */ - struct slang_operation_ *initializer; - unsigned int address; - unsigned int size; - int global; -} slang_variable; +extern int +slang_variable_scope_copy(slang_variable_scope *, + const slang_variable_scope *); + +slang_variable * +slang_variable_scope_grow(slang_variable_scope *); -int slang_variable_construct (slang_variable *); -void slang_variable_destruct (slang_variable *); -int slang_variable_copy (slang_variable *, const slang_variable *); +extern int +slang_variable_construct(slang_variable *); + +extern void +slang_variable_destruct(slang_variable *); + +extern int +slang_variable_copy(slang_variable *, const slang_variable *); + +extern slang_variable * +_slang_locate_variable(const slang_variable_scope *, const slang_atom a_name, + GLboolean all); + +extern GLboolean +_slang_build_export_data_table(slang_export_data_table *, + slang_variable_scope *); -slang_variable *_slang_locate_variable (slang_variable_scope *, slang_atom a_name, GLboolean all); -GLboolean _slang_build_export_data_table (slang_export_data_table *, slang_variable_scope *); #ifdef __cplusplus } #endif -#endif - +#endif /* SLANG_COMPILE_VARIABLE_H */ diff --git a/src/mesa/shader/slang/slang_execute.c b/src/mesa/shader/slang/slang_execute.c index 98bfd896c4e..e469de02075 100644 --- a/src/mesa/shader/slang/slang_execute.c +++ b/src/mesa/shader/slang/slang_execute.c @@ -36,571 +36,625 @@ #define DEBUG_SLANG 0 -GLvoid slang_machine_ctr (slang_machine *self) +GLvoid +slang_machine_ctr(slang_machine * self) { - slang_machine_init (self); + slang_machine_init(self); self->infolog = NULL; #if defined(USE_X86_ASM) || defined(SLANG_X86) - self->x86.compiled_func = NULL; + self->x86.compiled_func = NULL; #endif } -GLvoid slang_machine_dtr (slang_machine *self) +GLvoid +slang_machine_dtr(slang_machine * self) { if (self->infolog != NULL) { - slang_info_log_destruct (self->infolog); - slang_alloc_free (self->infolog); + slang_info_log_destruct(self->infolog); + slang_alloc_free(self->infolog); } #if defined(USE_X86_ASM) || defined(SLANG_X86) - if (self->x86.compiled_func != NULL) - _mesa_exec_free (self->x86.compiled_func); + if (self->x86.compiled_func != NULL) + _mesa_exec_free(self->x86.compiled_func); #endif } -void slang_machine_init (slang_machine *mach) + +/** + * Initialize the shader virtual machine. + * NOTE: stack grows downward in memory. + */ +void +slang_machine_init(slang_machine * mach) { - mach->ip = 0; - mach->sp = SLANG_MACHINE_STACK_SIZE; - mach->bp = 0; - mach->kill = 0; - mach->exit = 0; + mach->ip = 0; + mach->sp = SLANG_MACHINE_STACK_SIZE; + mach->bp = 0; + mach->kill = GL_FALSE; + mach->exit = GL_FALSE; } #if DEBUG_SLANG -static void dump_instruction (FILE *f, slang_assembly *a, unsigned int i) +static void +dump_instruction(FILE * f, slang_assembly * a, unsigned int i) { - fprintf (f, "%.5u:\t", i); - - switch (a->type) - { - /* core */ - case slang_asm_none: - fprintf (f, "none"); - break; - case slang_asm_float_copy: - fprintf (f, "float_copy\t%d, %d", a->param[0], a->param[1]); - break; - case slang_asm_float_move: - fprintf (f, "float_move\t%d, %d", a->param[0], a->param[1]); - break; - case slang_asm_float_push: - fprintf (f, "float_push\t%f", a->literal); - break; - case slang_asm_float_deref: - fprintf (f, "float_deref"); - break; - case slang_asm_float_add: - fprintf (f, "float_add"); - break; - case slang_asm_float_multiply: - fprintf (f, "float_multiply"); - break; - case slang_asm_float_divide: - fprintf (f, "float_divide"); - break; - case slang_asm_float_negate: - fprintf (f, "float_negate"); - break; - case slang_asm_float_less: - fprintf (f, "float_less"); - break; - case slang_asm_float_equal_exp: - fprintf (f, "float_equal"); - break; - case slang_asm_float_equal_int: - fprintf (f, "float_equal\t%d, %d", a->param[0], a->param[1]); - break; - case slang_asm_float_to_int: - fprintf (f, "float_to_int"); - break; - case slang_asm_float_sine: - fprintf (f, "float_sine"); - break; - case slang_asm_float_arcsine: - fprintf (f, "float_arcsine"); - break; - case slang_asm_float_arctan: - fprintf (f, "float_arctan"); - break; - case slang_asm_float_power: - fprintf (f, "float_power"); - break; - case slang_asm_float_log2: - fprintf (f, "float_log2"); - break; - case slang_asm_float_floor: - fprintf (f, "float_floor"); - break; - case slang_asm_float_ceil: - fprintf (f, "float_ceil"); - break; - case slang_asm_float_noise1: - fprintf (f, "float_noise1"); - break; - case slang_asm_float_noise2: - fprintf (f, "float_noise2"); - break; - case slang_asm_float_noise3: - fprintf (f, "float_noise3"); - break; - case slang_asm_float_noise4: - fprintf (f, "float_noise4"); - break; - case slang_asm_int_copy: - fprintf (f, "int_copy\t%d, %d", a->param[0], a->param[1]); - break; - case slang_asm_int_move: - fprintf (f, "int_move\t%d, %d", a->param[0], a->param[1]); - break; - case slang_asm_int_push: - fprintf (f, "int_push\t%d", (GLint) a->literal); - break; - case slang_asm_int_deref: - fprintf (f, "int_deref"); - break; - case slang_asm_int_to_float: - fprintf (f, "int_to_float"); - break; - case slang_asm_int_to_addr: - fprintf (f, "int_to_addr"); - break; - case slang_asm_bool_copy: - fprintf (f, "bool_copy\t%d, %d", a->param[0], a->param[1]); - break; - case slang_asm_bool_move: - fprintf (f, "bool_move\t%d, %d", a->param[0], a->param[1]); - break; - case slang_asm_bool_push: - fprintf (f, "bool_push\t%d", a->literal != 0.0f); - break; - case slang_asm_bool_deref: - fprintf (f, "bool_deref"); - break; - case slang_asm_addr_copy: - fprintf (f, "addr_copy"); - break; - case slang_asm_addr_push: - fprintf (f, "addr_push\t%u", a->param[0]); - break; - case slang_asm_addr_deref: - fprintf (f, "addr_deref"); - break; - case slang_asm_addr_add: - fprintf (f, "addr_add"); - break; - case slang_asm_addr_multiply: - fprintf (f, "addr_multiply"); - break; - case slang_asm_vec4_tex1d: - fprintf (f, "vec4_tex1d"); - break; - case slang_asm_vec4_tex2d: - fprintf (f, "vec4_tex2d"); - break; - case slang_asm_vec4_tex3d: - fprintf (f, "vec4_tex3d"); - break; - case slang_asm_vec4_texcube: - fprintf (f, "vec4_texcube"); - break; - case slang_asm_vec4_shad1d: - fprintf (f, "vec4_shad1d"); - break; - case slang_asm_vec4_shad2d: - fprintf (f, "vec4_shad2d"); - break; - case slang_asm_jump: - fprintf (f, "jump\t%u", a->param[0]); - break; - case slang_asm_jump_if_zero: - fprintf (f, "jump_if_zero\t%u", a->param[0]); - break; - case slang_asm_enter: - fprintf (f, "enter\t%u", a->param[0]); - break; - case slang_asm_leave: - fprintf (f, "leave"); - break; - case slang_asm_local_alloc: - fprintf (f, "local_alloc\t%u", a->param[0]); - break; - case slang_asm_local_free: - fprintf (f, "local_free\t%u", a->param[0]); - break; - case slang_asm_local_addr: - fprintf (f, "local_addr\t%u, %u", a->param[0], a->param[1]); - break; - case slang_asm_global_addr: - fprintf (f, "global_addr\t%u", a->param[0]); - break; - case slang_asm_call: - fprintf (f, "call\t%u", a->param[0]); - break; - case slang_asm_return: - fprintf (f, "return"); - break; - case slang_asm_discard: - fprintf (f, "discard"); - break; - case slang_asm_exit: - fprintf (f, "exit"); - break; - /* GL_MESA_shader_debug */ - case slang_asm_float_print: - fprintf (f, "float_print"); - break; - case slang_asm_int_print: - fprintf (f, "int_print"); - break; - case slang_asm_bool_print: - fprintf (f, "bool_print"); - break; - /* vec4 */ + fprintf(f, "%.5u:\t", i); + + switch (a->type) { + /* core */ + case slang_asm_none: + fprintf(f, "none"); + break; + case slang_asm_float_copy: + fprintf(f, "float_copy\t%d, %d", a->param[0], a->param[1]); + break; + case slang_asm_float_move: + fprintf(f, "float_move\t%d, %d", a->param[0], a->param[1]); + break; + case slang_asm_float_push: + fprintf(f, "float_push\t%f", a->literal); + break; + case slang_asm_float_deref: + fprintf(f, "float_deref"); + break; + case slang_asm_float_add: + fprintf(f, "float_add"); + break; + case slang_asm_float_multiply: + fprintf(f, "float_multiply"); + break; + case slang_asm_float_divide: + fprintf(f, "float_divide"); + break; + case slang_asm_float_negate: + fprintf(f, "float_negate"); + break; + case slang_asm_float_less: + fprintf(f, "float_less"); + break; + case slang_asm_float_equal_exp: + fprintf(f, "float_equal"); + break; + case slang_asm_float_equal_int: + fprintf(f, "float_equal\t%d, %d", a->param[0], a->param[1]); + break; + case slang_asm_float_to_int: + fprintf(f, "float_to_int"); + break; + case slang_asm_float_sine: + fprintf(f, "float_sine"); + break; + case slang_asm_float_arcsine: + fprintf(f, "float_arcsine"); + break; + case slang_asm_float_arctan: + fprintf(f, "float_arctan"); + break; + case slang_asm_float_power: + fprintf(f, "float_power"); + break; + case slang_asm_float_log2: + fprintf(f, "float_log2"); + break; + case slang_asm_float_floor: + fprintf(f, "float_floor"); + break; + case slang_asm_float_ceil: + fprintf(f, "float_ceil"); + break; + case slang_asm_float_noise1: + fprintf(f, "float_noise1"); + break; + case slang_asm_float_noise2: + fprintf(f, "float_noise2"); + break; + case slang_asm_float_noise3: + fprintf(f, "float_noise3"); + break; + case slang_asm_float_noise4: + fprintf(f, "float_noise4"); + break; + case slang_asm_int_copy: + fprintf(f, "int_copy\t%d, %d", a->param[0], a->param[1]); + break; + case slang_asm_int_move: + fprintf(f, "int_move\t%d, %d", a->param[0], a->param[1]); + break; + case slang_asm_int_push: + fprintf(f, "int_push\t%d", (GLint) a->literal); + break; + case slang_asm_int_deref: + fprintf(f, "int_deref"); + break; + case slang_asm_int_to_float: + fprintf(f, "int_to_float"); + break; + case slang_asm_int_to_addr: + fprintf(f, "int_to_addr"); + break; + case slang_asm_bool_copy: + fprintf(f, "bool_copy\t%d, %d", a->param[0], a->param[1]); + break; + case slang_asm_bool_move: + fprintf(f, "bool_move\t%d, %d", a->param[0], a->param[1]); + break; + case slang_asm_bool_push: + fprintf(f, "bool_push\t%d", a->literal != 0.0f); + break; + case slang_asm_bool_deref: + fprintf(f, "bool_deref"); + break; + case slang_asm_addr_copy: + fprintf(f, "addr_copy"); + break; + case slang_asm_addr_push: + fprintf(f, "addr_push\t%u", a->param[0]); + break; + case slang_asm_addr_deref: + fprintf(f, "addr_deref"); + break; + case slang_asm_addr_add: + fprintf(f, "addr_add"); + break; + case slang_asm_addr_multiply: + fprintf(f, "addr_multiply"); + break; + case slang_asm_vec4_tex1d: + fprintf(f, "vec4_tex1d"); + break; + case slang_asm_vec4_tex2d: + fprintf(f, "vec4_tex2d"); + break; + case slang_asm_vec4_tex3d: + fprintf(f, "vec4_tex3d"); + break; + case slang_asm_vec4_texcube: + fprintf(f, "vec4_texcube"); + break; + case slang_asm_vec4_shad1d: + fprintf(f, "vec4_shad1d"); + break; + case slang_asm_vec4_shad2d: + fprintf(f, "vec4_shad2d"); + break; + case slang_asm_jump: + fprintf(f, "jump\t%u", a->param[0]); + break; + case slang_asm_jump_if_zero: + fprintf(f, "jump_if_zero\t%u", a->param[0]); + break; + case slang_asm_enter: + fprintf(f, "enter\t%u", a->param[0]); + break; + case slang_asm_leave: + fprintf(f, "leave"); + break; + case slang_asm_local_alloc: + fprintf(f, "local_alloc\t%u", a->param[0]); + break; + case slang_asm_local_free: + fprintf(f, "local_free\t%u", a->param[0]); + break; + case slang_asm_local_addr: + fprintf(f, "local_addr\t%u, %u", a->param[0], a->param[1]); + break; + case slang_asm_global_addr: + fprintf(f, "global_addr\t%u", a->param[0]); + break; + case slang_asm_call: + fprintf(f, "call\t%u", a->param[0]); + break; + case slang_asm_return: + fprintf(f, "return"); + break; + case slang_asm_discard: + fprintf(f, "discard"); + break; + case slang_asm_exit: + fprintf(f, "exit"); + break; + /* GL_MESA_shader_debug */ + case slang_asm_float_print: + fprintf(f, "float_print"); + break; + case slang_asm_int_print: + fprintf(f, "int_print"); + break; + case slang_asm_bool_print: + fprintf(f, "bool_print"); + break; + /* vec4 */ case slang_asm_float_to_vec4: - fprintf (f, "float_to_vec4"); + fprintf(f, "float_to_vec4"); break; case slang_asm_vec4_add: - fprintf (f, "vec4_add"); + fprintf(f, "vec4_add"); break; case slang_asm_vec4_subtract: - fprintf (f, "vec4_subtract"); + fprintf(f, "vec4_subtract"); break; case slang_asm_vec4_multiply: - fprintf (f, "vec4_multiply"); + fprintf(f, "vec4_multiply"); break; case slang_asm_vec4_divide: - fprintf (f, "vec4_divide"); + fprintf(f, "vec4_divide"); break; case slang_asm_vec4_negate: - fprintf (f, "vec4_negate"); + fprintf(f, "vec4_negate"); break; case slang_asm_vec4_dot: - fprintf (f, "vec4_dot"); + fprintf(f, "vec4_dot"); break; case slang_asm_vec4_copy: - fprintf (f, "vec4_copy"); + fprintf(f, "vec4_copy"); break; case slang_asm_vec4_deref: - fprintf (f, "vec4_deref"); + fprintf(f, "vec4_deref"); break; case slang_asm_vec4_equal_int: - fprintf (f, "vec4_equal"); + fprintf(f, "vec4_equal"); break; default: - break; - } + break; + } - fprintf (f, "\n"); + fprintf(f, "\n"); } -static void dump (const slang_assembly_file *file) +static void +dump(const slang_assembly_file * file) { - unsigned int i; - static unsigned int counter = 0; - FILE *f; - char filename[256]; + unsigned int i; + static unsigned int counter = 0; + FILE *f; + char filename[256]; - counter++; - _mesa_sprintf (filename, "~mesa-slang-assembly-dump-(%u).txt", counter); - f = fopen (filename, "w"); - if (f == NULL) - return; + counter++; + _mesa_sprintf(filename, "~mesa-slang-assembly-dump-(%u).txt", counter); + f = fopen(filename, "w"); + if (f == NULL) + return; - for (i = 0; i < file->count; i++) - dump_instruction (f, file->code + i, i); + for (i = 0; i < file->count; i++) + dump_instruction(f, file->code + i, i); - fclose (f); + fclose(f); } #endif static GLvoid -ensure_infolog_created (slang_info_log **infolog) +ensure_infolog_created(slang_info_log ** infolog) { if (*infolog == NULL) { - *infolog = slang_alloc_malloc (sizeof (slang_info_log)); + *infolog = slang_alloc_malloc(sizeof(slang_info_log)); if (*infolog == NULL) return; - slang_info_log_construct (*infolog); + slang_info_log_construct(*infolog); } } GLboolean -_slang_execute2 (const slang_assembly_file *file, slang_machine *mach) +_slang_execute2(const slang_assembly_file * file, slang_machine * mach) { - slang_machine_slot *stack; + slang_machine_slot *stack; #if DEBUG_SLANG - static unsigned int counter = 0; - char filename[256]; - FILE *f; + static unsigned int counter = 0; + char filename[256]; + FILE *f; #endif - /* assume 32-bit floats and uints; should work fine also on 64-bit platforms */ - static_assert(sizeof (GLfloat) == 4); - static_assert(sizeof (GLuint) == 4); + /* assume 32-bit floats and uints; should work fine also on 64-bit platforms */ + static_assert(sizeof(GLfloat) == 4); + static_assert(sizeof(GLuint) == 4); #if DEBUG_SLANG - dump (file); - counter++; - _mesa_sprintf (filename, "~mesa-slang-assembly-exec-(%u).txt", counter); - f = fopen (filename, "w"); + dump(file); + counter++; + _mesa_sprintf(filename, "~mesa-slang-assembly-exec-(%u).txt", counter); + f = fopen(filename, "w"); #endif #if defined(USE_X86_ASM) || defined(SLANG_X86) - if (mach->x86.compiled_func != NULL) - { - mach->x86.compiled_func (mach); - return GL_TRUE; - } + if (mach->x86.compiled_func != NULL) { + mach->x86.compiled_func(mach); + return GL_TRUE; + } #endif - stack = mach->mem + SLANG_MACHINE_GLOBAL_SIZE; + stack = mach->mem + SLANG_MACHINE_GLOBAL_SIZE; - while (!mach->exit) - { - slang_assembly *a = &file->code[mach->ip]; + while (!mach->exit) { + const slang_assembly *a = &file->code[mach->ip]; #if DEBUG_SLANG - if (f != NULL && a->type != slang_asm_none) - { - unsigned int i; + if (f != NULL && a->type != slang_asm_none) { + unsigned int i; - dump_instruction (f, file->code + mach->ip, mach->ip); - fprintf (f, "\t\tsp=%u bp=%u\n", mach->sp, mach->bp); - for (i = mach->sp; i < SLANG_MACHINE_STACK_SIZE; i++) - fprintf (f, "\t%.5u\t%6f\t%u\n", i, stack[i]._float, stack[i]._addr); - fflush (f); - } + dump_instruction(f, file->code + mach->ip, mach->ip); + fprintf(f, "\t\tsp=%u bp=%u\n", mach->sp, mach->bp); + for (i = mach->sp; i < SLANG_MACHINE_STACK_SIZE; i++) + fprintf(f, "\t%.5u\t%6f\t%u\n", i, stack[i]._float, + stack[i]._addr); + fflush(f); + } #endif - mach->ip++; + mach->ip++; - switch (a->type) - { - /* core */ - case slang_asm_none: - break; - case slang_asm_float_copy: - case slang_asm_int_copy: - case slang_asm_bool_copy: - mach->mem[(stack[mach->sp + a->param[0] / 4]._addr + a->param[1]) / 4]._float = - stack[mach->sp]._float; - mach->sp++; - break; - case slang_asm_float_move: - case slang_asm_int_move: - case slang_asm_bool_move: - stack[mach->sp + a->param[0] / 4]._float = - stack[mach->sp + (stack[mach->sp]._addr + a->param[1]) / 4]._float; - break; - case slang_asm_float_push: - case slang_asm_int_push: - case slang_asm_bool_push: - mach->sp--; - stack[mach->sp]._float = a->literal; - break; - case slang_asm_float_deref: - case slang_asm_int_deref: - case slang_asm_bool_deref: - stack[mach->sp]._float = mach->mem[stack[mach->sp]._addr / 4]._float; - break; - case slang_asm_float_add: - stack[mach->sp + 1]._float += stack[mach->sp]._float; - mach->sp++; - break; - case slang_asm_float_multiply: - stack[mach->sp + 1]._float *= stack[mach->sp]._float; - mach->sp++; - break; - case slang_asm_float_divide: - stack[mach->sp + 1]._float /= stack[mach->sp]._float; - mach->sp++; - break; - case slang_asm_float_negate: - stack[mach->sp]._float = -stack[mach->sp]._float; - break; - case slang_asm_float_less: - stack[mach->sp + 1]._float = - stack[mach->sp + 1]._float < stack[mach->sp]._float ? (GLfloat) 1 : (GLfloat) 0; - mach->sp++; - break; - case slang_asm_float_equal_exp: - stack[mach->sp + 1]._float = - stack[mach->sp + 1]._float == stack[mach->sp]._float ? (GLfloat) 1 : (GLfloat) 0; - mach->sp++; - break; - case slang_asm_float_equal_int: - mach->sp--; - stack[mach->sp]._float = stack[mach->sp + 1 + a->param[0] / 4]._float == - stack[mach->sp + 1 + a->param[1] / 4]._float ? (GLfloat) 1 : (GLfloat) 0; - break; - case slang_asm_float_to_int: - stack[mach->sp]._float = (GLfloat) (GLint) stack[mach->sp]._float; - break; - case slang_asm_float_sine: - stack[mach->sp]._float = (GLfloat) _mesa_sin (stack[mach->sp]._float); - break; - case slang_asm_float_arcsine: - stack[mach->sp]._float = _mesa_asinf (stack[mach->sp]._float); - break; - case slang_asm_float_arctan: - stack[mach->sp]._float = _mesa_atanf (stack[mach->sp]._float); - break; - case slang_asm_float_power: - stack[mach->sp + 1]._float = - (GLfloat) _mesa_pow (stack[mach->sp + 1]._float, stack[mach->sp]._float); - mach->sp++; - break; - case slang_asm_float_log2: - stack[mach->sp]._float = LOG2 (stack[mach->sp]._float); - break; - case slang_asm_float_floor: - stack[mach->sp]._float = FLOORF (stack[mach->sp]._float); - break; - case slang_asm_float_ceil: - stack[mach->sp]._float = CEILF (stack[mach->sp]._float); - break; - case slang_asm_float_noise1: - stack[mach->sp]._float = _slang_library_noise1 (stack[mach->sp]._float); - break; - case slang_asm_float_noise2: - stack[mach->sp + 1]._float = _slang_library_noise2 (stack[mach->sp]._float, - stack[mach->sp + 1]._float); - mach->sp++; - break; - case slang_asm_float_noise3: - stack[mach->sp + 2]._float = _slang_library_noise3 (stack[mach->sp]._float, - stack[mach->sp + 1]._float, stack[mach->sp + 2]._float); - mach->sp += 2; - break; - case slang_asm_float_noise4: - stack[mach->sp + 3]._float = _slang_library_noise4 (stack[mach->sp]._float, - stack[mach->sp + 1]._float, stack[mach->sp + 2]._float, stack[mach->sp + 3]._float); - mach->sp += 3; - break; - case slang_asm_int_to_float: - break; - case slang_asm_int_to_addr: - stack[mach->sp]._addr = (GLuint) (GLint) stack[mach->sp]._float; - break; - case slang_asm_addr_copy: - mach->mem[stack[mach->sp + 1]._addr / 4]._addr = stack[mach->sp]._addr; - mach->sp++; - break; - case slang_asm_addr_push: - case slang_asm_global_addr: - mach->sp--; - stack[mach->sp]._addr = a->param[0]; - break; - case slang_asm_addr_deref: - stack[mach->sp]._addr = mach->mem[stack[mach->sp]._addr / 4]._addr; - break; - case slang_asm_addr_add: - stack[mach->sp + 1]._addr += stack[mach->sp]._addr; - mach->sp++; - break; - case slang_asm_addr_multiply: - stack[mach->sp + 1]._addr *= stack[mach->sp]._addr; - mach->sp++; - break; - case slang_asm_vec4_tex1d: - _slang_library_tex1d (stack[mach->sp]._float, stack[mach->sp + 1]._float, - stack[mach->sp + 2]._float, &mach->mem[stack[mach->sp + 3]._addr / 4]._float); - mach->sp += 3; - break; - case slang_asm_vec4_tex2d: - _slang_library_tex2d (stack[mach->sp]._float, stack[mach->sp + 1]._float, - stack[mach->sp + 2]._float, stack[mach->sp + 3]._float, - &mach->mem[stack[mach->sp + 4]._addr / 4]._float); - mach->sp += 4; - break; - case slang_asm_vec4_tex3d: - _slang_library_tex3d (stack[mach->sp]._float, stack[mach->sp + 1]._float, - stack[mach->sp + 2]._float, stack[mach->sp + 3]._float, stack[mach->sp + 4]._float, - &mach->mem[stack[mach->sp + 5]._addr / 4]._float); - mach->sp += 5; - break; - case slang_asm_vec4_texcube: - _slang_library_texcube (stack[mach->sp]._float, stack[mach->sp + 1]._float, - stack[mach->sp + 2]._float, stack[mach->sp + 3]._float, stack[mach->sp + 4]._float, - &mach->mem[stack[mach->sp + 5]._addr / 4]._float); - mach->sp += 5; - break; - case slang_asm_vec4_shad1d: - _slang_library_shad1d (stack[mach->sp]._float, stack[mach->sp + 1]._float, - stack[mach->sp + 2]._float, stack[mach->sp + 3]._float, stack[mach->sp + 4]._float, - &mach->mem[stack[mach->sp + 5]._addr / 4]._float); - mach->sp += 5; - break; - case slang_asm_vec4_shad2d: - _slang_library_shad2d (stack[mach->sp]._float, stack[mach->sp + 1]._float, - stack[mach->sp + 2]._float, stack[mach->sp + 3]._float, stack[mach->sp + 4]._float, - &mach->mem[stack[mach->sp + 5]._addr / 4]._float); - mach->sp += 5; - break; - case slang_asm_jump: - mach->ip = a->param[0]; - break; - case slang_asm_jump_if_zero: - if (stack[mach->sp]._float == 0.0f) - mach->ip = a->param[0]; - mach->sp++; - break; - case slang_asm_enter: - mach->sp--; - stack[mach->sp]._addr = mach->bp; - mach->bp = mach->sp + a->param[0] / 4; - break; - case slang_asm_leave: - mach->bp = stack[mach->sp]._addr; - mach->sp++; - break; - case slang_asm_local_alloc: - mach->sp -= a->param[0] / 4; - break; - case slang_asm_local_free: - mach->sp += a->param[0] / 4; - break; - case slang_asm_local_addr: - mach->sp--; - stack[mach->sp]._addr = SLANG_MACHINE_GLOBAL_SIZE * 4 + mach->bp * 4 - - (a->param[0] + a->param[1]) + 4; - break; - case slang_asm_call: - mach->sp--; - stack[mach->sp]._addr = mach->ip; - mach->ip = a->param[0]; - break; - case slang_asm_return: - mach->ip = stack[mach->sp]._addr; - mach->sp++; - break; - case slang_asm_discard: - mach->kill = 1; - break; - case slang_asm_exit: - mach->exit = 1; - break; - /* GL_MESA_shader_debug */ - case slang_asm_float_print: - _mesa_printf ("slang print: %f\n", stack[mach->sp]._float); - ensure_infolog_created (&mach->infolog); - slang_info_log_print (mach->infolog, "%f", stack[mach->sp]._float); - break; - case slang_asm_int_print: - _mesa_printf ("slang print: %d\n", (GLint) stack[mach->sp]._float); - ensure_infolog_created (&mach->infolog); - slang_info_log_print (mach->infolog, "%d", (GLint) (stack[mach->sp]._float)); - break; - case slang_asm_bool_print: - _mesa_printf ("slang print: %s\n", (GLint) stack[mach->sp]._float ? "true" : "false"); - ensure_infolog_created (&mach->infolog); - slang_info_log_print (mach->infolog, "%s", - (GLint) (stack[mach->sp]._float) ? "true" : "false"); - break; - /* vec4 */ + switch (a->type) { + /* core */ + case slang_asm_none: + break; + case slang_asm_float_copy: + case slang_asm_int_copy: + case slang_asm_bool_copy: + /* store top value on stack to memory */ + { + GLuint address + = (stack[mach->sp + a->param[0] / 4]._addr + a->param[1]) / 4; + GLfloat value = stack[mach->sp]._float; + mach->mem[address]._float = value; + } + mach->sp++; + break; + case slang_asm_float_move: + case slang_asm_int_move: + case slang_asm_bool_move: + stack[mach->sp + a->param[0] / 4]._float = + stack[mach->sp + + (stack[mach->sp]._addr + a->param[1]) / 4]._float; + break; + case slang_asm_float_push: + case slang_asm_int_push: + case slang_asm_bool_push: + /* push float/int/bool literal onto stop of stack */ + mach->sp--; + stack[mach->sp]._float = a->literal; + break; + case slang_asm_float_deref: + case slang_asm_int_deref: + case slang_asm_bool_deref: + /* load value from memory, replace stop of stack with it */ + stack[mach->sp]._float = mach->mem[stack[mach->sp]._addr / 4]._float; + break; + case slang_asm_float_add: + /* pop two top floats, push sum */ + stack[mach->sp + 1]._float += stack[mach->sp]._float; + mach->sp++; + break; + case slang_asm_float_multiply: + stack[mach->sp + 1]._float *= stack[mach->sp]._float; + mach->sp++; + break; + case slang_asm_float_divide: + stack[mach->sp + 1]._float /= stack[mach->sp]._float; + mach->sp++; + break; + case slang_asm_float_negate: + stack[mach->sp]._float = -stack[mach->sp]._float; + break; + case slang_asm_float_less: + stack[mach->sp + 1]._float = + (stack[mach->sp + 1]._float < stack[mach->sp]._float) + ? (GLfloat) 1 : (GLfloat) 0; + mach->sp++; + break; + case slang_asm_float_equal_exp: + stack[mach->sp + 1]._float = + (stack[mach->sp + 1]._float == stack[mach->sp]._float) + ? (GLfloat) 1 : (GLfloat) 0; + mach->sp++; + break; + case slang_asm_float_equal_int: + /* pop top two values, compare, push 0 or 1 */ + mach->sp--; + stack[mach->sp]._float = + (stack[mach->sp + 1 + a->param[0] / 4]._float == + stack[mach->sp + 1 + a->param[1] / 4]._float) + ? (GLfloat) 1 : (GLfloat) 0; + break; + case slang_asm_float_to_int: + stack[mach->sp]._float = (GLfloat) (GLint) stack[mach->sp]._float; + break; + case slang_asm_float_sine: + stack[mach->sp]._float = (GLfloat) _mesa_sin(stack[mach->sp]._float); + break; + case slang_asm_float_arcsine: + stack[mach->sp]._float = _mesa_asinf(stack[mach->sp]._float); + break; + case slang_asm_float_arctan: + stack[mach->sp]._float = _mesa_atanf(stack[mach->sp]._float); + break; + case slang_asm_float_power: + stack[mach->sp + 1]._float = (GLfloat) + _mesa_pow(stack[mach->sp + 1]._float, stack[mach->sp]._float); + mach->sp++; + break; + case slang_asm_float_log2: + stack[mach->sp]._float = LOG2(stack[mach->sp]._float); + break; + case slang_asm_float_floor: + stack[mach->sp]._float = FLOORF(stack[mach->sp]._float); + break; + case slang_asm_float_ceil: + stack[mach->sp]._float = CEILF(stack[mach->sp]._float); + break; + case slang_asm_float_noise1: + stack[mach->sp]._float = + _slang_library_noise1(stack[mach->sp]._float); + break; + case slang_asm_float_noise2: + stack[mach->sp + 1]._float = + _slang_library_noise2(stack[mach->sp]._float, + stack[mach->sp + 1]._float); + mach->sp++; + break; + case slang_asm_float_noise3: + stack[mach->sp + 2]._float = + _slang_library_noise3(stack[mach->sp]._float, + stack[mach->sp + 1]._float, + stack[mach->sp + 2]._float); + mach->sp += 2; + break; + case slang_asm_float_noise4: + stack[mach->sp + 3]._float = + _slang_library_noise4(stack[mach->sp]._float, + stack[mach->sp + 1]._float, + stack[mach->sp + 2]._float, + stack[mach->sp + 3]._float); + mach->sp += 3; + break; + case slang_asm_int_to_float: + break; + case slang_asm_int_to_addr: + stack[mach->sp]._addr = (GLuint) (GLint) stack[mach->sp]._float; + break; + case slang_asm_addr_copy: + mach->mem[stack[mach->sp + 1]._addr / 4]._addr = + stack[mach->sp]._addr; + mach->sp++; + break; + case slang_asm_addr_push: + case slang_asm_global_addr: + mach->sp--; + stack[mach->sp]._addr = a->param[0]; + break; + case slang_asm_addr_deref: + stack[mach->sp]._addr = mach->mem[stack[mach->sp]._addr / 4]._addr; + break; + case slang_asm_addr_add: + stack[mach->sp + 1]._addr += stack[mach->sp]._addr; + mach->sp++; + break; + case slang_asm_addr_multiply: + stack[mach->sp + 1]._addr *= stack[mach->sp]._addr; + mach->sp++; + break; + case slang_asm_vec4_tex1d: + _slang_library_tex1d(stack[mach->sp]._float, + stack[mach->sp + 1]._float, + stack[mach->sp + 2]._float, + &mach->mem[stack[mach->sp + 3]._addr / + 4]._float); + mach->sp += 3; + break; + case slang_asm_vec4_tex2d: + _slang_library_tex2d(stack[mach->sp]._float, + stack[mach->sp + 1]._float, + stack[mach->sp + 2]._float, + stack[mach->sp + 3]._float, + &mach->mem[stack[mach->sp + 4]._addr / + 4]._float); + mach->sp += 4; + break; + case slang_asm_vec4_tex3d: + _slang_library_tex3d(stack[mach->sp]._float, + stack[mach->sp + 1]._float, + stack[mach->sp + 2]._float, + stack[mach->sp + 3]._float, + stack[mach->sp + 4]._float, + &mach->mem[stack[mach->sp + 5]._addr / + 4]._float); + mach->sp += 5; + break; + case slang_asm_vec4_texcube: + _slang_library_texcube(stack[mach->sp]._float, + stack[mach->sp + 1]._float, + stack[mach->sp + 2]._float, + stack[mach->sp + 3]._float, + stack[mach->sp + 4]._float, + &mach->mem[stack[mach->sp + 5]._addr / + 4]._float); + mach->sp += 5; + break; + case slang_asm_vec4_shad1d: + _slang_library_shad1d(stack[mach->sp]._float, + stack[mach->sp + 1]._float, + stack[mach->sp + 2]._float, + stack[mach->sp + 3]._float, + stack[mach->sp + 4]._float, + &mach->mem[stack[mach->sp + 5]._addr / + 4]._float); + mach->sp += 5; + break; + case slang_asm_vec4_shad2d: + _slang_library_shad2d(stack[mach->sp]._float, + stack[mach->sp + 1]._float, + stack[mach->sp + 2]._float, + stack[mach->sp + 3]._float, + stack[mach->sp + 4]._float, + &mach->mem[stack[mach->sp + 5]._addr / + 4]._float); + mach->sp += 5; + break; + case slang_asm_jump: + mach->ip = a->param[0]; + break; + case slang_asm_jump_if_zero: + if (stack[mach->sp]._float == 0.0f) + mach->ip = a->param[0]; + mach->sp++; + break; + case slang_asm_enter: + mach->sp--; + stack[mach->sp]._addr = mach->bp; + mach->bp = mach->sp + a->param[0] / 4; + break; + case slang_asm_leave: + mach->bp = stack[mach->sp]._addr; + mach->sp++; + break; + case slang_asm_local_alloc: + mach->sp -= a->param[0] / 4; + break; + case slang_asm_local_free: + mach->sp += a->param[0] / 4; + break; + case slang_asm_local_addr: + mach->sp--; + stack[mach->sp]._addr = + SLANG_MACHINE_GLOBAL_SIZE * 4 + mach->bp * 4 - (a->param[0] + + a->param[1]) + 4; + break; + case slang_asm_call: + mach->sp--; + stack[mach->sp]._addr = mach->ip; + mach->ip = a->param[0]; + break; + case slang_asm_return: + mach->ip = stack[mach->sp]._addr; + mach->sp++; + break; + case slang_asm_discard: + mach->kill = GL_TRUE; + break; + case slang_asm_exit: + mach->exit = GL_TRUE; + break; + /* GL_MESA_shader_debug */ + case slang_asm_float_print: + _mesa_printf("slang print: %f\n", stack[mach->sp]._float); + ensure_infolog_created(&mach->infolog); + slang_info_log_print(mach->infolog, "%f", stack[mach->sp]._float); + break; + case slang_asm_int_print: + _mesa_printf("slang print: %d\n", (GLint) stack[mach->sp]._float); + ensure_infolog_created(&mach->infolog); + slang_info_log_print(mach->infolog, "%d", + (GLint) (stack[mach->sp]._float)); + break; + case slang_asm_bool_print: + _mesa_printf("slang print: %s\n", + (GLint) stack[mach->sp]._float ? "true" : "false"); + ensure_infolog_created(&mach->infolog); + slang_info_log_print(mach->infolog, "%s", + (GLint) (stack[mach->sp]. + _float) ? "true" : "false"); + break; + /* vec4 */ case slang_asm_float_to_vec4: /* [vec4] | float > [vec4] */ { @@ -660,7 +714,8 @@ _slang_execute2 (const slang_assembly_file *file, slang_machine *mach) mach->mem[da / 4]._float = -mach->mem[da / 4]._float; mach->mem[(da + 4) / 4]._float = -mach->mem[(da + 4) / 4]._float; mach->mem[(da + 8) / 4]._float = -mach->mem[(da + 8) / 4]._float; - mach->mem[(da + 12) / 4]._float = -mach->mem[(da + 12) / 4]._float; + mach->mem[(da + 12) / 4]._float = + -mach->mem[(da + 12) / 4]._float; } break; case slang_asm_vec4_dot: @@ -721,9 +776,8 @@ _slang_execute2 (const slang_assembly_file *file, slang_machine *mach) #if DEBUG_SLANG if (f != NULL) - fclose (f); + fclose(f); #endif return GL_TRUE; } - diff --git a/src/mesa/shader/slang/slang_execute.h b/src/mesa/shader/slang/slang_execute.h index cb152c71420..138f1393081 100644 --- a/src/mesa/shader/slang/slang_execute.h +++ b/src/mesa/shader/slang/slang_execute.h @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.2 * * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. * @@ -22,7 +22,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if !defined SLANG_EXECUTE_H +#ifndef SLANG_EXECUTE_H #define SLANG_EXECUTE_H #include "slang_assemble.h" @@ -31,55 +31,75 @@ extern "C" { #endif + +/** + * A memory location + */ typedef union slang_machine_slot_ { - GLfloat _float; - GLuint _addr; + GLfloat _float; + GLuint _addr; } slang_machine_slot; #define SLANG_MACHINE_GLOBAL_SIZE 3072 #define SLANG_MACHINE_STACK_SIZE 1024 #define SLANG_MACHINE_MEMORY_SIZE (SLANG_MACHINE_GLOBAL_SIZE + SLANG_MACHINE_STACK_SIZE) + #if defined(USE_X86_ASM) || defined(SLANG_X86) +/** + * Extra machine state for x86 execution. + */ typedef struct { - GLvoid (* compiled_func) (struct slang_machine_ *); - GLuint esp_restore; - GLshort fpucntl_rnd_neg; - GLshort fpucntl_restore; + GLvoid(*compiled_func) (struct slang_machine_ *); + GLuint esp_restore; + GLshort fpucntl_rnd_neg; + GLshort fpucntl_restore; } slang_machine_x86; #endif + +/** + * Runtime shader machine state. + */ typedef struct slang_machine_ { - GLuint ip; /* instruction pointer, for flow control */ - GLuint sp; /* stack pointer, for stack access */ - GLuint bp; /* base pointer, for local variable access */ - GLuint kill; /* discard the fragment */ - GLuint exit; /* terminate the shader */ - slang_machine_slot mem[SLANG_MACHINE_MEMORY_SIZE]; - struct slang_info_log_ *infolog; /* printMESA() support */ + GLuint ip; /**< instruction pointer, for flow control */ + GLuint sp; /**< stack pointer, for stack access */ + GLuint bp; /**< base pointer, for local variable access */ + GLboolean kill; /**< discard the fragment? */ + GLboolean exit; /**< terminate the shader */ + /** Machine memory */ + slang_machine_slot mem[SLANG_MACHINE_MEMORY_SIZE]; + struct slang_info_log_ *infolog; /**< printMESA() support */ #if defined(USE_X86_ASM) || defined(SLANG_X86) - slang_machine_x86 x86; + slang_machine_x86 x86; #endif } slang_machine; -GLvoid slang_machine_ctr (slang_machine *); -GLvoid slang_machine_dtr (slang_machine *); -void slang_machine_init (slang_machine *); +extern GLvoid +slang_machine_ctr(slang_machine *); + +extern GLvoid +slang_machine_dtr(slang_machine *); + +extern void +slang_machine_init(slang_machine *); + +extern GLboolean +_slang_execute2(const slang_assembly_file *, slang_machine *); -GLboolean -_slang_execute2 (const slang_assembly_file *, slang_machine *); #if defined(USE_X86_ASM) || defined(SLANG_X86) -GLboolean _slang_x86_codegen (slang_machine *, slang_assembly_file *, GLuint); +extern GLboolean +_slang_x86_codegen(slang_machine *, slang_assembly_file *, GLuint); #endif + #ifdef __cplusplus } #endif #endif - diff --git a/src/mesa/shader/slang/slang_execute_x86.c b/src/mesa/shader/slang/slang_execute_x86.c index 3e21edff6a3..958086ff07c 100644 --- a/src/mesa/shader/slang/slang_execute_x86.c +++ b/src/mesa/shader/slang/slang_execute_x86.c @@ -40,40 +40,42 @@ typedef struct { - GLuint index; - GLubyte *csr; + GLuint index; + GLubyte *csr; } fixup; typedef struct { - struct x86_function f; - struct x86_reg r_eax; - struct x86_reg r_ecx; - struct x86_reg r_edx; + struct x86_function f; + struct x86_reg r_eax; + struct x86_reg r_ecx; + struct x86_reg r_edx; struct x86_reg r_ebx; - struct x86_reg r_esp; - struct x86_reg r_ebp; - struct x86_reg r_st0; - struct x86_reg r_st1; - struct x86_reg r_st2; - struct x86_reg r_st3; + struct x86_reg r_esp; + struct x86_reg r_ebp; + struct x86_reg r_st0; + struct x86_reg r_st1; + struct x86_reg r_st2; + struct x86_reg r_st3; struct x86_reg r_st4; - fixup *fixups; - GLuint fixup_count; - GLubyte **labels; - slang_machine *mach; - GLubyte *l_discard; - GLubyte *l_exit; - GLshort fpucntl; + fixup *fixups; + GLuint fixup_count; + GLubyte **labels; + slang_machine *mach; + GLubyte *l_discard; + GLubyte *l_exit; + GLshort fpucntl; } codegen_ctx; -static GLvoid add_fixup (codegen_ctx *G, GLuint index, GLubyte *csr) +static GLvoid +add_fixup(codegen_ctx * G, GLuint index, GLubyte * csr) { - G->fixups = (fixup *) slang_alloc_realloc (G->fixups, G->fixup_count * sizeof (fixup), - (G->fixup_count + 1) * sizeof (fixup)); - G->fixups[G->fixup_count].index = index; - G->fixups[G->fixup_count].csr = csr; - G->fixup_count++; + G->fixups = + (fixup *) slang_alloc_realloc(G->fixups, G->fixup_count * sizeof(fixup), + (G->fixup_count + 1) * sizeof(fixup)); + G->fixups[G->fixup_count].index = index; + G->fixups[G->fixup_count].csr = csr; + G->fixup_count++; } #ifdef NO_FAST_MATH @@ -88,661 +90,665 @@ static GLvoid add_fixup (codegen_ctx *G, GLuint index, GLubyte *csr) /* * XXX - * These should produce a valid code that computes powers. Unfortunately, it does not. + * These should produce a valid code that computes powers. + * Unfortunately, it does not. */ -static void set_fpu_round_neg_inf (codegen_ctx *G) +static void +set_fpu_round_neg_inf(codegen_ctx * G) { - if (G->fpucntl != RND_NEG_FPU) - { - G->fpucntl = RND_NEG_FPU; - x87_fnclex (&G->f); - x86_mov_reg_imm (&G->f, G->r_eax, (GLint) &G->mach->x86.fpucntl_rnd_neg); - x87_fldcw (&G->f, x86_deref (G->r_eax)); - } + if (G->fpucntl != RND_NEG_FPU) { + G->fpucntl = RND_NEG_FPU; + x87_fnclex(&G->f); + x86_mov_reg_imm(&G->f, G->r_eax, + (GLint) & G->mach->x86.fpucntl_rnd_neg); + x87_fldcw(&G->f, x86_deref(G->r_eax)); + } } -static void emit_x87_ex2 (codegen_ctx *G) +static void +emit_x87_ex2(codegen_ctx * G) { - set_fpu_round_neg_inf (G); - - x87_fld (&G->f, G->r_st0); /* a a */ - x87_fprndint (&G->f); /* int(a) a */ - x87_fld (&G->f, G->r_st0); /* int(a) int(a) a */ - x87_fstp (&G->f, G->r_st3); /* int(a) a int(a)*/ - x87_fsubp (&G->f, G->r_st1);/* frac(a) int(a) */ - x87_f2xm1 (&G->f); /* (2^frac(a))-1 int(a)*/ - x87_fld1 (&G->f); /* 1 (2^frac(a))-1 int(a)*/ - x87_faddp (&G->f, G->r_st1);/* 2^frac(a) int(a) */ - x87_fscale (&G->f); /* 2^a */ + set_fpu_round_neg_inf(G); + + x87_fld(&G->f, G->r_st0); /* a a */ + x87_fprndint(&G->f); /* int(a) a */ + x87_fld(&G->f, G->r_st0); /* int(a) int(a) a */ + x87_fstp(&G->f, G->r_st3); /* int(a) a int(a) */ + x87_fsubp(&G->f, G->r_st1); /* frac(a) int(a) */ + x87_f2xm1(&G->f); /* (2^frac(a))-1 int(a) */ + x87_fld1(&G->f); /* 1 (2^frac(a))-1 int(a) */ + x87_faddp(&G->f, G->r_st1); /* 2^frac(a) int(a) */ + x87_fscale(&G->f); /* 2^a */ } -static void emit_pow (codegen_ctx *G) +static void +emit_pow(codegen_ctx * G) { - x87_fld (&G->f, x86_deref (G->r_esp)); - x87_fld (&G->f, x86_make_disp (G->r_esp, 4)); - x87_fyl2x (&G->f); - emit_x87_ex2 (G); + x87_fld(&G->f, x86_deref(G->r_esp)); + x87_fld(&G->f, x86_make_disp(G->r_esp, 4)); + x87_fyl2x(&G->f); + emit_x87_ex2(G); } #endif -static GLfloat do_ceilf (GLfloat x) +static GLfloat +do_ceilf(GLfloat x) { - return CEILF (x); + return CEILF(x); } -static GLfloat do_floorf (GLfloat x) +static GLfloat +do_floorf(GLfloat x) { - return FLOORF (x); + return FLOORF(x); } static GLfloat -do_ftoi (GLfloat x) +do_ftoi(GLfloat x) { return (GLfloat) ((GLint) (x)); } -static GLfloat do_powf (GLfloat y, GLfloat x) +static GLfloat +do_powf(GLfloat y, GLfloat x) { - return (GLfloat) _mesa_pow ((GLdouble) x, (GLdouble) y); + return (GLfloat) _mesa_pow((GLdouble) x, (GLdouble) y); } static GLvoid -ensure_infolog_created (slang_info_log **infolog) +ensure_infolog_created(slang_info_log ** infolog) { if (*infolog == NULL) { - *infolog = slang_alloc_malloc (sizeof (slang_info_log)); + *infolog = slang_alloc_malloc(sizeof(slang_info_log)); if (*infolog == NULL) return; - slang_info_log_construct (*infolog); + slang_info_log_construct(*infolog); } } -static GLvoid do_print_float (slang_info_log **infolog, GLfloat x) +static GLvoid +do_print_float(slang_info_log ** infolog, GLfloat x) { - _mesa_printf ("slang print: %f\n", x); - ensure_infolog_created (infolog); - slang_info_log_print (*infolog, "%f", x); + _mesa_printf("slang print: %f\n", x); + ensure_infolog_created(infolog); + slang_info_log_print(*infolog, "%f", x); } -static GLvoid do_print_int (slang_info_log **infolog, GLfloat x) +static GLvoid +do_print_int(slang_info_log ** infolog, GLfloat x) { - _mesa_printf ("slang print: %d\n", (GLint) (x)); - ensure_infolog_created (infolog); - slang_info_log_print (*infolog, "%d", (GLint) (x)); + _mesa_printf("slang print: %d\n", (GLint) (x)); + ensure_infolog_created(infolog); + slang_info_log_print(*infolog, "%d", (GLint) (x)); } -static GLvoid do_print_bool (slang_info_log **infolog, GLfloat x) +static GLvoid +do_print_bool(slang_info_log ** infolog, GLfloat x) { - _mesa_printf ("slang print: %s\n", (GLint) (x) ? "true" : "false"); - ensure_infolog_created (infolog); - slang_info_log_print (*infolog, "%s", (GLint) (x) ? "true" : "false"); + _mesa_printf("slang print: %s\n", (GLint) (x) ? "true" : "false"); + ensure_infolog_created(infolog); + slang_info_log_print(*infolog, "%s", (GLint) (x) ? "true" : "false"); } #define FLOAT_ONE 0x3f800000 #define FLOAT_ZERO 0 -static GLvoid codegen_assem (codegen_ctx *G, slang_assembly *a, slang_info_log **infolog) +static GLvoid +codegen_assem(codegen_ctx * G, slang_assembly * a, slang_info_log ** infolog) { - GLint disp, i; - - switch (a->type) - { - case slang_asm_none: - break; - case slang_asm_float_copy: - case slang_asm_int_copy: - case slang_asm_bool_copy: - x86_mov (&G->f, G->r_eax, x86_make_disp (G->r_esp, a->param[0])); - x86_pop (&G->f, G->r_ecx); - x86_mov (&G->f, x86_make_disp (G->r_eax, a->param[1]), G->r_ecx); - break; - case slang_asm_float_move: - case slang_asm_int_move: - case slang_asm_bool_move: - x86_lea (&G->f, G->r_eax, x86_make_disp (G->r_esp, a->param[1])); - x86_add (&G->f, G->r_eax, x86_deref (G->r_esp)); - x86_mov (&G->f, G->r_eax, x86_deref (G->r_eax)); - x86_mov (&G->f, x86_make_disp (G->r_esp, a->param[0]), G->r_eax); - break; - case slang_asm_float_push: - case slang_asm_int_push: - case slang_asm_bool_push: - /* TODO: use push imm32 */ - x86_mov_reg_imm (&G->f, G->r_eax, *((GLint *) &a->literal)); - x86_push (&G->f, G->r_eax); - break; - case slang_asm_float_deref: - case slang_asm_int_deref: - case slang_asm_bool_deref: - case slang_asm_addr_deref: - x86_mov (&G->f, G->r_eax, x86_deref (G->r_esp)); - x86_mov (&G->f, G->r_eax, x86_deref (G->r_eax)); - x86_mov (&G->f, x86_deref (G->r_esp), G->r_eax); - break; - case slang_asm_float_add: - x87_fld (&G->f, x86_make_disp (G->r_esp, 4)); - x87_fld (&G->f, x86_deref (G->r_esp)); - x87_faddp (&G->f, G->r_st1); - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4)); - x87_fstp (&G->f, x86_deref (G->r_esp)); - break; - case slang_asm_float_multiply: - x87_fld (&G->f, x86_make_disp (G->r_esp, 4)); - x87_fld (&G->f, x86_deref (G->r_esp)); - x87_fmulp (&G->f, G->r_st1); - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4)); - x87_fstp (&G->f, x86_deref (G->r_esp)); - break; - case slang_asm_float_divide: - x87_fld (&G->f, x86_make_disp (G->r_esp, 4)); - x87_fld (&G->f, x86_deref (G->r_esp)); - x87_fdivp (&G->f, G->r_st1); - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4)); - x87_fstp (&G->f, x86_deref (G->r_esp)); - break; - case slang_asm_float_negate: - x87_fld (&G->f, x86_deref (G->r_esp)); - x87_fchs (&G->f); - x87_fstp (&G->f, x86_deref (G->r_esp)); - break; - case slang_asm_float_less: - x87_fld (&G->f, x86_make_disp (G->r_esp, 4)); - x87_fcomp (&G->f, x86_deref (G->r_esp)); - x87_fnstsw (&G->f, G->r_eax); - /* TODO: use test r8,imm8 */ - x86_mov_reg_imm (&G->f, G->r_ecx, 0x100); - x86_test (&G->f, G->r_eax, G->r_ecx); - { - GLubyte *lab0, *lab1; - - /* TODO: use jcc rel8 */ - lab0 = x86_jcc_forward (&G->f, cc_E); - x86_mov_reg_imm (&G->f, G->r_ecx, FLOAT_ONE); - /* TODO: use jmp rel8 */ - lab1 = x86_jmp_forward (&G->f); - x86_fixup_fwd_jump (&G->f, lab0); - x86_mov_reg_imm (&G->f, G->r_ecx, FLOAT_ZERO); - x86_fixup_fwd_jump (&G->f, lab1); - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4)); - x86_mov (&G->f, x86_deref (G->r_esp), G->r_ecx); - } - break; - case slang_asm_float_equal_exp: - x87_fld (&G->f, x86_make_disp (G->r_esp, 4)); - x87_fcomp (&G->f, x86_deref (G->r_esp)); - x87_fnstsw (&G->f, G->r_eax); - /* TODO: use test r8,imm8 */ - x86_mov_reg_imm (&G->f, G->r_ecx, 0x4000); - x86_test (&G->f, G->r_eax, G->r_ecx); - { - GLubyte *lab0, *lab1; - - /* TODO: use jcc rel8 */ - lab0 = x86_jcc_forward (&G->f, cc_E); - x86_mov_reg_imm (&G->f, G->r_ecx, FLOAT_ONE); - /* TODO: use jmp rel8 */ - lab1 = x86_jmp_forward (&G->f); - x86_fixup_fwd_jump (&G->f, lab0); - x86_mov_reg_imm (&G->f, G->r_ecx, FLOAT_ZERO); - x86_fixup_fwd_jump (&G->f, lab1); - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4)); - x86_mov (&G->f, x86_deref (G->r_esp), G->r_ecx); - } - break; - case slang_asm_float_equal_int: - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, -4)); - x87_fld (&G->f, x86_make_disp (G->r_esp, a->param[0] + 4)); - x87_fcomp (&G->f, x86_make_disp (G->r_esp, a->param[1] + 4)); - x87_fnstsw (&G->f, G->r_eax); - /* TODO: use test r8,imm8 */ - x86_mov_reg_imm (&G->f, G->r_ecx, 0x4000); - x86_test (&G->f, G->r_eax, G->r_ecx); - { - GLubyte *lab0, *lab1; - - /* TODO: use jcc rel8 */ - lab0 = x86_jcc_forward (&G->f, cc_E); - x86_mov_reg_imm (&G->f, G->r_ecx, FLOAT_ONE); - /* TODO: use jmp rel8 */ - lab1 = x86_jmp_forward (&G->f); - x86_fixup_fwd_jump (&G->f, lab0); - x86_mov_reg_imm (&G->f, G->r_ecx, FLOAT_ZERO); - x86_fixup_fwd_jump (&G->f, lab1); - x86_mov (&G->f, x86_deref (G->r_esp), G->r_ecx); - } - break; - case slang_asm_float_to_int: + GLint disp, i; + + switch (a->type) { + case slang_asm_none: + break; + case slang_asm_float_copy: + case slang_asm_int_copy: + case slang_asm_bool_copy: + x86_mov(&G->f, G->r_eax, x86_make_disp(G->r_esp, a->param[0])); + x86_pop(&G->f, G->r_ecx); + x86_mov(&G->f, x86_make_disp(G->r_eax, a->param[1]), G->r_ecx); + break; + case slang_asm_float_move: + case slang_asm_int_move: + case slang_asm_bool_move: + x86_lea(&G->f, G->r_eax, x86_make_disp(G->r_esp, a->param[1])); + x86_add(&G->f, G->r_eax, x86_deref(G->r_esp)); + x86_mov(&G->f, G->r_eax, x86_deref(G->r_eax)); + x86_mov(&G->f, x86_make_disp(G->r_esp, a->param[0]), G->r_eax); + break; + case slang_asm_float_push: + case slang_asm_int_push: + case slang_asm_bool_push: + /* TODO: use push imm32 */ + x86_mov_reg_imm(&G->f, G->r_eax, *((GLint *) & a->literal)); + x86_push(&G->f, G->r_eax); + break; + case slang_asm_float_deref: + case slang_asm_int_deref: + case slang_asm_bool_deref: + case slang_asm_addr_deref: + x86_mov(&G->f, G->r_eax, x86_deref(G->r_esp)); + x86_mov(&G->f, G->r_eax, x86_deref(G->r_eax)); + x86_mov(&G->f, x86_deref(G->r_esp), G->r_eax); + break; + case slang_asm_float_add: + x87_fld(&G->f, x86_make_disp(G->r_esp, 4)); + x87_fld(&G->f, x86_deref(G->r_esp)); + x87_faddp(&G->f, G->r_st1); + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); + x87_fstp(&G->f, x86_deref(G->r_esp)); + break; + case slang_asm_float_multiply: + x87_fld(&G->f, x86_make_disp(G->r_esp, 4)); + x87_fld(&G->f, x86_deref(G->r_esp)); + x87_fmulp(&G->f, G->r_st1); + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); + x87_fstp(&G->f, x86_deref(G->r_esp)); + break; + case slang_asm_float_divide: + x87_fld(&G->f, x86_make_disp(G->r_esp, 4)); + x87_fld(&G->f, x86_deref(G->r_esp)); + x87_fdivp(&G->f, G->r_st1); + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); + x87_fstp(&G->f, x86_deref(G->r_esp)); + break; + case slang_asm_float_negate: + x87_fld(&G->f, x86_deref(G->r_esp)); + x87_fchs(&G->f); + x87_fstp(&G->f, x86_deref(G->r_esp)); + break; + case slang_asm_float_less: + x87_fld(&G->f, x86_make_disp(G->r_esp, 4)); + x87_fcomp(&G->f, x86_deref(G->r_esp)); + x87_fnstsw(&G->f, G->r_eax); + /* TODO: use test r8,imm8 */ + x86_mov_reg_imm(&G->f, G->r_ecx, 0x100); + x86_test(&G->f, G->r_eax, G->r_ecx); + { + GLubyte *lab0, *lab1; + /* TODO: use jcc rel8 */ + lab0 = x86_jcc_forward(&G->f, cc_E); + x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ONE); + /* TODO: use jmp rel8 */ + lab1 = x86_jmp_forward(&G->f); + x86_fixup_fwd_jump(&G->f, lab0); + x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ZERO); + x86_fixup_fwd_jump(&G->f, lab1); + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); + x86_mov(&G->f, x86_deref(G->r_esp), G->r_ecx); + } + break; + case slang_asm_float_equal_exp: + x87_fld(&G->f, x86_make_disp(G->r_esp, 4)); + x87_fcomp(&G->f, x86_deref(G->r_esp)); + x87_fnstsw(&G->f, G->r_eax); + /* TODO: use test r8,imm8 */ + x86_mov_reg_imm(&G->f, G->r_ecx, 0x4000); + x86_test(&G->f, G->r_eax, G->r_ecx); + { + GLubyte *lab0, *lab1; + /* TODO: use jcc rel8 */ + lab0 = x86_jcc_forward(&G->f, cc_E); + x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ONE); + /* TODO: use jmp rel8 */ + lab1 = x86_jmp_forward(&G->f); + x86_fixup_fwd_jump(&G->f, lab0); + x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ZERO); + x86_fixup_fwd_jump(&G->f, lab1); + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); + x86_mov(&G->f, x86_deref(G->r_esp), G->r_ecx); + } + break; + case slang_asm_float_equal_int: + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, -4)); + x87_fld(&G->f, x86_make_disp(G->r_esp, a->param[0] + 4)); + x87_fcomp(&G->f, x86_make_disp(G->r_esp, a->param[1] + 4)); + x87_fnstsw(&G->f, G->r_eax); + /* TODO: use test r8,imm8 */ + x86_mov_reg_imm(&G->f, G->r_ecx, 0x4000); + x86_test(&G->f, G->r_eax, G->r_ecx); + { + GLubyte *lab0, *lab1; + /* TODO: use jcc rel8 */ + lab0 = x86_jcc_forward(&G->f, cc_E); + x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ONE); + /* TODO: use jmp rel8 */ + lab1 = x86_jmp_forward(&G->f); + x86_fixup_fwd_jump(&G->f, lab0); + x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ZERO); + x86_fixup_fwd_jump(&G->f, lab1); + x86_mov(&G->f, x86_deref(G->r_esp), G->r_ecx); + } + break; + case slang_asm_float_to_int: /* TODO: use fistp without rounding */ - x86_call (&G->f, (GLubyte *) (do_ftoi)); - x87_fstp (&G->f, x86_deref (G->r_esp)); - break; - case slang_asm_float_sine: - /* TODO: use fsin */ - x86_call (&G->f, (GLubyte *) _mesa_sinf); - x87_fstp (&G->f, x86_deref (G->r_esp)); - break; - case slang_asm_float_arcsine: - /* TODO: use fpatan (?) */ - x86_call (&G->f, (GLubyte *) _mesa_asinf); - x87_fstp (&G->f, x86_deref (G->r_esp)); - break; - case slang_asm_float_arctan: - /* TODO: use fpatan */ - x86_call (&G->f, (GLubyte *) _mesa_atanf); - x87_fstp (&G->f, x86_deref (G->r_esp)); - break; - case slang_asm_float_power: - /* TODO: use emit_pow() */ - x86_call (&G->f, (GLubyte *) do_powf); - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4)); - x87_fstp (&G->f, x86_deref (G->r_esp)); - break; - case slang_asm_float_log2: - x87_fld1 (&G->f); - x87_fld (&G->f, x86_deref (G->r_esp)); - x87_fyl2x (&G->f); - x87_fstp (&G->f, x86_deref (G->r_esp)); - break; - case slang_asm_float_floor: - x86_call (&G->f, (GLubyte *) do_floorf); - x87_fstp (&G->f, x86_deref (G->r_esp)); - break; - case slang_asm_float_ceil: - x86_call (&G->f, (GLubyte *) do_ceilf); - x87_fstp (&G->f, x86_deref (G->r_esp)); - break; - case slang_asm_float_noise1: - x86_call (&G->f, (GLubyte *) _slang_library_noise1); - x87_fstp (&G->f, x86_deref (G->r_esp)); - break; - case slang_asm_float_noise2: - x86_call (&G->f, (GLubyte *) _slang_library_noise2); - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4)); - x87_fstp (&G->f, x86_deref (G->r_esp)); - break; - case slang_asm_float_noise3: - x86_call (&G->f, (GLubyte *) _slang_library_noise4); - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 8)); - x87_fstp (&G->f, x86_deref (G->r_esp)); - break; - case slang_asm_float_noise4: - x86_call (&G->f, (GLubyte *) _slang_library_noise4); - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 12)); - x87_fstp (&G->f, x86_deref (G->r_esp)); - break; - case slang_asm_int_to_float: - break; - case slang_asm_int_to_addr: - x87_fld (&G->f, x86_deref (G->r_esp)); - x87_fistp (&G->f, x86_deref (G->r_esp)); - break; - case slang_asm_addr_copy: - x86_pop (&G->f, G->r_eax); - x86_mov (&G->f, G->r_ecx, x86_deref (G->r_esp)); - x86_mov (&G->f, x86_deref (G->r_ecx), G->r_eax); - break; - case slang_asm_addr_push: - /* TODO: use push imm32 */ - x86_mov_reg_imm (&G->f, G->r_eax, (GLint) a->param[0]); - x86_push (&G->f, G->r_eax); - break; - case slang_asm_addr_add: - x86_pop (&G->f, G->r_eax); - x86_add (&G->f, x86_deref (G->r_esp), G->r_eax); - break; - case slang_asm_addr_multiply: - x86_pop (&G->f, G->r_ecx); - x86_mov (&G->f, G->r_eax, x86_deref (G->r_esp)); - x86_mul (&G->f, G->r_ecx); - x86_mov (&G->f, x86_deref (G->r_esp), G->r_eax); - break; - case slang_asm_vec4_tex1d: - x86_call (&G->f, (GLubyte *) _slang_library_tex1d); - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 12)); - break; - case slang_asm_vec4_tex2d: - x86_call (&G->f, (GLubyte *) _slang_library_tex2d); - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 16)); - break; - case slang_asm_vec4_tex3d: - x86_call (&G->f, (GLubyte *) _slang_library_tex3d); - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 20)); - break; - case slang_asm_vec4_texcube: - x86_call (&G->f, (GLubyte *) _slang_library_texcube); - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 20)); - break; - case slang_asm_vec4_shad1d: - x86_call (&G->f, (GLubyte *) _slang_library_shad1d); - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 20)); - break; - case slang_asm_vec4_shad2d: - x86_call (&G->f, (GLubyte *) _slang_library_shad2d); - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 20)); - break; - case slang_asm_jump: - add_fixup (G, a->param[0], x86_jmp_forward (&G->f)); - break; - case slang_asm_jump_if_zero: - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4)); - x86_xor (&G->f, G->r_eax, G->r_eax); - x86_cmp (&G->f, G->r_eax, x86_make_disp (G->r_esp, -4)); - { - GLubyte *lab0; - - /* TODO: use jcc rel8 */ - lab0 = x86_jcc_forward (&G->f, cc_NE); - add_fixup (G, a->param[0], x86_jmp_forward (&G->f)); - x86_fixup_fwd_jump (&G->f, lab0); - } - break; - case slang_asm_enter: - /* FIXME: x86_make_disp(esp, 0) + x86_lea() generates bogus code */ - assert (a->param[0] != 0); - x86_push (&G->f, G->r_ebp); - x86_lea (&G->f, G->r_ebp, x86_make_disp (G->r_esp, (GLint) a->param[0])); - break; - case slang_asm_leave: - x86_pop (&G->f, G->r_ebp); - break; - case slang_asm_local_alloc: - /* FIXME: x86_make_disp(esp, 0) + x86_lea() generates bogus code */ - assert (a->param[0] != 0); - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, -(GLint) a->param[0])); - break; - case slang_asm_local_free: - /* FIXME: x86_make_disp(esp, 0) + x86_lea() generates bogus code */ - assert (a->param[0] != 0); - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, (GLint) a->param[0])); - break; - case slang_asm_local_addr: - disp = -(GLint) (a->param[0] + a->param[1]) + 4; - if (disp != 0) - { - x86_lea (&G->f, G->r_eax, x86_make_disp (G->r_ebp, disp)); - x86_push (&G->f, G->r_eax); - } - else - x86_push (&G->f, G->r_ebp); - break; - case slang_asm_global_addr: - /* TODO: use push imm32 */ - x86_mov_reg_imm (&G->f, G->r_eax, (GLint) &G->mach->mem + a->param[0]); - x86_push (&G->f, G->r_eax); - break; - case slang_asm_call: - add_fixup (G, a->param[0], x86_call_forward (&G->f)); - break; - case slang_asm_return: - x86_ret (&G->f); - break; - case slang_asm_discard: - x86_jmp (&G->f, G->l_discard); - break; - case slang_asm_exit: - x86_jmp (&G->f, G->l_exit); - break; - /* GL_MESA_shader_debug */ + x86_call(&G->f, (GLubyte *) (do_ftoi)); + x87_fstp(&G->f, x86_deref(G->r_esp)); + break; + case slang_asm_float_sine: + /* TODO: use fsin */ + x86_call(&G->f, (GLubyte *) _mesa_sinf); + x87_fstp(&G->f, x86_deref(G->r_esp)); + break; + case slang_asm_float_arcsine: + /* TODO: use fpatan (?) */ + x86_call(&G->f, (GLubyte *) _mesa_asinf); + x87_fstp(&G->f, x86_deref(G->r_esp)); + break; + case slang_asm_float_arctan: + /* TODO: use fpatan */ + x86_call(&G->f, (GLubyte *) _mesa_atanf); + x87_fstp(&G->f, x86_deref(G->r_esp)); + break; + case slang_asm_float_power: + /* TODO: use emit_pow() */ + x86_call(&G->f, (GLubyte *) do_powf); + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); + x87_fstp(&G->f, x86_deref(G->r_esp)); + break; + case slang_asm_float_log2: + x87_fld1(&G->f); + x87_fld(&G->f, x86_deref(G->r_esp)); + x87_fyl2x(&G->f); + x87_fstp(&G->f, x86_deref(G->r_esp)); + break; + case slang_asm_float_floor: + x86_call(&G->f, (GLubyte *) do_floorf); + x87_fstp(&G->f, x86_deref(G->r_esp)); + break; + case slang_asm_float_ceil: + x86_call(&G->f, (GLubyte *) do_ceilf); + x87_fstp(&G->f, x86_deref(G->r_esp)); + break; + case slang_asm_float_noise1: + x86_call(&G->f, (GLubyte *) _slang_library_noise1); + x87_fstp(&G->f, x86_deref(G->r_esp)); + break; + case slang_asm_float_noise2: + x86_call(&G->f, (GLubyte *) _slang_library_noise2); + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); + x87_fstp(&G->f, x86_deref(G->r_esp)); + break; + case slang_asm_float_noise3: + x86_call(&G->f, (GLubyte *) _slang_library_noise4); + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 8)); + x87_fstp(&G->f, x86_deref(G->r_esp)); + break; + case slang_asm_float_noise4: + x86_call(&G->f, (GLubyte *) _slang_library_noise4); + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 12)); + x87_fstp(&G->f, x86_deref(G->r_esp)); + break; + case slang_asm_int_to_float: + break; + case slang_asm_int_to_addr: + x87_fld(&G->f, x86_deref(G->r_esp)); + x87_fistp(&G->f, x86_deref(G->r_esp)); + break; + case slang_asm_addr_copy: + x86_pop(&G->f, G->r_eax); + x86_mov(&G->f, G->r_ecx, x86_deref(G->r_esp)); + x86_mov(&G->f, x86_deref(G->r_ecx), G->r_eax); + break; + case slang_asm_addr_push: + /* TODO: use push imm32 */ + x86_mov_reg_imm(&G->f, G->r_eax, (GLint) a->param[0]); + x86_push(&G->f, G->r_eax); + break; + case slang_asm_addr_add: + x86_pop(&G->f, G->r_eax); + x86_add(&G->f, x86_deref(G->r_esp), G->r_eax); + break; + case slang_asm_addr_multiply: + x86_pop(&G->f, G->r_ecx); + x86_mov(&G->f, G->r_eax, x86_deref(G->r_esp)); + x86_mul(&G->f, G->r_ecx); + x86_mov(&G->f, x86_deref(G->r_esp), G->r_eax); + break; + case slang_asm_vec4_tex1d: + x86_call(&G->f, (GLubyte *) _slang_library_tex1d); + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 12)); + break; + case slang_asm_vec4_tex2d: + x86_call(&G->f, (GLubyte *) _slang_library_tex2d); + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 16)); + break; + case slang_asm_vec4_tex3d: + x86_call(&G->f, (GLubyte *) _slang_library_tex3d); + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 20)); + break; + case slang_asm_vec4_texcube: + x86_call(&G->f, (GLubyte *) _slang_library_texcube); + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 20)); + break; + case slang_asm_vec4_shad1d: + x86_call(&G->f, (GLubyte *) _slang_library_shad1d); + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 20)); + break; + case slang_asm_vec4_shad2d: + x86_call(&G->f, (GLubyte *) _slang_library_shad2d); + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 20)); + break; + case slang_asm_jump: + add_fixup(G, a->param[0], x86_jmp_forward(&G->f)); + break; + case slang_asm_jump_if_zero: + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); + x86_xor(&G->f, G->r_eax, G->r_eax); + x86_cmp(&G->f, G->r_eax, x86_make_disp(G->r_esp, -4)); + { + GLubyte *lab0; + /* TODO: use jcc rel8 */ + lab0 = x86_jcc_forward(&G->f, cc_NE); + add_fixup(G, a->param[0], x86_jmp_forward(&G->f)); + x86_fixup_fwd_jump(&G->f, lab0); + } + break; + case slang_asm_enter: + /* FIXME: x86_make_disp(esp, 0) + x86_lea() generates bogus code */ + assert(a->param[0] != 0); + x86_push(&G->f, G->r_ebp); + x86_lea(&G->f, G->r_ebp, x86_make_disp(G->r_esp, (GLint) a->param[0])); + break; + case slang_asm_leave: + x86_pop(&G->f, G->r_ebp); + break; + case slang_asm_local_alloc: + /* FIXME: x86_make_disp(esp, 0) + x86_lea() generates bogus code */ + assert(a->param[0] != 0); + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, -(GLint) a->param[0])); + break; + case slang_asm_local_free: + /* FIXME: x86_make_disp(esp, 0) + x86_lea() generates bogus code */ + assert(a->param[0] != 0); + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, (GLint) a->param[0])); + break; + case slang_asm_local_addr: + disp = -(GLint) (a->param[0] + a->param[1]) + 4; + if (disp != 0) { + x86_lea(&G->f, G->r_eax, x86_make_disp(G->r_ebp, disp)); + x86_push(&G->f, G->r_eax); + } + else + x86_push(&G->f, G->r_ebp); + break; + case slang_asm_global_addr: + /* TODO: use push imm32 */ + x86_mov_reg_imm(&G->f, G->r_eax, (GLint) & G->mach->mem + a->param[0]); + x86_push(&G->f, G->r_eax); + break; + case slang_asm_call: + add_fixup(G, a->param[0], x86_call_forward(&G->f)); + break; + case slang_asm_return: + x86_ret(&G->f); + break; + case slang_asm_discard: + x86_jmp(&G->f, G->l_discard); + break; + case slang_asm_exit: + x86_jmp(&G->f, G->l_exit); + break; + /* GL_MESA_shader_debug */ case slang_asm_float_print: /* TODO: use push imm32 */ - x86_mov_reg_imm (&G->f, G->r_eax, (GLint) (infolog)); - x86_push (&G->f, G->r_eax); - x86_call (&G->f, (GLubyte *) (do_print_float)); - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4)); + x86_mov_reg_imm(&G->f, G->r_eax, (GLint) (infolog)); + x86_push(&G->f, G->r_eax); + x86_call(&G->f, (GLubyte *) (do_print_float)); + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); break; - case slang_asm_int_print: + case slang_asm_int_print: /* TODO: use push imm32 */ - x86_mov_reg_imm (&G->f, G->r_eax, (GLint) (infolog)); - x86_push (&G->f, G->r_eax); - x86_call (&G->f, (GLubyte *) do_print_int); - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4)); - break; - case slang_asm_bool_print: + x86_mov_reg_imm(&G->f, G->r_eax, (GLint) (infolog)); + x86_push(&G->f, G->r_eax); + x86_call(&G->f, (GLubyte *) do_print_int); + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); + break; + case slang_asm_bool_print: /* TODO: use push imm32 */ - x86_mov_reg_imm (&G->f, G->r_eax, (GLint) (infolog)); - x86_push (&G->f, G->r_eax); - x86_call (&G->f, (GLubyte *) do_print_bool); - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4)); - break; - /* vec4 */ + x86_mov_reg_imm(&G->f, G->r_eax, (GLint) (infolog)); + x86_push(&G->f, G->r_eax); + x86_call(&G->f, (GLubyte *) do_print_bool); + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); + break; + /* vec4 */ case slang_asm_float_to_vec4: /* [vec4] | float > [vec4] */ - x87_fld (&G->f, x86_deref (G->r_esp)); - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4)); - x86_mov (&G->f, G->r_eax, x86_deref (G->r_esp)); - x87_fst (&G->f, x86_make_disp (G->r_eax, 12)); - x87_fst (&G->f, x86_make_disp (G->r_eax, 8)); - x87_fst (&G->f, x86_make_disp (G->r_eax, 4)); - x87_fstp (&G->f, x86_deref (G->r_eax)); + x87_fld(&G->f, x86_deref(G->r_esp)); + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); + x86_mov(&G->f, G->r_eax, x86_deref(G->r_esp)); + x87_fst(&G->f, x86_make_disp(G->r_eax, 12)); + x87_fst(&G->f, x86_make_disp(G->r_eax, 8)); + x87_fst(&G->f, x86_make_disp(G->r_eax, 4)); + x87_fstp(&G->f, x86_deref(G->r_eax)); break; case slang_asm_vec4_add: /* [vec4] | vec4 > [vec4] */ - x86_mov (&G->f, G->r_eax, x86_make_disp (G->r_esp, 16)); + x86_mov(&G->f, G->r_eax, x86_make_disp(G->r_esp, 16)); for (i = 0; i < 4; i++) - x87_fld (&G->f, x86_make_disp (G->r_eax, i * 4)); + x87_fld(&G->f, x86_make_disp(G->r_eax, i * 4)); for (i = 0; i < 4; i++) - x87_fld (&G->f, x86_make_disp (G->r_esp, i * 4)); - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 16)); + x87_fld(&G->f, x86_make_disp(G->r_esp, i * 4)); + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 16)); for (i = 0; i < 4; i++) - x87_faddp (&G->f, G->r_st4); + x87_faddp(&G->f, G->r_st4); for (i = 0; i < 4; i++) - x87_fstp (&G->f, x86_make_disp (G->r_eax, 12 - i * 4)); + x87_fstp(&G->f, x86_make_disp(G->r_eax, 12 - i * 4)); break; case slang_asm_vec4_subtract: /* [vec4] | vec4 > [vec4] */ - x86_mov (&G->f, G->r_eax, x86_make_disp (G->r_esp, 16)); + x86_mov(&G->f, G->r_eax, x86_make_disp(G->r_esp, 16)); for (i = 0; i < 4; i++) - x87_fld (&G->f, x86_make_disp (G->r_eax, i * 4)); + x87_fld(&G->f, x86_make_disp(G->r_eax, i * 4)); for (i = 0; i < 4; i++) - x87_fld (&G->f, x86_make_disp (G->r_esp, i * 4)); - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 16)); + x87_fld(&G->f, x86_make_disp(G->r_esp, i * 4)); + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 16)); for (i = 0; i < 4; i++) - x87_fsubp (&G->f, G->r_st4); + x87_fsubp(&G->f, G->r_st4); for (i = 0; i < 4; i++) - x87_fstp (&G->f, x86_make_disp (G->r_eax, 12 - i * 4)); + x87_fstp(&G->f, x86_make_disp(G->r_eax, 12 - i * 4)); break; case slang_asm_vec4_multiply: /* [vec4] | vec4 > [vec4] */ - x86_mov (&G->f, G->r_eax, x86_make_disp (G->r_esp, 16)); + x86_mov(&G->f, G->r_eax, x86_make_disp(G->r_esp, 16)); for (i = 0; i < 4; i++) - x87_fld (&G->f, x86_make_disp (G->r_eax, i * 4)); + x87_fld(&G->f, x86_make_disp(G->r_eax, i * 4)); for (i = 0; i < 4; i++) - x87_fld (&G->f, x86_make_disp (G->r_esp, i * 4)); - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 16)); + x87_fld(&G->f, x86_make_disp(G->r_esp, i * 4)); + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 16)); for (i = 0; i < 4; i++) - x87_fmulp (&G->f, G->r_st4); + x87_fmulp(&G->f, G->r_st4); for (i = 0; i < 4; i++) - x87_fstp (&G->f, x86_make_disp (G->r_eax, 12 - i * 4)); + x87_fstp(&G->f, x86_make_disp(G->r_eax, 12 - i * 4)); break; case slang_asm_vec4_divide: /* [vec4] | vec4 > [vec4] */ - x86_mov (&G->f, G->r_eax, x86_make_disp (G->r_esp, 16)); + x86_mov(&G->f, G->r_eax, x86_make_disp(G->r_esp, 16)); for (i = 0; i < 4; i++) - x87_fld (&G->f, x86_make_disp (G->r_eax, i * 4)); + x87_fld(&G->f, x86_make_disp(G->r_eax, i * 4)); for (i = 0; i < 4; i++) - x87_fld (&G->f, x86_make_disp (G->r_esp, i * 4)); - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 16)); + x87_fld(&G->f, x86_make_disp(G->r_esp, i * 4)); + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 16)); for (i = 0; i < 4; i++) - x87_fdivp (&G->f, G->r_st4); + x87_fdivp(&G->f, G->r_st4); for (i = 0; i < 4; i++) - x87_fstp (&G->f, x86_make_disp (G->r_eax, 12 - i * 4)); + x87_fstp(&G->f, x86_make_disp(G->r_eax, 12 - i * 4)); break; case slang_asm_vec4_negate: /* [vec4] > [vec4] */ - x86_mov (&G->f, G->r_eax, x86_deref (G->r_esp)); + x86_mov(&G->f, G->r_eax, x86_deref(G->r_esp)); for (i = 0; i < 4; i++) - x87_fld (&G->f, x86_make_disp (G->r_eax, i * 4)); + x87_fld(&G->f, x86_make_disp(G->r_eax, i * 4)); for (i = 0; i < 4; i++) { - x87_fchs (&G->f); - x87_fstp (&G->f, x86_make_disp (G->r_eax, 12 - i * 4)); + x87_fchs(&G->f); + x87_fstp(&G->f, x86_make_disp(G->r_eax, 12 - i * 4)); } break; case slang_asm_vec4_dot: /* [vec4] | vec4 > [float] */ for (i = 0; i < 4; i++) - x87_fld (&G->f, x86_make_disp (G->r_esp, i * 4)); - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 16)); - x86_mov (&G->f, G->r_eax, x86_deref (G->r_esp)); + x87_fld(&G->f, x86_make_disp(G->r_esp, i * 4)); + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 16)); + x86_mov(&G->f, G->r_eax, x86_deref(G->r_esp)); for (i = 0; i < 4; i++) - x87_fld (&G->f, x86_make_disp (G->r_eax, i * 4)); + x87_fld(&G->f, x86_make_disp(G->r_eax, i * 4)); for (i = 0; i < 4; i++) - x87_fmulp (&G->f, G->r_st4); + x87_fmulp(&G->f, G->r_st4); for (i = 0; i < 3; i++) - x87_faddp (&G->f, G->r_st1); - x87_fstp (&G->f, x86_deref (G->r_eax)); + x87_faddp(&G->f, G->r_st1); + x87_fstp(&G->f, x86_deref(G->r_eax)); break; case slang_asm_vec4_copy: /* [vec4] | vec4 > [vec4] */ - x86_mov (&G->f, G->r_eax, x86_make_disp (G->r_esp, a->param[0])); - x86_pop (&G->f, G->r_ecx); - x86_pop (&G->f, G->r_edx); - x86_mov (&G->f, x86_make_disp (G->r_eax, a->param[1]), G->r_ecx); - x86_pop (&G->f, G->r_ebx); - x86_mov (&G->f, x86_make_disp (G->r_eax, a->param[1] + 4), G->r_edx); - x86_pop (&G->f, G->r_ecx); - x86_mov (&G->f, x86_make_disp (G->r_eax, a->param[1] + 8), G->r_ebx); - x86_mov (&G->f, x86_make_disp (G->r_eax, a->param[1] + 12), G->r_ecx); + x86_mov(&G->f, G->r_eax, x86_make_disp(G->r_esp, a->param[0])); + x86_pop(&G->f, G->r_ecx); + x86_pop(&G->f, G->r_edx); + x86_mov(&G->f, x86_make_disp(G->r_eax, a->param[1]), G->r_ecx); + x86_pop(&G->f, G->r_ebx); + x86_mov(&G->f, x86_make_disp(G->r_eax, a->param[1] + 4), G->r_edx); + x86_pop(&G->f, G->r_ecx); + x86_mov(&G->f, x86_make_disp(G->r_eax, a->param[1] + 8), G->r_ebx); + x86_mov(&G->f, x86_make_disp(G->r_eax, a->param[1] + 12), G->r_ecx); break; case slang_asm_vec4_deref: /* [vec4] > vec4 */ - x86_mov (&G->f, G->r_eax, x86_deref (G->r_esp)); - x86_mov (&G->f, G->r_ecx, x86_make_disp (G->r_eax, 12)); - x86_mov (&G->f, G->r_edx, x86_make_disp (G->r_eax, 8)); - x86_mov (&G->f, x86_deref (G->r_esp), G->r_ecx); - x86_mov (&G->f, G->r_ebx, x86_make_disp (G->r_eax, 4)); - x86_push (&G->f, G->r_edx); - x86_mov (&G->f, G->r_ecx, x86_deref (G->r_eax)); - x86_push (&G->f, G->r_ebx); - x86_push (&G->f, G->r_ecx); + x86_mov(&G->f, G->r_eax, x86_deref(G->r_esp)); + x86_mov(&G->f, G->r_ecx, x86_make_disp(G->r_eax, 12)); + x86_mov(&G->f, G->r_edx, x86_make_disp(G->r_eax, 8)); + x86_mov(&G->f, x86_deref(G->r_esp), G->r_ecx); + x86_mov(&G->f, G->r_ebx, x86_make_disp(G->r_eax, 4)); + x86_push(&G->f, G->r_edx); + x86_mov(&G->f, G->r_ecx, x86_deref(G->r_eax)); + x86_push(&G->f, G->r_ebx); + x86_push(&G->f, G->r_ecx); break; case slang_asm_vec4_equal_int: - x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, -4)); - x86_mov_reg_imm (&G->f, G->r_edx, 0x4000); + x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, -4)); + x86_mov_reg_imm(&G->f, G->r_edx, 0x4000); for (i = 0; i < 4; i++) { - x87_fld (&G->f, x86_make_disp (G->r_esp, a->param[0] + 4 + i * 4)); - x87_fcomp (&G->f, x86_make_disp (G->r_esp, a->param[1] + 4 + i * 4)); - x87_fnstsw (&G->f, G->r_eax); - x86_and (&G->f, G->r_edx, G->r_eax); + x87_fld(&G->f, x86_make_disp(G->r_esp, a->param[0] + 4 + i * 4)); + x87_fcomp(&G->f, x86_make_disp(G->r_esp, a->param[1] + 4 + i * 4)); + x87_fnstsw(&G->f, G->r_eax); + x86_and(&G->f, G->r_edx, G->r_eax); } /* TODO: use test r8,imm8 */ - x86_mov_reg_imm (&G->f, G->r_ecx, 0x4000); - x86_test (&G->f, G->r_edx, G->r_ecx); + x86_mov_reg_imm(&G->f, G->r_ecx, 0x4000); + x86_test(&G->f, G->r_edx, G->r_ecx); { GLubyte *lab0, *lab1; /* TODO: use jcc rel8 */ - lab0 = x86_jcc_forward (&G->f, cc_E); - x86_mov_reg_imm (&G->f, G->r_ecx, FLOAT_ONE); + lab0 = x86_jcc_forward(&G->f, cc_E); + x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ONE); /* TODO: use jmp rel8 */ - lab1 = x86_jmp_forward (&G->f); - x86_fixup_fwd_jump (&G->f, lab0); - x86_mov_reg_imm (&G->f, G->r_ecx, FLOAT_ZERO); - x86_fixup_fwd_jump (&G->f, lab1); - x86_mov (&G->f, x86_deref (G->r_esp), G->r_ecx); + lab1 = x86_jmp_forward(&G->f); + x86_fixup_fwd_jump(&G->f, lab0); + x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ZERO); + x86_fixup_fwd_jump(&G->f, lab1); + x86_mov(&G->f, x86_deref(G->r_esp), G->r_ecx); } break; default: - assert (0); + _mesa_problem(NULL, "Unexpected switch case in codegen_assem"); } } -GLboolean _slang_x86_codegen (slang_machine *mach, slang_assembly_file *file, GLuint start) +GLboolean +_slang_x86_codegen(slang_machine * mach, slang_assembly_file * file, + GLuint start) { - codegen_ctx G; - GLubyte *j_body, *j_exit; - GLuint i; + codegen_ctx G; + GLubyte *j_body, *j_exit; + GLuint i; /* Free the old code - if any. */ if (mach->x86.compiled_func != NULL) { - _mesa_exec_free (mach->x86.compiled_func); + _mesa_exec_free(mach->x86.compiled_func); mach->x86.compiled_func = NULL; } - /* - * We need as much as 1M because *all* assembly, including built-in library, is - * being translated to x86. - * The built-in library occupies 450K, so we can be safe for now. - * It is going to change in the future, when we get assembly analysis running. - */ - x86_init_func_size (&G.f, 1048576); - G.r_eax = x86_make_reg (file_REG32, reg_AX); - G.r_ecx = x86_make_reg (file_REG32, reg_CX); - G.r_edx = x86_make_reg (file_REG32, reg_DX); - G.r_ebx = x86_make_reg (file_REG32, reg_BX); - G.r_esp = x86_make_reg (file_REG32, reg_SP); - G.r_ebp = x86_make_reg (file_REG32, reg_BP); - G.r_st0 = x86_make_reg (file_x87, 0); - G.r_st1 = x86_make_reg (file_x87, 1); - G.r_st2 = x86_make_reg (file_x87, 2); - G.r_st3 = x86_make_reg (file_x87, 3); - G.r_st4 = x86_make_reg (file_x87, 4); - G.fixups = NULL; - G.fixup_count = 0; - G.labels = (GLubyte **) slang_alloc_malloc (file->count * sizeof (GLubyte *)); - G.mach = mach; - G.fpucntl = RESTORE_FPU; - - mach->x86.fpucntl_rnd_neg = RND_NEG_FPU; - mach->x86.fpucntl_restore = RESTORE_FPU; - - /* prepare stack and jump to start */ - x86_push (&G.f, G.r_ebp); - x86_mov_reg_imm (&G.f, G.r_eax, (GLint) &mach->x86.esp_restore); - x86_push (&G.f, G.r_esp); - x86_pop (&G.f, G.r_ecx); - x86_mov (&G.f, x86_deref (G.r_eax), G.r_ecx); - j_body = x86_jmp_forward (&G.f); - - /* "discard" instructions jump to this label */ - G.l_discard = x86_get_label (&G.f); - x86_mov_reg_imm (&G.f, G.r_eax, (GLint) &G.mach->kill); - x86_mov_reg_imm (&G.f, G.r_ecx, 1); - x86_mov (&G.f, x86_deref (G.r_eax), G.r_ecx); - G.l_exit = x86_get_label (&G.f); - j_exit = x86_jmp_forward (&G.f); - - for (i = 0; i < file->count; i++) - { - G.labels[i] = x86_get_label (&G.f); - if (i == start) - x86_fixup_fwd_jump (&G.f, j_body); - codegen_assem (&G, &file->code[i], &mach->infolog); - } - - /* - * Restore stack and return. - * This must be handled this way, because "discard" can be invoked from any - * place in the code. - */ - x86_fixup_fwd_jump (&G.f, j_exit); - x86_mov_reg_imm (&G.f, G.r_eax, (GLint) &mach->x86.esp_restore); - x86_mov (&G.f, G.r_esp, x86_deref (G.r_eax)); - x86_pop (&G.f, G.r_ebp); - if (G.fpucntl != RESTORE_FPU) - { - x87_fnclex (&G.f); - x86_mov_reg_imm (&G.f, G.r_eax, (GLint) &G.mach->x86.fpucntl_restore); - x87_fldcw (&G.f, x86_deref (G.r_eax)); - } - x86_ret (&G.f); - - /* fixup forward labels */ - for (i = 0; i < G.fixup_count; i++) - { - G.f.csr = G.labels[G.fixups[i].index]; - x86_fixup_fwd_jump (&G.f, G.fixups[i].csr); - } - - slang_alloc_free (G.fixups); - slang_alloc_free (G.labels); - - /* install new code */ - mach->x86.compiled_func = (GLvoid (*) (slang_machine *)) x86_get_func (&G.f); - - return GL_TRUE; + /* + * We need as much as 1M because *all* assembly, including built-in library, is + * being translated to x86. + * The built-in library occupies 450K, so we can be safe for now. + * It is going to change in the future, when we get assembly analysis running. + */ + x86_init_func_size(&G.f, 1048576); + G.r_eax = x86_make_reg(file_REG32, reg_AX); + G.r_ecx = x86_make_reg(file_REG32, reg_CX); + G.r_edx = x86_make_reg(file_REG32, reg_DX); + G.r_ebx = x86_make_reg(file_REG32, reg_BX); + G.r_esp = x86_make_reg(file_REG32, reg_SP); + G.r_ebp = x86_make_reg(file_REG32, reg_BP); + G.r_st0 = x86_make_reg(file_x87, 0); + G.r_st1 = x86_make_reg(file_x87, 1); + G.r_st2 = x86_make_reg(file_x87, 2); + G.r_st3 = x86_make_reg(file_x87, 3); + G.r_st4 = x86_make_reg(file_x87, 4); + G.fixups = NULL; + G.fixup_count = 0; + G.labels = + (GLubyte **) slang_alloc_malloc(file->count * sizeof(GLubyte *)); + G.mach = mach; + G.fpucntl = RESTORE_FPU; + + mach->x86.fpucntl_rnd_neg = RND_NEG_FPU; + mach->x86.fpucntl_restore = RESTORE_FPU; + + /* prepare stack and jump to start */ + x86_push(&G.f, G.r_ebp); + x86_mov_reg_imm(&G.f, G.r_eax, (GLint) & mach->x86.esp_restore); + x86_push(&G.f, G.r_esp); + x86_pop(&G.f, G.r_ecx); + x86_mov(&G.f, x86_deref(G.r_eax), G.r_ecx); + j_body = x86_jmp_forward(&G.f); + + /* "discard" instructions jump to this label */ + G.l_discard = x86_get_label(&G.f); + x86_mov_reg_imm(&G.f, G.r_eax, (GLint) & G.mach->kill); + x86_mov_reg_imm(&G.f, G.r_ecx, 1); + x86_mov(&G.f, x86_deref(G.r_eax), G.r_ecx); + G.l_exit = x86_get_label(&G.f); + j_exit = x86_jmp_forward(&G.f); + + for (i = 0; i < file->count; i++) { + G.labels[i] = x86_get_label(&G.f); + if (i == start) + x86_fixup_fwd_jump(&G.f, j_body); + codegen_assem(&G, &file->code[i], &mach->infolog); + } + + /* + * Restore stack and return. + * This must be handled this way, because "discard" can be invoked from any + * place in the code. + */ + x86_fixup_fwd_jump(&G.f, j_exit); + x86_mov_reg_imm(&G.f, G.r_eax, (GLint) & mach->x86.esp_restore); + x86_mov(&G.f, G.r_esp, x86_deref(G.r_eax)); + x86_pop(&G.f, G.r_ebp); + if (G.fpucntl != RESTORE_FPU) { + x87_fnclex(&G.f); + x86_mov_reg_imm(&G.f, G.r_eax, (GLint) & G.mach->x86.fpucntl_restore); + x87_fldcw(&G.f, x86_deref(G.r_eax)); + } + x86_ret(&G.f); + + /* fixup forward labels */ + for (i = 0; i < G.fixup_count; i++) { + G.f.csr = G.labels[G.fixups[i].index]; + x86_fixup_fwd_jump(&G.f, G.fixups[i].csr); + } + + slang_alloc_free(G.fixups); + slang_alloc_free(G.labels); + + /* install new code */ + mach->x86.compiled_func = (GLvoid(*)(slang_machine *)) x86_get_func(&G.f); + + return GL_TRUE; } #endif - diff --git a/src/mesa/shader/slang/slang_link.h b/src/mesa/shader/slang/slang_link.h index 2195ec5bdfa..433964223a5 100644 --- a/src/mesa/shader/slang/slang_link.h +++ b/src/mesa/shader/slang/slang_link.h @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.6 + * Version: 6.5.2 * * Copyright (C) 2006 Brian Paul All Rights Reserved. * @@ -38,13 +38,15 @@ enum SLANG_SHADER_MAX }; -/* + +/** * Active variables. * - * Active uniforms/attribs can be queried by the application to get a list of - * uniforms/attribs actually used by shaders (uniforms) or vertex shader only (attribs). + * Active uniforms/attribs can be queried by the application to get a + * list of uniforms/attribs actually used by shaders (uniforms) or + * vertex shader only (attribs). */ - +/*@{*/ typedef struct { slang_export_data_quant *quant; @@ -56,14 +58,17 @@ 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. + * 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; @@ -75,26 +80,33 @@ typedef struct slang_attrib_override *table; GLuint count; } slang_attrib_overrides; +/*@}*/ + extern 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. + * 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. + * 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; @@ -107,16 +119,20 @@ typedef struct slang_uniform_binding *table; 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. + * 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; @@ -126,8 +142,8 @@ typedef struct typedef struct { - GLuint addr; /* memory location */ - GLuint fill; /* 1..4, number of components used */ + GLuint addr; /**< memory location */ + GLuint fill; /**< 1..4, number of components used */ } slang_attrib_slot; typedef struct @@ -136,16 +152,20 @@ typedef struct 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. + * 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 { GLuint vert_addr; @@ -166,20 +186,25 @@ typedef struct slang_varying_slot slots[MAX_VARYING_FLOATS]; 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. + * 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. + * 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; @@ -191,6 +216,8 @@ typedef struct slang_texture_usage *table; GLuint count; } slang_texture_usages; +/*@}*/ + extern GLvoid _slang_texture_usages_ctr (slang_texture_usages *); diff --git a/src/mesa/shader/slang/slang_preprocess.c b/src/mesa/shader/slang/slang_preprocess.c index 43aa9a1e95e..66a6a983927 100644 --- a/src/mesa/shader/slang/slang_preprocess.c +++ b/src/mesa/shader/slang/slang_preprocess.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.6 + * Version: 6.5.2 * * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. * @@ -32,15 +32,15 @@ #include "grammar_mesa.h" #include "slang_preprocess.h" -static const char *slang_pp_directives_syn = +LONGSTRING static const char *slang_pp_directives_syn = #include "library/slang_pp_directives_syn.h" ; -static const char *slang_pp_expression_syn = +LONGSTRING static const char *slang_pp_expression_syn = #include "library/slang_pp_expression_syn.h" ; -static const char *slang_pp_version_syn = +LONGSTRING static const char *slang_pp_version_syn = #include "library/slang_pp_version_syn.h" ; diff --git a/src/mesa/shader/slang/slang_utility.c b/src/mesa/shader/slang/slang_utility.c index 54fcc8a2382..256d52455db 100644 --- a/src/mesa/shader/slang/slang_utility.c +++ b/src/mesa/shader/slang/slang_utility.c @@ -131,75 +131,92 @@ slang_string_cstr (slang_string *self) /* slang_atom_pool */ -void slang_atom_pool_construct (slang_atom_pool *pool) +void +slang_atom_pool_construct(slang_atom_pool * pool) { - GLuint i; + GLuint i; - for (i = 0; i < SLANG_ATOM_POOL_SIZE; i++) - pool->entries[i] = NULL; + for (i = 0; i < SLANG_ATOM_POOL_SIZE; i++) + pool->entries[i] = NULL; } -void slang_atom_pool_destruct (slang_atom_pool *pool) +void +slang_atom_pool_destruct (slang_atom_pool * pool) { - GLuint i; + GLuint i; - for (i = 0; i < SLANG_ATOM_POOL_SIZE; i++) - { - slang_atom_entry *entry; + for (i = 0; i < SLANG_ATOM_POOL_SIZE; i++) { + slang_atom_entry * entry; - entry = pool->entries[i]; - while (entry != NULL) - { - slang_atom_entry *next; - - next = entry->next; - slang_alloc_free (entry->id); - slang_alloc_free (entry); - entry = next; + entry = pool->entries[i]; + while (entry != NULL) { + slang_atom_entry *next; + + next = entry->next; + slang_alloc_free(entry->id); + slang_alloc_free(entry); + entry = next; } } } -slang_atom slang_atom_pool_atom (slang_atom_pool *pool, const char *id) +/* + * Search the atom pool for an atom with a given name. + * If atom is not found, create and add it to the pool. + * Returns ATOM_NULL if the atom was not found and the function failed to create a new atom. + */ +slang_atom +slang_atom_pool_atom(slang_atom_pool * pool, const char * id) { - GLuint hash; - const char *p = id; - slang_atom_entry **entry; - - hash = 0; - while (*p != '\0') - { - GLuint g; - - hash = (hash << 4) + (GLuint) *p++; - g = hash & 0xf0000000; - if (g != 0) - hash ^= g >> 24; - hash &= ~g; - } - hash %= SLANG_ATOM_POOL_SIZE; - - entry = &pool->entries[hash]; - while (*entry != NULL) - { - if (slang_string_compare ((**entry).id, id) == 0) - return (slang_atom) (**entry).id; - entry = &(**entry).next; - } - - *entry = (slang_atom_entry *) slang_alloc_malloc (sizeof (slang_atom_entry)); - if (*entry == NULL) - return SLANG_ATOM_NULL; + GLuint hash; + const char * p = id; + slang_atom_entry ** entry; + + /* Hash a given string to a number in the range [0, ATOM_POOL_SIZE). */ + hash = 0; + while (*p != '\0') { + GLuint g; + + hash = (hash << 4) + (GLuint) (*p++); + g = hash & 0xf0000000; + if (g != 0) + hash ^= g >> 24; + hash &= ~g; + } + hash %= SLANG_ATOM_POOL_SIZE; + + /* Now the hash points to a linked list of atoms with names that have the same hash value. + * Search the linked list for a given name. */ + entry = &pool->entries[hash]; + while (*entry != NULL) { + /* If the same, return the associated atom. */ + if (slang_string_compare((**entry).id, id) == 0) + return (slang_atom) (**entry).id; + /* Grab the next atom in the linked list. */ + entry = &(**entry).next; + } - (**entry).next = NULL; - (**entry).id = slang_string_duplicate (id); - if ((**entry).id == NULL) - return SLANG_ATOM_NULL; - return (slang_atom) (**entry).id; + /* Okay, we have not found an atom. Create a new entry for it. + * Note that the <entry> points to the last entry's <next> field. */ + *entry = (slang_atom_entry *) (slang_alloc_malloc(sizeof(slang_atom_entry))); + if (*entry == NULL) + return SLANG_ATOM_NULL; + + /* Initialize a new entry. Because we'll need the actual name of the atom, we use the pointer + * to this string as an actual atom's value. */ + (**entry).next = NULL; + (**entry).id = slang_string_duplicate(id); + if ((**entry).id == NULL) + return SLANG_ATOM_NULL; + return (slang_atom) (**entry).id; } -const char *slang_atom_pool_id (slang_atom_pool *pool, slang_atom atom) +/* + * Return the name of a given atom. + */ +const char * +slang_atom_pool_id(slang_atom_pool * pool, slang_atom atom) { - return (const char *) atom; + return (const char *) (atom); } diff --git a/src/mesa/shader/slang/sources b/src/mesa/shader/slang/sources index f03f1ed187a..00d617fa8af 100644 --- a/src/mesa/shader/slang/sources +++ b/src/mesa/shader/slang/sources @@ -19,3 +19,26 @@ slang_link.c \ slang_preprocess.c \ slang_storage.c \ slang_utility.c + +MESA_SHADER_SLANG_HEADERS = \ +slang_analyse.h \ +slang_assemble.h \ +slang_assemble_assignment.h \ +slang_assemble_conditional.h \ +slang_assemble_constructor.h \ +slang_assemble_typeinfo.h \ +slang_compile.h \ +slang_compile_function.h \ +slang_compile_operation.h \ +slang_compile_struct.h \ +slang_compile_variable.h \ +slang_execute.h \ +slang_export.h \ +slang_library_noise.h \ +slang_library_texsample.h \ +slang_link.h \ +slang_mesa.h \ +slang_preprocess.h \ +slang_storage.h \ +slang_utility.h \ +traverse_wrap.h diff --git a/src/mesa/shader/sources b/src/mesa/shader/sources index 573be89b9ab..27871872766 100644 --- a/src/mesa/shader/sources +++ b/src/mesa/shader/sources @@ -1,4 +1,4 @@ -# List of ource files in this directory used for X.org xserver build +# List of source files in this directory used for X.org xserver build MESA_SHADER_SOURCES = \ arbprogparse.c \ arbprogram.c \ @@ -11,3 +11,18 @@ program.c \ programopt.c \ shaderobjects.c \ shaderobjects_3dlabs.c + +MESA_SHADER_HEADERS = \ +arbprogparse.h \ +arbprogram.h \ +arbprogram_syn.h \ +atifragshader.h \ +nvfragparse.h \ +nvprogram.h \ +nvvertexec.h \ +nvvertparse.h \ +programopt.h \ +program.h \ +program_instruction.h \ +shaderobjects.h \ +shaderobjects_3dlabs.h |