More GLSL code:
authorMichal Krol <mjkrol@gmail.org>
Tue, 4 Apr 2006 10:18:07 +0000 (10:18 +0000)
committerMichal Krol <mjkrol@gmail.org>
Tue, 4 Apr 2006 10:18:07 +0000 (10:18 +0000)
- add support for varyings;

GLSL fixes:
- pow was wrongly computed in x86 back-end;

src/mesa/shader/shaderobjects.h
src/mesa/shader/shaderobjects_3dlabs.c
src/mesa/shader/slang/slang_analyse.c
src/mesa/shader/slang/slang_execute_x86.c
src/mesa/shader/slang/slang_export.c
src/mesa/shader/slang/slang_export.h
src/mesa/shader/slang/slang_link.c
src/mesa/shader/slang/slang_link.h

index 060328163bc3d2ce32c3dc1ba3f1276dddc0b806..19c4e8d3f8a49ef4537c86b42b311a389a67e64d 100644 (file)
@@ -2,7 +2,7 @@
  * Mesa 3-D graphics library
  * Version:  6.5
  *
- * Copyright (C) 2004-2005  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2004-2006  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -85,14 +85,15 @@ struct gl2_program_intf
    GLboolean (* GetLinkStatus) (struct gl2_program_intf **);
    GLboolean (* GetValidateStatus) (struct gl2_program_intf **);
    GLvoid (* Link) (struct gl2_program_intf **);
-   GLvoid (* Validate) (struct gl2_program_intf **);\r
-   GLvoid (* UpdateFixedUniforms) (struct gl2_program_intf **);\r
-   GLvoid (* UpdateFixedAttribute) (struct gl2_program_intf **, GLuint, GLvoid *, GLuint, GLuint,\r
-      GLboolean);\r
-   GLvoid (* UpdateFixedVarying) (struct gl2_program_intf **, GLuint, GLvoid *, GLuint, GLuint,\r
-      GLboolean);\r
-   GLvoid (* GetTextureImageUsage) (struct gl2_program_intf **, GLbitfield *);\r
+   GLvoid (* Validate) (struct gl2_program_intf **);
+   GLvoid (* UpdateFixedUniforms) (struct gl2_program_intf **);
+   GLvoid (* UpdateFixedAttribute) (struct gl2_program_intf **, GLuint, GLvoid *, GLuint, GLuint,
+      GLboolean);
+   GLvoid (* UpdateFixedVarying) (struct gl2_program_intf **, GLuint, GLvoid *, GLuint, GLuint,
+      GLboolean);
+   GLvoid (* GetTextureImageUsage) (struct gl2_program_intf **, GLbitfield *);
    GLboolean (* IsShaderPresent) (struct gl2_program_intf **, GLenum);
+   GLvoid (* UpdateVarying) (struct gl2_program_intf **, GLuint, GLfloat *, GLboolean);
 };
 
 struct gl2_fragment_shader_intf
