summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configs/linux-static5
-rw-r--r--debian/changelog7
-rw-r--r--debian/patches/02_use-ieee-fp-on-s390-and-m68k.patch2
-rw-r--r--docs/mangling.html4
-rw-r--r--docs/relnotes-6.5.2.html3
-rw-r--r--include/GL/gl.h31
-rw-r--r--include/GL/gl_mangle.h18
-rw-r--r--src/glu/sgi/libutil/mipmap.c44
-rw-r--r--src/mesa/drivers/dri/i965/brw_save_api.c10
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_tnl.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_fp.c2
-rw-r--r--src/mesa/drivers/dri/r200/r200_context.c23
-rw-r--r--src/mesa/drivers/dri/r200/r200_context.h1
-rw-r--r--src/mesa/drivers/dri/r200/r200_lock.c14
-rw-r--r--src/mesa/drivers/dri/r200/r200_state.c35
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.h26
-rw-r--r--src/mesa/drivers/dri/r300/r300_fragprog.c7
-rw-r--r--src/mesa/drivers/dri/r300/r300_maos.c4
-rw-r--r--src/mesa/drivers/dri/r300/r300_shader.c17
-rw-r--r--src/mesa/drivers/dri/r300/r300_state.c80
-rw-r--r--src/mesa/drivers/dri/r300/r300_vertexprog.c482
-rw-r--r--src/mesa/drivers/dri/savage/savagespan.c2
-rw-r--r--src/mesa/glapi/glprocs.h50
-rw-r--r--src/mesa/main/api_arrayelt.c94
-rw-r--r--src/mesa/main/api_arrayelt.h5
-rw-r--r--src/mesa/main/attrib.c8
-rw-r--r--src/mesa/main/config.h1
-rw-r--r--src/mesa/main/context.c11
-rw-r--r--src/mesa/main/enums.c2
-rw-r--r--src/mesa/main/image.c6
-rw-r--r--src/mesa/main/imports.h9
-rw-r--r--src/mesa/main/texcompress_fxt1.c4
-rw-r--r--src/mesa/main/texenvprogram.c2
-rw-r--r--src/mesa/shader/arbprogparse.c17
-rw-r--r--src/mesa/shader/descrip.mms7
-rw-r--r--src/mesa/shader/nvfragparse.c8
-rw-r--r--src/mesa/shader/program.c111
-rw-r--r--src/mesa/shader/program.h19
-rw-r--r--src/mesa/shader/program_instruction.h7
-rw-r--r--src/mesa/shader/programopt.c2
-rw-r--r--src/mesa/shader/shaderobjects.c14
-rw-r--r--src/mesa/shader/slang/slang_assemble.c24
-rw-r--r--src/mesa/shader/slang/slang_assemble.h288
-rw-r--r--src/mesa/shader/slang/slang_assemble_typeinfo.c1036
-rw-r--r--src/mesa/shader/slang/slang_assemble_typeinfo.h138
-rw-r--r--src/mesa/shader/slang/slang_compile.c3170
-rw-r--r--src/mesa/shader/slang/slang_compile_function.c252
-rw-r--r--src/mesa/shader/slang/slang_compile_function.h72
-rw-r--r--src/mesa/shader/slang/slang_compile_operation.h120
-rw-r--r--src/mesa/shader/slang/slang_compile_variable.c2
-rw-r--r--src/mesa/shader/slang/slang_compile_variable.h98
-rw-r--r--src/mesa/shader/slang/slang_execute.c1032
-rw-r--r--src/mesa/shader/slang/slang_execute.h66
-rw-r--r--src/mesa/shader/slang/slang_preprocess.c8
-rw-r--r--src/mesa/shader/slang/slang_utility.c125
-rw-r--r--src/mesa/swrast/s_nvfragprog.c53
-rw-r--r--src/mesa/tnl/t_save_api.c8
-rw-r--r--src/mesa/tnl/t_vp_build.c4
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, &param->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, &param->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, &param->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, &param->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, &param->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, &param->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, &param->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, &param->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);
}