ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

slang_vartable.c
Go to the documentation of this file.
00001 
00002 #include "main/imports.h"
00003 #include "shader/program.h"
00004 #include "shader/prog_print.h"
00005 #include "slang_compile.h"
00006 #include "slang_compile_variable.h"
00007 #include "slang_emit.h"
00008 #include "slang_mem.h"
00009 #include "slang_vartable.h"
00010 #include "slang_ir.h"
00011 
00012 
00013 static int dbg = 0;
00014 
00015 
00016 typedef enum {
00017    FREE,
00018    VAR,
00019    TEMP
00020 } TempState;
00021 
00022 
00026 struct table
00027 {
00028    int Level;
00029    int NumVars;
00030    slang_variable **Vars;  /* array [NumVars] */
00031 
00032    TempState Temps[MAX_PROGRAM_TEMPS * 4];  /* per-component state */
00033    int ValSize[MAX_PROGRAM_TEMPS * 4];     
00035    struct table *Parent;  
00036 };
00037 
00038 
00042 struct slang_var_table_
00043 {
00044    GLint CurLevel;
00045    GLuint MaxRegisters;
00046    struct table *Top;  
00047 };
00048 
00049 
00050 
00051 slang_var_table *
00052 _slang_new_var_table(GLuint maxRegisters)
00053 {
00054    slang_var_table *vt
00055       = (slang_var_table *) _slang_alloc(sizeof(slang_var_table));
00056    if (vt) {
00057       vt->MaxRegisters = maxRegisters;
00058    }
00059    return vt;
00060 }
00061 
00062 
00063 void
00064 _slang_delete_var_table(slang_var_table *vt)
00065 {
00066    if (vt->Top) {
00067       _mesa_problem(NULL, "non-empty var table in _slang_delete_var_table()");
00068       return;
00069    }
00070    _slang_free(vt);
00071 }
00072 
00073 
00074 
00079 void
00080 _slang_push_var_table(slang_var_table *vt)
00081 {
00082    struct table *t = (struct table *) _slang_alloc(sizeof(struct table));
00083    if (t) {
00084       t->Level = vt->CurLevel++;
00085       t->Parent = vt->Top;
00086       if (t->Parent) {
00087          /* copy the info indicating which temp regs are in use */
00088          memcpy(t->Temps, t->Parent->Temps, sizeof(t->Temps));
00089          memcpy(t->ValSize, t->Parent->ValSize, sizeof(t->ValSize));
00090       }
00091       vt->Top = t;
00092       if (dbg) printf("Pushing level %d\n", t->Level);
00093    }
00094 }
00095 
00096 
00101 void
00102 _slang_pop_var_table(slang_var_table *vt)
00103 {
00104    struct table *t = vt->Top;
00105    int i;
00106 
00107    if (dbg) printf("Popping level %d\n", t->Level);
00108 
00109    /* free the storage allocated for each variable */
00110    for (i = 0; i < t->NumVars; i++) {
00111       slang_ir_storage *store = t->Vars[i]->store;
00112       GLint j;
00113       GLuint comp;
00114       if (dbg) printf("  Free var %s, size %d at %d.%s\n",
00115                       (char*) t->Vars[i]->a_name, store->Size,
00116                       store->Index,
00117                       _mesa_swizzle_string(store->Swizzle, 0, 0));
00118 
00119       if (store->File == PROGRAM_SAMPLER) {
00120          /* samplers have no storage */
00121          continue;
00122       }
00123 
00124       if (store->Size == 1)
00125          comp = GET_SWZ(store->Swizzle, 0);
00126       else
00127          comp = 0;
00128 
00129       /* store->Index may be -1 if we run out of registers */
00130       if (store->Index >= 0) {
00131          for (j = 0; j < store->Size; j++) {
00132             assert(t->Temps[store->Index * 4 + j + comp] == VAR);
00133             t->Temps[store->Index * 4 + j + comp] = FREE;
00134          }
00135       }
00136       store->Index = -1;
00137    }
00138    if (t->Parent) {
00139       /* just verify that any remaining allocations in this scope 
00140        * were for temps
00141        */
00142       for (i = 0; i < (int) vt->MaxRegisters * 4; i++) {
00143          if (t->Temps[i] != FREE && t->Parent->Temps[i] == FREE) {
00144             if (dbg) printf("  Free reg %d\n", i/4);
00145             assert(t->Temps[i] == TEMP);
00146          }
00147       }
00148    }
00149 
00150    if (t->Vars) {
00151       _slang_free(t->Vars);
00152       t->Vars = NULL;
00153    }
00154 
00155    vt->Top = t->Parent;
00156    _slang_free(t);
00157    vt->CurLevel--;
00158 }
00159 
00160 
00164 void
00165 _slang_add_variable(slang_var_table *vt, slang_variable *v)
00166 {
00167    struct table *t;
00168    assert(vt);
00169    t = vt->Top;
00170    assert(t);
00171    if (dbg) printf("Adding var %s, store %p\n", (char *) v->a_name, (void *) v->store);
00172    t->Vars = (slang_variable **)
00173       _slang_realloc(t->Vars,
00174                      t->NumVars * sizeof(slang_variable *),
00175                      (t->NumVars + 1) * sizeof(slang_variable *));
00176    t->Vars[t->NumVars] = v;
00177    t->NumVars++;
00178 }
00179 
00180 
00185 slang_variable *
00186 _slang_find_variable(const slang_var_table *vt, slang_atom name)
00187 {
00188    struct table *t = vt->Top;
00189    while (1) {
00190       int i;
00191       for (i = 0; i < t->NumVars; i++) {
00192          if (t->Vars[i]->a_name == name)
00193             return t->Vars[i];
00194       }
00195       if (t->Parent)
00196          t = t->Parent;
00197       else
00198          return NULL;
00199    }
00200 }
00201 
00202 
00208 static GLint
00209 alloc_reg(slang_var_table *vt, GLint size, GLboolean isTemp)
00210 {
00211    struct table *t = vt->Top;
00212    /* if size == 1, allocate anywhere, else, pos must be multiple of 4 */
00213    const GLuint step = (size == 1) ? 1 : 4;
00214    GLuint i, j;
00215    assert(size > 0); /* number of floats */
00216 
00217    for (i = 0; i <= vt->MaxRegisters * 4 - size; i += step) {
00218       GLuint found = 0;
00219       for (j = 0; j < (GLuint) size; j++) {
00220          assert(i + j < 4 * MAX_PROGRAM_TEMPS);
00221          if (i + j < vt->MaxRegisters * 4 && t->Temps[i + j] == FREE) {
00222             found++;
00223          }
00224          else {
00225             break;
00226          }
00227       }
00228       if (found == size) {
00229          /* found block of size free regs */
00230          if (size > 1)
00231             assert(i % 4 == 0);
00232          for (j = 0; j < (GLuint) size; j++) {
00233             assert(i + j < 4 * MAX_PROGRAM_TEMPS);
00234             t->Temps[i + j] = isTemp ? TEMP : VAR;
00235          }
00236          assert(i < MAX_PROGRAM_TEMPS * 4);
00237          t->ValSize[i] = size;
00238          return i;
00239       }
00240    }
00241 
00242    /* if we get here, we ran out of registers */
00243    return -1;
00244 }
00245 
00246 
00253 GLboolean
00254 _slang_alloc_var(slang_var_table *vt, slang_ir_storage *store)
00255 {
00256    struct table *t = vt->Top;
00257    int i;
00258 
00259    if (store->File == PROGRAM_SAMPLER) {
00260       /* don't really allocate storage */
00261       store->Index = 0;
00262       return GL_TRUE;
00263    }
00264 
00265    i = alloc_reg(vt, store->Size, GL_FALSE);
00266    if (i < 0)
00267       return GL_FALSE;
00268 
00269    store->Index = i / 4;
00270    store->Swizzle = _slang_var_swizzle(store->Size, i % 4);
00271 
00272    if (dbg)
00273       printf("Alloc var storage sz %d at %d.%s (level %d) store %p\n",
00274              store->Size, store->Index,
00275              _mesa_swizzle_string(store->Swizzle, 0, 0),
00276              t->Level,
00277              (void*) store);
00278 
00279    return GL_TRUE;
00280 }
00281 
00282 
00283 
00287 GLboolean
00288 _slang_alloc_temp(slang_var_table *vt, slang_ir_storage *store)
00289 {
00290    struct table *t = vt->Top;
00291    const int i = alloc_reg(vt, store->Size, GL_TRUE);
00292    if (i < 0)
00293       return GL_FALSE;
00294 
00295    assert(store->Index < 0);
00296 
00297    store->Index = i / 4;
00298    store->Swizzle = _slang_var_swizzle(store->Size, i % 4);
00299 
00300    if (dbg) printf("Alloc temp sz %d at %d.%s (level %d) store %p\n",
00301                    store->Size, store->Index,
00302                    _mesa_swizzle_string(store->Swizzle, 0, 0), t->Level,
00303                    (void *) store);
00304 
00305    return GL_TRUE;
00306 }
00307 
00308 
00309 void
00310 _slang_free_temp(slang_var_table *vt, slang_ir_storage *store)
00311 {
00312    struct table *t = vt->Top;
00313    GLuint i;
00314    GLuint r = store->Index;
00315    assert(store->Size > 0);
00316    assert(r >= 0);
00317    assert(r + store->Size <= vt->MaxRegisters * 4);
00318    if (dbg) printf("Free temp sz %d at %d.%s (level %d) store %p\n",
00319                    store->Size, r,
00320                    _mesa_swizzle_string(store->Swizzle, 0, 0),
00321                    t->Level, (void *) store);
00322    if (store->Size == 1) {
00323       const GLuint comp = GET_SWZ(store->Swizzle, 0);
00324       /* we can actually fail some of these assertions because of the
00325        * troublesome IR_SWIZZLE handling.
00326        */
00327 #if 0
00328       assert(store->Swizzle == MAKE_SWIZZLE4(comp, comp, comp, comp));
00329       assert(comp < 4);
00330       assert(t->ValSize[r * 4 + comp] == 1);
00331 #endif
00332       assert(t->Temps[r * 4 + comp] == TEMP);
00333       t->Temps[r * 4 + comp] = FREE;
00334    }
00335    else {
00336       /*assert(store->Swizzle == SWIZZLE_NOOP);*/
00337       assert(t->ValSize[r*4] == store->Size);
00338       for (i = 0; i < (GLuint) store->Size; i++) {
00339          assert(t->Temps[r * 4 + i] == TEMP);
00340          t->Temps[r * 4 + i] = FREE;
00341       }
00342    }
00343 }
00344 
00345 
00346 GLboolean
00347 _slang_is_temp(const slang_var_table *vt, const slang_ir_storage *store)
00348 {
00349    struct table *t = vt->Top;
00350    GLuint comp;
00351    assert(store->Index >= 0);
00352    assert(store->Index < (int) vt->MaxRegisters);
00353    if (store->Swizzle == SWIZZLE_NOOP)
00354       comp = 0;
00355    else
00356       comp = GET_SWZ(store->Swizzle, 0);
00357 
00358    if (t->Temps[store->Index * 4 + comp] == TEMP)
00359       return GL_TRUE;
00360    else
00361       return GL_FALSE;
00362 }

Generated on Fri May 25 2012 04:18:50 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.