index 0b0ae414fdefd0c37a9a3762d613dd29f69a24c1..fa38a1c9af33a1269a257a40bccf9d77e161ed10 100755 (executable)
@@ -1150,9 +1150,7 @@ _program_GetTextureImageUsage (struct gl2_program_intf **intf, GLbitfield *texim
        {\r
                GLuint n, addr, j;\r
 \r
-               n = pro->texture_usage.table[i].quant->array_len;\r
-               if (n == 0)\r
-                       n = 1;\r
+               n = slang_export_data_quant_elements (pro->texture_usage.table[i].quant);\r
                addr = pro->texture_usage.table[i].frag_address;\r
                for (j = 0; j < n; j++)\r
                {\r
@@ -1163,7 +1161,7 @@ _program_GetTextureImageUsage (struct gl2_program_intf **intf, GLbitfield *texim
                        image = (GLuint) *((GLfloat *) mem);\r
                        if (image >= 0 && image < ctx->Const.MaxTextureImageUnits)\r
                        {\r
-                               switch (pro->texture_usage.table[i].quant->u.basic_type)\r
+                               switch (slang_export_data_quant_type (pro->texture_usage.table[i].quant))\r
                                {\r
                                case GL_SAMPLER_1D_ARB:\r
                                case GL_SAMPLER_1D_SHADOW_ARB:\r
@@ -1204,6 +1202,29 @@ _program_IsShaderPresent (struct gl2_program_intf **intf, GLenum subtype)
        }\r
 }\r
 \r
+static GLvoid\r
+_program_UpdateVarying (struct gl2_program_intf **intf, GLuint index, GLfloat *value,\r
+       GLboolean vert)\r
+{\r
+       struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;\r
+       slang_program *pro = &impl->_obj.prog;\r
+       GLuint addr;\r
+\r
+       if (index >= pro->varyings.total)\r
+               return;\r
+       if (vert)\r
+               addr = pro->varyings.slots[index].vert_addr / 4;\r
+       else\r
+               addr = pro->varyings.slots[index].frag_addr / 4;\r
+       if (addr != ~0)\r
+       {\r
+               if (vert)\r
+                       *value = pro->machines[SLANG_SHADER_VERTEX]->mem[addr]._float;\r
+               else\r
+                       pro->machines[SLANG_SHADER_FRAGMENT]->mem[addr]._float = *value;\r
+       }\r
+}\r
+\r
 static struct gl2_program_intf _program_vftbl = {\r
        {\r
                {\r
@@ -1231,7 +1252,8 @@ static struct gl2_program_intf _program_vftbl = {
        _program_UpdateFixedAttribute,\r
        _program_UpdateFixedVarying,\r
        _program_GetTextureImageUsage,\r
-       _program_IsShaderPresent\r
+       _program_IsShaderPresent,\r
+       _program_UpdateVarying\r
 };\r
 \r
 static void\r
@@ -1514,10 +1536,10 @@ GLboolean _slang_write_uniform (struct gl2_program_intf **pro, GLint loc, GLsize
 \r
        b = &bind->table[loc];\r
        /* TODO: check sizes */\r
-       if (b->quant->structure != NULL)\r
+       if (slang_export_data_quant_struct (b->quant))\r
                return GL_FALSE;\r
 \r
-       switch (b->quant->u.basic_type)\r
+       switch (slang_export_data_quant_type (b->quant))\r
        {\r
        case GL_BOOL_ARB:\r
                types_match = (type == GL_FLOAT) || (type == GL_INT);\r
@@ -1556,7 +1578,7 @@ GLboolean _slang_write_uniform (struct gl2_program_intf **pro, GLint loc, GLsize
                types_match = (type == GL_INT);\r
                break;\r
        default:\r
-               types_match = (type == b->quant->u.basic_type);\r
+               types_match = (type == slang_export_data_quant_type (b->quant));\r
                break;\r
        }\r
 \r
@@ -1581,8 +1603,9 @@ GLboolean _slang_write_uniform (struct gl2_program_intf **pro, GLint loc, GLsize
                                const GLfloat *src = (GLfloat *) (data);\r
                                GLfloat *dst = (GLfloat *) (&impl->_obj.prog.machines[i]->mem[b->address[i] / 4]);\r
                                GLuint j;\r
+                               GLuint total = count * slang_export_data_quant_components (b->quant);\r
 \r
-                               for (j = 0; j < count * b->quant->size / 4; j++)\r
+                               for (j = 0; j < total; j++)\r
                                        dst[j] = src[j] != 0.0f ? 1.0f : 0.0f;\r
                        }\r
        }\r
@@ -1594,8 +1617,9 @@ GLboolean _slang_write_uniform (struct gl2_program_intf **pro, GLint loc, GLsize
                                const GLuint *src = (GLuint *) (data);\r
                                GLfloat *dst = (GLfloat *) (&impl->_obj.prog.machines[i]->mem[b->address[i] / 4]);\r
                                GLuint j;\r
+                               GLuint total = count * slang_export_data_quant_components (b->quant);\r
 \r
-                               for (j = 0; j < count * b->quant->size / 4; j++)\r
+                               for (j = 0; j < total; j++)\r
                                        dst[j] = src[j] ? 1.0f : 0.0f;\r
                        }\r
        }\r
@@ -1607,8 +1631,9 @@ GLboolean _slang_write_uniform (struct gl2_program_intf **pro, GLint loc, GLsize
                                const GLuint *src = (GLuint *) (data);\r
                                GLfloat *dst = (GLfloat *) (&impl->_obj.prog.machines[i]->mem[b->address[i] / 4]);\r
                                GLuint j;\r
+                               GLuint total = count * slang_export_data_quant_components (b->quant);\r
 \r
-                               for (j = 0; j < count * b->quant->size / 4; j++)\r
+                               for (j = 0; j < total; j++)\r
                                        dst[j] = (GLfloat) src[j];\r
                        }\r
        }\r
@@ -1618,7 +1643,7 @@ GLboolean _slang_write_uniform (struct gl2_program_intf **pro, GLint loc, GLsize
                        if (b->address[i] != ~0)\r
                        {\r
                                _mesa_memcpy (&impl->_obj.prog.machines[i]->mem[b->address[i] / 4], data,\r
-                                       count * b->quant->size);\r
+                                       count * slang_export_data_quant_size (b->quant));\r
                        }\r
        }\r
        return GL_TRUE;\r
@@ -1664,11 +1689,8 @@ GLvoid _slang_get_active_uniform (struct gl2_program_intf **pro, GLuint index, G
        name[len] = '\0';\r
        if (length != NULL)\r
                *length = len;\r
-       *type = u->quant->u.basic_type;\r
-       if (u->quant->array_len == 0)\r
-               *size = 1;\r
-       else\r
-               *size = u->quant->array_len;\r
+       *type = slang_export_data_quant_type (u->quant);\r
+       *size = slang_export_data_quant_elements (u->quant);\r
 }\r
 \r
 void\r
index 164dbec3503131c7412e6d19b31c648c74fc5d10..76320848b5578e14730971982f023e8166079524 100644 (file)
@@ -49,9 +49,9 @@ GLboolean _slang_analyse_texture_usage (slang_program *prog)
        {\r
                slang_uniform_binding *b = &prog->uniforms.table[i];\r
 \r
-               if (b->address[SLANG_SHADER_FRAGMENT] != ~0 && b->quant->structure == NULL)\r
+               if (b->address[SLANG_SHADER_FRAGMENT] != ~0 && !slang_export_data_quant_struct (b->quant))\r
                {\r
-                       switch (b->quant->u.basic_type)\r
+                       switch (slang_export_data_quant_type (b->quant))\r
                        {\r
                        case GL_SAMPLER_1D_ARB:\r
                        case GL_SAMPLER_2D_ARB:\r
@@ -77,9 +77,9 @@ GLboolean _slang_analyse_texture_usage (slang_program *prog)
        {\r
                slang_uniform_binding *b = &prog->uniforms.table[i];\r
 \r
-               if (b->address[SLANG_SHADER_FRAGMENT] != ~0 && b->quant->structure == NULL)\r
+               if (b->address[SLANG_SHADER_FRAGMENT] != ~0 && !slang_export_data_quant_struct (b->quant))\r
                {\r
-                       switch (b->quant->u.basic_type)\r
+                       switch (slang_export_data_quant_type (b->quant))\r
                        {\r
                        case GL_SAMPLER_1D_ARB:\r
                        case GL_SAMPLER_2D_ARB:\r
index eabe368596398acb59b2d3bd1b24413cee5f2ed9..b578838e826aa242513bb19616bad09e20547747 100644 (file)
@@ -81,6 +81,12 @@ static GLvoid add_fixup (codegen_ctx *G, GLuint index, GLubyte *csr)
 #define RND_NEG_FPU (FAST_X86_FPU | 0x400)\r
 #endif\r
 \r
+#if 0\r
+\r
+/*\r
+ * XXX\r
+ * These should produce a valid code that computes powers. Unfortunately, it does not.\r
+ */\r
 static void set_fpu_round_neg_inf (codegen_ctx *G)\r
 {\r
        if (G->fpucntl != RND_NEG_FPU)\r
@@ -107,6 +113,16 @@ static void emit_x87_ex2 (codegen_ctx *G)
        x87_fscale (&G->f);                     /* 2^a */\r
 }\r
 \r
+static void emit_pow (codegen_ctx *G)\r
+{\r
+       x87_fld (&G->f, x86_deref (G->r_esp));\r
+       x87_fld (&G->f, x86_make_disp (G->r_esp, 4));\r
+       x87_fyl2x (&G->f);\r
+       emit_x87_ex2 (G);\r
+}\r
+\r
+#endif\r
+\r
 static GLfloat do_ceilf (GLfloat x)\r
 {\r
        return CEILF (x);\r
@@ -117,6 +133,11 @@ static GLfloat do_floorf (GLfloat x)
        return FLOORF (x);\r
 }\r
 \r
+static GLfloat do_powf (GLfloat y, GLfloat x)\r
+{\r
+       return (GLfloat) _mesa_pow ((GLdouble) x, (GLdouble) y);\r
+}\r
+\r
 static GLvoid do_print_float (GLfloat x)\r
 {\r
        _mesa_printf ("slang print: %f\n", x);\r
@@ -285,10 +306,8 @@ static GLvoid codegen_assem (codegen_ctx *G, slang_assembly *a)
                x87_fstp (&G->f, x86_deref (G->r_esp));\r
                break;\r
        case slang_asm_float_power:\r
-               x87_fld (&G->f, x86_deref (G->r_esp));\r
-               x87_fld (&G->f, x86_make_disp (G->r_esp, 4));\r
-               x87_fyl2x (&G->f);\r
-               emit_x87_ex2 (G);\r
+               /* TODO: use emit_pow() */\r
+               x86_call (&G->f, (GLubyte *) do_powf);\r
                x86_lea (&G->f, G->r_esp, x86_make_disp (G->r_esp, 4));\r
                x87_fstp (&G->f, x86_deref (G->r_esp));\r
                break;\r
index 43ce35de49733759f14a6778d3b4668f9b956e60..515c03fb6412053e0ebda5ad35bf064185c25c53 100644 (file)
@@ -69,6 +69,45 @@ slang_export_data_quant *slang_export_data_quant_add_field (slang_export_data_qu
        return &self->structure[n];\r
 }\r
 \r
+GLboolean slang_export_data_quant_array (slang_export_data_quant *self)\r
+{\r
+       return self->array_len != 0;\r
+}\r
+\r
+GLboolean slang_export_data_quant_struct (slang_export_data_quant *self)\r
+{\r
+       return self->structure != NULL;\r
+}\r
+\r
+GLenum slang_export_data_quant_type (slang_export_data_quant *self)\r
+{\r
+       assert (self->structure == NULL);\r
+       return self->u.basic_type;\r
+}\r
+\r
+GLuint slang_export_data_quant_fields (slang_export_data_quant *self)\r
+{\r
+       assert (self->structure != NULL);\r
+       return self->u.field_count;\r
+}\r
+\r
+GLuint slang_export_data_quant_elements (slang_export_data_quant *self)\r
+{\r
+       if (self->array_len == 0)\r
+               return 1;\r
+       return self->array_len;\r
+}\r
+\r
+GLuint slang_export_data_quant_components (slang_export_data_quant *self)\r
+{\r
+       return self->size / 4;\r
+}\r
+\r
+GLuint slang_export_data_quant_size (slang_export_data_quant *self)\r
+{\r
+       return self->size;\r
+}\r
+\r
 /*\r
  * slang_export_data_entry\r
  */\r
@@ -254,19 +293,19 @@ static GLboolean validate_extracted (slang_export_data_quant *q, GLuint element,
        case EXTRACT_BASIC:\r
                return GL_TRUE;\r
        case EXTRACT_ARRAY:\r
-               return element < q->array_len;\r
+               return element < slang_export_data_quant_elements (q);\r
        case EXTRACT_STRUCT:\r
-               return q->structure != NULL;\r
+               return slang_export_data_quant_struct (q);\r
        case EXTRACT_STRUCT_ARRAY:\r
-               return q->structure != NULL && element < q->array_len;\r
+               return slang_export_data_quant_struct (q) && element < slang_export_data_quant_elements (q);\r
        }\r
        return GL_FALSE;\r
 }\r
 \r
 static GLuint calculate_offset (slang_export_data_quant *q, GLuint element)\r
 {\r
-       if (q->array_len != 0)\r
-               return element * q->size;\r
+       if (slang_export_data_quant_array (q))\r
+               return element * slang_export_data_quant_size (q);\r
        return 0;\r
 }\r
 \r
@@ -277,6 +316,7 @@ static GLboolean find_exported_data (slang_export_data_quant *q, const char *nam
        GLuint result, element, i;\r
        const char *end;\r
        slang_atom atom;\r
+       const GLuint fields = slang_export_data_quant_fields (q);\r
 \r
        result = extract_name (name, parsed, &element, &end);\r
        if (result == EXTRACT_ERROR)\r
@@ -286,7 +326,7 @@ static GLboolean find_exported_data (slang_export_data_quant *q, const char *nam
        if (atom == SLANG_ATOM_NULL)\r
                return GL_FALSE;\r
 \r
-       for (i = 0; i < q->u.field_count; i++)\r
+       for (i = 0; i < fields; i++)\r
                if (q->structure[i].name == atom)\r
                {\r
                        if (!validate_extracted (&q->structure[i], element, result))\r
index 88a74fe26b05a5e0c2ed8b689be23f49e9cd48d6..c158eb444318be7f6ec039020d57532b94d00360 100644 (file)
@@ -35,7 +35,7 @@ extern "C" {
  * Basic data quantity to transfer between application and assembly.\r
  * The <size> is the actual size of the data quantity including padding, if any. It is\r
  * used to calculate offsets from the beginning of the data.\r
- * The <array_len> is not 0, the data quantity is an array of <array_len> size.\r
+ * If the <array_len> is not 0, the data quantity is an array of <array_len> size.\r
  * If the <structure> is not NULL, the data quantity is a struct. The <basic_type> is\r
  * invalid and the <field_count> holds the size of the <structure> array.\r
  * The <basic_type> values match those of <type> parameter for glGetActiveUniformARB.\r
@@ -58,6 +58,43 @@ GLvoid slang_export_data_quant_ctr (slang_export_data_quant *);
 GLvoid slang_export_data_quant_dtr (slang_export_data_quant *);\r
 slang_export_data_quant *slang_export_data_quant_add_field (slang_export_data_quant *);\r
 \r
+/*\r
+ * Returns GL_FALSE if the quant is not an array.\r
+ */\r
+GLboolean slang_export_data_quant_array (slang_export_data_quant *);\r
+\r
+/*\r
+ * Returns GL_FALSE if the quant is not a structure.\r
+ */\r
+GLboolean slang_export_data_quant_struct (slang_export_data_quant *);\r
+\r
+/*\r
+ * Returns basic type of the quant. It must not be a structure.\r
+ */\r
+GLenum slang_export_data_quant_type (slang_export_data_quant *);\r
+\r
+/*\r
+ * Returns number of fields in the quant that is a structure.\r
+ */\r
+GLuint slang_export_data_quant_fields (slang_export_data_quant *);\r
+\r
+/*\r
+ * Return number of elements in the quant.\r
+ * For arrays, return the size of the array.\r
+ * For scalars, return 1.\r
+ */\r
+GLuint slang_export_data_quant_elements (slang_export_data_quant *);\r
+\r
+/*\r
+ * Returns total number of components withing the quant element.\r
+ */\r
+GLuint slang_export_data_quant_components (slang_export_data_quant *);\r
+\r
+/*\r
+ * Returns size of the quant element.\r
+ */\r
+GLuint slang_export_data_quant_size (slang_export_data_quant *);\r
+\r
 /*\r
  * Data access pattern. Specifies how data is accessed at what frequency.\r
  */\r
index 58d17c15580739fc5d46876c82ad90abcf8897bc..a72ec2eaa0bf9f27862edf820c7428923e9891b1 100644 (file)
@@ -79,46 +79,42 @@ static GLboolean slang_uniform_bindings_add (slang_uniform_bindings *self, slang
        return GL_TRUE;\r
 }\r
 \r
-static GLboolean insert_binding (slang_uniform_bindings *bind, slang_export_data_quant *q,\r
+static GLboolean insert_uniform_binding (slang_uniform_bindings *bind, slang_export_data_quant *q,\r
        char *name, slang_atom_pool *atoms, GLuint index, GLuint addr)\r
 {\r
        GLuint count, i;\r
 \r
        slang_string_concat (name, slang_atom_pool_id (atoms, q->name));\r
-\r
-       if (q->array_len == 0)\r
-               count = 1;\r
-       else\r
-               count = q->array_len;\r
-\r
+       count = slang_export_data_quant_elements (q);\r
        for (i = 0; i < count; i++)\r
        {\r
                GLuint save;\r
 \r
                save = slang_string_length (name);\r
-               if (q->array_len != 0)\r
+               if (slang_export_data_quant_array (q))\r
                        _mesa_sprintf (name + slang_string_length (name), "[%d]", i);\r
 \r
-               if (q->structure != NULL)\r
+               if (slang_export_data_quant_struct (q))\r
                {\r
                        GLuint save, i;\r
+                       const GLuint fields = slang_export_data_quant_fields (q);\r
 \r
                        slang_string_concat (name, ".");\r
                        save = slang_string_length (name);\r
 \r
-                       for (i = 0; i < q->u.field_count; i++)\r
+                       for (i = 0; i < fields; i++)\r
                        {\r
-                               if (!insert_binding (bind, &q->structure[i], name, atoms, index, addr))\r
+                               if (!insert_uniform_binding (bind, &q->structure[i], name, atoms, index, addr))\r
                                        return GL_FALSE;\r
                                name[save] = '\0';\r
-                               addr += q->structure[i].size;\r
+                               addr += slang_export_data_quant_size (&q->structure[i]);\r
                        }\r
                }\r
                else\r
                {\r
                        if (!slang_uniform_bindings_add (bind, q, name, index, addr))\r
                                return GL_FALSE;\r
-                       addr += q->size;\r
+                       addr += slang_export_data_quant_size (q);\r
                }\r
                name[save] = '\0';\r
        }\r
@@ -126,8 +122,8 @@ static GLboolean insert_binding (slang_uniform_bindings *bind, slang_export_data
        return GL_TRUE;\r
 }\r
 \r
-static GLboolean gather_uniform_bindings (slang_uniform_bindings *bind, slang_export_data_table *tbl,\r
-       GLuint index)\r
+static GLboolean gather_uniform_bindings (slang_uniform_bindings *bind,\r
+       slang_export_data_table *tbl, GLuint index)\r
 {\r
        GLuint i;\r
 \r
@@ -136,7 +132,7 @@ static GLboolean gather_uniform_bindings (slang_uniform_bindings *bind, slang_ex
                {\r
                        char name[1024] = "";\r
 \r
-                       if (!insert_binding (bind, &tbl->entries[i].quant, name, tbl->atoms, index,\r
+                       if (!insert_uniform_binding (bind, &tbl->entries[i].quant, name, tbl->atoms, index,\r
                                        tbl->entries[i].address))\r
                                return GL_FALSE;\r
                }\r
@@ -184,17 +180,18 @@ static GLboolean insert_uniform (slang_active_uniforms *u, slang_export_data_qua
        slang_atom_pool *atoms)\r
 {\r
        slang_string_concat (name, slang_atom_pool_id (atoms, q->name));\r
-       if (q->array_len != 0)\r
+       if (slang_export_data_quant_array (q))\r
                slang_string_concat (name, "[0]");\r
 \r
-       if (q->structure != NULL)\r
+       if (slang_export_data_quant_struct (q))\r
        {\r
                GLuint save, i;\r
+               const GLuint fields = slang_export_data_quant_fields (q);\r
 \r
                slang_string_concat (name, ".");\r
                save = slang_string_length (name);\r
 \r
-               for (i = 0; i < q->u.field_count; i++)\r
+               for (i = 0; i < fields; i++)\r
                {\r
                        if (!insert_uniform (u, &q->structure[i], name, atoms))\r
                                return GL_FALSE;\r
@@ -223,6 +220,97 @@ static GLboolean gather_active_uniforms (slang_active_uniforms *u, slang_export_
        return GL_TRUE;\r
 }\r
 \r
+/*\r
+ * slang_varying_bindings\r
+ */\r
+\r
+static GLvoid slang_varying_bindings_ctr (slang_varying_bindings *self)\r
+{\r
+       self->count = 0;\r
+       self->total = 0;\r
+}\r
+\r
+static GLvoid slang_varying_bindings_dtr (slang_varying_bindings *self)\r
+{\r
+       GLuint i;\r
+\r
+       for (i = 0; i < self->count; i++)\r
+               slang_alloc_free (self->table[i].name);\r
+}\r
+\r
+static GLvoid update_varying_slots (slang_varying_slot *slots, GLuint count, GLboolean vert,\r
+       GLuint address, GLuint do_offset)\r
+{\r
+       GLuint i;\r
+\r
+       for (i = 0; i < count; i++)\r
+               if (vert)\r
+                       slots[i].vert_addr = address + i * 4 * do_offset;\r
+               else\r
+                       slots[i].frag_addr = address + i * 4 * do_offset;\r
+}\r
+\r
+static GLboolean slang_varying_bindings_add (slang_varying_bindings *self,\r
+       slang_export_data_quant *q, const char *name, GLboolean vert, GLuint address)\r
+{\r
+       const GLuint n = self->count;\r
+       const GLuint total_components =\r
+               slang_export_data_quant_components (q) * slang_export_data_quant_elements (q);\r
+       GLuint i;\r
+\r
+       for (i = 0; i < n; i++)\r
+               if (slang_string_compare (self->table[i].name, name) == 0)\r
+               {\r
+                       /* TODO: data quantities must match, or else link fails */\r
+                       update_varying_slots (&self->slots[self->table[i].slot], total_components, vert,\r
+                               address, 1);\r
+                       return GL_TRUE;\r
+               }\r
+\r
+       if (self->total + total_components > MAX_VARYING_FLOATS)\r
+       {\r
+               /* TODO: info log: error: MAX_VARYING_FLOATS exceeded */\r
+               return GL_FALSE;\r
+       }\r
+\r
+       self->table[n].quant = q;\r
+       self->table[n].slot = self->total;\r
+       self->table[n].name = slang_string_duplicate (name);\r
+       if (self->table[n].name == NULL)\r
+               return GL_FALSE;\r
+       self->count++;\r
+\r
+       update_varying_slots (&self->slots[self->table[n].slot], total_components, vert, address, 1);\r
+       update_varying_slots (&self->slots[self->table[n].slot], total_components, !vert, ~0, 0);\r
+       self->total += total_components;\r
+\r
+       return GL_TRUE;\r
+}\r
+\r
+static GLboolean entry_has_gl_prefix (slang_atom name, slang_atom_pool *atoms)\r
+{\r
+       const char *str = slang_atom_pool_id (atoms, name);\r
+       return str[0] == 'g' && str[1] == 'l' && str[2] == '_';\r
+}\r
+\r
+static GLboolean gather_varying_bindings (slang_varying_bindings *bind,\r
+       slang_export_data_table *tbl, GLboolean vert)\r
+{\r
+       GLuint i;\r
+\r
+       for (i = 0; i < tbl->count; i++)\r
+               if (tbl->entries[i].access == slang_exp_varying &&\r
+                       !entry_has_gl_prefix (tbl->entries[i].quant.name, tbl->atoms))\r
+               {\r
+                       if (!slang_varying_bindings_add (bind, &tbl->entries[i].quant,\r
+                               slang_atom_pool_id (tbl->atoms, tbl->entries[i].quant.name), vert,\r
+                               tbl->entries[i].address))\r
+                               return GL_FALSE;\r
+               }\r
+\r
+       return GL_TRUE;\r
+}\r
+\r
 /*\r
  * slang_texture_bindings\r
  */\r
@@ -248,6 +336,7 @@ GLvoid slang_program_ctr (slang_program *self)
 \r
        slang_uniform_bindings_ctr (&self->uniforms);\r
        slang_active_uniforms_ctr (&self->active_uniforms);\r
+       slang_varying_bindings_ctr (&self->varyings);\r
        slang_texture_usages_ctr (&self->texture_usage);\r
        for (i = 0; i < SLANG_SHADER_MAX; i++)\r
        {\r
@@ -270,6 +359,7 @@ GLvoid slang_program_dtr (slang_program *self)
 {\r
        slang_uniform_bindings_dtr (&self->uniforms);\r
        slang_active_uniforms_dtr (&self->active_uniforms);\r
+       slang_varying_bindings_dtr (&self->varyings);\r
        slang_texture_usages_dtr (&self->texture_usage);\r
 }\r
 \r
@@ -423,12 +513,17 @@ GLboolean _slang_link (slang_program *prog, slang_translation_unit **units, GLui
                        return GL_FALSE;\r
                if (!gather_active_uniforms (&prog->active_uniforms, &units[i]->exp_data))\r
                        return GL_FALSE;\r
+               if (!gather_varying_bindings (&prog->varyings, &units[i]->exp_data,\r
+                       index == SLANG_SHADER_VERTEX))\r
+                       return GL_FALSE;\r
                resolve_common_fixed (prog->common_fixed_entries[index], &units[i]->exp_data);\r
                resolve_common_code (prog->code[index], &units[i]->exp_code);\r
                prog->machines[index] = units[i]->machine;\r
                prog->assemblies[index] = units[i]->assembly;\r
        }\r
 \r
+       /* TODO: all varyings read by fragment shader must be written by vertex shader */\r
+\r
        if (!_slang_analyse_texture_usage (prog))\r
                return GL_FALSE;\r
 \r
index 1592aefe2ecf88c801f62e0827eadfa799f4e302..e74c2565621d5f334f7098c93e70eb7a5857eb33 100644 (file)
@@ -63,6 +63,27 @@ typedef struct
        GLuint count;\r
 } slang_active_uniforms;\r
 \r
+typedef struct\r
+{\r
+       GLuint vert_addr;\r
+       GLuint frag_addr;\r
+} slang_varying_slot;\r
+\r
+typedef struct\r
+{\r
+       slang_export_data_quant *quant;\r
+       char *name;\r
+       GLuint slot;\r
+} slang_varying_binding;\r
+\r
+typedef struct\r
+{\r
+       slang_varying_binding table[MAX_VARYING_FLOATS];\r
+       GLuint count;\r
+       slang_varying_slot slots[MAX_VARYING_FLOATS];\r
+       GLuint total;\r
+} slang_varying_bindings;\r
+\r
 typedef struct\r
 {\r
        slang_export_data_quant *quant;\r
@@ -173,6 +194,7 @@ typedef struct
 {\r
        slang_uniform_bindings uniforms;\r
        slang_active_uniforms active_uniforms;\r
+       slang_varying_bindings varyings;\r
        slang_texture_usages texture_usage;\r
        GLuint common_fixed_entries[SLANG_SHADER_MAX][SLANG_COMMON_FIXED_MAX];\r
        GLuint vertex_fixed_entries[SLANG_VERTEX_FIXED_MAX];\r