mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-25 18:50:31 +01:00
Lots of vartable clean-ups, fixes. Report an error message when we run out
of registers, rather than crash.
This commit is contained in:
parent
602dc1a638
commit
4de6fac4da
5 changed files with 169 additions and 97 deletions
|
|
@ -2141,13 +2141,13 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper)
|
|||
{
|
||||
slang_ir_node *n;
|
||||
|
||||
A->vartable = _slang_push_var_table(A->vartable);
|
||||
_slang_push_var_table(A->vartable);
|
||||
|
||||
oper->type = slang_oper_block_no_new_scope; /* temp change */
|
||||
n = _slang_gen_operation(A, oper);
|
||||
oper->type = slang_oper_block_new_scope; /* restore */
|
||||
|
||||
A->vartable = _slang_pop_var_table(A->vartable);
|
||||
_slang_pop_var_table(A->vartable);
|
||||
|
||||
if (n)
|
||||
n = new_node(IR_SCOPE, n, NULL);
|
||||
|
|
@ -2640,7 +2640,7 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun)
|
|||
A->CurFunction->end_label = slang_atom_pool_gen(A->atoms, "__endOfFunc_main_");
|
||||
|
||||
/* push new vartable scope */
|
||||
A->vartable = _slang_push_var_table(A->vartable);
|
||||
_slang_push_var_table(A->vartable);
|
||||
|
||||
/* Generate IR tree for the function body code */
|
||||
n = _slang_gen_operation(A, fun->body);
|
||||
|
|
@ -2648,7 +2648,7 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun)
|
|||
n = new_node(IR_SCOPE, n, NULL);
|
||||
|
||||
/* pop vartable, restore previous */
|
||||
A->vartable = _slang_pop_var_table(A->vartable);
|
||||
_slang_pop_var_table(A->vartable);
|
||||
|
||||
if (!n) {
|
||||
/* XXX record error */
|
||||
|
|
|
|||
|
|
@ -1978,8 +1978,20 @@ static GLboolean
|
|||
parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit,
|
||||
struct gl_program *program)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
slang_output_ctx o;
|
||||
GLboolean success;
|
||||
GLuint maxRegs;
|
||||
|
||||
if (unit->type == slang_unit_fragment_builtin ||
|
||||
unit->type == slang_unit_fragment_shader) {
|
||||
maxRegs = ctx->Const.FragmentProgram.MaxTemps;
|
||||
}
|
||||
else {
|
||||
assert(unit->type == slang_unit_vertex_builtin ||
|
||||
unit->type == slang_unit_vertex_shader);
|
||||
maxRegs = ctx->Const.VertexProgram.MaxTemps;
|
||||
}
|
||||
|
||||
/* setup output context */
|
||||
o.funs = &unit->funs;
|
||||
|
|
@ -1989,7 +2001,8 @@ parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit,
|
|||
o.global_pool = &unit->object->varpool;
|
||||
o.machine = &unit->object->machine;
|
||||
o.program = program;
|
||||
o.vartable = _slang_push_var_table(NULL);
|
||||
o.vartable = _slang_new_var_table(maxRegs);
|
||||
_slang_push_var_table(o.vartable);
|
||||
|
||||
/* parse individual functions and declarations */
|
||||
while (*C->I != EXTERNAL_NULL) {
|
||||
|
|
|
|||
|
|
@ -332,14 +332,17 @@ slang_print_ir(const slang_ir_node *n, int indent)
|
|||
* Allocate temporary storage for an intermediate result (such as for
|
||||
* a multiply or add, etc.
|
||||
*/
|
||||
static void
|
||||
static GLboolean
|
||||
alloc_temp_storage(slang_var_table *vt, slang_ir_node *n, GLint size)
|
||||
{
|
||||
assert(!n->Var);
|
||||
assert(!n->Store);
|
||||
assert(size > 0);
|
||||
n->Store = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, size);
|
||||
(void) _slang_alloc_temp(vt, n->Store);
|
||||
if (!_slang_alloc_temp(vt, n->Store)) {
|
||||
RETURN_ERROR("Ran out of registers, too many temporaries", 0);
|
||||
}
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -634,7 +637,8 @@ emit_binop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
|
|||
}
|
||||
|
||||
if (!n->Store) {
|
||||
alloc_temp_storage(vt, n, info->ResultSize);
|
||||
if (!alloc_temp_storage(vt, n, info->ResultSize))
|
||||
return NULL;
|
||||
}
|
||||
storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
|
||||
|
||||
|
|
@ -667,7 +671,8 @@ emit_unop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
|
|||
free_temp_storage(vt, n->Children[0]);
|
||||
|
||||
if (!n->Store) {
|
||||
alloc_temp_storage(vt, n, info->ResultSize);
|
||||
if (!alloc_temp_storage(vt, n, info->ResultSize))
|
||||
return NULL;
|
||||
}
|
||||
storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
|
||||
|
||||
|
|
@ -691,7 +696,8 @@ emit_negation(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
|
|||
emit(vt, n->Children[0], prog);
|
||||
|
||||
if (!n->Store)
|
||||
alloc_temp_storage(vt, n, n->Children[0]->Store->Size);
|
||||
if (!alloc_temp_storage(vt, n, n->Children[0]->Store->Size))
|
||||
return NULL;
|
||||
|
||||
inst = new_instruction(prog, OPCODE_MOV);
|
||||
storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
|
||||
|
|
@ -768,7 +774,8 @@ emit_tex(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
|
|||
}
|
||||
|
||||
if (!n->Store)
|
||||
alloc_temp_storage(vt, n, 4);
|
||||
if (!alloc_temp_storage(vt, n, 4))
|
||||
return NULL;
|
||||
|
||||
storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
|
||||
|
||||
|
|
@ -880,7 +887,8 @@ emit_cond(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
|
|||
* Note: must use full 4-component vector since all four
|
||||
* condition codes must be set identically.
|
||||
*/
|
||||
alloc_temp_storage(vt, n, 4);
|
||||
if (!alloc_temp_storage(vt, n, 4))
|
||||
return NULL;
|
||||
inst = new_instruction(prog, OPCODE_MOV);
|
||||
inst->CondUpdate = GL_TRUE;
|
||||
storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
|
||||
|
|
@ -912,9 +920,9 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
|
|||
|
||||
case IR_SCOPE:
|
||||
/* new variable scope */
|
||||
vt = _slang_push_var_table(vt);
|
||||
_slang_push_var_table(vt);
|
||||
inst = emit(vt, n->Children[0], prog);
|
||||
vt = _slang_pop_var_table(vt);
|
||||
_slang_pop_var_table(vt);
|
||||
return inst;
|
||||
|
||||
case IR_VAR_DECL:
|
||||
|
|
@ -925,19 +933,20 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
|
|||
assert(n->Store->Index < 0);
|
||||
if (!n->Var || n->Var->isTemp) {
|
||||
/* a nameless/temporary variable, will be freed after first use */
|
||||
(void) _slang_alloc_temp(vt, n->Store);
|
||||
if (!_slang_alloc_temp(vt, n->Store))
|
||||
RETURN_ERROR("Ran out of registers, too many temporaries", 0);
|
||||
}
|
||||
else {
|
||||
/* a regular variable */
|
||||
_slang_add_variable(vt, n->Var);
|
||||
(void) _slang_alloc_var(vt, n->Store);
|
||||
if (!_slang_alloc_var(vt, n->Store))
|
||||
RETURN_ERROR("Ran out of registers, too many variables", 0);
|
||||
/*
|
||||
printf("IR_VAR_DECL %s %d store %p\n",
|
||||
(char*) n->Var->a_name, n->Store->Index, (void*) n->Store);
|
||||
*/
|
||||
assert(n->Var->aux == n->Store);
|
||||
}
|
||||
assert(n->Store->Index >= 0);
|
||||
break;
|
||||
|
||||
case IR_VAR:
|
||||
|
|
|
|||
|
|
@ -16,96 +16,132 @@ typedef enum {
|
|||
TEMP
|
||||
} TempState;
|
||||
|
||||
static int Level = 0;
|
||||
|
||||
/**
|
||||
* Variable/register info for one variable scope.
|
||||
*/
|
||||
struct table
|
||||
{
|
||||
int Level;
|
||||
int NumVars;
|
||||
slang_variable **Vars; /* array [NumVars] */
|
||||
|
||||
TempState Temps[MAX_PROGRAM_TEMPS * 4]; /* per-component state */
|
||||
int ValSize[MAX_PROGRAM_TEMPS]; /* For debug only */
|
||||
|
||||
struct table *Parent; /** Parent scope table */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A variable table is a stack of tables, one per scope.
|
||||
*/
|
||||
struct slang_var_table_
|
||||
{
|
||||
int level;
|
||||
int num_entries;
|
||||
slang_variable **vars; /* array [num_entries] */
|
||||
|
||||
TempState temps[MAX_PROGRAM_TEMPS * 4]; /* per-component state */
|
||||
int size[MAX_PROGRAM_TEMPS]; /* For debug only */
|
||||
|
||||
struct slang_var_table_ *parent;
|
||||
GLint CurLevel;
|
||||
GLuint MaxRegisters;
|
||||
struct table *Top; /**< Table at top of stack */
|
||||
};
|
||||
|
||||
|
||||
|
||||
slang_var_table *
|
||||
_slang_new_var_table(GLuint maxRegisters)
|
||||
{
|
||||
slang_var_table *vt
|
||||
= (slang_var_table *) _mesa_calloc(sizeof(slang_var_table));
|
||||
if (vt) {
|
||||
vt->MaxRegisters = maxRegisters;
|
||||
}
|
||||
return vt;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_slang_delete_var_table(slang_var_table *vt)
|
||||
{
|
||||
if (vt->Top) {
|
||||
_mesa_problem(NULL, "non-empty var table in _slang_delete_var_table()");
|
||||
return;
|
||||
}
|
||||
_mesa_free(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.
|
||||
*/
|
||||
slang_var_table *
|
||||
_slang_push_var_table(slang_var_table *parent)
|
||||
void
|
||||
_slang_push_var_table(slang_var_table *vt)
|
||||
{
|
||||
slang_var_table *t
|
||||
= (slang_var_table *) _mesa_calloc(sizeof(slang_var_table));
|
||||
struct table *t = (struct table *) _mesa_calloc(sizeof(struct table));
|
||||
if (t) {
|
||||
t->level = Level++;
|
||||
t->parent = parent;
|
||||
if (parent) {
|
||||
t->Level = vt->CurLevel++;
|
||||
t->Parent = vt->Top;
|
||||
if (t->Parent) {
|
||||
/* copy the info indicating which temp regs are in use */
|
||||
memcpy(t->temps, parent->temps, sizeof(t->temps));
|
||||
memcpy(t->size, parent->size, sizeof(t->size));
|
||||
memcpy(t->Temps, t->Parent->Temps, sizeof(t->Temps));
|
||||
memcpy(t->ValSize, t->Parent->ValSize, sizeof(t->ValSize));
|
||||
}
|
||||
if (dbg) printf("Pushing level %d\n", t->level);
|
||||
vt->Top = t;
|
||||
if (dbg) printf("Pushing level %d\n", t->Level);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destroy given table, return ptr to parent
|
||||
* Destroy given table, return ptr to Parent
|
||||
*/
|
||||
slang_var_table *
|
||||
_slang_pop_var_table(slang_var_table *t)
|
||||
void
|
||||
_slang_pop_var_table(slang_var_table *vt)
|
||||
{
|
||||
slang_var_table *parent = t->parent;
|
||||
struct table *t = vt->Top;
|
||||
int i;
|
||||
|
||||
if (dbg) printf("Popping level %d\n", t->level);
|
||||
if (dbg) printf("Popping level %d\n", t->Level);
|
||||
|
||||
/* free the storage allocated for each variable */
|
||||
for (i = 0; i < t->num_entries; i++) {
|
||||
slang_ir_storage *store = (slang_ir_storage *) t->vars[i]->aux;
|
||||
for (i = 0; i < t->NumVars; i++) {
|
||||
slang_ir_storage *store = (slang_ir_storage *) t->Vars[i]->aux;
|
||||
GLint j;
|
||||
const GLuint sz = store->Size;
|
||||
GLuint comp;
|
||||
if (dbg) printf(" Free var %s, size %d at %d\n",
|
||||
(char*) t->vars[i]->a_name, store->Size,
|
||||
(char*) t->Vars[i]->a_name, store->Size,
|
||||
store->Index);
|
||||
|
||||
if (sz == 1)
|
||||
if (store->Size == 1)
|
||||
comp = GET_SWZ(store->Swizzle, 0);
|
||||
else
|
||||
comp = 0;
|
||||
|
||||
assert(store->Index >= 0);
|
||||
for (j = 0; j < sz; j++) {
|
||||
assert(t->temps[store->Index * 4 + j + comp] == VAR);
|
||||
t->temps[store->Index * 4 + j + comp] = FREE;
|
||||
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;
|
||||
}
|
||||
if (t->parent) {
|
||||
if (t->Parent) {
|
||||
/* just verify that any remaining allocations in this scope
|
||||
* were for temps
|
||||
*/
|
||||
for (i = 0; i < MAX_PROGRAM_TEMPS * 4; i++) {
|
||||
if (t->temps[i] != FREE && t->parent->temps[i] == FREE) {
|
||||
for (i = 0; i < vt->MaxRegisters * 4; i++) {
|
||||
if (t->Temps[i] != FREE && t->Parent->Temps[i] == FREE) {
|
||||
if (dbg) printf(" Free reg %d\n", i/4);
|
||||
assert(t->temps[i] == TEMP);
|
||||
assert(t->Temps[i] == TEMP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (t->vars)
|
||||
free(t->vars);
|
||||
if (t->Vars)
|
||||
free(t->Vars);
|
||||
|
||||
vt->Top = t->Parent;
|
||||
free(t);
|
||||
Level--;
|
||||
return parent;
|
||||
vt->CurLevel--;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -113,31 +149,35 @@ _slang_pop_var_table(slang_var_table *t)
|
|||
* Add a new variable to the given symbol table.
|
||||
*/
|
||||
void
|
||||
_slang_add_variable(slang_var_table *t, slang_variable *v)
|
||||
_slang_add_variable(slang_var_table *vt, slang_variable *v)
|
||||
{
|
||||
struct table *t;
|
||||
assert(vt);
|
||||
t = vt->Top;
|
||||
assert(t);
|
||||
if (dbg) printf("Adding var %s\n", (char *) v->a_name);
|
||||
t->vars = realloc(t->vars, (t->num_entries + 1) * sizeof(slang_variable *));
|
||||
t->vars[t->num_entries] = v;
|
||||
t->num_entries++;
|
||||
t->Vars = realloc(t->Vars, (t->NumVars + 1) * sizeof(slang_variable *));
|
||||
t->Vars[t->NumVars] = v;
|
||||
t->NumVars++;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Look for variable by name in given table.
|
||||
* If not found, parent table will be searched.
|
||||
* If not found, Parent table will be searched.
|
||||
*/
|
||||
slang_variable *
|
||||
_slang_find_variable(const slang_var_table *t, slang_atom name)
|
||||
_slang_find_variable(const slang_var_table *vt, slang_atom name)
|
||||
{
|
||||
struct table *t = vt->Top;
|
||||
while (1) {
|
||||
int i;
|
||||
for (i = 0; i < t->num_entries; i++) {
|
||||
if (t->vars[i]->a_name == name)
|
||||
return t->vars[i];
|
||||
for (i = 0; i < t->NumVars; i++) {
|
||||
if (t->Vars[i]->a_name == name)
|
||||
return t->Vars[i];
|
||||
}
|
||||
if (t->parent)
|
||||
t = t->parent;
|
||||
if (t->Parent)
|
||||
t = t->Parent;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -150,17 +190,18 @@ _slang_find_variable(const slang_var_table *t, slang_atom name)
|
|||
* \return position for var, measured in floats
|
||||
*/
|
||||
static GLint
|
||||
alloc_reg(slang_var_table *t, GLint size, GLboolean isTemp)
|
||||
alloc_reg(slang_var_table *vt, GLint size, GLboolean isTemp)
|
||||
{
|
||||
struct table *t = vt->Top;
|
||||
/* if size == 1, allocate anywhere, else, pos must be multiple of 4 */
|
||||
const GLuint step = (size == 1) ? 1 : 4;
|
||||
GLuint i, j;
|
||||
assert(size > 0); /* number of floats */
|
||||
|
||||
for (i = 0; i < MAX_PROGRAM_TEMPS - size; i += step) {
|
||||
for (i = 0; i <= vt->MaxRegisters * 4 - size; i += step) {
|
||||
GLuint found = 0;
|
||||
for (j = 0; j < size; j++) {
|
||||
if (i + j < MAX_PROGRAM_TEMPS && t->temps[i + j] == FREE) {
|
||||
if (i + j < vt->MaxRegisters * 4 && t->Temps[i + j] == FREE) {
|
||||
found++;
|
||||
}
|
||||
else {
|
||||
|
|
@ -172,9 +213,8 @@ alloc_reg(slang_var_table *t, GLint size, GLboolean isTemp)
|
|||
if (size > 1)
|
||||
assert(i % 4 == 0);
|
||||
for (j = 0; j < size; j++)
|
||||
t->temps[i + j] = isTemp ? TEMP : VAR;
|
||||
printf("t->size[%d] = %d\n", i, size);
|
||||
t->size[i] = size;
|
||||
t->Temps[i + j] = isTemp ? TEMP : VAR;
|
||||
t->ValSize[i] = size;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
|
@ -189,9 +229,10 @@ alloc_reg(slang_var_table *t, GLint size, GLboolean isTemp)
|
|||
* \return register allocated, or -1
|
||||
*/
|
||||
GLboolean
|
||||
_slang_alloc_var(slang_var_table *t, slang_ir_storage *store)
|
||||
_slang_alloc_var(slang_var_table *vt, slang_ir_storage *store)
|
||||
{
|
||||
const int i = alloc_reg(t, store->Size, GL_FALSE);
|
||||
struct table *t = vt->Top;
|
||||
const int i = alloc_reg(vt, store->Size, GL_FALSE);
|
||||
if (i < 0)
|
||||
return GL_FALSE;
|
||||
|
||||
|
|
@ -200,12 +241,12 @@ _slang_alloc_var(slang_var_table *t, slang_ir_storage *store)
|
|||
const GLuint comp = i % 4;
|
||||
store->Swizzle = MAKE_SWIZZLE4(comp, comp, comp, comp);
|
||||
if (dbg) printf("Alloc var sz %d at %d.%c (level %d)\n",
|
||||
store->Size, store->Index, "xyzw"[comp], t->level);
|
||||
store->Size, store->Index, "xyzw"[comp], t->Level);
|
||||
}
|
||||
else {
|
||||
store->Swizzle = SWIZZLE_NOOP;
|
||||
if (dbg) printf("Alloc var sz %d at %d.xyzw (level %d)\n",
|
||||
store->Size, store->Index, t->level);
|
||||
store->Size, store->Index, t->Level);
|
||||
}
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
|
@ -216,9 +257,10 @@ _slang_alloc_var(slang_var_table *t, slang_ir_storage *store)
|
|||
* Allocate temp register(s) for storing an unnamed intermediate value.
|
||||
*/
|
||||
GLboolean
|
||||
_slang_alloc_temp(slang_var_table *t, slang_ir_storage *store)
|
||||
_slang_alloc_temp(slang_var_table *vt, slang_ir_storage *store)
|
||||
{
|
||||
const int i = alloc_reg(t, store->Size, GL_TRUE);
|
||||
struct table *t = vt->Top;
|
||||
const int i = alloc_reg(vt, store->Size, GL_TRUE);
|
||||
if (i < 0)
|
||||
return GL_FALSE;
|
||||
|
||||
|
|
@ -227,57 +269,59 @@ _slang_alloc_temp(slang_var_table *t, slang_ir_storage *store)
|
|||
const GLuint comp = i % 4;
|
||||
store->Swizzle = MAKE_SWIZZLE4(comp, comp, comp, comp);
|
||||
if (dbg) printf("Alloc temp sz %d at %d.%c (level %d)\n",
|
||||
store->Size, store->Index, "xyzw"[comp], t->level);
|
||||
store->Size, store->Index, "xyzw"[comp], t->Level);
|
||||
}
|
||||
else {
|
||||
store->Swizzle = SWIZZLE_NOOP;
|
||||
if (dbg) printf("Alloc temp sz %d at %d.xyzw (level %d)\n",
|
||||
store->Size, store->Index, t->level);
|
||||
store->Size, store->Index, t->Level);
|
||||
}
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_slang_free_temp(slang_var_table *t, slang_ir_storage *store)
|
||||
_slang_free_temp(slang_var_table *vt, slang_ir_storage *store)
|
||||
{
|
||||
struct table *t = vt->Top;
|
||||
GLuint i;
|
||||
GLuint r = store->Index;
|
||||
assert(store->Size > 0);
|
||||
assert(r >= 0);
|
||||
assert(r + store->Size <= MAX_PROGRAM_TEMPS);
|
||||
if (dbg) printf("Free temp sz %d at %d (level %d)\n", store->Size, r, t->level);
|
||||
assert(r + store->Size <= vt->MaxRegisters * 4);
|
||||
if (dbg) printf("Free temp sz %d at %d (level %d)\n", store->Size, r, t->Level);
|
||||
if (store->Size == 1) {
|
||||
const GLuint comp = GET_SWZ(store->Swizzle, 0);
|
||||
assert(store->Swizzle == MAKE_SWIZZLE4(comp, comp, comp, comp));
|
||||
assert(comp < 4);
|
||||
assert(t->size[r * 4 + comp] == 1);
|
||||
assert(t->temps[r * 4 + comp] == TEMP);
|
||||
t->temps[r * 4 + comp] = FREE;
|
||||
assert(t->ValSize[r * 4 + comp] == 1);
|
||||
assert(t->Temps[r * 4 + comp] == TEMP);
|
||||
t->Temps[r * 4 + comp] = FREE;
|
||||
}
|
||||
else {
|
||||
assert(store->Swizzle == SWIZZLE_NOOP);
|
||||
assert(t->size[r*4] == store->Size);
|
||||
assert(t->ValSize[r*4] == store->Size);
|
||||
for (i = 0; i < store->Size; i++) {
|
||||
assert(t->temps[r * 4 + i] == TEMP);
|
||||
t->temps[r * 4 + i] = FREE;
|
||||
assert(t->Temps[r * 4 + i] == TEMP);
|
||||
t->Temps[r * 4 + i] = FREE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GLboolean
|
||||
_slang_is_temp(slang_var_table *t, slang_ir_storage *store)
|
||||
_slang_is_temp(const slang_var_table *vt, const slang_ir_storage *store)
|
||||
{
|
||||
struct table *t = vt->Top;
|
||||
assert(store->Index >= 0);
|
||||
assert(store->Index < MAX_PROGRAM_TEMPS);
|
||||
assert(store->Index < vt->MaxRegisters);
|
||||
GLuint comp;
|
||||
if (store->Swizzle == SWIZZLE_NOOP)
|
||||
comp = 0;
|
||||
else
|
||||
comp = GET_SWZ(store->Swizzle, 0);
|
||||
|
||||
if (t->temps[store->Index * 4 + comp] == TEMP)
|
||||
if (t->Temps[store->Index * 4 + comp] == TEMP)
|
||||
return GL_TRUE;
|
||||
else
|
||||
return GL_FALSE;
|
||||
|
|
|
|||
|
|
@ -9,9 +9,15 @@ typedef struct slang_var_table_ slang_var_table;
|
|||
struct slang_variable_;
|
||||
|
||||
extern slang_var_table *
|
||||
_slang_new_var_table(GLuint maxRegisters);
|
||||
|
||||
extern void
|
||||
_slang_delete_var_table(slang_var_table *vt);
|
||||
|
||||
extern void
|
||||
_slang_push_var_table(slang_var_table *parent);
|
||||
|
||||
extern slang_var_table *
|
||||
extern void
|
||||
_slang_pop_var_table(slang_var_table *t);
|
||||
|
||||
extern void
|
||||
|
|
@ -30,7 +36,7 @@ extern void
|
|||
_slang_free_temp(slang_var_table *t, struct _slang_ir_storage *store);
|
||||
|
||||
extern GLboolean
|
||||
_slang_is_temp(slang_var_table *t, struct _slang_ir_storage *store);
|
||||
_slang_is_temp(const slang_var_table *t, const struct _slang_ir_storage *store);
|
||||
|
||||
|
||||
#endif /* SLANG_VARTABLE_H */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue