Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenslang_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
1.7.6.1
|