diff options
58 files changed, 4359 insertions, 3333 deletions
diff --git a/configs/linux-static b/configs/linux-static index 0104d34022b..85141ea643f 100644 --- a/configs/linux-static +++ b/configs/linux-static @@ -19,3 +19,8 @@ OSMESA_LIB_DEPS = GLU_LIB_DEPS = GLUT_LIB_DEPS = GLW_LIB_DEPS = + +# Need to specify all libraries we may need +APP_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) -lm \ + -L/usr/X11R6/lib/ -lX11 -lXmu -lXi -lpthread + diff --git a/debian/changelog b/debian/changelog index 0c87f58f519..ca239b9d547 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +mesa (6.5.2~rc2-1) experimental; urgency=low + + * New upstream release candidate: + + Refresh 02_use-ieee-fp-on-s390-and-m68k.patch. + + -- Thierry Reding <[email protected]> Wed, 22 Nov 2006 20:49:06 +0100 + mesa (6.5.2~rc1-1) experimental; urgency=low * New upstream release candidate. diff --git a/debian/patches/02_use-ieee-fp-on-s390-and-m68k.patch b/debian/patches/02_use-ieee-fp-on-s390-and-m68k.patch index d219de8f267..f54457521c5 100644 --- a/debian/patches/02_use-ieee-fp-on-s390-and-m68k.patch +++ b/debian/patches/02_use-ieee-fp-on-s390-and-m68k.patch @@ -4,7 +4,7 @@ This patch by David Nusinow. --- a/src/mesa/main/imports.h +++ b/src/mesa/main/imports.h -@@ -146,8 +146,9 @@ +@@ -155,8 +155,9 @@ *** USE_IEEE: Determine if we're using IEEE floating point ***/ #if defined(__i386__) || defined(__386__) || defined(__sparc__) || \ diff --git a/docs/mangling.html b/docs/mangling.html index 3f550ba5ec6..55071544fa6 100644 --- a/docs/mangling.html +++ b/docs/mangling.html @@ -19,6 +19,10 @@ This results in all the Mesa functions being prefixed with <p> To do this, recompile Mesa with the compiler flag -DUSE_MGL_NAMESPACE. Add the flag to CFLAGS in the configuration file which you want to use. +For example: +<pre> +CFLAGS += -DUSE_MGL_NAMESPACE +</pre> </p> diff --git a/docs/relnotes-6.5.2.html b/docs/relnotes-6.5.2.html index 1ba936413a8..ba99420d7d1 100644 --- a/docs/relnotes-6.5.2.html +++ b/docs/relnotes-6.5.2.html @@ -66,6 +66,9 @@ copy texturing). <li>Fixed some fragment program bugs in Intel i915 DRI driver <li>Fixed glGetVertexAttribfvARB bug 8883 <li>Implemented glGetUniform[fi]vARB() functions +<li>Fixed glDrawPixels(GL_COLOR_INDEX, GL_BITMAP) segfault (bug 9044) +<li>Fixed some gluBuild2DMipmaps() bugs (Greg McGarragh) +<li>Fixed broken "mgl" name mangling </ul> diff --git a/include/GL/gl.h b/include/GL/gl.h index 5b30e3f3865..78a00aeb8b3 100644 --- a/include/GL/gl.h +++ b/include/GL/gl.h @@ -2173,37 +2173,6 @@ GLAPI GLsizei APIENTRY glGetDebugLogLengthMESA (GLhandleARB obj, GLenum logType, /* - * ???. GL_MESA_trace - * XXX obsolete - */ -#ifndef GL_MESA_trace -#define GL_MESA_trace 1 - -#define GL_TRACE_ALL_BITS_MESA 0xFFFF -#define GL_TRACE_OPERATIONS_BIT_MESA 0x0001 -#define GL_TRACE_PRIMITIVES_BIT_MESA 0x0002 -#define GL_TRACE_ARRAYS_BIT_MESA 0x0004 -#define GL_TRACE_TEXTURES_BIT_MESA 0x0008 -#define GL_TRACE_PIXELS_BIT_MESA 0x0010 -#define GL_TRACE_ERRORS_BIT_MESA 0x0020 -#define GL_TRACE_MASK_MESA 0x8755 -#define GL_TRACE_NAME_MESA 0x8756 - -GLAPI void GLAPIENTRY glEnableTraceMESA( GLbitfield mask ); -GLAPI void GLAPIENTRY glDisableTraceMESA( GLbitfield mask ); -GLAPI void GLAPIENTRY glNewTraceMESA( GLbitfield mask, const GLubyte * traceName ); -GLAPI void GLAPIENTRY glEndTraceMESA( void ); -GLAPI void GLAPIENTRY glTraceAssertAttribMESA( GLbitfield attribMask ); -GLAPI void GLAPIENTRY glTraceCommentMESA( const GLubyte * comment ); -GLAPI void GLAPIENTRY glTraceTextureMESA( GLuint name, const GLubyte* comment ); -GLAPI void GLAPIENTRY glTraceListMESA( GLuint name, const GLubyte* comment ); -GLAPI void GLAPIENTRY glTracePointerMESA( GLvoid* pointer, const GLubyte* comment ); -GLAPI void GLAPIENTRY glTracePointerRangeMESA( const GLvoid* first, const GLvoid* last, const GLubyte* comment ); - -#endif /* GL_MESA_trace */ - - -/* * ???. GL_MESA_packed_depth_stencil * XXX obsolete */ diff --git a/include/GL/gl_mangle.h b/include/GL/gl_mangle.h index 2e6558def1a..7416d5372cd 100644 --- a/include/GL/gl_mangle.h +++ b/include/GL/gl_mangle.h @@ -274,7 +274,6 @@ #define glDetailTexFuncSGIS MANGLE(DetailTexFuncSGIS) #define glDisableClientState MANGLE(DisableClientState) #define glDisable MANGLE(Disable) -#define glDisableTraceMESA MANGLE(DisableTraceMESA) #define glDisableVariantClientStateEXT MANGLE(DisableVariantClientStateEXT) #define glDisableVertexAttribArrayARB MANGLE(DisableVertexAttribArrayARB) #define glDisableVertexAttribArray MANGLE(DisableVertexAttribArray) @@ -302,7 +301,6 @@ #define glElementPointerATI MANGLE(ElementPointerATI) #define glEnableClientState MANGLE(EnableClientState) #define glEnable MANGLE(Enable) -#define glEnableTraceMESA MANGLE(EnableTraceMESA) #define glEnableVariantClientStateEXT MANGLE(EnableVariantClientStateEXT) #define glEnableVertexAttribArrayARB MANGLE(EnableVertexAttribArrayARB) #define glEnableVertexAttribArray MANGLE(EnableVertexAttribArray) @@ -312,7 +310,6 @@ #define glEndOcclusionQueryNV MANGLE(EndOcclusionQueryNV) #define glEndQueryARB MANGLE(EndQueryARB) #define glEndQuery MANGLE(EndQuery) -#define glEndTraceMESA MANGLE(EndTraceMESA) #define glEndVertexShaderEXT MANGLE(EndVertexShaderEXT) #define glEvalCoord1d MANGLE(EvalCoord1d) #define glEvalCoord1dv MANGLE(EvalCoord1dv) @@ -781,7 +778,6 @@ #define glMultTransposeMatrixf MANGLE(MultTransposeMatrixf) #define glNewList MANGLE(NewList) #define glNewObjectBufferATI MANGLE(NewObjectBufferATI) -#define glNewTraceMESA MANGLE(NewTraceMESA) #define glNormal3b MANGLE(Normal3b) #define glNormal3bv MANGLE(Normal3bv) #define glNormal3d MANGLE(Normal3d) @@ -923,6 +919,7 @@ #define glRectsv MANGLE(Rectsv) #define glReferencePlaneSGIX MANGLE(ReferencePlaneSGIX) #define glRenderbufferStorageEXT MANGLE(RenderbufferStorageEXT) +#define glRenderbufferStorageMultisampleEXT MANGLE(RenderbufferStorageMultisampleEXT) #define glRenderMode MANGLE(RenderMode) #define glReplacementCodePointerSUN MANGLE(ReplacementCodePointerSUN) #define glReplacementCodeubSUN MANGLE(ReplacementCodeubSUN) @@ -1022,6 +1019,7 @@ #define glSpriteParameteriSGIX MANGLE(SpriteParameteriSGIX) #define glSpriteParameterivSGIX MANGLE(SpriteParameterivSGIX) #define glStartInstrumentsSGIX MANGLE(StartInstrumentsSGIX) +#define glStencilClearTagEXT MANGLE(StencilClearTagEXT) #define glStencilFunc MANGLE(StencilFunc) #define glStencilFuncSeparateATI MANGLE(StencilFuncSeparateATI) #define glStencilFuncSeparate MANGLE(StencilFuncSeparate) @@ -1140,12 +1138,6 @@ #define glTextureLightEXT MANGLE(TextureLightEXT) #define glTextureMaterialEXT MANGLE(TextureMaterialEXT) #define glTextureNormalEXT MANGLE(TextureNormalEXT) -#define glTraceAssertAttribMESA MANGLE(TraceAssertAttribMESA) -#define glTraceCommentMESA MANGLE(TraceCommentMESA) -#define glTraceListMESA MANGLE(TraceListMESA) -#define glTracePointerMESA MANGLE(TracePointerMESA) -#define glTracePointerRangeMESA MANGLE(TracePointerRangeMESA) -#define glTraceTextureMESA MANGLE(TraceTextureMESA) #define glTrackMatrixNV MANGLE(TrackMatrixNV) #define glTranslated MANGLE(Translated) #define glTranslatef MANGLE(Translatef) @@ -1183,10 +1175,16 @@ #define glUniform4iv MANGLE(Uniform4iv) #define glUniformMatrix2fvARB MANGLE(UniformMatrix2fvARB) #define glUniformMatrix2fv MANGLE(UniformMatrix2fv) +#define glUniformMatrix2x3fv MANGLE(UniformMatrix2x3fv) +#define glUniformMatrix2x4fv MANGLE(UniformMatrix2x4fv) #define glUniformMatrix3fvARB MANGLE(UniformMatrix3fvARB) #define glUniformMatrix3fv MANGLE(UniformMatrix3fv) +#define glUniformMatrix3x2fv MANGLE(UniformMatrix3x2fv) +#define glUniformMatrix3x4fv MANGLE(UniformMatrix3x4fv) #define glUniformMatrix4fvARB MANGLE(UniformMatrix4fvARB) #define glUniformMatrix4fv MANGLE(UniformMatrix4fv) +#define glUniformMatrix4x2fv MANGLE(UniformMatrix4x2fv) +#define glUniformMatrix4x3fv MANGLE(UniformMatrix4x3fv) #define glUnlockArraysEXT MANGLE(UnlockArraysEXT) #define glUnmapBufferARB MANGLE(UnmapBufferARB) #define glUnmapBuffer MANGLE(UnmapBuffer) diff --git a/src/glu/sgi/libutil/mipmap.c b/src/glu/sgi/libutil/mipmap.c index 5c28c858ec6..44f519a4e21 100644 --- a/src/glu/sgi/libutil/mipmap.c +++ b/src/glu/sgi/libutil/mipmap.c @@ -377,6 +377,7 @@ static void halveImage_ubyte(GLint components, GLuint width, GLuint height, { int i, j, k; int newwidth, newheight; + int padBytes; GLubyte *s; const char *t; @@ -390,6 +391,7 @@ static void halveImage_ubyte(GLint components, GLuint width, GLuint height, newwidth = width / 2; newheight = height / 2; + padBytes = ysize - (width*group_size); s = dataout; t = (const char *)datain; @@ -405,6 +407,7 @@ static void halveImage_ubyte(GLint components, GLuint width, GLuint height, } t += group_size; } + t += padBytes; t += ysize; } } @@ -476,6 +479,7 @@ static void halveImage_byte(GLint components, GLuint width, GLuint height, { int i, j, k; int newwidth, newheight; + int padBytes; GLbyte *s; const char *t; @@ -489,6 +493,7 @@ static void halveImage_byte(GLint components, GLuint width, GLuint height, newwidth = width / 2; newheight = height / 2; + padBytes = ysize - (width*group_size); s = dataout; t = (const char *)datain; @@ -504,6 +509,7 @@ static void halveImage_byte(GLint components, GLuint width, GLuint height, } t += group_size; } + t += padBytes; t += ysize; } } @@ -573,6 +579,7 @@ static void halveImage_ushort(GLint components, GLuint width, GLuint height, { int i, j, k; int newwidth, newheight; + int padBytes; GLushort *s; const char *t; @@ -586,6 +593,7 @@ static void halveImage_ushort(GLint components, GLuint width, GLuint height, newwidth = width / 2; newheight = height / 2; + padBytes = ysize - (width*group_size); s = dataout; t = (const char *)datain; @@ -602,6 +610,7 @@ static void halveImage_ushort(GLint components, GLuint width, GLuint height, } t += group_size; } + t += padBytes; t += ysize; } else @@ -616,6 +625,7 @@ static void halveImage_ushort(GLint components, GLuint width, GLuint height, } t += group_size; } + t += padBytes; t += ysize; } } @@ -708,6 +718,7 @@ static void halveImage_short(GLint components, GLuint width, GLuint height, { int i, j, k; int newwidth, newheight; + int padBytes; GLshort *s; const char *t; @@ -721,6 +732,7 @@ static void halveImage_short(GLint components, GLuint width, GLuint height, newwidth = width / 2; newheight = height / 2; + padBytes = ysize - (width*group_size); s = dataout; t = (const char *)datain; @@ -737,6 +749,7 @@ static void halveImage_short(GLint components, GLuint width, GLuint height, } t += group_size; } + t += padBytes; t += ysize; } else @@ -758,6 +771,7 @@ static void halveImage_short(GLint components, GLuint width, GLuint height, } t += group_size; } + t += padBytes; t += ysize; } } @@ -850,6 +864,7 @@ static void halveImage_uint(GLint components, GLuint width, GLuint height, { int i, j, k; int newwidth, newheight; + int padBytes; GLuint *s; const char *t; @@ -863,6 +878,7 @@ static void halveImage_uint(GLint components, GLuint width, GLuint height, newwidth = width / 2; newheight = height / 2; + padBytes = ysize - (width*group_size); s = dataout; t = (const char *)datain; @@ -881,6 +897,7 @@ static void halveImage_uint(GLint components, GLuint width, GLuint height, } t += group_size; } + t += padBytes; t += ysize; } else @@ -899,6 +916,7 @@ static void halveImage_uint(GLint components, GLuint width, GLuint height, } t += group_size; } + t += padBytes; t += ysize; } } @@ -990,6 +1008,7 @@ static void halveImage_int(GLint components, GLuint width, GLuint height, { int i, j, k; int newwidth, newheight; + int padBytes; GLint *s; const char *t; @@ -1003,6 +1022,7 @@ static void halveImage_int(GLint components, GLuint width, GLuint height, newwidth = width / 2; newheight = height / 2; + padBytes = ysize - (width*group_size); s = dataout; t = (const char *)datain; @@ -1019,6 +1039,7 @@ static void halveImage_int(GLint components, GLuint width, GLuint height, } t += group_size; } + t += padBytes; t += ysize; } else @@ -1041,6 +1062,7 @@ static void halveImage_int(GLint components, GLuint width, GLuint height, } t += group_size; } + t += padBytes; t += ysize; } } @@ -1134,6 +1156,7 @@ static void halveImage_float(GLint components, GLuint width, GLuint height, { int i, j, k; int newwidth, newheight; + int padBytes; GLfloat *s; const char *t; @@ -1147,6 +1170,7 @@ static void halveImage_float(GLint components, GLuint width, GLuint height, newwidth = width / 2; newheight = height / 2; + padBytes = ysize - (width*group_size); s = dataout; t = (const char *)datain; @@ -1163,6 +1187,7 @@ static void halveImage_float(GLint components, GLuint width, GLuint height, } t += group_size; } + t += padBytes; t += ysize; } else @@ -1183,6 +1208,7 @@ static void halveImage_float(GLint components, GLuint width, GLuint height, } t += group_size; } + t += padBytes; t += ysize; } } @@ -3845,10 +3871,12 @@ static int gluBuild2DMipmapLevelsCore(GLenum target, GLint internalFormat, if (width == newwidth && height == newheight) { /* Use usersImage for level userLevel */ if (baseLevel <= level && level <= maxLevel) { + glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); glTexImage2D(target, level, internalFormat, width, height, 0, format, type, usersImage); } + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); if(levels == 0) { /* we're done. clean up and return */ glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); @@ -8643,7 +8671,8 @@ static void halveImageSlice(int components, int halfHeight= height / 2; int halfDepth= depth / 2; const char *src= (const char *)dataIn; - int padBytes= rowSizeInBytes - (width * groupSizeInBytes); + int rowPadBytes= rowSizeInBytes - (width * groupSizeInBytes); + int imagePadBytes= imageSizeInBytes - (width*height*groupSizeInBytes); int outIndex= 0; assert((width == 1 || height == 1) && depth >= 2); @@ -8727,7 +8756,7 @@ static void halveImageSlice(int components, /* skip over to next horizontal square of 4 */ src+= groupSizeInBytes; } /* for jj */ - src+= padBytes; + src+= rowPadBytes; src+= rowSizeInBytes; } /* for ii */ @@ -8772,11 +8801,12 @@ static void halveImageSlice(int components, src+= elementSizeInBytes; } /* for cc */ - src+= padBytes; + src+= rowPadBytes; /* skip over to next vertical square of 4 */ src+= rowSizeInBytes; } /* for jj */ + src+= imagePadBytes; src+= imageSizeInBytes; } /* for ii */ @@ -8816,7 +8846,8 @@ static void halveImage3D(int components, int halfHeight= height / 2; int halfDepth= depth / 2; const char *src= (const char *) dataIn; - int padBytes= rowSizeInBytes - (width*groupSizeInBytes); + int rowPadBytes= rowSizeInBytes - (width*groupSizeInBytes); + int imagePadBytes= imageSizeInBytes - (width*height*groupSizeInBytes); int outIndex= 0; for (dd= 0; dd < halfDepth; dd++) { @@ -8872,7 +8903,7 @@ static void halveImage3D(int components, src+= groupSizeInBytes; } /* for jj */ /* skip past pad bytes, if any, to get to next row */ - src+= padBytes; + src+= rowPadBytes; /* src is at beginning of a row here, but it's the second row of * the square block of 4 pixels that we just worked on so we @@ -8887,6 +8918,9 @@ static void halveImage3D(int components, src+= rowSizeInBytes; } /* for ii */ + /* skip past pad bytes, if any, to get to next image */ + src+= imagePadBytes; + src+= imageSizeInBytes; } /* for dd */ diff --git a/src/mesa/drivers/dri/i965/brw_save_api.c b/src/mesa/drivers/dri/i965/brw_save_api.c index 9c0e4af48a5..c541fbe0f46 100644 --- a/src/mesa/drivers/dri/i965/brw_save_api.c +++ b/src/mesa/drivers/dri/i965/brw_save_api.c @@ -529,7 +529,7 @@ static void _save_upgrade_vertex( GLcontext *ctx, /* Need to note this and fix up at runtime (or loopback): */ - if (save->currentsz[attr][0] == 0) { + if (attr != BRW_ATTRIB_POS && save->currentsz[attr][0] == 0) { assert(oldsz == 0); save->dangling_attr_ref = GL_TRUE; } @@ -855,10 +855,14 @@ static void GLAPIENTRY _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei co if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) return; + _ae_map_vbos( ctx ); + brw_save_NotifyBegin( ctx, mode | BRW_SAVE_PRIM_WEAK ); for (i = 0; i < count; i++) CALL_ArrayElement(GET_DISPATCH(), (start + i)); CALL_End(GET_DISPATCH(), ()); + + _ae_unmap_vbos( ctx ); } /* Could do better by copying the arrays and element list intact and @@ -873,6 +877,8 @@ static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) return; + _ae_map_vbos( ctx ); + brw_save_NotifyBegin( ctx, mode | BRW_SAVE_PRIM_WEAK ); switch (type) { @@ -894,6 +900,8 @@ static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum } CALL_End(GET_DISPATCH(), ()); + + _ae_unmap_vbos( ctx ); } static void GLAPIENTRY _save_OBE_DrawRangeElements(GLenum mode, diff --git a/src/mesa/drivers/dri/i965/brw_vs_tnl.c b/src/mesa/drivers/dri/i965/brw_vs_tnl.c index 1df111f6457..52bdb9d7614 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_tnl.c +++ b/src/mesa/drivers/dri/i965/brw_vs_tnl.c @@ -404,7 +404,7 @@ static struct ureg register_const4f( struct tnl_program *p, values[1] = s1; values[2] = s2; values[3] = s3; - idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values ); + idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4 ); return make_ureg(PROGRAM_STATE_VAR, idx); } diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c index 04c7555b9b8..bb0aa356150 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_fp.c +++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c @@ -432,7 +432,7 @@ static struct prog_src_register search_or_add_const4f( struct brw_wm_compile *c, return src_reg(PROGRAM_STATE_VAR, idx); } - idx = _mesa_add_unnamed_constant( paramList, values ); + idx = _mesa_add_unnamed_constant( paramList, values, 4 ); return src_reg(PROGRAM_STATE_VAR, idx); } diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c index 06b2a152d9f..bb7a16c9327 100644 --- a/src/mesa/drivers/dri/r200/r200_context.c +++ b/src/mesa/drivers/dri/r200/r200_context.c @@ -87,21 +87,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. int R200_DEBUG = (0); #endif - -/* Return the width and height of the given buffer. - */ -static void r200GetBufferSize( GLframebuffer *buffer, - GLuint *width, GLuint *height ) -{ - GET_CURRENT_CONTEXT(ctx); - r200ContextPtr rmesa = R200_CONTEXT(ctx); - - LOCK_HARDWARE( rmesa ); - *width = rmesa->dri.drawable->w; - *height = rmesa->dri.drawable->h; - UNLOCK_HARDWARE( rmesa ); -} - /* Return various strings for glGetString(). */ static const GLubyte *r200GetString( GLcontext *ctx, GLenum name ) @@ -233,7 +218,7 @@ static const struct tnl_pipeline_stage *r200_pipeline[] = { */ static void r200InitDriverFuncs( struct dd_function_table *functions ) { - functions->GetBufferSize = r200GetBufferSize; + functions->GetBufferSize = NULL; /* OBSOLETE */ functions->GetString = r200GetString; } @@ -700,7 +685,13 @@ r200MakeCurrent( __DRIcontextPrivate *driContextPriv, if ( newCtx->dri.drawable != driDrawPriv ) { driDrawableInitVBlank( driDrawPriv, newCtx->vblank_flags, &newCtx->vbl_seq ); + } + + if ( newCtx->dri.drawable != driDrawPriv || + newCtx->dri.readable != driReadPriv ) { newCtx->dri.drawable = driDrawPriv; + newCtx->dri.readable = driReadPriv; + r200UpdateWindow( newCtx->glCtx ); r200UpdateViewportOffset( newCtx->glCtx ); } diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h index c6910f5238a..9f109e07ff5 100644 --- a/src/mesa/drivers/dri/r200/r200_context.h +++ b/src/mesa/drivers/dri/r200/r200_context.h @@ -699,6 +699,7 @@ struct r200_dri_mirror { __DRIcontextPrivate *context; /* DRI context */ __DRIscreenPrivate *screen; /* DRI screen */ __DRIdrawablePrivate *drawable; /* DRI drawable bound to this ctx */ + __DRIdrawablePrivate *readable; /* DRI readable bound to this ctx */ drm_context_t hwContext; drm_hw_lock_t *hwLock; diff --git a/src/mesa/drivers/dri/r200/r200_lock.c b/src/mesa/drivers/dri/r200/r200_lock.c index 66bb075864f..bcc0c916396 100644 --- a/src/mesa/drivers/dri/r200/r200_lock.c +++ b/src/mesa/drivers/dri/r200/r200_lock.c @@ -69,7 +69,8 @@ r200UpdatePageFlipping( r200ContextPtr rmesa ) */ void r200GetLock( r200ContextPtr rmesa, GLuint flags ) { - __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; + __DRIdrawablePrivate *drawable = rmesa->dri.drawable; + __DRIdrawablePrivate *readable = rmesa->dri.readable; __DRIscreenPrivate *sPriv = rmesa->dri.screen; drm_radeon_sarea_t *sarea = rmesa->sarea; int i; @@ -84,17 +85,20 @@ void r200GetLock( r200ContextPtr rmesa, GLuint flags ) * Since the hardware state depends on having the latest drawable * clip rects, all state checking must be done _after_ this call. */ - DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv ); + DRI_VALIDATE_DRAWABLE_INFO( sPriv, drawable ); + if (drawable != readable) { + DRI_VALIDATE_DRAWABLE_INFO( sPriv, readable ); + } - if ( rmesa->lastStamp != dPriv->lastStamp ) { + if ( rmesa->lastStamp != drawable->lastStamp ) { r200UpdatePageFlipping( rmesa ); if (rmesa->glCtx->DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_BACK_LEFT) r200SetCliprects( rmesa, GL_BACK_LEFT ); else r200SetCliprects( rmesa, GL_FRONT_LEFT ); r200UpdateViewportOffset( rmesa->glCtx ); - driUpdateFramebufferSize(rmesa->glCtx, dPriv); - rmesa->lastStamp = dPriv->lastStamp; + driUpdateFramebufferSize(rmesa->glCtx, drawable); + rmesa->lastStamp = drawable->lastStamp; } R200_STATECHANGE( rmesa, ctx ); diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c index 097fbc868a4..dc1fbef72ee 100644 --- a/src/mesa/drivers/dri/r200/r200_state.c +++ b/src/mesa/drivers/dri/r200/r200_state.c @@ -40,6 +40,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "enums.h" #include "colormac.h" #include "light.h" +#include "framebuffer.h" #include "swrast/swrast.h" #include "array_cache/acache.h" @@ -1845,23 +1846,26 @@ static void r200LogicOpCode( GLcontext *ctx, GLenum opcode ) void r200SetCliprects( r200ContextPtr rmesa, GLenum mode ) { - __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; + __DRIdrawablePrivate *const drawable = rmesa->dri.drawable; + __DRIdrawablePrivate *const readable = rmesa->dri.readable; + GLframebuffer *const draw_fb = (GLframebuffer*) drawable->driverPrivate; + GLframebuffer *const read_fb = (GLframebuffer*) readable->driverPrivate; switch ( mode ) { case GL_FRONT_LEFT: - rmesa->numClipRects = dPriv->numClipRects; - rmesa->pClipRects = dPriv->pClipRects; + rmesa->numClipRects = drawable->numClipRects; + rmesa->pClipRects = drawable->pClipRects; break; case GL_BACK_LEFT: /* Can't ignore 2d windows if we are page flipping. */ - if ( dPriv->numBackClipRects == 0 || rmesa->doPageFlip ) { - rmesa->numClipRects = dPriv->numClipRects; - rmesa->pClipRects = dPriv->pClipRects; + if ( drawable->numBackClipRects == 0 || rmesa->doPageFlip ) { + rmesa->numClipRects = drawable->numClipRects; + rmesa->pClipRects = drawable->pClipRects; } else { - rmesa->numClipRects = dPriv->numBackClipRects; - rmesa->pClipRects = dPriv->pBackClipRects; + rmesa->numClipRects = drawable->numBackClipRects; + rmesa->pClipRects = drawable->pBackClipRects; } break; default: @@ -1869,6 +1873,21 @@ void r200SetCliprects( r200ContextPtr rmesa, GLenum mode ) return; } + if ((draw_fb->Width != drawable->w) || (draw_fb->Height != drawable->h)) { + _mesa_resize_framebuffer(rmesa->glCtx, draw_fb, + drawable->w, drawable->h); + draw_fb->Initialized = GL_TRUE; + } + + if (drawable != readable) { + if ((read_fb->Width != readable->w) || + (read_fb->Height != readable->h)) { + _mesa_resize_framebuffer(rmesa->glCtx, read_fb, + readable->w, readable->h); + read_fb->Initialized = GL_TRUE; + } + } + if (rmesa->state.scissor.enabled) r200RecalcScissorRects( rmesa ); } diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index df73cdedc11..dd3ecbb2357 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -549,6 +549,7 @@ struct r300_stencilbuffer_state { /* Can be tested with colormat currently. */ #define VSF_MAX_FRAGMENT_TEMPS (14) +#define STATE_R300_WINDOW_DIMENSION (STATE_INTERNAL_DRIVER+0) struct r300_vertex_shader_fragment { int length; @@ -592,7 +593,8 @@ struct r300_vertex_shader_state { extern int hw_tcl_on; -#define CURRENT_VERTEX_SHADER(ctx) (ctx->VertexProgram._Current) +//#define CURRENT_VERTEX_SHADER(ctx) (ctx->VertexProgram._Current) +#define CURRENT_VERTEX_SHADER(ctx) (R300_CONTEXT(ctx)->selected_vp) /* Should but doesnt work */ //#define CURRENT_VERTEX_SHADER(ctx) (R300_CONTEXT(ctx)->curr_vp) @@ -607,15 +609,22 @@ extern int hw_tcl_on; /* r300_vertex_shader_state and r300_vertex_program should probably be merged together someday. * Keeping them them seperate for now should ensure fixed pipeline keeps functioning properly. */ + +struct r300_vertex_program_key { + GLuint InputsRead; + GLuint OutputsWritten; +}; + struct r300_vertex_program { - struct gl_vertex_program mesa_program; /* Must be first */ + struct r300_vertex_program *next; + struct r300_vertex_program_key key; int translated; struct r300_vertex_shader_fragment program; - struct r300_vertex_shader_fragment params; int pos_end; int num_temporaries; /* Number of temp vars used by program */ + int wpos_idx; int inputs[VERT_ATTRIB_MAX]; int outputs[VERT_RESULT_MAX]; int native; @@ -623,6 +632,12 @@ struct r300_vertex_program { int use_ref_count; }; +struct r300_vertex_program_cont { + struct gl_vertex_program mesa_program; /* Must be first */ + struct r300_vertex_shader_fragment params; + struct r300_vertex_program *progs; +}; + #define PFS_MAX_ALU_INST 64 #define PFS_MAX_TEX_INST 64 #define PFS_MAX_TEX_INDIRECT 4 @@ -797,6 +812,7 @@ struct r300_context { struct r300_cmdbuf cmdbuf; struct r300_state state; struct gl_vertex_program *curr_vp; + struct r300_vertex_program *selected_vp; /* Vertex buffers */ @@ -854,9 +870,9 @@ extern GLboolean r300CreateContext(const __GLcontextModes * glVisual, extern int r300_get_num_verts(r300ContextPtr rmesa, int num_verts, int prim); -void r300_translate_vertex_shader(struct r300_vertex_program *vp); +extern void r300_select_vertex_shader(r300ContextPtr r300); extern void r300InitShaderFuncs(struct dd_function_table *functions); -extern int r300VertexProgUpdateParams(GLcontext *ctx, struct r300_vertex_program *vp, float *dst); +extern int r300VertexProgUpdateParams(GLcontext *ctx, struct r300_vertex_program_cont *vp, float *dst); extern int r300Fallback(GLcontext *ctx); extern void radeon_vb_to_rvb(r300ContextPtr rmesa, struct radeon_vertex_buffer *rvb, struct vertex_buffer *vb); diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c index 7793c5eb2e3..cab54512146 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog.c @@ -1555,6 +1555,13 @@ static void init_program(struct r300_fragment_program *rp) } InputsRead &= ~FRAG_BITS_TEX_ANY; + /* fragment position treated as a texcoord */ + if (InputsRead & FRAG_BIT_WPOS) { + cs->inputs[FRAG_ATTRIB_WPOS].refcount = 0; + cs->inputs[FRAG_ATTRIB_WPOS].reg = get_hw_temp(rp); + } + InputsRead &= ~FRAG_BIT_WPOS; + /* Then primary colour */ if (InputsRead & FRAG_BIT_COL0) { cs->inputs[FRAG_ATTRIB_COL0].refcount = 0; diff --git a/src/mesa/drivers/dri/r300/r300_maos.c b/src/mesa/drivers/dri/r300/r300_maos.c index 2fdad519fd5..fcb87cbbb59 100644 --- a/src/mesa/drivers/dri/r300/r300_maos.c +++ b/src/mesa/drivers/dri/r300/r300_maos.c @@ -407,8 +407,8 @@ int r300EmitArrays(GLcontext *ctx) if (hw_tcl_on) { struct r300_vertex_program *prog=(struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx); inputs = prog->inputs; - InputsRead = CURRENT_VERTEX_SHADER(ctx)->Base.InputsRead; - OutputsWritten = CURRENT_VERTEX_SHADER(ctx)->Base.OutputsWritten; + InputsRead = CURRENT_VERTEX_SHADER(ctx)->key.InputsRead; + OutputsWritten = CURRENT_VERTEX_SHADER(ctx)->key.OutputsWritten; } else { DECLARE_RENDERINPUTS(inputs_bitset); inputs = r300->state.sw_tcl_inputs; diff --git a/src/mesa/drivers/dri/r300/r300_shader.c b/src/mesa/drivers/dri/r300/r300_shader.c index 576b18953f9..26721e8dfda 100644 --- a/src/mesa/drivers/dri/r300/r300_shader.c +++ b/src/mesa/drivers/dri/r300/r300_shader.c @@ -12,13 +12,13 @@ r300BindProgram(GLcontext *ctx, GLenum target, struct gl_program *prog) { r300ContextPtr rmesa = R300_CONTEXT(ctx); - struct r300_vertex_program *vp=(void *)prog; + struct r300_vertex_program_cont *vp=(void *)prog; switch(target){ case GL_VERTEX_PROGRAM_ARB: - rmesa->curr_vp = (struct gl_vertex_program *)vp; - vp->ref_count++; + //rmesa->curr_vp = (struct gl_vertex_program *)vp; + //vp->ref_count++; #if 0 if((vp->ref_count % 1500) == 0) { fprintf(stderr, "id %p, ref_count %d\n", vp, vp->ref_count); @@ -37,13 +37,13 @@ r300BindProgram(GLcontext *ctx, GLenum target, struct gl_program *prog) static struct gl_program * r300NewProgram(GLcontext *ctx, GLenum target, GLuint id) { - struct r300_vertex_program *vp; + struct r300_vertex_program_cont *vp; struct r300_fragment_program *fp; switch(target){ case GL_VERTEX_STATE_PROGRAM_NV: case GL_VERTEX_PROGRAM_ARB: - vp=CALLOC_STRUCT(r300_vertex_program); + vp=CALLOC_STRUCT(r300_vertex_program_cont); return _mesa_init_vertex_program(ctx, &vp->mesa_program, target, id); case GL_FRAGMENT_PROGRAM_ARB: fp=CALLOC_STRUCT(r300_fragment_program); @@ -77,13 +77,14 @@ r300DeleteProgram(GLcontext *ctx, struct gl_program *prog) static void r300ProgramStringNotify(GLcontext *ctx, GLenum target, struct gl_program *prog) { - struct r300_vertex_program *vp=(void *)prog; + struct r300_vertex_program_cont *vp=(void *)prog; struct r300_fragment_program *fp = (struct r300_fragment_program *) prog; switch(target) { case GL_VERTEX_PROGRAM_ARB: - vp->translated = GL_FALSE; - memset(&vp->translated, 0, sizeof(struct r300_vertex_program) - sizeof(struct gl_vertex_program)); + vp->progs = NULL; + /*vp->translated = GL_FALSE; + memset(&vp->translated, 0, sizeof(struct r300_vertex_program) - sizeof(struct gl_vertex_program));*/ /*r300_translate_vertex_shader(vp);*/ break; case GL_FRAGMENT_PROGRAM_ARB: diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index b06336457de..72255066d59 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -1044,6 +1044,59 @@ r300UpdateDrawBuffer(GLcontext *ctx) #endif } +static void r300FetchStateParameter(GLcontext *ctx, const enum state_index state[], + GLfloat *value) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + + switch(state[0]) + { + case STATE_INTERNAL: + switch(state[1]) + { + case STATE_R300_WINDOW_DIMENSION: + value[0] = r300->radeon.dri.drawable->w; /* width */ + value[1] = r300->radeon.dri.drawable->h; /* height */ + value[2] = 0.5F; /* for moving range [-1 1] -> [0 1] */ + value[3] = 1.0F; /* not used */ + break; + default:; + } + default:; + } +} + +/** + * Update R300's own internal state parameters. + * For now just STATE_R300_WINDOW_DIMENSION + */ +static void r300UpdateStateParameters(GLcontext * ctx, GLuint new_state) +{ + struct r300_vertex_program_cont *vpc; + struct gl_program_parameter_list *paramList; + GLuint i; + + if(!(new_state & (_NEW_BUFFERS|_NEW_PROGRAM))) + return; + + vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current; + if (!vpc) + return; + + paramList = vpc->mesa_program.Base.Parameters; + + if (!paramList) + return; + + for (i = 0; i < paramList->NumParameters; i++) { + if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR){ + r300FetchStateParameter(ctx, + paramList->Parameters[i].StateIndexes, + paramList->ParameterValues[i]); + } + } +} + /* ============================================================= * Polygon state */ @@ -1285,7 +1338,7 @@ void r300_setup_rs_unit(GLcontext *ctx) int i; if(hw_tcl_on) - OutputsWritten.vp_outputs = CURRENT_VERTEX_SHADER(ctx)->Base.OutputsWritten; + OutputsWritten.vp_outputs = CURRENT_VERTEX_SHADER(ctx)->key.OutputsWritten; else RENDERINPUTS_COPY( OutputsWritten.index_bitset, r300->state.render_inputs_bitset ); @@ -1304,6 +1357,20 @@ void r300_setup_rs_unit(GLcontext *ctx) r300->hw.rr.cmd[R300_RR_ROUTE_1] = 0; + if (InputsRead & FRAG_BIT_WPOS){ + for (i = 0; i < ctx->Const.MaxTextureUnits; i++) + if (!(InputsRead & (FRAG_BIT_TEX0 << i))) + break; + + if(i == ctx->Const.MaxTextureUnits){ + fprintf(stderr, "\tno free texcoord found...\n"); + exit(0); + } + + InputsRead |= (FRAG_BIT_TEX0 << i); + InputsRead &= ~FRAG_BIT_WPOS; + } + for (i=0;i<ctx->Const.MaxTextureUnits;i++) { r300->hw.ri.cmd[R300_RI_INTERP_0+i] = 0 | R300_RS_INTERP_USED @@ -1610,7 +1677,7 @@ void r300SetupVertexProgram(r300ContextPtr rmesa) ((drm_r300_cmd_header_t*)rmesa->hw.vpp.cmd)->vpu.count = 0; R300_STATECHANGE(rmesa, vpp); - param_count = r300VertexProgUpdateParams(ctx, prog, (float *)&rmesa->hw.vpp.cmd[R300_VPP_PARAM_0]); + param_count = r300VertexProgUpdateParams(ctx, (struct r300_vertex_program_cont *)ctx->VertexProgram._Current/*prog*/, (float *)&rmesa->hw.vpp.cmd[R300_VPP_PARAM_0]); bump_vpu_count(rmesa->hw.vpp.cmd, param_count); param_count /= 4; @@ -1669,9 +1736,10 @@ void r300UpdateShaders(r300ContextPtr rmesa) TNL_CONTEXT(ctx)->vb.AttribPtr[i] = rmesa->temp_attrib[i]; } + r300_select_vertex_shader(rmesa); vp = (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx); - if (vp->translated == GL_FALSE) - r300_translate_vertex_shader(vp); + /*if (vp->translated == GL_FALSE) + r300_translate_vertex_shader(vp);*/ if (vp->translated == GL_FALSE) { fprintf(stderr, "Failing back to sw-tcl\n"); hw_tcl_on = future_hw_tcl_on = 0; @@ -1679,6 +1747,7 @@ void r300UpdateShaders(r300ContextPtr rmesa) return ; } + r300UpdateStateParameters(ctx, _NEW_PROGRAM); } } @@ -1812,6 +1881,9 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state) if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { r300UpdateDrawBuffer(ctx); } + + r300UpdateStateParameters(ctx, new_state); + #ifndef CB_DPATH /* Go inefficiency! */ r300ResetHwState(r300); diff --git a/src/mesa/drivers/dri/r300/r300_vertexprog.c b/src/mesa/drivers/dri/r300/r300_vertexprog.c index cc932b86d99..2492a4a3a0a 100644 --- a/src/mesa/drivers/dri/r300/r300_vertexprog.c +++ b/src/mesa/drivers/dri/r300/r300_vertexprog.c @@ -95,7 +95,7 @@ static struct{ }; #undef OPN -int r300VertexProgUpdateParams(GLcontext *ctx, struct r300_vertex_program *vp, float *dst) +int r300VertexProgUpdateParams(GLcontext *ctx, struct r300_vertex_program_cont *vp, float *dst) { int pi; struct gl_vertex_program *mesa_vp = &vp->mesa_program; @@ -177,17 +177,9 @@ static unsigned long t_dst_class(enum register_file file) static unsigned long t_dst_index(struct r300_vertex_program *vp, struct prog_dst_register *dst) { - if(dst->File == PROGRAM_OUTPUT) { - if (vp->outputs[dst->Index] != -1) - return vp->outputs[dst->Index]; - else { - WARN_ONCE("Unknown output %d\n", dst->Index); - return 10; - } - }else if(dst->File == PROGRAM_ADDRESS) { - assert(dst->Index == 0); - } - + if(dst->File == PROGRAM_OUTPUT) + return vp->outputs[dst->Index]; + return dst->Index; } @@ -335,6 +327,18 @@ static unsigned long op_operands(enum prog_opcode opcode) return 0; } +static GLboolean valid_dst(struct r300_vertex_program *vp, struct prog_dst_register *dst) +{ + if(dst->File == PROGRAM_OUTPUT && vp->outputs[dst->Index] == -1){ + WARN_ONCE("Output %d not used by fragment program\n", dst->Index); + return GL_FALSE; + }else if(dst->File == PROGRAM_ADDRESS) { + assert(dst->Index == 0); + } + + return GL_TRUE; +} + /* TODO: Get rid of t_src_class call */ #define CMP_SRCS(a, b) ((a.RelAddr != b.RelAddr) || (a.Index != b.Index && \ ((t_src_class(a.File) == VSF_IN_CLASS_PARAM && \ @@ -384,10 +388,8 @@ static unsigned long op_operands(enum prog_opcode opcode) u_temp_i=VSF_MAX_FRAGMENT_TEMPS-1; \ } while (0) -void r300_translate_vertex_shader(struct r300_vertex_program *vp) +static void r300_translate_vertex_shader(struct r300_vertex_program *vp, struct prog_instruction *vpi) { - struct gl_vertex_program *mesa_vp= &vp->mesa_program; - struct prog_instruction *vpi; int i, cur_reg=0; VERTEX_SHADER_INSTRUCTION *o_inst; unsigned long operands; @@ -399,131 +401,9 @@ void r300_translate_vertex_shader(struct r300_vertex_program *vp) int u_temp_i=VSF_MAX_FRAGMENT_TEMPS-1; struct prog_src_register src[3]; - if (mesa_vp->Base.NumInstructions == 0) - return; - - if (getenv("R300_VP_SAFETY")) { - WARN_ONCE("R300_VP_SAFETY enabled.\n"); - - vpi = malloc((mesa_vp->Base.NumInstructions + VSF_MAX_FRAGMENT_TEMPS) * sizeof(struct prog_instruction)); - memset(vpi, 0, VSF_MAX_FRAGMENT_TEMPS * sizeof(struct prog_instruction)); - - for (i=0; i < VSF_MAX_FRAGMENT_TEMPS; i++) { - vpi[i].Opcode = OPCODE_MOV; - vpi[i].StringPos = 0; - vpi[i].Data = 0; - - vpi[i].DstReg.File = PROGRAM_TEMPORARY; - vpi[i].DstReg.Index = i; - vpi[i].DstReg.WriteMask = WRITEMASK_XYZW; - vpi[i].DstReg.CondMask = COND_TR; - - vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR; - vpi[i].SrcReg[0].Index = 0; - vpi[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE); - } - - memcpy(&vpi[i], mesa_vp->Base.Instructions, mesa_vp->Base.NumInstructions * sizeof(struct prog_instruction)); - - free(mesa_vp->Base.Instructions); - - mesa_vp->Base.Instructions = vpi; - - mesa_vp->Base.NumInstructions += VSF_MAX_FRAGMENT_TEMPS; - vpi = &mesa_vp->Base.Instructions[mesa_vp->Base.NumInstructions-1]; - - assert(vpi->Opcode == OPCODE_END); - } - - if (mesa_vp->IsPositionInvariant) { - struct gl_program_parameter_list *paramList; - GLint tokens[6] = { STATE_MATRIX, STATE_MVP, 0, 0, 0, STATE_MATRIX }; - -#ifdef PREFER_DP4 - tokens[5] = STATE_MATRIX; -#else - tokens[5] = STATE_MATRIX_TRANSPOSE; -#endif - paramList = mesa_vp->Base.Parameters; - - vpi = malloc((mesa_vp->Base.NumInstructions + 4) * sizeof(struct prog_instruction)); - memset(vpi, 0, 4 * sizeof(struct prog_instruction)); - - for (i=0; i < 4; i++) { - GLint idx; - tokens[3] = tokens[4] = i; - idx = _mesa_add_state_reference(paramList, tokens); -#ifdef PREFER_DP4 - vpi[i].Opcode = OPCODE_DP4; - vpi[i].StringPos = 0; - vpi[i].Data = 0; - - vpi[i].DstReg.File = PROGRAM_OUTPUT; - vpi[i].DstReg.Index = VERT_RESULT_HPOS; - vpi[i].DstReg.WriteMask = 1 << i; - vpi[i].DstReg.CondMask = COND_TR; - - vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR; - vpi[i].SrcReg[0].Index = idx; - vpi[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W); - - vpi[i].SrcReg[1].File = PROGRAM_INPUT; - vpi[i].SrcReg[1].Index = VERT_ATTRIB_POS; - vpi[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W); -#else - if (i == 0) - vpi[i].Opcode = OPCODE_MUL; - else - vpi[i].Opcode = OPCODE_MAD; - - vpi[i].StringPos = 0; - vpi[i].Data = 0; - - if (i == 3) - vpi[i].DstReg.File = PROGRAM_OUTPUT; - else - vpi[i].DstReg.File = PROGRAM_TEMPORARY; - vpi[i].DstReg.Index = 0; - vpi[i].DstReg.WriteMask = 0xf; - vpi[i].DstReg.CondMask = COND_TR; - - vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR; - vpi[i].SrcReg[0].Index = idx; - vpi[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W); - - vpi[i].SrcReg[1].File = PROGRAM_INPUT; - vpi[i].SrcReg[1].Index = VERT_ATTRIB_POS; - vpi[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(i, i, i, i); - - if (i > 0) { - vpi[i].SrcReg[2].File = PROGRAM_TEMPORARY; - vpi[i].SrcReg[2].Index = 0; - vpi[i].SrcReg[2].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W); - } -#endif - } - - memcpy(&vpi[i], mesa_vp->Base.Instructions, mesa_vp->Base.NumInstructions * sizeof(struct prog_instruction)); - - free(mesa_vp->Base.Instructions); - - mesa_vp->Base.Instructions = vpi; - - mesa_vp->Base.NumInstructions += 4; - vpi = &mesa_vp->Base.Instructions[mesa_vp->Base.NumInstructions-1]; - - assert(vpi->Opcode == OPCODE_END); - - mesa_vp->Base.InputsRead |= (1 << VERT_ATTRIB_POS); - mesa_vp->Base.OutputsWritten |= (1 << VERT_RESULT_HPOS); - - //fprintf(stderr, "IsPositionInvariant is set!\n"); - //_mesa_print_program(&mesa_vp->Base); - } - vp->pos_end=0; /* Not supported yet */ vp->program.length=0; - vp->num_temporaries=mesa_vp->Base.NumTemporaries; + /*vp->num_temporaries=mesa_vp->Base.NumTemporaries;*/ for(i=0; i < VERT_ATTRIB_MAX; i++) vp->inputs[i] = -1; @@ -531,42 +411,49 @@ void r300_translate_vertex_shader(struct r300_vertex_program *vp) for(i=0; i < VERT_RESULT_MAX; i++) vp->outputs[i] = -1; - assert(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS)); + assert(vp->key.OutputsWritten & (1 << VERT_RESULT_HPOS)); /* Assign outputs */ - if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS)) + if(vp->key.OutputsWritten & (1 << VERT_RESULT_HPOS)) vp->outputs[VERT_RESULT_HPOS] = cur_reg++; - if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_PSIZ)) + if(vp->key.OutputsWritten & (1 << VERT_RESULT_PSIZ)) vp->outputs[VERT_RESULT_PSIZ] = cur_reg++; - if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_COL0)) + if(vp->key.OutputsWritten & (1 << VERT_RESULT_COL0)) vp->outputs[VERT_RESULT_COL0] = cur_reg++; - if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_COL1)) + if(vp->key.OutputsWritten & (1 << VERT_RESULT_COL1)) vp->outputs[VERT_RESULT_COL1] = cur_reg++; #if 0 /* Not supported yet */ - if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_BFC0)) + if(vp->key.OutputsWritten & (1 << VERT_RESULT_BFC0)) vp->outputs[VERT_RESULT_BFC0] = cur_reg++; - if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_BFC1)) + if(vp->key.OutputsWritten & (1 << VERT_RESULT_BFC1)) vp->outputs[VERT_RESULT_BFC1] = cur_reg++; - if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_FOGC)) + if(vp->key.OutputsWritten & (1 << VERT_RESULT_FOGC)) vp->outputs[VERT_RESULT_FOGC] = cur_reg++; #endif for(i=VERT_RESULT_TEX0; i <= VERT_RESULT_TEX7; i++) - if(mesa_vp->Base.OutputsWritten & (1 << i)) + if(vp->key.OutputsWritten & (1 << i)) vp->outputs[i] = cur_reg++; vp->translated = GL_TRUE; vp->native = GL_TRUE; o_inst=vp->program.body.i; - for(vpi=mesa_vp->Base.Instructions; vpi->Opcode != OPCODE_END; vpi++, o_inst++){ + for(; vpi->Opcode != OPCODE_END; vpi++, o_inst++){ FREE_TEMPS(); + + if(!valid_dst(vp, &vpi->DstReg)) + { + /* redirect result to unused temp */ + vpi->DstReg.File = PROGRAM_TEMPORARY; + vpi->DstReg.Index = u_temp_i; + } operands=op_operands(vpi->Opcode); are_srcs_scalar=operands & SCALAR_FLAG; @@ -987,3 +874,302 @@ void r300_translate_vertex_shader(struct r300_vertex_program *vp) #endif } +static void position_invariant(struct gl_program *prog) +{ + struct prog_instruction *vpi; + struct gl_program_parameter_list *paramList; + int i; + + GLint tokens[6] = { STATE_MATRIX, STATE_MVP, 0, 0, 0, STATE_MATRIX }; + +#ifdef PREFER_DP4 + tokens[5] = STATE_MATRIX; +#else + tokens[5] = STATE_MATRIX_TRANSPOSE; +#endif + paramList = prog->Parameters; + + vpi = malloc((prog->NumInstructions + 4) * sizeof(struct prog_instruction)); + memset(vpi, 0, 4 * sizeof(struct prog_instruction)); + + for (i=0; i < 4; i++) { + GLint idx; + tokens[3] = tokens[4] = i; + idx = _mesa_add_state_reference(paramList, tokens); +#ifdef PREFER_DP4 + vpi[i].Opcode = OPCODE_DP4; + vpi[i].StringPos = 0; + vpi[i].Data = 0; + + vpi[i].DstReg.File = PROGRAM_OUTPUT; + vpi[i].DstReg.Index = VERT_RESULT_HPOS; + vpi[i].DstReg.WriteMask = 1 << i; + vpi[i].DstReg.CondMask = COND_TR; + + vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR; + vpi[i].SrcReg[0].Index = idx; + vpi[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W); + + vpi[i].SrcReg[1].File = PROGRAM_INPUT; + vpi[i].SrcReg[1].Index = VERT_ATTRIB_POS; + vpi[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W); +#else + if (i == 0) + vpi[i].Opcode = OPCODE_MUL; + else + vpi[i].Opcode = OPCODE_MAD; + + vpi[i].StringPos = 0; + vpi[i].Data = 0; + + if (i == 3) + vpi[i].DstReg.File = PROGRAM_OUTPUT; + else + vpi[i].DstReg.File = PROGRAM_TEMPORARY; + vpi[i].DstReg.Index = 0; + vpi[i].DstReg.WriteMask = 0xf; + vpi[i].DstReg.CondMask = COND_TR; + + vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR; + vpi[i].SrcReg[0].Index = idx; + vpi[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W); + + vpi[i].SrcReg[1].File = PROGRAM_INPUT; + vpi[i].SrcReg[1].Index = VERT_ATTRIB_POS; + vpi[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(i, i, i, i); + + if (i > 0) { + vpi[i].SrcReg[2].File = PROGRAM_TEMPORARY; + vpi[i].SrcReg[2].Index = 0; + vpi[i].SrcReg[2].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W); + } +#endif + } + + memcpy(&vpi[i], prog->Instructions, prog->NumInstructions * sizeof(struct prog_instruction)); + + free(prog->Instructions); + + prog->Instructions = vpi; + + prog->NumInstructions += 4; + vpi = &prog->Instructions[prog->NumInstructions-1]; + + assert(vpi->Opcode == OPCODE_END); +} + +static void insert_wpos(struct r300_vertex_program *vp, + struct gl_program *prog, + GLint pos) +{ + + GLint tokens[6] = { STATE_INTERNAL, STATE_R300_WINDOW_DIMENSION, 0, 0, 0, 0 }; + struct prog_instruction *vpi; + struct prog_instruction *vpi_insert; + GLuint temp_index; + GLuint window_index; + int i = 0; + + vpi = malloc((prog->NumInstructions + 5) * sizeof(struct prog_instruction)); + memcpy(vpi, prog->Instructions, (pos+1) * sizeof(struct prog_instruction)); + + vpi_insert = &vpi[pos]; + + /* make a copy before outputting VERT_RESULT_HPOS */ + vpi_insert->DstReg.File = vpi_insert->SrcReg[2].File; + vpi_insert->DstReg.Index = temp_index = vpi_insert->SrcReg[2].Index; + + vpi_insert++; + memset(vpi_insert, 0, 5 * sizeof(struct prog_instruction)); + + vpi_insert[i].Opcode = OPCODE_MOV; + + vpi_insert[i].DstReg.File = PROGRAM_OUTPUT; + vpi_insert[i].DstReg.Index = VERT_RESULT_HPOS; + vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZW; + vpi_insert[i].DstReg.CondMask = COND_TR; + + vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY; + vpi_insert[i].SrcReg[0].Index = temp_index; + vpi_insert[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W); + i++; + + /* perspective divide */ + vpi_insert[i].Opcode = OPCODE_RCP; + + vpi_insert[i].DstReg.File = PROGRAM_TEMPORARY; + vpi_insert[i].DstReg.Index = temp_index; + vpi_insert[i].DstReg.WriteMask = WRITEMASK_W; + vpi_insert[i].DstReg.CondMask = COND_TR; + + vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY; + vpi_insert[i].SrcReg[0].Index = temp_index; + vpi_insert[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_W, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO); + i++; + + vpi_insert[i].Opcode = OPCODE_MUL; + + vpi_insert[i].DstReg.File = PROGRAM_TEMPORARY; + vpi_insert[i].DstReg.Index = temp_index; + vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZ; + vpi_insert[i].DstReg.CondMask = COND_TR; + + vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY; + vpi_insert[i].SrcReg[0].Index = temp_index; + vpi_insert[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO); + + vpi_insert[i].SrcReg[1].File = PROGRAM_TEMPORARY; + vpi_insert[i].SrcReg[1].Index = temp_index; + vpi_insert[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_ZERO); + i++; + + /* viewport transformation */ + window_index = _mesa_add_state_reference(prog->Parameters, tokens); + + vpi_insert[i].Opcode = OPCODE_MAD; + + vpi_insert[i].DstReg.File = PROGRAM_TEMPORARY; + vpi_insert[i].DstReg.Index = temp_index; + vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZ; + vpi_insert[i].DstReg.CondMask = COND_TR; + + vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY; + vpi_insert[i].SrcReg[0].Index = temp_index; + vpi_insert[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO); + + vpi_insert[i].SrcReg[1].File = PROGRAM_STATE_VAR; + vpi_insert[i].SrcReg[1].Index = window_index; + vpi_insert[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_ZERO); + + vpi_insert[i].SrcReg[2].File = PROGRAM_STATE_VAR; + vpi_insert[i].SrcReg[2].Index = window_index; + vpi_insert[i].SrcReg[2].Swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_ZERO); + i++; + + vpi_insert[i].Opcode = OPCODE_MUL; + + vpi_insert[i].DstReg.File = PROGRAM_OUTPUT; + vpi_insert[i].DstReg.Index = VERT_RESULT_TEX0+vp->wpos_idx; + vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZW; + vpi_insert[i].DstReg.CondMask = COND_TR; + + vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY; + vpi_insert[i].SrcReg[0].Index = temp_index; + vpi_insert[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W); + + vpi_insert[i].SrcReg[1].File = PROGRAM_STATE_VAR; + vpi_insert[i].SrcReg[1].Index = window_index; + vpi_insert[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ONE, SWIZZLE_ONE); + i++; + + memcpy(&vpi_insert[i], &prog->Instructions[pos+1], (prog->NumInstructions-(pos+1)) * sizeof(struct prog_instruction)); + + free(prog->Instructions); + + prog->Instructions = vpi; + + prog->NumInstructions += i; + vpi = &prog->Instructions[prog->NumInstructions-1]; + + assert(vpi->Opcode == OPCODE_END); +} + +static void pos_as_texcoord(struct r300_vertex_program *vp, + struct gl_program *prog) +{ + struct prog_instruction *vpi; + int pos = 0; + + for(vpi = prog->Instructions; vpi->Opcode != OPCODE_END; vpi++, pos++){ + if( vpi->DstReg.File == PROGRAM_OUTPUT && + vpi->DstReg.Index == VERT_RESULT_HPOS ){ + insert_wpos(vp, prog, pos); + break; + } + } + +} + +static struct r300_vertex_program *build_program(struct r300_vertex_program_key *wanted_key, + struct gl_vertex_program *mesa_vp, + GLint wpos_idx) +{ + struct r300_vertex_program *vp; + + vp = _mesa_calloc(sizeof(*vp)); + _mesa_memcpy(&vp->key, wanted_key, sizeof(vp->key)); + + vp->wpos_idx = wpos_idx; + + if(mesa_vp->IsPositionInvariant) + position_invariant(&mesa_vp->Base); + + if(wpos_idx > -1) + pos_as_texcoord(vp, &mesa_vp->Base); + + assert(mesa_vp->Base.NumInstructions); + + vp->num_temporaries=mesa_vp->Base.NumTemporaries; + + r300_translate_vertex_shader(vp, mesa_vp->Base.Instructions); + + return vp; +} + +void r300_select_vertex_shader(r300ContextPtr r300) +{ + GLcontext *ctx = ctx = r300->radeon.glCtx; + GLuint InputsRead; + struct r300_vertex_program_key wanted_key = { 0 }; + GLint i; + struct r300_vertex_program_cont *vpc; + struct r300_vertex_program *vp; + GLint wpos_idx; + + vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current; + InputsRead = ctx->FragmentProgram._Current->Base.InputsRead; + + wanted_key.OutputsWritten |= 1 << VERT_RESULT_HPOS; + + wpos_idx = -1; + if (InputsRead & FRAG_BIT_WPOS){ + for (i = 0; i < ctx->Const.MaxTextureUnits; i++) + if (!(InputsRead & (FRAG_BIT_TEX0 << i))) + break; + + if(i == ctx->Const.MaxTextureUnits){ + fprintf(stderr, "\tno free texcoord found\n"); + exit(0); + } + + InputsRead |= (FRAG_BIT_TEX0 << i); + wpos_idx = i; + } + + if (InputsRead & FRAG_BIT_COL0) + wanted_key.OutputsWritten |= 1 << VERT_RESULT_COL0; + + if ((InputsRead & FRAG_BIT_COL1) /*|| + (InputsRead & FRAG_BIT_FOGC)*/) + wanted_key.OutputsWritten |= 1 << VERT_RESULT_COL1; + + for (i = 0; i < ctx->Const.MaxTextureUnits; i++) + if (InputsRead & (FRAG_BIT_TEX0 << i)) + wanted_key.OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i); + + wanted_key.InputsRead = vpc->mesa_program.Base.InputsRead; + + for (vp = vpc->progs; vp; vp = vp->next) + if (_mesa_memcmp(&vp->key, &wanted_key, sizeof(wanted_key)) == 0) { + r300->selected_vp = vp; + return ; + } + + //_mesa_print_program(&vpc->mesa_program.Base); + + vp = build_program(&wanted_key, &vpc->mesa_program, wpos_idx); + vp->next = vpc->progs; + vpc->progs = vp; + + r300->selected_vp = vp; +} diff --git a/src/mesa/drivers/dri/savage/savagespan.c b/src/mesa/drivers/dri/savage/savagespan.c index 2fe991a6b99..61ab9e6d64a 100644 --- a/src/mesa/drivers/dri/savage/savagespan.c +++ b/src/mesa/drivers/dri/savage/savagespan.c @@ -33,7 +33,6 @@ #define DBG 0 #define LOCAL_VARS \ - savageContextPtr imesa = SAVAGE_CONTEXT(ctx); \ driRenderbuffer *drb = (driRenderbuffer *) rb; \ __DRIdrawablePrivate *const dPriv = drb->dPriv; \ GLuint cpp = drb->cpp; \ @@ -44,7 +43,6 @@ (void) p #define LOCAL_DEPTH_VARS \ - savageContextPtr imesa = SAVAGE_CONTEXT(ctx); \ driRenderbuffer *drb = (driRenderbuffer *) rb; \ __DRIdrawablePrivate *const dPriv = drb->dPriv; \ GLuint zpp = drb->cpp; \ diff --git a/src/mesa/glapi/glprocs.h b/src/mesa/glapi/glprocs.h index 548c271bdf7..905c65862d1 100644 --- a/src/mesa/glapi/glprocs.h +++ b/src/mesa/glapi/glprocs.h @@ -1094,6 +1094,56 @@ static const char gl_string_table[] = "glBlendEquationSeparateATI\0" ; + +#ifdef USE_MGL_NAMESPACE +#define gl_dispatch_stub_343 mgl_dispatch_stub_343 +#define gl_dispatch_stub_344 mgl_dispatch_stub_344 +#define gl_dispatch_stub_345 mgl_dispatch_stub_345 +#define gl_dispatch_stub_356 mgl_dispatch_stub_356 +#define gl_dispatch_stub_357 mgl_dispatch_stub_357 +#define gl_dispatch_stub_358 mgl_dispatch_stub_358 +#define gl_dispatch_stub_359 mgl_dispatch_stub_359 +#define gl_dispatch_stub_361 mgl_dispatch_stub_361 +#define gl_dispatch_stub_362 mgl_dispatch_stub_362 +#define gl_dispatch_stub_363 mgl_dispatch_stub_363 +#define gl_dispatch_stub_364 mgl_dispatch_stub_364 +#define gl_dispatch_stub_365 mgl_dispatch_stub_365 +#define gl_dispatch_stub_366 mgl_dispatch_stub_366 +#define gl_dispatch_stub_562 mgl_dispatch_stub_562 +#define gl_dispatch_stub_563 mgl_dispatch_stub_563 +#define gl_dispatch_stub_564 mgl_dispatch_stub_564 +#define gl_dispatch_stub_565 mgl_dispatch_stub_565 +#define gl_dispatch_stub_566 mgl_dispatch_stub_566 +#define gl_dispatch_stub_567 mgl_dispatch_stub_567 +#define gl_dispatch_stub_568 mgl_dispatch_stub_568 +#define gl_dispatch_stub_569 mgl_dispatch_stub_569 +#define gl_dispatch_stub_580 mgl_dispatch_stub_580 +#define gl_dispatch_stub_581 mgl_dispatch_stub_581 +#define gl_dispatch_stub_606 mgl_dispatch_stub_606 +#define gl_dispatch_stub_648 mgl_dispatch_stub_648 +#define gl_dispatch_stub_649 mgl_dispatch_stub_649 +#define gl_dispatch_stub_650 mgl_dispatch_stub_650 +#define gl_dispatch_stub_651 mgl_dispatch_stub_651 +#define gl_dispatch_stub_652 mgl_dispatch_stub_652 +#define gl_dispatch_stub_653 mgl_dispatch_stub_653 +#define gl_dispatch_stub_654 mgl_dispatch_stub_654 +#define gl_dispatch_stub_655 mgl_dispatch_stub_655 +#define gl_dispatch_stub_656 mgl_dispatch_stub_656 +#define gl_dispatch_stub_737 mgl_dispatch_stub_737 +#define gl_dispatch_stub_738 mgl_dispatch_stub_738 +#define gl_dispatch_stub_739 mgl_dispatch_stub_739 +#define gl_dispatch_stub_740 mgl_dispatch_stub_740 +#define gl_dispatch_stub_741 mgl_dispatch_stub_741 +#define gl_dispatch_stub_748 mgl_dispatch_stub_748 +#define gl_dispatch_stub_749 mgl_dispatch_stub_749 +#define gl_dispatch_stub_767 mgl_dispatch_stub_767 +#define gl_dispatch_stub_768 mgl_dispatch_stub_768 +#define gl_dispatch_stub_769 mgl_dispatch_stub_769 +#define gl_dispatch_stub_770 mgl_dispatch_stub_770 +#define gl_dispatch_stub_771 mgl_dispatch_stub_771 +#endif /* USE_MGL_NAMESPACE */ + + /* FIXME: Having these (incorrect) prototypes here is ugly. */ #if defined(NEED_FUNCTION_POINTER) || defined(GLX_INDIRECT_RENDERING) extern void gl_dispatch_stub_343(void); diff --git a/src/mesa/main/api_arrayelt.c b/src/mesa/main/api_arrayelt.c index dda659bbc3f..804700118f2 100644 --- a/src/mesa/main/api_arrayelt.c +++ b/src/mesa/main/api_arrayelt.c @@ -53,6 +53,11 @@ typedef struct { AEarray arrays[32]; AEattrib attribs[VERT_ATTRIB_MAX + 1]; GLuint NewState; + + struct gl_buffer_object *vbo[VERT_ATTRIB_MAX]; + GLuint nr_vbos; + GLboolean mapped_vbos; + } AEcontext; #define AE_CONTEXT(ctx) ((AEcontext *)(ctx)->aelt_context) @@ -1063,6 +1068,18 @@ void _ae_destroy_context( GLcontext *ctx ) } } +static void check_vbo( AEcontext *actx, + struct gl_buffer_object *vbo ) +{ + if (vbo->Name && !vbo->Pointer) { + GLuint i; + for (i = 0; i < actx->nr_vbos; i++) + if (actx->vbo[i] == vbo) + return; + actx->vbo[actx->nr_vbos++] = vbo; + } +} + /** * Make a list of per-vertex functions to call for each glArrayElement call. @@ -1081,31 +1098,37 @@ static void _ae_update_state( GLcontext *ctx ) if (ctx->Array.ArrayObj->Index.Enabled) { aa->array = &ctx->Array.ArrayObj->Index; aa->offset = IndexFuncs[TYPE_IDX(aa->array->Type)]; + check_vbo(actx, aa->array->BufferObj); aa++; } if (ctx->Array.ArrayObj->EdgeFlag.Enabled) { aa->array = &ctx->Array.ArrayObj->EdgeFlag; aa->offset = _gloffset_EdgeFlagv; + check_vbo(actx, aa->array->BufferObj); aa++; } if (ctx->Array.ArrayObj->Normal.Enabled) { aa->array = &ctx->Array.ArrayObj->Normal; aa->offset = NormalFuncs[TYPE_IDX(aa->array->Type)]; + check_vbo(actx, aa->array->BufferObj); aa++; } if (ctx->Array.ArrayObj->Color.Enabled) { aa->array = &ctx->Array.ArrayObj->Color; aa->offset = ColorFuncs[aa->array->Size-3][TYPE_IDX(aa->array->Type)]; + check_vbo(actx, aa->array->BufferObj); aa++; } if (ctx->Array.ArrayObj->SecondaryColor.Enabled) { aa->array = &ctx->Array.ArrayObj->SecondaryColor; aa->offset = SecondaryColorFuncs[TYPE_IDX(aa->array->Type)]; + check_vbo(actx, aa->array->BufferObj); aa++; } if (ctx->Array.ArrayObj->FogCoord.Enabled) { aa->array = &ctx->Array.ArrayObj->FogCoord; aa->offset = FogCoordFuncs[TYPE_IDX(aa->array->Type)]; + check_vbo(actx, aa->array->BufferObj); aa++; } for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { @@ -1120,11 +1143,12 @@ static void _ae_update_state( GLcontext *ctx ) [at->array->Size-1] [TYPE_IDX(at->array->Type)]; at->index = VERT_ATTRIB_TEX0 + i; + check_vbo(actx, aa->array->BufferObj); at++; } } - /* generic vertex attribute arrays */ + /* generic vertex attribute arrays */ for (i = 1; i < VERT_ATTRIB_MAX; i++) { /* skip zero! */ struct gl_client_array *attribArray = &ctx->Array.ArrayObj->VertexAttrib[i]; if (attribArray->Enabled) { @@ -1146,6 +1170,7 @@ static void _ae_update_state( GLcontext *ctx ) [TYPE_IDX(at->array->Type)]; } at->index = i; + check_vbo(actx, aa->array->BufferObj); at++; } } @@ -1158,14 +1183,18 @@ static void _ae_update_state( GLcontext *ctx ) aa->array = &ctx->Array.ArrayObj->VertexAttrib[0]; assert(aa->array->Size >= 2); /* XXX fix someday? */ aa->offset = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)]; + check_vbo(actx, aa->array->BufferObj); aa++; } else if (ctx->Array.ArrayObj->Vertex.Enabled) { aa->array = &ctx->Array.ArrayObj->Vertex; aa->offset = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)]; + check_vbo(actx, aa->array->BufferObj); aa++; } + check_vbo(actx, ctx->Array.ElementArrayBufferObj); + ASSERT(at - actx->attribs <= VERT_ATTRIB_MAX); ASSERT(aa - actx->arrays < 32); at->func = NULL; /* terminate the list */ @@ -1174,6 +1203,44 @@ static void _ae_update_state( GLcontext *ctx ) actx->NewState = 0; } +void _ae_map_vbos( GLcontext *ctx ) +{ + AEcontext *actx = AE_CONTEXT(ctx); + GLuint i; + + if (actx->mapped_vbos) + return; + + if (actx->NewState) + _ae_update_state(ctx); + + for (i = 0; i < actx->nr_vbos; i++) + ctx->Driver.MapBuffer(ctx, + GL_ARRAY_BUFFER_ARB, + GL_DYNAMIC_DRAW_ARB, + actx->vbo[i]); + + actx->mapped_vbos = GL_TRUE; +} + +void _ae_unmap_vbos( GLcontext *ctx ) +{ + AEcontext *actx = AE_CONTEXT(ctx); + GLuint i; + + if (!actx->mapped_vbos) + return; + + assert (!actx->NewState); + + for (i = 0; i < actx->nr_vbos; i++) + ctx->Driver.UnmapBuffer(ctx, + GL_ARRAY_BUFFER_ARB, + actx->vbo[i]); + + actx->mapped_vbos = GL_FALSE; +} + /** * Called via glArrayElement() and glDrawArrays(). @@ -1188,15 +1255,24 @@ void GLAPIENTRY _ae_loopback_array_elt( GLint elt ) const AEarray *aa; const AEattrib *at; const struct _glapi_table * const disp = GET_DISPATCH(); + GLboolean do_map; - - if (actx->NewState) + if (actx->NewState) { + assert(!actx->mapped_vbos); _ae_update_state( ctx ); + } + do_map = actx->nr_vbos && !actx->mapped_vbos; + + /* + */ + if (do_map) + _ae_map_vbos(ctx); + /* generic attributes */ for (at = actx->attribs; at->func; at++) { const GLubyte *src - = ADD_POINTERS(at->array->BufferObj->Data, at->array->Ptr) + = ADD_POINTERS(at->array->BufferObj->Pointer, at->array->Ptr) + elt * at->array->StrideB; at->func( at->index, src ); } @@ -1204,15 +1280,21 @@ void GLAPIENTRY _ae_loopback_array_elt( GLint elt ) /* conventional arrays */ for (aa = actx->arrays; aa->offset != -1 ; aa++) { const GLubyte *src - = ADD_POINTERS(aa->array->BufferObj->Data, aa->array->Ptr) + = ADD_POINTERS(aa->array->BufferObj->Pointer, aa->array->Ptr) + elt * aa->array->StrideB; CALL_by_offset( disp, (array_func), aa->offset, ((const void *) src) ); } + + if (do_map) + _ae_unmap_vbos(ctx); } void _ae_invalidate_state( GLcontext *ctx, GLuint new_state ) { - AE_CONTEXT(ctx)->NewState |= new_state; + AEcontext *actx = AE_CONTEXT(ctx); + + assert(!actx->mapped_vbos); + actx->NewState |= new_state; } diff --git a/src/mesa/main/api_arrayelt.h b/src/mesa/main/api_arrayelt.h index 1c0af9f3ea8..e621724fb29 100644 --- a/src/mesa/main/api_arrayelt.h +++ b/src/mesa/main/api_arrayelt.h @@ -34,4 +34,9 @@ extern void _ae_destroy_context( GLcontext *ctx ); extern void _ae_invalidate_state( GLcontext *ctx, GLuint new_state ); extern void GLAPIENTRY _ae_loopback_array_elt( GLint elt ); +/* May optionally be called before a batch of element calls: + */ +extern void _ae_map_vbos( GLcontext *ctx ); +extern void _ae_unmap_vbos( GLcontext *ctx ); + #endif diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index e22edc1bbcf..9993a0021bc 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -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. * @@ -1009,9 +1009,6 @@ _mesa_PopAttrib(void) (GLfloat) light->Model.TwoSide); _mesa_LightModelf(GL_LIGHT_MODEL_COLOR_CONTROL, (GLfloat) light->Model.ColorControl); - /* materials */ - MEMCPY(&ctx->Light.Material, &light->Material, - sizeof(struct gl_material)); /* shade model */ _mesa_ShadeModel(light->ShadeModel); /* color material */ @@ -1019,6 +1016,9 @@ _mesa_PopAttrib(void) light->ColorMaterialMode); _mesa_set_enable(ctx, GL_COLOR_MATERIAL, light->ColorMaterialEnabled); + /* materials */ + MEMCPY(&ctx->Light.Material, &light->Material, + sizeof(struct gl_material)); } break; case GL_LINE_BIT: diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h index 5a0481328ff..13c6281f077 100644 --- a/src/mesa/main/config.h +++ b/src/mesa/main/config.h @@ -198,6 +198,7 @@ #define MAX_PROGRAM_LOCAL_PARAMS 128 /* KW: power of two */ #define MAX_PROGRAM_MATRICES 8 #define MAX_PROGRAM_MATRIX_STACK_DEPTH 4 +#define MAX_PROGRAM_CALL_DEPTH 8 /*@}*/ /** For GL_ARB_fragment_shader */ diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index c8acc6b55ca..44ee0465690 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -876,6 +876,16 @@ delete_arrayobj_cb(GLuint id, void *data, void *userData) _mesa_delete_array_object(ctx, arrayObj); } +/** + * Callback for deleting an shader object. Called by _mesa_HashDeleteAll(). + */ +static void +delete_shaderobj_cb(GLuint id, void *data, void *userData) +{ + /* XXX probably need to fix this */ + _mesa_free(data); +} + /** * Deallocate a shared state object and all children structures. @@ -938,6 +948,7 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss ) _mesa_DeleteHashTable(ss->ArrayObjects); #if FEATURE_ARB_shader_objects + _mesa_HashDeleteAll(ss->GL2Objects, delete_shaderobj_cb, ctx); _mesa_DeleteHashTable(ss->GL2Objects); #endif diff --git a/src/mesa/main/enums.c b/src/mesa/main/enums.c index d864cd22aa4..fc56809e978 100644 --- a/src/mesa/main/enums.c +++ b/src/mesa/main/enums.c @@ -34,7 +34,7 @@ typedef struct { int n; } enum_elt; -static const char enum_string_table[] = +LONGSTRING static const char enum_string_table[] = "GL_2D\0" "GL_2_BYTES\0" "GL_3D\0" diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c index 695aab5227f..6ff4089f0ea 100644 --- a/src/mesa/main/image.c +++ b/src/mesa/main/image.c @@ -1168,7 +1168,7 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4], const GLint comps = _mesa_components_in_format(dstFormat); GLuint i; - if (dstType != GL_FLOAT) { + if (dstType != GL_FLOAT || ctx->Color.ClampReadColor == GL_TRUE) { /* need to clamp to [0, 1] */ transferOps |= IMAGE_CLAMP_BIT; } @@ -1182,7 +1182,7 @@ _mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4], if (dstFormat == GL_LUMINANCE || dstFormat == GL_LUMINANCE_ALPHA) { /* compute luminance values */ - if (ctx->Color.ClampReadColor == GL_TRUE || dstType != GL_FLOAT) { + if (dstType != GL_FLOAT || ctx->Color.ClampReadColor == GL_TRUE) { for (i = 0; i < n; i++) { GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP]; luminance[i] = CLAMP(sum, 0.0F, 1.0F); @@ -4173,7 +4173,7 @@ _mesa_unpack_image( GLuint dimensions, if (width <= 0 || height <= 0 || depth <= 0) return NULL; /* generate error later */ - if (format == GL_BITMAP) { + if (type == GL_BITMAP) { bytesPerRow = (width + 7) >> 3; flipBytes = !unpack->LsbFirst; swap2 = swap4 = GL_FALSE; diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h index 9fb02a7e9cd..dad2767e72d 100644 --- a/src/mesa/main/imports.h +++ b/src/mesa/main/imports.h @@ -55,6 +55,15 @@ extern "C" { #define NULL 0 #endif + +/** gcc -pedantic warns about long string literals, LONGSTRING silences that */ +#if !defined(__GNUC__) || (__GNUC__ < 2) || \ + ((__GNUC__ == 2) && (__GNUC_MINOR__ <= 7)) +# define LONGSTRING +#else +# define LONGSTRING __extension__ +#endif + /*@}*/ diff --git a/src/mesa/main/texcompress_fxt1.c b/src/mesa/main/texcompress_fxt1.c index 2ac2c80a082..d3011cedce4 100644 --- a/src/mesa/main/texcompress_fxt1.c +++ b/src/mesa/main/texcompress_fxt1.c @@ -105,7 +105,7 @@ texstore_rgb_fxt1(TEXSTORE_PARAMS) } dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0, - GL_COMPRESSED_RGB_FXT1_3DFX, + dstFormat->MesaFormat, texWidth, (GLubyte *) dstAddr); fxt1_encode(srcWidth, srcHeight, 3, pixels, srcRowStride, @@ -162,7 +162,7 @@ texstore_rgba_fxt1(TEXSTORE_PARAMS) } dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0, - GL_COMPRESSED_RGBA_FXT1_3DFX, + dstFormat->MesaFormat, texWidth, (GLubyte *) dstAddr); fxt1_encode(srcWidth, srcHeight, 4, pixels, srcRowStride, diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index c99ff5cdc46..5329719cbbb 100644 --- a/src/mesa/main/texenvprogram.c +++ b/src/mesa/main/texenvprogram.c @@ -575,7 +575,7 @@ static struct ureg register_const4f( struct texenv_fragment_program *p, values[1] = s1; values[2] = s2; values[3] = s3; - idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values ); + idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4 ); return make_ureg(PROGRAM_STATE_VAR, idx); } diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c index 43e3bc183d4..5a61f30193b 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++; @@ -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/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/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/program.c b/src/mesa/shader/program.c index eabfbc24d7c..789d36eba02 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -430,14 +430,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 +457,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 +480,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 +516,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 +546,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 +584,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 +993,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 +1072,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 +1346,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; } diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h index 50958394c20..af06c03598f 100644 --- a/src/mesa/shader/program.h +++ b/src/mesa/shader/program.h @@ -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); 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 a2416c28726..da4d5c84721 100644 --- a/src/mesa/shader/shaderobjects.c +++ b/src/mesa/shader/shaderobjects.c @@ -307,14 +307,14 @@ _mesa_UseProgramObjectARB(GLhandleARB programObj) FLUSH_VERTICES(ctx, _NEW_PROGRAM); if (programObj != 0) { - GET_PROGRAM(pro, programObj, "glUseProgramObjectARB"); + GET_PROGRAM(pro, programObj, "glUseProgramObjectARB(program)"); if (pro == NULL) return; if ((**pro).GetLinkStatus(pro) == GL_FALSE) { RELEASE_PROGRAM(pro); - _mesa_error(ctx, GL_INVALID_OPERATION, "glUseProgramObjectARB"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glUseProgramObjectARB(not linked)"); return; } @@ -1013,7 +1013,7 @@ _mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params) switch (pname) { case GL_DELETE_STATUS: - *params = (**pro)._container._generic.GetDeleteStatus((struct gl2_generic_inf **) pro); + *params = (**pro)._container._generic.GetDeleteStatus((struct gl2_generic_intf **) pro); break; case GL_LINK_STATUS: *params = (**pro).GetLinkStatus(pro); @@ -1022,10 +1022,10 @@ _mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params) *params = (**pro).GetValidateStatus(pro); break; case GL_INFO_LOG_LENGTH: - *params = (**pro)._container._generic.GetInfoLogLength( (struct gl2_unknown_inf **) pro ); + *params = (**pro)._container._generic.GetInfoLogLength( (struct gl2_generic_intf **) pro ); break; case GL_ATTACHED_SHADERS: - *params = (**pro)._container.GetAttachedCount( (struct gl2_unknown_inf **) pro ); + *params = (**pro)._container.GetAttachedCount( (struct gl2_container_intf **) pro ); break; case GL_ACTIVE_ATTRIBUTES: *params = (**pro).GetActiveAttribCount(pro); @@ -1066,13 +1066,13 @@ _mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params) *params = (**sh).GetSubType(sh); break; case GL_DELETE_STATUS: - *params = (**sh)._generic.GetDeleteStatus((struct gl2_generic_inf **) sh); + *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_inf **)sh); + *params = (**sh)._generic.GetInfoLogLength((struct gl2_generic_intf **)sh); break; case GL_SHADER_SOURCE_LENGTH: { diff --git a/src/mesa/shader/slang/slang_assemble.c b/src/mesa/shader/slang/slang_assemble.c index 603fd4f7f87..0cba5d5d007 100644 --- a/src/mesa/shader/slang/slang_assemble.c +++ b/src/mesa/shader/slang/slang_assemble.c @@ -232,9 +232,9 @@ collect_locals(slang_assemble_ctx * A, slang_operation * op, GLuint * size) /* _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_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; @@ -289,24 +289,18 @@ _slang_assemble_function(slang_assemble_ctx * A, slang_function * fun) 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++; + /* 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 { - GLuint i; - /* 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); 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_typeinfo.c b/src/mesa/shader/slang/slang_assemble_typeinfo.c index 58f4e24f256..f4ee573df73 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 number of elements in 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..5d951226a1e 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; /**< type: spec_struct */ + struct slang_type_specifier_ *_array; /**< 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..77a293ea45e 100644 --- a/src/mesa/shader/slang/slang_compile.c +++ b/src/mesa/shader/slang/slang_compile.c @@ -35,21 +35,23 @@ #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) +static GLuint +slang_var_pool_alloc(slang_var_pool * pool, unsigned int size) { - GLuint addr; + GLuint addr; - addr = pool->next_addr; - pool->next_addr += size; - return addr; + addr = pool->next_addr; + pool->next_addr += size; + return addr; } /* @@ -57,20 +59,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 +81,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 +395,139 @@ 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; + + 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; } -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 +537,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 +594,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 +781,486 @@ 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 +1272,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 +1384,256 @@ 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; + + 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; } -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 +1647,95 @@ 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 */ + 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; #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 +1746,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 +1919,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 +1931,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 +1970,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 +1980,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 +2062,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..8835544bf38 100644 --- a/src/mesa/shader/slang/slang_compile_function.h +++ b/src/mesa/shader/slang/slang_compile_function.h @@ -31,53 +31,77 @@ 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; + slang_variable_scope *parameters; + unsigned int param_count; + slang_operation *body; /**< The instruction tree */ + unsigned int address; + slang_fixup_table fixups; } 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 *); -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 int +slang_function_scope_find_by_name(slang_function_scope *, slang_atom, 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 } diff --git a/src/mesa/shader/slang/slang_compile_operation.h b/src/mesa/shader/slang/slang_compile_operation.h index d9bce36b9bd..f5fee1e50e6 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. * @@ -29,85 +29,97 @@ extern "C" { #endif +/** + * Types of slang operations. + * These are the basic intermediate code representations. + * [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_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, - 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_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, - slang_oper_logicalor, - slang_oper_logicalxor, - slang_oper_logicaland, + 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, - slang_oper_notequal, - slang_oper_less, - slang_oper_greater, - slang_oper_lessequal, - slang_oper_greaterequal, + 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, - slang_oper_subtract, - slang_oper_multiply, - slang_oper_divide, + 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, - slang_oper_predecrement, - slang_oper_plus, - slang_oper_minus, + slang_oper_preincrement, /* "++" [var] */ + slang_oper_predecrement, /* "--" [var] */ + slang_oper_plus, /* "-" [expr] */ + slang_oper_minus, /* "+" [expr] */ /*slang_oper_complement,*/ - slang_oper_not, - slang_oper_subscript, - slang_oper_call, - slang_oper_field, - slang_oper_postincrement, - slang_oper_postdecrement + 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 conditiona, a function call, etc). + */ 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; + float 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 int slang_operation_construct (slang_operation *); +extern void slang_operation_destruct (slang_operation *); +extern int slang_operation_copy (slang_operation *, const slang_operation *); + #ifdef __cplusplus } diff --git a/src/mesa/shader/slang/slang_compile_variable.c b/src/mesa/shader/slang/slang_compile_variable.c index b62743addb0..679d93b951a 100644 --- a/src/mesa/shader/slang/slang_compile_variable.c +++ b/src/mesa/shader/slang/slang_compile_variable.c @@ -183,7 +183,7 @@ int slang_variable_construct (slang_variable *var) var->initializer = NULL; var->address = ~0; var->size = 0; - var->global = 0; + var->global = GL_FALSE; return 1; } diff --git a/src/mesa/shader/slang/slang_compile_variable.h b/src/mesa/shader/slang/slang_compile_variable.h index 6b9679a3b75..3b6e1987c82 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. * @@ -29,67 +29,95 @@ 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 *); + typedef struct slang_variable_scope_ { - struct slang_variable_ *variables; + struct slang_variable_ *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 *); + +extern void +slang_variable_scope_destruct(slang_variable_scope *); + +extern int +slang_variable_scope_copy(slang_variable_scope *, + const slang_variable_scope *); -void slang_variable_scope_destruct (slang_variable_scope *); -int slang_variable_scope_copy (slang_variable_scope *, const 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_fully_specified_type type; + slang_atom a_name; + GLuint array_len; /* type: spec_array */ + struct slang_operation_ *initializer; + unsigned int address; + unsigned int size; + GLboolean global; } slang_variable; -int slang_variable_construct (slang_variable *); -void slang_variable_destruct (slang_variable *); -int slang_variable_copy (slang_variable *, const slang_variable *); -slang_variable *_slang_locate_variable (slang_variable_scope *, slang_atom a_name, GLboolean all); +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(slang_variable_scope *, slang_atom a_name, + GLboolean all); + +extern GLboolean +_slang_build_export_data_table(slang_export_data_table *, + slang_variable_scope *); -GLboolean _slang_build_export_data_table (slang_export_data_table *, slang_variable_scope *); #ifdef __cplusplus } #endif #endif - 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_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/swrast/s_nvfragprog.c b/src/mesa/swrast/s_nvfragprog.c index 7a6785b1d29..028ddc0090d 100644 --- a/src/mesa/swrast/s_nvfragprog.c +++ b/src/mesa/swrast/s_nvfragprog.c @@ -57,6 +57,9 @@ struct fp_machine GLfloat Inputs[MAX_NV_FRAGMENT_PROGRAM_INPUTS][4]; GLfloat Outputs[MAX_NV_FRAGMENT_PROGRAM_OUTPUTS][4]; GLuint CondCodes[4]; /**< COND_* value for x/y/z/w */ + + GLuint CallStack[MAX_PROGRAM_CALL_DEPTH]; /**< For CAL/RET instructions */ + GLuint StackDepth; /**< Index/ptr to top of CallStack[] */ }; @@ -697,6 +700,37 @@ execute_program( GLcontext *ctx, } } break; + case OPCODE_BRA: /* conditional branch */ + { + /* NOTE: The return is conditional! */ + const GLuint swizzle = inst->DstReg.CondSwizzle; + const GLuint condMask = inst->DstReg.CondMask; + if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { + /* take branch */ + pc = inst->BranchTarget; + } + } + break; + case OPCODE_CAL: /* Call subroutine */ + { + /* NOTE: The call is conditional! */ + const GLuint swizzle = inst->DstReg.CondSwizzle; + const GLuint condMask = inst->DstReg.CondMask; + if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { + if (machine->StackDepth >= MAX_PROGRAM_CALL_DEPTH) { + return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ + } + machine->CallStack[machine->StackDepth++] = pc + 1; + pc = inst->BranchTarget; + } + } + break; case OPCODE_CMP: { GLfloat a[4], b[4], c[4], result[4]; @@ -1093,6 +1127,22 @@ execute_program( GLcontext *ctx, store_vector4( inst, machine, result ); } break; + case OPCODE_RET: /* return from subroutine */ + { + /* NOTE: The return is conditional! */ + const GLuint swizzle = inst->DstReg.CondSwizzle; + const GLuint condMask = inst->DstReg.CondMask; + if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { + if (machine->StackDepth == 0) { + return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ + } + pc = machine->CallStack[--machine->StackDepth]; + } + } + break; case OPCODE_RFL: /* reflection vector */ { GLfloat axis[4], dir[4], result[4], tmpX, tmpW; @@ -1539,6 +1589,9 @@ init_machine( GLcontext *ctx, struct fp_machine *machine, machine->CondCodes[1] = COND_EQ; machine->CondCodes[2] = COND_EQ; machine->CondCodes[3] = COND_EQ; + + /* init call stack */ + machine->StackDepth = 0; } diff --git a/src/mesa/tnl/t_save_api.c b/src/mesa/tnl/t_save_api.c index 11d21301d94..dbbd095fe47 100644 --- a/src/mesa/tnl/t_save_api.c +++ b/src/mesa/tnl/t_save_api.c @@ -1413,10 +1413,14 @@ static void GLAPIENTRY _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei co if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) return; + _ae_map_vbos( ctx ); + _save_NotifyBegin( ctx, mode | PRIM_WEAK ); for (i = 0; i < count; i++) CALL_ArrayElement(GET_DISPATCH(), (start + i)); CALL_End(GET_DISPATCH(), ()); + + _ae_unmap_vbos( ctx ); } @@ -1429,6 +1433,8 @@ static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) return; + _ae_map_vbos( ctx ); + _save_NotifyBegin( ctx, mode | PRIM_WEAK ); switch (type) { @@ -1450,6 +1456,8 @@ static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum } CALL_End(GET_DISPATCH(), ()); + + _ae_unmap_vbos( ctx ); } static void GLAPIENTRY _save_OBE_DrawRangeElements(GLenum mode, diff --git a/src/mesa/tnl/t_vp_build.c b/src/mesa/tnl/t_vp_build.c index 894a13b7046..805d05ae728 100644 --- a/src/mesa/tnl/t_vp_build.c +++ b/src/mesa/tnl/t_vp_build.c @@ -33,7 +33,7 @@ #include "glheader.h" #include "macros.h" #include "enums.h" -#include "t_context.h" +#include "t_context.h" /* NOTE: very light dependency on this */ #include "t_vp_build.h" #include "shader/program.h" @@ -386,7 +386,7 @@ static struct ureg register_const4f( struct tnl_program *p, values[1] = s1; values[2] = s2; values[3] = s3; - idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values ); + idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4 ); return make_ureg(PROGRAM_STATE_VAR, idx); } |