Merge branch 'master' into r300g-glsl
[mesa.git] / src / mesa / shader / slang / slang_vartable.c
index 95971a70a932c16cc1719d149bd996b06cf5ac2f..a4ebacc093661e825ee796046a68a41d178f4e1a 100644 (file)
@@ -4,6 +4,7 @@
 #include "shader/prog_print.h"
 #include "slang_compile.h"
 #include "slang_compile_variable.h"
+#include "slang_emit.h"
 #include "slang_mem.h"
 #include "slang_vartable.h"
 #include "slang_ir.h"
@@ -72,9 +73,8 @@ _slang_delete_var_table(slang_var_table *vt)
 
 
 /**
- * Create new table, put at head, return ptr to it.
- * XXX we should take a maxTemps parameter to indicate how many temporaries
- * are available for the current shader/program target.
+ * Create new table on top of vartable stack.
+ * Used when we enter a {} block.
  */
 void
 _slang_push_var_table(slang_var_table *vt)
@@ -95,7 +95,8 @@ _slang_push_var_table(slang_var_table *vt)
 
 
 /**
- * Destroy given table, return ptr to Parent
+ * Pop top entry from variable table.
+ * Used when we leave a {} block.
  */
 void
 _slang_pop_var_table(slang_var_table *vt)
@@ -107,7 +108,7 @@ _slang_pop_var_table(slang_var_table *vt)
 
    /* free the storage allocated for each variable */
    for (i = 0; i < t->NumVars; i++) {
-      slang_ir_storage *store = (slang_ir_storage *) t->Vars[i]->aux;
+      slang_ir_storage *store = t->Vars[i]->store;
       GLint j;
       GLuint comp;
       if (dbg) printf("  Free var %s, size %d at %d.%s\n",
@@ -125,10 +126,12 @@ _slang_pop_var_table(slang_var_table *vt)
       else
          comp = 0;
 
-      assert(store->Index >= 0);
-      for (j = 0; j < store->Size; j++) {
-         assert(t->Temps[store->Index * 4 + j + comp] == VAR);
-         t->Temps[store->Index * 4 + j + comp] = FREE;
+      /* store->Index may be -1 if we run out of registers */
+      if (store->Index >= 0) {
+         for (j = 0; j < store->Size; j++) {
+            assert(t->Temps[store->Index * 4 + j + comp] == VAR);
+            t->Temps[store->Index * 4 + j + comp] = FREE;
+         }
       }
       store->Index = -1;
    }
@@ -156,7 +159,7 @@ _slang_pop_var_table(slang_var_table *vt)
 
 
 /**
- * Add a new variable to the given symbol table.
+ * Add a new variable to the given var/symbol table.
  */
 void
 _slang_add_variable(slang_var_table *vt, slang_variable *v)
@@ -165,7 +168,7 @@ _slang_add_variable(slang_var_table *vt, slang_variable *v)
    assert(vt);
    t = vt->Top;
    assert(t);
-   if (dbg) printf("Adding var %s, store %p\n", (char *) v->a_name, v->aux);
+   if (dbg) printf("Adding var %s, store %p\n", (char *) v->a_name, (void *) v->store);
    t->Vars = (slang_variable **)
       _slang_realloc(t->Vars,
                      t->NumVars * sizeof(slang_variable *),
@@ -214,6 +217,7 @@ alloc_reg(slang_var_table *vt, GLint size, GLboolean isTemp)
    for (i = 0; i <= vt->MaxRegisters * 4 - size; i += step) {
       GLuint found = 0;
       for (j = 0; j < (GLuint) size; j++) {
+         assert(i + j < 4 * MAX_PROGRAM_TEMPS);
          if (i + j < vt->MaxRegisters * 4 && t->Temps[i + j] == FREE) {
             found++;
          }
@@ -225,13 +229,17 @@ alloc_reg(slang_var_table *vt, GLint size, GLboolean isTemp)
          /* found block of size free regs */
          if (size > 1)
             assert(i % 4 == 0);
-         for (j = 0; j < (GLuint) size; j++)
+         for (j = 0; j < (GLuint) size; j++) {
+            assert(i + j < 4 * MAX_PROGRAM_TEMPS);
             t->Temps[i + j] = isTemp ? TEMP : VAR;
+         }
          assert(i < MAX_PROGRAM_TEMPS * 4);
          t->ValSize[i] = size;
          return i;
       }
    }
+
+   /* if we get here, we ran out of registers */
    return -1;
 }
 
@@ -259,21 +267,7 @@ _slang_alloc_var(slang_var_table *vt, slang_ir_storage *store)
       return GL_FALSE;
 
    store->Index = i / 4;
-   if (store->Size == 1) {
-      const GLuint comp = i % 4;
-      store->Swizzle = MAKE_SWIZZLE4(comp, comp, comp, comp);
-   }
-   else if (store->Size == 2) {
-      store->Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
-                                     SWIZZLE_NIL, SWIZZLE_NIL);
-   }
-   else if (store->Size == 3) {
-      store->Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
-                                     SWIZZLE_Z, SWIZZLE_NIL);
-   }
-   else {
-      store->Swizzle = SWIZZLE_NOOP;
-   }
+   store->Swizzle = _slang_var_swizzle(store->Size, i % 4);
 
    if (dbg)
       printf("Alloc var storage sz %d at %d.%s (level %d) store %p\n",
@@ -301,20 +295,7 @@ _slang_alloc_temp(slang_var_table *vt, slang_ir_storage *store)
    assert(store->Index < 0);
 
    store->Index = i / 4;
-   if (store->Size == 1) {
-      const GLuint comp = i % 4;
-      store->Swizzle = MAKE_SWIZZLE4(comp, comp, comp, comp);
-   }
-   else {
-      /* XXX improve swizzled for size=2/3, use for writemask... */
-#if 1
-      if (store->Size == 2) {
-         store->Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
-                                        SWIZZLE_NIL, SWIZZLE_NIL);
-      }
-#endif
-      store->Swizzle = SWIZZLE_NOOP;
-   }
+   store->Swizzle = _slang_var_swizzle(store->Size, i % 4);
 
    if (dbg) printf("Alloc temp sz %d at %d.%s (level %d) store %p\n",
                    store->Size, store->Index,