summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mesa/shader/slang/slang_assemble.c456
-rw-r--r--src/mesa/shader/slang/slang_assemble.h62
-rw-r--r--src/mesa/shader/slang/slang_assemble_assignment.c49
-rw-r--r--src/mesa/shader/slang/slang_assemble_assignment.h8
-rw-r--r--src/mesa/shader/slang/slang_compile.c81
-rw-r--r--src/mesa/shader/slang/slang_compile_function.c16
-rw-r--r--src/mesa/shader/slang/slang_compile_function.h10
7 files changed, 382 insertions, 300 deletions
diff --git a/src/mesa/shader/slang/slang_assemble.c b/src/mesa/shader/slang/slang_assemble.c
index 45b6b1961cc..698b3bf747b 100644
--- a/src/mesa/shader/slang/slang_assemble.c
+++ b/src/mesa/shader/slang/slang_assemble.c
@@ -268,22 +268,36 @@ slang_function *_slang_locate_function (slang_function_scope *funcs, slang_atom
/* _slang_assemble_function() */
-int _slang_assemble_function (slang_assembly_file *file, slang_function *fun,
- slang_assembly_name_space *space, slang_machine *mach, slang_atom_pool *atoms)
+int _slang_assemble_function (slang_assemble_ctx *A, slang_function *fun)
{
unsigned int param_size, local_size;
unsigned int skip, cleanup;
- slang_assembly_flow_control flow;
- slang_assembly_local_info info;
- slang_assembly_stack_info stk;
- fun->address = file->count;
+ fun->address = A->file->count;
if (fun->body == NULL)
{
- /* TODO: jump to the actual function body */
+ /* jump to the actual function body - we do not know it, so add the instruction
+ * to fixup table */
+ fun->fixups.table = (GLuint *) slang_alloc_realloc (fun->fixups.table,
+ fun->fixups.count * sizeof (GLuint), (fun->fixups.count + 1) * sizeof (GLuint));
+ if (fun->fixups.table == NULL)
+ return 0;
+ fun->fixups.table[fun->fixups.count] = fun->address;
+ fun->fixups.count++;
+ if (!PUSH (A->file, slang_asm_jump))
+ return 0;
return 1;
}
+ else
+ {
+ GLuint i;
+
+ /* resolve all fixup table entries and delete it */
+ for (i = 0; i < fun->fixups.count; i++)
+ A->file->code[fun->fixups.table[i]].param[0] = fun->address;
+ slang_fixup_table_free (&fun->fixups);
+ }
/* At this point traverse function formal parameters and code to calculate
* total memory size to be allocated on the stack.
@@ -294,71 +308,82 @@ int _slang_assemble_function (slang_assembly_file *file, slang_function *fun,
/* calculate return value size */
param_size = 0;
if (fun->header.type.specifier.type != slang_spec_void)
- if (!sizeof_variable (&fun->header.type.specifier, slang_qual_none, NULL, space,
- &param_size, mach, file, atoms))
+ if (!sizeof_variable (&fun->header.type.specifier, slang_qual_none, NULL, &A->space,
+ &param_size, A->mach, A->file, A->atoms))
return 0;
- info.ret_size = param_size;
+ A->local.ret_size = param_size;
/* calculate formal parameter list size */
- if (!sizeof_variables (fun->parameters, 0, fun->param_count, space, &param_size, mach, file,
- atoms))
+ if (!sizeof_variables (fun->parameters, 0, fun->param_count, &A->space, &param_size, A->mach, A->file,
+ A->atoms))
return 0;
/* calculate local variables size - take into account the four-byte return address and
* temporaries for various tasks (4 for addr and 16 for swizzle temporaries).
* these include variables from the formal parameter scope and from the code */
- info.addr_tmp = param_size + 4;
- info.swizzle_tmp = param_size + 4 + 4;
+ A->local.addr_tmp = param_size + 4;
+ A->local.swizzle_tmp = param_size + 4 + 4;
local_size = param_size + 4 + 4 + 16;
- if (!sizeof_variables (fun->parameters, fun->param_count, fun->parameters->num_variables, space,
- &local_size, mach, file, atoms))
+ if (!sizeof_variables (fun->parameters, fun->param_count, fun->parameters->num_variables, &A->space,
+ &local_size, A->mach, A->file, A->atoms))
return 0;
- if (!collect_locals (fun->body, space, &local_size, mach, file, atoms))
+ if (!collect_locals (fun->body, &A->space, &local_size, A->mach, A->file, A->atoms))
return 0;
/* allocate local variable storage */
- if (!PLAB (file, slang_asm_local_alloc, local_size - param_size - 4))
+ if (!PLAB (A->file, slang_asm_local_alloc, local_size - param_size - 4))
return 0;
/* mark a new frame for function variable storage */
- if (!PLAB (file, slang_asm_enter, local_size))
+ if (!PLAB (A->file, slang_asm_enter, local_size))
return 0;
/* jump directly to the actual code */
- skip = file->count;
- if (!push_new (file))
+ skip = A->file->count;
+ if (!push_new (A->file))
return 0;
- file->code[skip].type = slang_asm_jump;
+ A->file->code[skip].type = slang_asm_jump;
/* all "return" statements will be directed here */
- flow.function_end = file->count;
- cleanup = file->count;
- if (!push_new (file))
+ A->flow.function_end = A->file->count;
+ cleanup = A->file->count;
+ if (!push_new (A->file))
return 0;
- file->code[cleanup].type = slang_asm_jump;
+ A->file->code[cleanup].type = slang_asm_jump;
/* execute the function body */
- file->code[skip].param[0] = file->count;
- if (!_slang_assemble_operation (file, fun->body, 0, &flow, space, &info, &stk, mach, atoms))
+ A->file->code[skip].param[0] = A->file->count;
+ if (!_slang_assemble_operation_ (A, fun->body, slang_ref_freelance))
return 0;
/* this is the end of the function - restore the old function frame */
- file->code[cleanup].param[0] = file->count;
- if (!PUSH (file, slang_asm_leave))
+ A->file->code[cleanup].param[0] = A->file->count;
+ if (!PUSH (A->file, slang_asm_leave))
return 0;
/* free local variable storage */
- if (!PLAB (file, slang_asm_local_free, local_size - param_size - 4))
+ if (!PLAB (A->file, slang_asm_local_free, local_size - param_size - 4))
return 0;
/* return from the function */
- if (!PUSH (file, slang_asm_return))
+ if (!PUSH (A->file, slang_asm_return))
return 0;
return 1;
}
int _slang_cleanup_stack (slang_assembly_file *file, slang_operation *op, int ref,
- slang_assembly_name_space *space, slang_machine *mach, slang_atom_pool *atoms)
+ slang_assembly_name_space *space, struct slang_machine_ *mach, slang_atom_pool *atoms)
+{
+ slang_assemble_ctx A;
+
+ A.file = file;
+ A.mach = mach;
+ A.atoms = atoms;
+ A.space = *space;
+ return _slang_cleanup_stack_ (&A, op);
+}
+
+int _slang_cleanup_stack_ (slang_assemble_ctx *A, slang_operation *op)
{
slang_assembly_typeinfo ti;
unsigned int size = 0;
@@ -366,15 +391,15 @@ int _slang_cleanup_stack (slang_assembly_file *file, slang_operation *op, int re
/* get type info of the operation and calculate its size */
if (!slang_assembly_typeinfo_construct (&ti))
return 0;
- if (!_slang_typeof_operation (op, space, &ti, atoms))
+ if (!_slang_typeof_operation (op, &A->space, &ti, A->atoms))
{
slang_assembly_typeinfo_destruct (&ti);
return 0;
}
- if (ref)
+ if (A->ref == slang_ref_force)
size = 4;
else if (ti.spec.type != slang_spec_void)
- if (!sizeof_variable (&ti.spec, slang_qual_none, NULL, space, &size, mach, file, atoms))
+ if (!sizeof_variable (&ti.spec, slang_qual_none, NULL, &A->space, &size, A->mach, A->file, A->atoms))
{
slang_assembly_typeinfo_destruct (&ti);
return 0;
@@ -384,7 +409,7 @@ int _slang_cleanup_stack (slang_assembly_file *file, slang_operation *op, int re
/* if nonzero, free it from the stack */
if (size != 0)
{
- if (!PLAB (file, slang_asm_local_free, size))
+ if (!PLAB (A->file, slang_asm_local_free, size))
return 0;
}
return 1;
@@ -499,9 +524,8 @@ int _slang_dereference (slang_assembly_file *file, slang_operation *op,
return result;
}
-int _slang_call_function (slang_assembly_file *file, slang_function *fun, slang_operation *params,
- unsigned int param_count, int assignment, slang_assembly_name_space *space,
- slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms)
+int _slang_assemble_function_call (slang_assemble_ctx *A, slang_function *fun,
+ slang_operation *params, GLuint param_count, GLboolean assignment)
{
unsigned int i;
slang_assembly_stack_info p_stk[64];
@@ -515,52 +539,50 @@ int _slang_call_function (slang_assembly_file *file, slang_function *fun, slang_
{
unsigned int ret_size = 0;
- if (!sizeof_variable (&fun->header.type.specifier, slang_qual_none, NULL, space,
- &ret_size, mach, file, atoms))
+ if (!sizeof_variable (&fun->header.type.specifier, slang_qual_none, NULL, &A->space,
+ &ret_size, A->mach, A->file, A->atoms))
return 0;
- if (!PLAB (file, slang_asm_local_alloc, ret_size))
+ if (!PLAB (A->file, slang_asm_local_alloc, ret_size))
return 0;
}
/* push the actual parameters on the stack */
for (i = 0; i < param_count; i++)
{
- slang_assembly_flow_control flow;
-
if (fun->parameters->variables[i].type.qualifier == slang_qual_inout ||
fun->parameters->variables[i].type.qualifier == slang_qual_out)
{
- if (!PLAB2 (file, slang_asm_local_addr, info->addr_tmp, 4))
+ if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
return 0;
/* TODO: optimize the "out" parameter case */
- if (!_slang_assemble_operation (file, &params[i], 1, &flow, space, info, &p_stk[i],
- mach, atoms))
+ if (!_slang_assemble_operation_ (A, &params[i], slang_ref_force))
return 0;
- if (!PUSH (file, slang_asm_addr_copy))
+ p_stk[i] = A->swz;
+ if (!PUSH (A->file, slang_asm_addr_copy))
return 0;
- if (!PUSH (file, slang_asm_addr_deref))
+ if (!PUSH (A->file, slang_asm_addr_deref))
return 0;
if (i == 0 && assignment)
{
/* duplicate the resulting address */
- if (!PLAB2 (file, slang_asm_local_addr, info->addr_tmp, 4))
+ if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
return 0;
- if (!PUSH (file, slang_asm_addr_deref))
+ if (!PUSH (A->file, slang_asm_addr_deref))
return 0;
}
- if (!_slang_dereference (file, &params[i], space, info, mach, atoms))
+ if (!_slang_dereference (A->file, &params[i], &A->space, &A->local, A->mach, A->atoms))
return 0;
}
else
{
- if (!_slang_assemble_operation (file, &params[i], 0, &flow, space, info, &p_stk[i],
- mach, atoms))
+ if (!_slang_assemble_operation_ (A, &params[i], slang_ref_forbid))
return 0;
+ p_stk[i] = A->swz;
}
}
/* call the function */
- if (!PLAB (file, slang_asm_call, fun->address))
+ if (!PLAB (A->file, slang_asm_call, fun->address))
return 0;
/* pop the parameters from the stack */
@@ -573,16 +595,17 @@ int _slang_call_function (slang_assembly_file *file, slang_function *fun, slang_
{
/* for output parameter copy the contents of the formal parameter
* back to the original actual parameter */
- if (!_slang_assemble_assignment (file, &params[j], space, info, &p_stk[j], mach, atoms))
+ A->swz = p_stk[j];
+ if (!_slang_assemble_assignment (A, &params[j]))
return 0;
/* pop the actual parameter's address */
- if (!PLAB (file, slang_asm_local_free, 4))
+ if (!PLAB (A->file, slang_asm_local_free, 4))
return 0;
}
else
{
/* pop the value of the parameter */
- if (!_slang_cleanup_stack (file, &params[j], 0, space, mach, atoms))
+ if (!_slang_cleanup_stack_ (A, &params[j]))
return 0;
}
}
@@ -590,27 +613,23 @@ int _slang_call_function (slang_assembly_file *file, slang_function *fun, slang_
return 1;
}
-/* TODO: migrate to full-atom version */
-int call_function_name (slang_assembly_file *file, const char *name, slang_operation *params,
- unsigned int param_count, int assignment, slang_assembly_name_space *space,
- slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms)
+int _slang_assemble_function_call_name (slang_assemble_ctx *A, const char *name,
+ slang_operation *params, GLuint param_count, GLboolean assignment)
{
slang_atom atom;
slang_function *fun;
- atom = slang_atom_pool_atom (atoms, name);
+ atom = slang_atom_pool_atom (A->atoms, name);
if (atom == SLANG_ATOM_NULL)
return 0;
- fun = _slang_locate_function (space->funcs, atom, params, param_count, space, atoms);
+ fun = _slang_locate_function (A->space.funcs, atom, params, param_count, &A->space, A->atoms);
if (fun == NULL)
return 0;
- return _slang_call_function (file, fun, params, param_count, assignment, space, info, mach,
- atoms);
+ return _slang_assemble_function_call (A, fun, params, param_count, assignment);
}
-static int call_function_name_dummyint (slang_assembly_file *file, const char *name,
- slang_operation *params, slang_assembly_name_space *space, slang_assembly_local_info *info,
- slang_machine *mach, slang_atom_pool *atoms)
+static int assemble_function_call_name_dummyint (slang_assemble_ctx *A, const char *name,
+ slang_operation *params)
{
slang_operation p[2];
int result;
@@ -619,7 +638,7 @@ static int call_function_name_dummyint (slang_assembly_file *file, const char *n
if (!slang_operation_construct (&p[1]))
return 0;
p[1].type = slang_oper_literal_int;
- result = call_function_name (file, name, p, 2, 0, space, info, mach, atoms);
+ result = _slang_assemble_function_call_name (A, name, p, 2, GL_FALSE);
slang_operation_destruct (&p[1]);
return result;
}
@@ -1001,19 +1020,40 @@ static int handle_field (slang_assembly_typeinfo *tia, slang_assembly_typeinfo *
return 1;
}
-int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, int reference,
- slang_assembly_flow_control *flow, slang_assembly_name_space *space,
- slang_assembly_local_info *info, slang_assembly_stack_info *stk, slang_machine *mach,
- slang_atom_pool *atoms)
+int _slang_assemble_operation (slang_assembly_file *file, struct slang_operation_ *op, int reference,
+ slang_assembly_flow_control *flow, slang_assembly_name_space *space, slang_assembly_local_info *info,
+ slang_assembly_stack_info *stk, struct slang_machine_ *mach, slang_atom_pool *atoms)
{
- unsigned int assem;
+ slang_assemble_ctx A;
+
+ A.file = file;
+ A.mach = mach;
+ A.atoms = atoms;
+ A.space = *space;
+ A.flow = *flow;
+ A.local = *info;
+ if (!_slang_assemble_operation_ (&A, op, reference ? slang_ref_force : slang_ref_forbid))
+ return 0;
+ *stk = A.swz;
+ return 1;
+}
- stk->swizzle.num_components = 0;
+int _slang_assemble_operation_ (slang_assemble_ctx *A, slang_operation *op, slang_ref_type ref)
+{
+ unsigned int assem;
+ slang_assembly_stack_info swz;
- assem = file->count;
- if (!push_new (file))
+ assem = A->file->count;
+ if (!push_new (A->file))
return 0;
+if (ref == slang_ref_freelance)
+ref = slang_ref_forbid;
+
+ /* set default results */
+ A->ref = (ref == slang_ref_freelance) ? slang_ref_force : ref;
+ swz.swizzle.num_components = 0;
+
switch (op->type)
{
case slang_oper_block_no_new_scope:
@@ -1023,13 +1063,9 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
for (i = 0; i < op->num_children; i++)
{
- slang_assembly_stack_info stk;
-
- if (!_slang_assemble_operation (file, &op->children[i], 0, flow, space, info, &stk,
- mach, atoms))
+ if (!_slang_assemble_operation_ (A, &op->children[i], slang_ref_freelance))
return 0;
- /* ignore the stk */
- if (!_slang_cleanup_stack (file, &op->children[i], 0, space, mach, atoms))
+ if (!_slang_cleanup_stack_ (A, &op->children[i]))
return 0;
}
}
@@ -1049,95 +1085,92 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
{
unsigned int i;
- for (i = 0; i < op->num_children; i++)
- {
- slang_assembly_stack_info stk;
-
- if (!_slang_assemble_operation (file, &op->children[i], i == 0, flow, space, info,
- &stk, mach, atoms))
+ if (!_slang_assemble_operation_ (A, &op->children[0], slang_ref_force))
+ return 0;
+ for (i = 1; i < op->num_children; i++)
+ if (!_slang_assemble_operation_ (A, &op->children[i], slang_ref_forbid))
return 0;
- /* __asm statement does not support any swizzles, so lets ignore stk for now */
- }
- if (!call_asm_instruction (file, op->a_id, atoms))
+ if (!call_asm_instruction (A->file, op->a_id, A->atoms))
return 0;
}
break;
case slang_oper_break:
- file->code[assem].type = slang_asm_jump;
- file->code[assem].param[0] = flow->loop_end;
+ A->file->code[assem].type = slang_asm_jump;
+ A->file->code[assem].param[0] = A->flow.loop_end;
break;
case slang_oper_continue:
- file->code[assem].type = slang_asm_jump;
- file->code[assem].param[0] = flow->loop_start;
+ A->file->code[assem].type = slang_asm_jump;
+ A->file->code[assem].param[0] = A->flow.loop_start;
break;
case slang_oper_discard:
- file->code[assem].type = slang_asm_discard;
- if (!PUSH (file, slang_asm_exit))
+ A->file->code[assem].type = slang_asm_discard;
+ if (!PUSH (A->file, slang_asm_exit))
return 0;
break;
case slang_oper_return:
- if (info->ret_size != 0)
+ if (A->local.ret_size != 0)
{
- slang_assembly_stack_info stk;
-
/* push the result's address */
- if (!PLAB2 (file, slang_asm_local_addr, 0, info->ret_size))
+ if (!PLAB2 (A->file, slang_asm_local_addr, 0, A->local.ret_size))
return 0;
- if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk,
- mach, atoms))
+ if (!_slang_assemble_operation_ (A, &op->children[0], slang_ref_forbid))
return 0;
- /* ignore the stk from latest operation, reset swizzle to 0 for the assignment */
- stk.swizzle.num_components = 0;
+ A->swz.swizzle.num_components = 0;
/* assign the operation to the function result (it was reserved on the stack) */
- if (!_slang_assemble_assignment (file, op->children, space, info, &stk, mach, atoms))
+ if (!_slang_assemble_assignment (A, op->children))
return 0;
- if (!PLAB (file, slang_asm_local_free, 4))
+ if (!PLAB (A->file, slang_asm_local_free, 4))
return 0;
}
- if (!PLAB (file, slang_asm_jump, flow->function_end))
+ if (!PLAB (A->file, slang_asm_jump, A->flow.function_end))
return 0;
break;
case slang_oper_expression:
- {
- slang_assembly_stack_info stk;
-
- assert (!reference);
- if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk, mach, atoms))
- return 0;
- /* ignore the stk info */
- }
+ if (ref == slang_ref_force)
+ return 0;
+ if (!_slang_assemble_operation_ (A, &op->children[0], ref))
+ return 0;
break;
case slang_oper_if:
- if (!_slang_assemble_if (file, op, flow, space, info, mach, atoms))
+ if (!_slang_assemble_if (A->file, op, &A->flow, &A->space, &A->local, A->mach, A->atoms))
return 0;
break;
case slang_oper_while:
- if (!_slang_assemble_while (file, op, flow, space, info, mach, atoms))
+ if (!_slang_assemble_while (A->file, op, &A->flow, &A->space, &A->local, A->mach, A->atoms))
return 0;
break;
case slang_oper_do:
- if (!_slang_assemble_do (file, op, flow, space, info, mach, atoms))
+ if (!_slang_assemble_do (A->file, op, &A->flow, &A->space, &A->local, A->mach, A->atoms))
return 0;
break;
case slang_oper_for:
- if (!_slang_assemble_for (file, op, flow, space, info, mach, atoms))
+ if (!_slang_assemble_for (A->file, op, &A->flow, &A->space, &A->local, A->mach, A->atoms))
return 0;
break;
case slang_oper_void:
break;
case slang_oper_literal_bool:
- file->code[assem].type = slang_asm_bool_push;
- file->code[assem].literal = op->literal;
+ if (ref == slang_ref_force)
+ return 0;
+ A->file->code[assem].type = slang_asm_bool_push;
+ A->file->code[assem].literal = op->literal;
+ A->ref = slang_ref_forbid;
break;
case slang_oper_literal_int:
- file->code[assem].type = slang_asm_int_push;
- file->code[assem].literal = op->literal;
+ if (ref == slang_ref_force)
+ return 0;
+ A->file->code[assem].type = slang_asm_int_push;
+ A->file->code[assem].literal = op->literal;
+ A->ref = slang_ref_forbid;
break;
case slang_oper_literal_float:
- file->code[assem].type = slang_asm_float_push;
- file->code[assem].literal = op->literal;
+ if (ref == slang_ref_force)
+ return 0;
+ A->file->code[assem].type = slang_asm_float_push;
+ A->file->code[assem].literal = op->literal;
+ A->ref = slang_ref_forbid;
break;
case slang_oper_identifier:
{
@@ -1149,69 +1182,64 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
if (var == NULL)
return 0;
size = 0;
- if (!sizeof_variable (&var->type.specifier, slang_qual_none, var->array_size, space,
- &size, mach, file, atoms))
+ if (!sizeof_variable (&var->type.specifier, slang_qual_none, var->array_size, &A->space,
+ &size, A->mach, A->file, A->atoms))
return 0;
/* prepare stack for dereferencing */
- if (!reference)
- if (!PLAB2 (file, slang_asm_local_addr, info->addr_tmp, 4))
+ if (ref == slang_ref_forbid)
+ if (!PLAB2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
return 0;
/* push the variable's address */
if (var->global)
{
- if (!PLAB (file, slang_asm_addr_push, var->address))
+ if (!PLAB (A->file, slang_asm_addr_push, var->address))
return 0;
}
else
{
- if (!PLAB2 (file, slang_asm_local_addr, var->address, size))
+ if (!PLAB2 (A->file, slang_asm_local_addr, var->address, size))
return 0;
}
/* perform the dereference */
- if (!reference)
+ if (ref == slang_ref_forbid)
{
- if (!PUSH (file, slang_asm_addr_copy))
+ if (!PUSH (A->file, slang_asm_addr_copy))
return 0;
- if (!PLAB (file, slang_asm_local_free, 4))
+ if (!PLAB (A->file, slang_asm_local_free, 4))
return 0;
- if (!_slang_dereference (file, op, space, info, mach, atoms))
+ if (!_slang_dereference (A->file, op, &A->space, &A->local, A->mach, A->atoms))
return 0;
}
}
break;
case slang_oper_sequence:
- {
- slang_assembly_stack_info stk;
-
- if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk,
- mach, atoms))
- return 0;
- /* TODO: pass-in stk to cleanup */
- if (!_slang_cleanup_stack (file, &op->children[0], 0, space, mach, atoms))
- return 0;
- if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info,
- &stk, mach, atoms))
- return 0;
- /* TODO: inspect stk */
- }
+ if (ref == slang_ref_force)
+ return 0;
+ if (!_slang_assemble_operation_ (A, &op->children[0], slang_ref_freelance))
+ return 0;
+ if (!_slang_cleanup_stack_ (A, &op->children[0]))
+ return 0;
+ if (!_slang_assemble_operation_ (A, &op->children[1], slang_ref_forbid))
+ return 0;
+ A->ref = slang_ref_forbid;
break;
case slang_oper_assign:
- if (!_slang_assemble_assign (file, op, "=", reference, space, info, mach, atoms))
+ if (!_slang_assemble_assign (A, op, "=", ref))
return 0;
break;
case slang_oper_addassign:
- if (!_slang_assemble_assign (file, op, "+=", reference, space, info, mach, atoms))
+ if (!_slang_assemble_assign (A, op, "+=", ref))
return 0;
break;
case slang_oper_subassign:
- if (!_slang_assemble_assign (file, op, "-=", reference, space, info, mach, atoms))
+ if (!_slang_assemble_assign (A, op, "-=", ref))
return 0;
break;
case slang_oper_mulassign:
- if (!_slang_assemble_assign (file, op, "*=", reference, space, info, mach, atoms))
+ if (!_slang_assemble_assign (A, op, "*=", ref))
return 0;
break;
/*case slang_oper_modassign:*/
@@ -1221,111 +1249,116 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
/*case slang_oper_xorassign:*/
/*case slang_oper_andassign:*/
case slang_oper_divassign:
- if (!_slang_assemble_assign (file, op, "/=", reference, space, info, mach, atoms))
+ if (!_slang_assemble_assign (A, op, "/=", ref))
return 0;
break;
case slang_oper_select:
- if (!_slang_assemble_select (file, op, flow, space, info, mach, atoms))
+ if (!_slang_assemble_select (A->file, op, &A->flow, &A->space, &A->local, A->mach, A->atoms))
return 0;
+ A->ref = slang_ref_forbid;
break;
case slang_oper_logicalor:
- if (!_slang_assemble_logicalor (file, op, flow, space, info, mach, atoms))
+ if (!_slang_assemble_logicalor (A->file, op, &A->flow, &A->space, &A->local, A->mach, A->atoms))
return 0;
+ A->ref = slang_ref_forbid;
break;
case slang_oper_logicaland:
- if (!_slang_assemble_logicaland (file, op, flow, space, info, mach, atoms))
+ if (!_slang_assemble_logicaland (A->file, op, &A->flow, &A->space, &A->local, A->mach, A->atoms))
return 0;
+ A->ref = slang_ref_forbid;
break;
case slang_oper_logicalxor:
- if (!call_function_name (file, "^^", op->children, 2, 0, space, info, mach, atoms))
+ if (!_slang_assemble_function_call_name (A, "^^", op->children, 2, GL_FALSE))
return 0;
+ A->ref = slang_ref_forbid;
break;
/*case slang_oper_bitor:*/
/*case slang_oper_bitxor:*/
/*case slang_oper_bitand:*/
case slang_oper_less:
- if (!call_function_name (file, "<", op->children, 2, 0, space, info, mach, atoms))
+ if (!_slang_assemble_function_call_name (A, "<", op->children, 2, GL_FALSE))
return 0;
+ A->ref = slang_ref_forbid;
break;
case slang_oper_greater:
- if (!call_function_name (file, ">", op->children, 2, 0, space, info, mach, atoms))
+ if (!_slang_assemble_function_call_name (A, ">", op->children, 2, GL_FALSE))
return 0;
+ A->ref = slang_ref_forbid;
break;
case slang_oper_lessequal:
- if (!call_function_name (file, "<=", op->children, 2, 0, space, info, mach, atoms))
+ if (!_slang_assemble_function_call_name (A, "<=", op->children, 2, GL_FALSE))
return 0;
+ A->ref = slang_ref_forbid;
break;
case slang_oper_greaterequal:
- if (!call_function_name (file, ">=", op->children, 2, 0, space, info, mach, atoms))
+ if (!_slang_assemble_function_call_name (A, ">=", op->children, 2, GL_FALSE))
return 0;
+ A->ref = slang_ref_forbid;
break;
/*case slang_oper_lshift:*/
/*case slang_oper_rshift:*/
case slang_oper_add:
- if (!call_function_name (file, "+", op->children, 2, 0, space, info, mach, atoms))
+ if (!_slang_assemble_function_call_name (A, "+", op->children, 2, GL_FALSE))
return 0;
+ A->ref = slang_ref_forbid;
break;
case slang_oper_subtract:
- if (!call_function_name (file, "-", op->children, 2, 0, space, info, mach, atoms))
+ if (!_slang_assemble_function_call_name (A, "-", op->children, 2, GL_FALSE))
return 0;
+ A->ref = slang_ref_forbid;
break;
case slang_oper_multiply:
- if (!call_function_name (file, "*", op->children, 2, 0, space, info, mach, atoms))
+ if (!_slang_assemble_function_call_name (A, "*", op->children, 2, GL_FALSE))
return 0;
+ A->ref = slang_ref_forbid;
break;
/*case slang_oper_modulus:*/
case slang_oper_divide:
- if (!call_function_name (file, "/", op->children, 2, 0, space, info, mach, atoms))
+ if (!_slang_assemble_function_call_name (A, "/", op->children, 2, GL_FALSE))
return 0;
+ A->ref = slang_ref_forbid;
break;
case slang_oper_equal:
- {
- slang_assembly_stack_info stk;
-
- if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk,
- mach, atoms))
- return 0;
- if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &stk,
- mach, atoms))
- return 0;
- if (!equality (file, op->children, space, info, 1, mach, atoms))
- return 0;
- }
+ if (!_slang_assemble_operation_ (A, &op->children[0], slang_ref_forbid))
+ return 0;
+ if (!_slang_assemble_operation_ (A, &op->children[1], slang_ref_forbid))
+ return 0;
+ if (!equality (A->file, op->children, &A->space, &A->local, 1, A->mach, A->atoms))
+ return 0;
+ A->ref = slang_ref_forbid;
break;
case slang_oper_notequal:
- {
- slang_assembly_stack_info stk;
-
- if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk,
- mach, atoms))
- return 0;
- if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &stk,
- mach, atoms))
- return 0;
- if (!equality (file, op->children, space, info, 0, mach, atoms))
- return 0;
- }
+ if (!_slang_assemble_operation_ (A, &op->children[0], slang_ref_forbid))
+ return 0;
+ if (!_slang_assemble_operation_ (A, &op->children[1], slang_ref_forbid))
+ return 0;
+ if (!equality (A->file, op->children, &A->space, &A->local, 0, A->mach, A->atoms))
+ return 0;
+ A->ref = slang_ref_forbid;
break;
case slang_oper_preincrement:
- if (!_slang_assemble_assign (file, op, "++", reference, space, info, mach, atoms))
+ if (!_slang_assemble_assign (A, op, "++", ref))
return 0;
break;
case slang_oper_predecrement:
- if (!_slang_assemble_assign (file, op, "--", reference, space, info, mach, atoms))
+ if (!_slang_assemble_assign (A, op, "--", ref))
return 0;
break;
case slang_oper_plus:
- if (!_slang_dereference (file, op, space, info, mach, atoms))
+ if (!_slang_dereference (A->file, op, &A->space, &A->local, A->mach, A->atoms))
return 0;
+ A->ref = slang_ref_forbid;
break;
case slang_oper_minus:
- if (!call_function_name (file, "-", op->children, 1, 0, space, info, mach, atoms))
+ if (!_slang_assemble_function_call_name (A, "-", op->children, 1, GL_FALSE))
return 0;
+ A->ref = slang_ref_forbid;
break;
/*case slang_oper_complement:*/
case slang_oper_not:
- if (!call_function_name (file, "!", op->children, 1, 0, space, info, mach, atoms))
+ if (!_slang_assemble_function_call_name (A, "!", op->children, 1, GL_FALSE))
return 0;
+ A->ref = slang_ref_forbid;
break;
case slang_oper_subscript:
{
@@ -1338,8 +1371,8 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
slang_assembly_typeinfo_destruct (&ti_arr);
return 0;
}
- if (!handle_subscript (&ti_elem, &ti_arr, file, op, reference, flow, space, info,
- mach, atoms))
+ if (!handle_subscript (&ti_elem, &ti_arr, A->file, op, ref != slang_ref_forbid, &A->flow, &A->space, &A->local,
+ A->mach, A->atoms))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
@@ -1353,8 +1386,8 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
{
slang_function *fun;
- fun = _slang_locate_function (space->funcs, op->a_id, op->children, op->num_children,
- space, atoms);
+ fun = _slang_locate_function (A->space.funcs, op->a_id, op->children, op->num_children,
+ &A->space, A->atoms);
if (fun == NULL)
{
/* if (!_slang_assemble_constructor (file, op, flow, space, info, mach))
@@ -1362,10 +1395,10 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
}
else
{
- if (!_slang_call_function (file, fun, op->children, op->num_children, 0, space,
- info, mach, atoms))
+ if (!_slang_assemble_function_call (A, fun, op->children, op->num_children, GL_FALSE))
return 0;
}
+ A->ref = slang_ref_forbid;
}
break;
case slang_oper_field:
@@ -1379,8 +1412,8 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
slang_assembly_typeinfo_destruct (&ti_after);
return 0;
}
- if (!handle_field (&ti_after, &ti_before, file, op, reference, flow, space, info, stk,
- mach, atoms))
+ if (!handle_field (&ti_after, &ti_before, A->file, op, ref != slang_ref_forbid, &A->flow, &A->space, &A->local, &swz,
+ A->mach, A->atoms))
{
slang_assembly_typeinfo_destruct (&ti_after);
slang_assembly_typeinfo_destruct (&ti_before);
@@ -1391,16 +1424,21 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
}
break;
case slang_oper_postincrement:
- if (!call_function_name_dummyint (file, "++", op->children, space, info, mach, atoms))
+ if (!assemble_function_call_name_dummyint (A, "++", op->children))
return 0;
+ A->ref = slang_ref_forbid;
break;
case slang_oper_postdecrement:
- if (!call_function_name_dummyint (file, "--", op->children, space, info, mach, atoms))
+ if (!assemble_function_call_name_dummyint (A, "--", op->children))
return 0;
+ A->ref = slang_ref_forbid;
break;
default:
return 0;
}
+
+ A->swz = swz;
+
return 1;
}
diff --git a/src/mesa/shader/slang/slang_assemble.h b/src/mesa/shader/slang/slang_assemble.h
index c3af8d8fed8..3d5eec21047 100644
--- a/src/mesa/shader/slang/slang_assemble.h
+++ b/src/mesa/shader/slang/slang_assemble.h
@@ -125,19 +125,19 @@ typedef struct slang_assembly_flow_control_
unsigned int function_end; /* for "return" statement */
} slang_assembly_flow_control;
-typedef struct slang_assembly_name_space_
+typedef struct slang_assembly_local_info_
{
- struct slang_function_scope_ *funcs;
- struct slang_struct_scope_ *structs;
- struct slang_variable_scope_ *vars;
-} slang_assembly_name_space;
-
-slang_function *_slang_locate_function (slang_function_scope *funcs, slang_atom a_name,
- slang_operation *params, unsigned int num_params, slang_assembly_name_space *space,
- slang_atom_pool *);
+ unsigned int ret_size;
+ unsigned int addr_tmp;
+ unsigned int swizzle_tmp;
+} slang_assembly_local_info;
-int _slang_assemble_function (slang_assembly_file *, struct slang_function_ *,
- slang_assembly_name_space *, struct slang_machine_ *, slang_atom_pool *);
+typedef enum
+{
+ slang_ref_force,
+ slang_ref_forbid,
+ slang_ref_freelance
+} slang_ref_type;
/*
holds a complete information about vector swizzle - the <swizzle> array contains
@@ -155,22 +155,48 @@ typedef struct slang_assembly_stack_info_
slang_swizzle swizzle;
} slang_assembly_stack_info;
-int _slang_cleanup_stack (slang_assembly_file *, slang_operation *, int ref,
- slang_assembly_name_space *, struct slang_machine_ *, slang_atom_pool *);
+typedef struct slang_assembly_name_space_
+{
+ struct slang_function_scope_ *funcs;
+ struct slang_struct_scope_ *structs;
+ struct slang_variable_scope_ *vars;
+} slang_assembly_name_space;
-typedef struct slang_assembly_local_info_
+typedef struct slang_assemble_ctx_
{
- unsigned int ret_size;
- unsigned int addr_tmp;
- unsigned int swizzle_tmp;
-} slang_assembly_local_info;
+ slang_assembly_file *file;
+ struct slang_machine_ *mach;
+ slang_atom_pool *atoms;
+ slang_assembly_name_space space;
+ slang_assembly_flow_control flow;
+ slang_assembly_local_info local;
+ slang_ref_type ref;
+ slang_assembly_stack_info swz;
+} slang_assemble_ctx;
+
+slang_function *_slang_locate_function (slang_function_scope *funcs, slang_atom a_name,
+ slang_operation *params, unsigned int num_params, slang_assembly_name_space *space,
+ slang_atom_pool *);
+
+int _slang_assemble_function (slang_assemble_ctx *, struct slang_function_ *);
+
+int _slang_cleanup_stack (slang_assembly_file *, slang_operation *, int ref,
+ slang_assembly_name_space *, struct slang_machine_ *, slang_atom_pool *);
+int _slang_cleanup_stack_ (slang_assemble_ctx *, slang_operation *);
int _slang_dereference (slang_assembly_file *, slang_operation *, slang_assembly_name_space *,
slang_assembly_local_info *, struct slang_machine_ *, slang_atom_pool *);
+int _slang_assemble_function_call (slang_assemble_ctx *, slang_function *,
+ slang_operation *, GLuint, GLboolean);
+
+int _slang_assemble_function_call_name (slang_assemble_ctx *, const char *,
+ slang_operation *, GLuint, GLboolean);
+
int _slang_assemble_operation (slang_assembly_file *, struct slang_operation_ *, int reference,
slang_assembly_flow_control *, slang_assembly_name_space *, slang_assembly_local_info *,
slang_assembly_stack_info *, struct slang_machine_ *, slang_atom_pool *);
+int _slang_assemble_operation_ (slang_assemble_ctx *, struct slang_operation_ *, slang_ref_type);
#ifdef __cplusplus
}
diff --git a/src/mesa/shader/slang/slang_assemble_assignment.c b/src/mesa/shader/slang/slang_assemble_assignment.c
index 3c35e862566..afecf08a491 100644
--- a/src/mesa/shader/slang/slang_assemble_assignment.c
+++ b/src/mesa/shader/slang/slang_assemble_assignment.c
@@ -117,9 +117,7 @@ static int assign_aggregate (slang_assembly_file *file, const slang_storage_aggr
return 1;
}
-int _slang_assemble_assignment (slang_assembly_file *file, slang_operation *op,
- slang_assembly_name_space *space, slang_assembly_local_info *info, slang_assembly_stack_info *stk,
- struct slang_machine_ *mach, slang_atom_pool *atoms)
+int _slang_assemble_assignment (slang_assemble_ctx *A, slang_operation *op)
{
slang_assembly_typeinfo ti;
int result;
@@ -128,7 +126,7 @@ int _slang_assemble_assignment (slang_assembly_file *file, slang_operation *op,
if (!slang_assembly_typeinfo_construct (&ti))
return 0;
- if (!_slang_typeof_operation (op, space, &ti, atoms))
+ if (!_slang_typeof_operation (op, &A->space, &ti, A->atoms))
{
slang_assembly_typeinfo_destruct (&ti);
return 0;
@@ -139,8 +137,8 @@ int _slang_assemble_assignment (slang_assembly_file *file, slang_operation *op,
slang_assembly_typeinfo_destruct (&ti);
return 0;
}
- if (!_slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs,
- space->vars, mach, file, atoms))
+ if (!_slang_aggregate_variable (&agg, &ti.spec, NULL, A->space.funcs, A->space.structs,
+ A->space.vars, A->mach, A->file, A->atoms))
{
slang_storage_aggregate_destruct (&agg);
slang_assembly_typeinfo_destruct (&ti);
@@ -149,7 +147,7 @@ int _slang_assemble_assignment (slang_assembly_file *file, slang_operation *op,
index = 0;
size = _slang_sizeof_aggregate (&agg);
- result = assign_aggregate (file, &agg, &index, size, info, stk);
+ result = assign_aggregate (A->file, &agg, &index, size, &A->local, &A->swz);
slang_storage_aggregate_destruct (&agg);
slang_assembly_typeinfo_destruct (&ti);
@@ -163,48 +161,41 @@ int _slang_assemble_assignment (slang_assembly_file *file, slang_operation *op,
children
*/
-int call_function_name (slang_assembly_file *file, const char *name, slang_operation *params,
- unsigned int param_count, int assignment, slang_assembly_name_space *space,
- slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms);
-
-int _slang_assemble_assign (slang_assembly_file *file, slang_operation *op, const char *oper,
- int ref, slang_assembly_name_space *space, slang_assembly_local_info *info,
- struct slang_machine_ *mach, slang_atom_pool *atoms)
+int _slang_assemble_assign (slang_assemble_ctx *A, slang_operation *op, const char *oper,
+ slang_ref_type ref)
{
- slang_assembly_stack_info l_stk, r_stk;
- slang_assembly_flow_control flow;
+ slang_assembly_stack_info stk;
- if (!ref)
+ if (ref == slang_ref_forbid)
{
- if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp, 4))
+ if (!slang_assembly_file_push_label2 (A->file, slang_asm_local_addr, A->local.addr_tmp, 4))
return 0;
}
if (slang_string_compare ("=", oper) == 0)
{
- if (!_slang_assemble_operation (file, &op->children[0], 1, &flow, space, info, &l_stk, mach,
- atoms))
+ if (!_slang_assemble_operation_ (A, &op->children[0], slang_ref_force))
return 0;
- if (!_slang_assemble_operation (file, &op->children[1], 0, &flow, space, info, &r_stk, mach,
- atoms))
+ stk = A->swz;
+ if (!_slang_assemble_operation_ (A, &op->children[1], slang_ref_forbid))
return 0;
- if (!_slang_assemble_assignment (file, op->children, space, info, &l_stk, mach, atoms))
+ A->swz = stk;
+ if (!_slang_assemble_assignment (A, op->children))
return 0;
}
else
{
- if (!call_function_name (file, oper, op->children, op->num_children, 1, space, info, mach,
- atoms))
+ if (!_slang_assemble_function_call_name (A, oper, op->children, op->num_children, GL_TRUE))
return 0;
}
- if (!ref)
+ if (ref == slang_ref_forbid)
{
- if (!slang_assembly_file_push (file, slang_asm_addr_copy))
+ if (!slang_assembly_file_push (A->file, slang_asm_addr_copy))
return 0;
- if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
+ if (!slang_assembly_file_push_label (A->file, slang_asm_local_free, 4))
return 0;
- if (!_slang_dereference (file, op->children, space, info, mach, atoms))
+ if (!_slang_dereference (A->file, op->children, &A->space, &A->local, A->mach, A->atoms))
return 0;
}
diff --git a/src/mesa/shader/slang/slang_assemble_assignment.h b/src/mesa/shader/slang/slang_assemble_assignment.h
index 1dc48b16a77..dfec8b0138f 100644
--- a/src/mesa/shader/slang/slang_assemble_assignment.h
+++ b/src/mesa/shader/slang/slang_assemble_assignment.h
@@ -31,13 +31,9 @@
extern "C" {
#endif
-int _slang_assemble_assignment (slang_assembly_file *, slang_operation *,
- slang_assembly_name_space *, slang_assembly_local_info *, slang_assembly_stack_info *,
- struct slang_machine_ *, slang_atom_pool *);
+int _slang_assemble_assignment (slang_assemble_ctx *, slang_operation *);
-int _slang_assemble_assign (slang_assembly_file *, slang_operation *, const char *, int ref,
- slang_assembly_name_space *, slang_assembly_local_info *, struct slang_machine_ *,
- slang_atom_pool *);
+int _slang_assemble_assign (slang_assemble_ctx *, slang_operation *, const char *, slang_ref_type);
#ifdef __cplusplus
}
diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c
index 11243202db6..eb02ccc1991 100644
--- a/src/mesa/shader/slang/slang_compile.c
+++ b/src/mesa/shader/slang/slang_compile.c
@@ -1489,8 +1489,7 @@ static int parse_function_definition (slang_parse_ctx *C, slang_output_ctx *O, s
return 1;
}
-static int initialize_global (slang_assembly_file *file, slang_machine *pmach,
- slang_assembly_name_space *space, slang_variable *var, slang_atom_pool *atoms)
+static int initialize_global (slang_assemble_ctx *A, slang_variable *var)
{
slang_assembly_file_restore_point point;
slang_machine mach;
@@ -1501,20 +1500,20 @@ static int initialize_global (slang_assembly_file *file, slang_machine *pmach,
slang_assembly_stack_info stk;
/* save the current assembly */
- if (!slang_assembly_file_restore_point_save (file, &point))
+ if (!slang_assembly_file_restore_point_save (A->file, &point))
return 0;
/* setup the machine */
- mach = *pmach;
- mach.ip = file->count;
+ mach = *A->mach;
+ mach.ip = A->file->count;
/* allocate local storage for expression */
info.ret_size = 0;
info.addr_tmp = 0;
info.swizzle_tmp = 4;
- if (!slang_assembly_file_push_label (file, slang_asm_local_alloc, 20))
+ if (!slang_assembly_file_push_label (A->file, slang_asm_local_alloc, 20))
return 0;
- if (!slang_assembly_file_push_label (file, slang_asm_enter, 20))
+ if (!slang_assembly_file_push_label (A->file, slang_asm_enter, 20))
return 0;
/* construct the left side of assignment */
@@ -1554,7 +1553,7 @@ static int initialize_global (slang_assembly_file *file, slang_machine *pmach,
op_assign.children[1] = *var->initializer;
/* insert the actual expression */
- result = _slang_assemble_operation (file, &op_assign, 0, &flow, space, &info, &stk, pmach, atoms);
+ result = _slang_assemble_operation (A->file, &op_assign, 0, &flow, &A->space, &info, &stk, A->mach, A->atoms);
/* carefully destroy the operations */
op_assign.num_children = 0;
@@ -1566,19 +1565,19 @@ static int initialize_global (slang_assembly_file *file, slang_machine *pmach,
if (!result)
return 0;
- if (!slang_assembly_file_push (file, slang_asm_exit))
+ if (!slang_assembly_file_push (A->file, slang_asm_exit))
return 0;
/* execute the expression */
- if (!_slang_execute2 (file, &mach))
+ if (!_slang_execute2 (A->file, &mach))
return 0;
/* restore the old assembly */
- if (!slang_assembly_file_restore_point_load (file, &point))
+ if (!slang_assembly_file_restore_point_load (A->file, &point))
return 0;
/* now we copy the contents of the initialized variable back to the original machine */
- _mesa_memcpy ((GLubyte *) pmach->mem + var->address, (GLubyte *) mach.mem + var->address,
+ _mesa_memcpy ((GLubyte *) A->mach->mem + var->address, (GLubyte *) mach.mem + var->address,
var->size);
return 1;
@@ -1728,12 +1727,15 @@ static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O,
/* initialize global variable */
if (C->global_scope && var->initializer != NULL)
{
- slang_assembly_name_space space;
-
- space.funcs = O->funs;
- space.structs = O->structs;
- space.vars = O->vars;
- if (!initialize_global (O->assembly, O->machine, &space, var, C->atoms))
+ slang_assemble_ctx A;
+
+ A.file = O->assembly;
+ A.mach = O->machine;
+ A.atoms = C->atoms;
+ A.space.funcs = O->funs;
+ A.space.structs = O->structs;
+ A.space.vars = O->vars;
+ if (!initialize_global (&A, var))
return 0;
}
return 1;
@@ -1783,7 +1785,7 @@ static int parse_function (slang_parse_ctx *C, slang_output_ctx *O, int definiti
return 0;
}
}
-/* else
+ else
{
if (!parse_function_prototype (C, O, &parsed_func))
{
@@ -1813,45 +1815,48 @@ static int parse_function (slang_parse_ctx *C, slang_output_ctx *O, int definiti
/* return the newly parsed function */
*parsed_func_ret = &O->funs->functions[O->funs->num_functions - 1];
}
-/* else
+ else
{
/* TODO: check function return type qualifiers and specifiers */
-/* if (definition)
- {
- /* destroy the existing function declaration and replace it with the new one */
-/* if (found_func->body != NULL)
+ if (definition)
+ {
+ if (found_func->body != NULL)
{
slang_info_log_error (C->L, "%s: function already has a body",
- parsed_func.header.name);
+ slang_atom_pool_id (C->atoms, parsed_func.header.a_name));
slang_function_destruct (&parsed_func);
return 0;
- }
+ }
+
+ /* destroy the existing function declaration and replace it with the new one,
+ * remember to save the fixup table */
+ parsed_func.fixups = found_func->fixups;
+ slang_fixup_table_init (&found_func->fixups);
slang_function_destruct (found_func);
*found_func = parsed_func;
}
else
{
/* another declaration of the same function prototype - ignore it */
-/* slang_function_destruct (&parsed_func);
+ slang_function_destruct (&parsed_func);
}
/* return the found function */
-/* *parsed_func_ret = found_func;
+ *parsed_func_ret = found_func;
}
/* assemble the parsed function */
- if (definition)
{
- slang_assembly_name_space space;
-
- space.funcs = O->funs;
- space.structs = O->structs;
- space.vars = O->vars;
- if (!_slang_assemble_function (O->assembly, *parsed_func_ret, &space, O->machine, C->atoms))
- {
- const char *name = slang_atom_pool_id (C->atoms, (**parsed_func_ret).header.a_name);
+ slang_assemble_ctx A;
+
+ A.file = O->assembly;
+ A.mach = O->machine;
+ A.atoms = C->atoms;
+ A.space.funcs = O->funs;
+ A.space.structs = O->structs;
+ A.space.vars = O->vars;
+ if (!_slang_assemble_function (&A, *parsed_func_ret))
return 0;
- }
}
return 1;
}
diff --git a/src/mesa/shader/slang/slang_compile_function.c b/src/mesa/shader/slang/slang_compile_function.c
index d62b009e662..5edba72cf77 100644
--- a/src/mesa/shader/slang/slang_compile_function.c
+++ b/src/mesa/shader/slang/slang_compile_function.c
@@ -34,6 +34,20 @@
#include "slang_compile_operation.h"
#include "slang_compile_function.h"
+/* slang_fixup_table */
+
+void slang_fixup_table_init (slang_fixup_table *fix)
+{
+ fix->table = NULL;
+ fix->count = 0;
+}
+
+void slang_fixup_table_free (slang_fixup_table *fix)
+{
+ slang_alloc_free (fix->table);
+ slang_fixup_table_init (fix);
+}
+
/* slang_function */
int slang_function_construct (slang_function *func)
@@ -56,6 +70,7 @@ int slang_function_construct (slang_function *func)
func->param_count = 0;
func->body = NULL;
func->address = ~0;
+ slang_fixup_table_init (&func->fixups);
return 1;
}
@@ -69,6 +84,7 @@ void slang_function_destruct (slang_function *func)
slang_operation_destruct (func->body);
slang_alloc_free (func->body);
}
+ slang_fixup_table_free (&func->fixups);
}
/* slang_function_scope */
diff --git a/src/mesa/shader/slang/slang_compile_function.h b/src/mesa/shader/slang/slang_compile_function.h
index 59743dfc29e..d1208817cfa 100644
--- a/src/mesa/shader/slang/slang_compile_function.h
+++ b/src/mesa/shader/slang/slang_compile_function.h
@@ -36,6 +36,15 @@ typedef enum slang_function_kind_
slang_func_operator
} slang_function_kind;
+typedef struct slang_fixup_table_
+{
+ GLuint *table;
+ GLuint count;
+} slang_fixup_table;
+
+void slang_fixup_table_init (slang_fixup_table *);
+void slang_fixup_table_free (slang_fixup_table *);
+
typedef struct slang_function_
{
slang_function_kind kind;
@@ -44,6 +53,7 @@ typedef struct slang_function_
unsigned int param_count;
slang_operation *body;
unsigned int address;
+ slang_fixup_table fixups;
} slang_function;
int slang_function_construct (slang_function *);