mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-03 20:48:08 +02:00
Lots of assorted changes.
Implement assignment/move for types larger than 4 floats. Fix codegen bug for "return expr" in inlined functions. More clean-up of storage allocation code (slang_resolve_storage).
This commit is contained in:
parent
6579245800
commit
bfc02dd30f
7 changed files with 243 additions and 155 deletions
|
|
@ -242,6 +242,12 @@ typedef struct slang_assembly_name_space_
|
|||
struct slang_variable_scope_ *vars;
|
||||
} slang_assembly_name_space;
|
||||
|
||||
|
||||
typedef struct {
|
||||
GLboolean TempUsed[MAX_PROGRAM_TEMPS];
|
||||
} slang_gen_context;
|
||||
|
||||
|
||||
typedef struct slang_assemble_ctx_
|
||||
{
|
||||
slang_assembly_file *file;
|
||||
|
|
@ -253,6 +259,7 @@ typedef struct slang_assemble_ctx_
|
|||
slang_ref_type ref;
|
||||
slang_swizzle swz;
|
||||
struct gl_program *program;
|
||||
slang_gen_context *codegen;
|
||||
} slang_assemble_ctx;
|
||||
|
||||
extern struct slang_function_ *
|
||||
|
|
|
|||
|
|
@ -53,37 +53,6 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper);
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* Allocate storage for given variable, attach it to 'ir'.
|
||||
*/
|
||||
static GLboolean
|
||||
slang_alloc_var_storage(slang_variable *variable, slang_ir_node *ir)
|
||||
{
|
||||
slang_ir_storage *store;
|
||||
|
||||
assert(variable);
|
||||
|
||||
/*assert(!variable->aux);*/
|
||||
|
||||
if (variable->aux) {
|
||||
store = (slang_ir_storage *) variable->aux;
|
||||
ir->Store = store;
|
||||
if (store)
|
||||
store->Size = -12;
|
||||
}
|
||||
else {
|
||||
/* alloc storage */
|
||||
store = (slang_ir_storage *) _mesa_calloc(sizeof(*store));
|
||||
store->File = PROGRAM_TEMPORARY;
|
||||
store->Index = -1;
|
||||
store->Size = -10;
|
||||
variable->aux = store;
|
||||
ir->Store = store;
|
||||
}
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
static slang_ir_node *
|
||||
new_node(slang_ir_opcode op, slang_ir_node *left, slang_ir_node *right)
|
||||
{
|
||||
|
|
@ -180,7 +149,7 @@ new_var(slang_assemble_ctx *A, slang_operation *oper,
|
|||
oper->var = v;
|
||||
n->Swizzle = swizzle;
|
||||
n->Var = v;
|
||||
slang_resolve_storage(NULL, n, A->program);
|
||||
slang_resolve_storage(A->codegen/**NULL**/, n, A->program);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
|
@ -221,15 +190,30 @@ slang_is_writemask(const char *field, GLuint *mask)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Assemble a "return" statement.
|
||||
*/
|
||||
static slang_ir_node *
|
||||
slang_assemble_return(slang_assemble_ctx * A, slang_operation *oper)
|
||||
{
|
||||
if (oper->num_children == 0) {
|
||||
/* Convert to:
|
||||
if (oper->num_children == 0 ||
|
||||
(oper->num_children == 1 &&
|
||||
oper->children[0].type == slang_oper_void)) {
|
||||
/* Convert from:
|
||||
* return;
|
||||
* To:
|
||||
* goto __endOfFunction;
|
||||
*/
|
||||
oper->type = slang_oper_goto;
|
||||
oper->a_id = slang_atom_pool_atom(A->atoms, CurFunction->end_label);
|
||||
slang_ir_node *n;
|
||||
slang_operation gotoOp;
|
||||
slang_operation_construct(&gotoOp);
|
||||
gotoOp.type = slang_oper_goto;
|
||||
gotoOp.a_id = slang_atom_pool_atom(A->atoms, CurFunction->end_label);
|
||||
/* assemble the new code */
|
||||
n = slang_assemble_operation(A, &gotoOp);
|
||||
/* destroy temp code */
|
||||
slang_operation_destruct(&gotoOp);
|
||||
return n;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
|
|
@ -241,11 +225,12 @@ slang_assemble_return(slang_assemble_ctx * A, slang_operation *oper)
|
|||
*/
|
||||
slang_operation *block, *assign, *jump;
|
||||
slang_atom a_retVal;
|
||||
slang_ir_node *n;
|
||||
|
||||
a_retVal = slang_atom_pool_atom(A->atoms, "__retVal");
|
||||
assert(a_retVal);
|
||||
|
||||
#if 1
|
||||
#if 1 /* DEBUG */
|
||||
{
|
||||
slang_variable *v
|
||||
= _slang_locate_variable(oper->locals, a_retVal, GL_TRUE);
|
||||
|
|
@ -266,17 +251,13 @@ slang_assemble_return(slang_assemble_ctx * A, slang_operation *oper)
|
|||
assign->locals->outer_scope = block->locals;
|
||||
assign->num_children = 2;
|
||||
assign->children = slang_operation_new(2);
|
||||
/* lhs */
|
||||
/* lhs (__retVal) */
|
||||
assign->children[0].type = slang_oper_identifier;
|
||||
assign->children[0].a_id = a_retVal;
|
||||
assign->children[0].locals->outer_scope = assign->locals;
|
||||
/* rhs */
|
||||
#if 0
|
||||
assign->children[1] = oper->children[0]; /* XXX copy */
|
||||
#else
|
||||
/* rhs (expr) */
|
||||
/* XXX we might be able to avoid this copy someday */
|
||||
slang_operation_copy(&assign->children[1], &oper->children[0]);
|
||||
#endif
|
||||
|
||||
|
||||
/* child[1]: goto __endOfFunction */
|
||||
jump = &block->children[1];
|
||||
|
|
@ -284,17 +265,16 @@ slang_assemble_return(slang_assemble_ctx * A, slang_operation *oper)
|
|||
assert(CurFunction->end_label);
|
||||
jump->a_id = slang_atom_pool_atom(A->atoms, CurFunction->end_label);
|
||||
|
||||
#if 00
|
||||
#if 0 /* debug */
|
||||
printf("NEW RETURN:\n");
|
||||
slang_print_tree(block, 0);
|
||||
#endif
|
||||
|
||||
slang_operation_copy(oper, block);
|
||||
/* XXX destruct block */
|
||||
/* assemble the new code */
|
||||
n = slang_assemble_operation(A, block);
|
||||
slang_operation_delete(block);
|
||||
return n;
|
||||
}
|
||||
|
||||
/* assemble the new code */
|
||||
return slang_assemble_operation(A, oper);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -426,28 +406,37 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper,
|
|||
}
|
||||
}
|
||||
break;
|
||||
#if 0 /* XXX rely on default case below */
|
||||
case slang_oper_return:
|
||||
/* do return replacement here too */
|
||||
slang_assemble_return(A, oper);
|
||||
slang_substitute(A, oper, substCount, substOld, substNew, GL_FALSE);
|
||||
assert(oper->num_children == 0 || oper->num_children == 1);
|
||||
if (oper->num_children == 1) {
|
||||
slang_substitute(A, &oper->children[0],
|
||||
substCount, substOld, substNew, GL_FALSE);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case slang_oper_assign:
|
||||
case slang_oper_subscript:
|
||||
/* special case:
|
||||
* child[0] can't have substitutions but child[1] can.
|
||||
*/
|
||||
slang_substitute(A, &oper->children[0], substCount, substOld, substNew, GL_TRUE);
|
||||
slang_substitute(A, &oper->children[1], substCount, substOld, substNew, GL_FALSE);
|
||||
slang_substitute(A, &oper->children[0],
|
||||
substCount, substOld, substNew, GL_TRUE);
|
||||
slang_substitute(A, &oper->children[1],
|
||||
substCount, substOld, substNew, GL_FALSE);
|
||||
break;
|
||||
case slang_oper_field:
|
||||
/* XXX NEW - test */
|
||||
slang_substitute(A, &oper->children[0], substCount, substOld, substNew, GL_TRUE);
|
||||
slang_substitute(A, &oper->children[0],
|
||||
substCount, substOld, substNew, GL_TRUE);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
GLuint i;
|
||||
for (i = 0; i < oper->num_children; i++)
|
||||
slang_substitute(A, &oper->children[i], substCount, substOld, substNew, GL_FALSE);
|
||||
slang_substitute(A, &oper->children[i],
|
||||
substCount, substOld, substNew, GL_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1015,11 +1004,10 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper)
|
|||
|
||||
assert(oper->num_children == 0 || oper->num_children == 1);
|
||||
|
||||
v = _slang_locate_variable(oper->locals,
|
||||
oper->a_id, GL_TRUE);
|
||||
v = _slang_locate_variable(oper->locals, oper->a_id, GL_TRUE);
|
||||
assert(v);
|
||||
varDecl = new_var_decl(A, v);
|
||||
slang_alloc_var_storage(v, varDecl);
|
||||
slang_resolve_storage(A->codegen, varDecl, A->program);
|
||||
|
||||
if (oper->num_children > 0) {
|
||||
/* child is initializer */
|
||||
|
|
@ -1027,18 +1015,26 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper)
|
|||
assert(oper->num_children == 1);
|
||||
var = new_var(A, oper, oper->a_id, SWIZZLE_NOOP);
|
||||
/* XXX make copy of this initializer? */
|
||||
/*
|
||||
printf("\n*** ASSEMBLE INITIALIZER %p\n", (void*) v->initializer);
|
||||
*/
|
||||
rhs = slang_assemble_operation(A, &oper->children[0]);
|
||||
init = new_node(IR_MOVE, var, rhs);
|
||||
/*assert(rhs->Opcode != IR_SEQ);*/
|
||||
n = new_seq(varDecl, init);
|
||||
}
|
||||
else if (v->initializer) {
|
||||
slang_ir_node *var, *init, *rhs;
|
||||
var = new_var(A, oper, oper->a_id, SWIZZLE_NOOP);
|
||||
/* XXX make copy of this initializer? */
|
||||
/*
|
||||
printf("\n*** ASSEMBLE INITIALIZER %p\n", (void*) v->initializer);
|
||||
*/
|
||||
rhs = slang_assemble_operation(A, v->initializer);
|
||||
init = new_node(IR_MOVE, var, rhs);
|
||||
/*
|
||||
assert(rhs->Opcode != IR_SEQ);
|
||||
*/
|
||||
n = new_seq(varDecl, init);
|
||||
}
|
||||
else {
|
||||
|
|
@ -1056,10 +1052,9 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper)
|
|||
oper->children[1].type == slang_oper_call) {
|
||||
/* special case */
|
||||
slang_ir_node *n;
|
||||
printf(">>>>>>>>>>>>>> Assign function call\n");
|
||||
n = slang_assemble_function_call_name(A,
|
||||
(const char *) oper->children[1].a_id,
|
||||
&oper->children[1], &oper->children[0]);
|
||||
(const char *) oper->children[1].a_id,
|
||||
&oper->children[1], &oper->children[0]);
|
||||
return n;
|
||||
}
|
||||
else
|
||||
|
|
@ -1077,6 +1072,9 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper)
|
|||
c1 = slang_assemble_operation(A, &oper->children[1]);
|
||||
|
||||
n = new_node(IR_MOVE, c0, c1);
|
||||
/*
|
||||
assert(c1->Opcode != IR_SEQ);
|
||||
*/
|
||||
n->Writemask = mask;
|
||||
return n;
|
||||
}
|
||||
|
|
@ -1148,33 +1146,29 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper)
|
|||
/* array dereference */
|
||||
if (oper->children[1].type == slang_oper_literal_int) {
|
||||
/* compile-time constant index - OK */
|
||||
slang_assembly_typeinfo ti;
|
||||
slang_assembly_typeinfo elem_ti;
|
||||
slang_ir_node *base;
|
||||
slang_ir_storage *store2;
|
||||
GLint index;
|
||||
slang_assembly_typeinfo_construct(&ti);
|
||||
_slang_typeof_operation(A, &oper->children[0], &ti);
|
||||
|
||||
/* get type of array element */
|
||||
slang_assembly_typeinfo_construct(&elem_ti);
|
||||
_slang_typeof_operation(A, oper, &elem_ti);
|
||||
|
||||
base = slang_assemble_operation(A, &oper->children[0]);
|
||||
assert(base->Opcode == IR_VAR);
|
||||
assert(base->Store);
|
||||
|
||||
index = (GLint) oper->children[1].literal[0];
|
||||
/*
|
||||
printf("element[%d]\n", index);
|
||||
*/
|
||||
#if 1
|
||||
store2 = (slang_ir_storage *) _mesa_calloc(sizeof(*store2));
|
||||
*store2 = *base->Store;
|
||||
base->Store = store2;
|
||||
base->Store->Size = -15;
|
||||
#endif
|
||||
assert(base->Store);
|
||||
/*printf("element[%d]\n", index);*/
|
||||
/* new storage info since we don't want to change the original */
|
||||
base->Store = _slang_clone_ir_storage(base->Store);
|
||||
/* bias Index by array subscript, update storage size */
|
||||
base->Store->Index += index;
|
||||
base->Store->Size = 1;
|
||||
base->Store->Size = _slang_sizeof_type_specifier(&elem_ti.spec);
|
||||
return base;
|
||||
}
|
||||
else {
|
||||
/* run-time index - TBD */
|
||||
/* run-time index - not supported yet - TBD */
|
||||
abort();
|
||||
}
|
||||
return NULL;
|
||||
|
|
@ -1192,6 +1186,7 @@ slang_assemble_operation(slang_assemble_ctx * A, slang_operation *oper)
|
|||
slang_ir_node *one = new_float_literal(1.0, 1.0, 1.0, 1.0);
|
||||
slang_ir_node *sum = new_node(IR_ADD, var, one);
|
||||
slang_ir_node *assign = new_node(IR_MOVE, var, sum);
|
||||
assert(sum->Opcode != IR_SEQ);
|
||||
return assign;
|
||||
}
|
||||
break;
|
||||
|
|
@ -1233,12 +1228,13 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun)
|
|||
return 0;
|
||||
|
||||
printf("\n*********** Assemble function2(%s)\n", (char*)fun->header.a_name);
|
||||
#if 0
|
||||
#if 1
|
||||
slang_print_function(fun, 1);
|
||||
#endif
|
||||
|
||||
A->program->Parameters = _mesa_new_parameter_list();
|
||||
A->program->Varying = _mesa_new_parameter_list();
|
||||
A->codegen = _slang_new_codegen_context();
|
||||
|
||||
/*printf("** Begin Simplify\n");*/
|
||||
slang_simplify(fun->body, &A->space, A->atoms);
|
||||
|
|
@ -1246,11 +1242,11 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun)
|
|||
|
||||
CurFunction = fun;
|
||||
|
||||
n = slang_assemble_operation(A, fun->body);
|
||||
|
||||
if (!CurFunction->end_label)
|
||||
CurFunction->end_label = slang_atom_pool_gen(A->atoms, "__endOfFunction_Main");
|
||||
|
||||
n = slang_assemble_operation(A, fun->body);
|
||||
|
||||
endLabel = new_label(fun->end_label);
|
||||
n = new_seq(n, endLabel);
|
||||
|
||||
|
|
@ -1263,14 +1259,13 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun)
|
|||
|
||||
printf("************* IR for %s *******\n", (char*)fun->header.a_name);
|
||||
slang_print_ir(n, 0);
|
||||
printf("************* End assemble function2 ************\n\n");
|
||||
#endif
|
||||
|
||||
if (_mesa_strcmp((char*) fun->header.a_name, "main") == 0) {
|
||||
_slang_emit_code(n, A->program);
|
||||
_slang_emit_code(n, A->codegen, A->program);
|
||||
}
|
||||
|
||||
printf("************* End assemble function2 ************\n\n");
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -135,6 +135,17 @@ slang_operation_new(GLuint count)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete operation and all children
|
||||
*/
|
||||
void
|
||||
slang_operation_delete(slang_operation *oper)
|
||||
{
|
||||
slang_operation_destruct(oper);
|
||||
_mesa_free(oper);
|
||||
}
|
||||
|
||||
|
||||
slang_operation *
|
||||
slang_operation_grow(GLuint *numChildren, slang_operation **children)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -138,6 +138,9 @@ slang_operation_copy(slang_operation *, const slang_operation *);
|
|||
extern slang_operation *
|
||||
slang_operation_new(GLuint count);
|
||||
|
||||
extern void
|
||||
slang_operation_delete(slang_operation *oper);
|
||||
|
||||
extern slang_operation *
|
||||
slang_operation_grow(GLuint *numChildren, slang_operation **children);
|
||||
|
||||
|
|
|
|||
|
|
@ -130,6 +130,15 @@ _slang_new_ir_storage(enum register_file file, GLint index, GLint size)
|
|||
}
|
||||
|
||||
|
||||
slang_ir_storage *
|
||||
_slang_clone_ir_storage(slang_ir_storage *store)
|
||||
{
|
||||
slang_ir_storage *clone
|
||||
= _slang_new_ir_storage(store->File, store->Index, store->Size);
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
swizzle_string(GLuint swizzle)
|
||||
{
|
||||
|
|
@ -194,10 +203,10 @@ sizeof_struct(const slang_struct *s)
|
|||
}
|
||||
|
||||
|
||||
static GLuint
|
||||
sizeof_type(const slang_fully_specified_type *t)
|
||||
GLuint
|
||||
_slang_sizeof_type_specifier(const slang_type_specifier *spec)
|
||||
{
|
||||
switch (t->specifier.type) {
|
||||
switch (spec->type) {
|
||||
case slang_spec_void:
|
||||
abort();
|
||||
return 0;
|
||||
|
|
@ -240,7 +249,7 @@ sizeof_type(const slang_fully_specified_type *t)
|
|||
abort();
|
||||
return 0;
|
||||
case slang_spec_struct:
|
||||
return sizeof_struct(t->specifier._struct);
|
||||
return sizeof_struct(spec->_struct);
|
||||
case slang_spec_array:
|
||||
return 1; /* XXX */
|
||||
default:
|
||||
|
|
@ -251,6 +260,14 @@ sizeof_type(const slang_fully_specified_type *t)
|
|||
}
|
||||
|
||||
|
||||
|
||||
static GLuint
|
||||
sizeof_type(const slang_fully_specified_type *t)
|
||||
{
|
||||
return _slang_sizeof_type_specifier(&t->specifier);
|
||||
}
|
||||
|
||||
|
||||
#define IND 0
|
||||
void
|
||||
slang_print_ir(const slang_ir_node *n, int indent)
|
||||
|
|
@ -269,7 +286,7 @@ slang_print_ir(const slang_ir_node *n, int indent)
|
|||
switch (n->Opcode) {
|
||||
case IR_SEQ:
|
||||
#if IND
|
||||
printf("SEQ store %p\n", (void*) n->Store);
|
||||
printf("SEQ at %p\n", (void*) n);
|
||||
#endif
|
||||
assert(n->Children[0]);
|
||||
assert(n->Children[1]);
|
||||
|
|
@ -325,12 +342,22 @@ slang_print_ir(const slang_ir_node *n, int indent)
|
|||
|
||||
|
||||
static GLint
|
||||
alloc_temporary(slang_gen_context *gc)
|
||||
alloc_temporary(slang_gen_context *gc, GLint size)
|
||||
{
|
||||
GLuint i;
|
||||
const GLuint sz4 = (size + 3) / 4;
|
||||
GLuint i, j;
|
||||
ASSERT(size > 0); /* number of floats */
|
||||
for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
|
||||
if (!gc->TempUsed[i]) {
|
||||
gc->TempUsed[i] = GL_TRUE;
|
||||
GLuint found = 0;
|
||||
for (j = 0; j < sz4; j++) {
|
||||
if (!gc->TempUsed[i + j]) {
|
||||
found++;
|
||||
}
|
||||
}
|
||||
if (found == sz4) {
|
||||
/* found block of size/4 free regs */
|
||||
for (j = 0; j < sz4; j++)
|
||||
gc->TempUsed[i + j] = GL_TRUE;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
|
@ -349,10 +376,14 @@ is_temporary(const slang_gen_context *gc, const slang_ir_storage *st)
|
|||
|
||||
|
||||
static void
|
||||
free_temporary(slang_gen_context *gc, GLuint r)
|
||||
free_temporary(slang_gen_context *gc, GLuint r, GLint size)
|
||||
{
|
||||
if (gc->TempUsed[r])
|
||||
gc->TempUsed[r] = GL_FALSE;
|
||||
const GLuint sz4 = (size + 3) / 4;
|
||||
GLuint i;
|
||||
for (i = 0; i < sz4; i++) {
|
||||
if (gc->TempUsed[r + i])
|
||||
gc->TempUsed[r + i] = GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -589,7 +620,7 @@ slang_alloc_temp_storage(slang_gen_context *gc, slang_ir_node *n, GLint size)
|
|||
assert(!n->Var);
|
||||
assert(!n->Store);
|
||||
assert(size > 0);
|
||||
indx = alloc_temporary(gc);
|
||||
indx = alloc_temporary(gc, size);
|
||||
n->Store = _slang_new_ir_storage(PROGRAM_TEMPORARY, indx, size);
|
||||
}
|
||||
|
||||
|
|
@ -609,9 +640,12 @@ void
|
|||
slang_resolve_storage(slang_gen_context *gc, slang_ir_node *n,
|
||||
struct gl_program *prog)
|
||||
{
|
||||
int k = 0;
|
||||
assert(gc);
|
||||
assert(n);
|
||||
assert(prog);
|
||||
|
||||
if (!n->Store) {
|
||||
/**assert(n->Var);**/
|
||||
/* allocate storage info for this node */
|
||||
if (n->Var && n->Var->aux) {
|
||||
/* node storage info = var storage info */
|
||||
n->Store = (slang_ir_storage *) n->Var->aux;
|
||||
|
|
@ -619,21 +653,19 @@ slang_resolve_storage(slang_gen_context *gc, slang_ir_node *n,
|
|||
else {
|
||||
/* alloc new storage info */
|
||||
n->Store = _slang_new_ir_storage(PROGRAM_UNDEFINED, -1, -5);
|
||||
k = 1;
|
||||
/*XXX n->Store->Size = sizeof(var's type) */
|
||||
if (n->Var)
|
||||
n->Var->aux = n->Store;
|
||||
}
|
||||
}
|
||||
|
||||
if (n->Opcode == IR_VAR_DECL) {
|
||||
/* allocate storage for a user's variable */
|
||||
/* storage declaration */
|
||||
assert(n->Var);
|
||||
if (n->Store->Index < 0) {
|
||||
if (n->Store->Index < 0) { /* XXX assert this? */
|
||||
assert(gc);
|
||||
n->Store->File = PROGRAM_TEMPORARY;
|
||||
n->Store->Index = alloc_temporary(gc);
|
||||
n->Store->Size = sizeof_type(&n->Var->type);
|
||||
n->Store->Index = alloc_temporary(gc, n->Store->Size);
|
||||
printf("alloc var %s storage at %d (size %d)\n",
|
||||
(char *) n->Var->a_name,
|
||||
n->Store->Index,
|
||||
|
|
@ -641,6 +673,7 @@ slang_resolve_storage(slang_gen_context *gc, slang_ir_node *n,
|
|||
assert(n->Store->Size > 0);
|
||||
n->Var->declared = GL_TRUE;
|
||||
}
|
||||
assert(n->Store->Size > 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -649,7 +682,12 @@ slang_resolve_storage(slang_gen_context *gc, slang_ir_node *n,
|
|||
GLint i;
|
||||
|
||||
assert(n->Var);
|
||||
assert(prog);
|
||||
|
||||
if (n->Store->Size < 0) {
|
||||
/* determine var/storage size now */
|
||||
n->Store->Size = sizeof_type(&n->Var->type);
|
||||
assert(n->Store->Size > 0);
|
||||
}
|
||||
|
||||
#if 0
|
||||
assert(n->Var->declared ||
|
||||
|
|
@ -665,7 +703,6 @@ slang_resolve_storage(slang_gen_context *gc, slang_ir_node *n,
|
|||
if (i >= 0) {
|
||||
n->Store->File = PROGRAM_INPUT;
|
||||
n->Store->Index = i;
|
||||
n->Store->Size = sizeof_type(&n->Var->type);
|
||||
assert(n->Store->Size > 0);
|
||||
prog->InputsRead |= (1 << i);
|
||||
return;
|
||||
|
|
@ -675,7 +712,6 @@ slang_resolve_storage(slang_gen_context *gc, slang_ir_node *n,
|
|||
if (i >= 0) {
|
||||
n->Store->File = PROGRAM_OUTPUT;
|
||||
n->Store->Index = i;
|
||||
n->Store->Size = sizeof_type(&n->Var->type);
|
||||
prog->OutputsWritten |= (1 << i);
|
||||
return;
|
||||
}
|
||||
|
|
@ -684,7 +720,6 @@ slang_resolve_storage(slang_gen_context *gc, slang_ir_node *n,
|
|||
if (i >= 0) {
|
||||
n->Store->File = PROGRAM_STATE_VAR;
|
||||
n->Store->Index = i;
|
||||
n->Store->Size = sizeof_type(&n->Var->type);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -692,7 +727,6 @@ slang_resolve_storage(slang_gen_context *gc, slang_ir_node *n,
|
|||
if (i >= 0) {
|
||||
n->Store->File = PROGRAM_CONSTANT;
|
||||
n->Store->Index = i;
|
||||
n->Store->Size = sizeof_type(&n->Var->type);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -702,7 +736,6 @@ slang_resolve_storage(slang_gen_context *gc, slang_ir_node *n,
|
|||
if (i >= 0) {
|
||||
n->Store->File = PROGRAM_UNIFORM;
|
||||
n->Store->Index = i;
|
||||
n->Store->Size = sizeof_type(&n->Var->type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -717,27 +750,17 @@ slang_resolve_storage(slang_gen_context *gc, slang_ir_node *n,
|
|||
#else
|
||||
n->Store->File = PROGRAM_VARYING;
|
||||
#endif
|
||||
n->Store->Size = sizeof_type(&n->Var->type);
|
||||
n->Store->Index = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* what is this?!? */
|
||||
/*
|
||||
abort();
|
||||
*/
|
||||
}
|
||||
|
||||
if (n->Store->File == PROGRAM_TEMPORARY && n->Store->Index < 0) {
|
||||
/* unnamed intermediate temporary */
|
||||
if (gc)
|
||||
n->Store->Index = alloc_temporary(gc);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gc && n->Store->File == PROGRAM_UNDEFINED && n->Store->Size < 0) {
|
||||
abort();
|
||||
if (n->Store->File == PROGRAM_UNDEFINED && n->Store->Index < 0) {
|
||||
/* ordinary local var */
|
||||
assert(n->Store->Size > 0);
|
||||
n->Store->File = PROGRAM_TEMPORARY;
|
||||
n->Store->Index = alloc_temporary(gc, n->Store->Size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -755,6 +778,7 @@ alloc_constant(const GLfloat v[], GLuint size, struct gl_program *prog)
|
|||
/**
|
||||
* Swizzle a swizzle.
|
||||
*/
|
||||
#if 0
|
||||
static GLuint
|
||||
swizzle_compose(GLuint swz1, GLuint swz2)
|
||||
{
|
||||
|
|
@ -766,6 +790,7 @@ swizzle_compose(GLuint swz1, GLuint swz2)
|
|||
swz = MAKE_SWIZZLE4(s[0], s[1], s[2], s[3]);
|
||||
return swz;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -783,6 +808,7 @@ storage_to_dst_reg(struct prog_dst_register *dst, const slang_ir_storage *st,
|
|||
};
|
||||
dst->File = st->File;
|
||||
dst->Index = st->Index;
|
||||
assert(st->File != PROGRAM_UNDEFINED);
|
||||
assert(st->Size >= 1);
|
||||
assert(st->Size <= 4);
|
||||
dst->WriteMask = defaultWritemask[st->Size - 1] & writemask;
|
||||
|
|
@ -805,6 +831,7 @@ storage_to_src_reg(struct prog_src_register *src, const slang_ir_storage *st,
|
|||
|
||||
src->File = st->File;
|
||||
src->Index = st->Index;
|
||||
assert(st->File != PROGRAM_UNDEFINED);
|
||||
assert(st->Size >= 1);
|
||||
assert(st->Size <= 4);
|
||||
/* XXX swizzling logic here may need some work */
|
||||
|
|
@ -945,7 +972,8 @@ gen(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
|
|||
* Just modify the RHS to put its result into the dest of this
|
||||
* MOVE operation. Then, this MOVE is a no-op.
|
||||
*/
|
||||
free_temporary(gc, n->Children[1]->Store->Index);
|
||||
free_temporary(gc, n->Children[1]->Store->Index,
|
||||
n->Children[1]->Store->Size);
|
||||
*n->Children[1]->Store = *n->Children[0]->Store;
|
||||
/* fixup the prev (RHS) instruction */
|
||||
storage_to_dst_reg(&inst->DstReg, n->Children[0]->Store, n->Writemask);
|
||||
|
|
@ -954,14 +982,40 @@ gen(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
|
|||
else
|
||||
#endif
|
||||
{
|
||||
inst = new_instruction(prog, OPCODE_MOV);
|
||||
storage_to_dst_reg(&inst->DstReg, n->Children[0]->Store, n->Writemask);
|
||||
storage_to_src_reg(&inst->SrcReg[0], n->Children[1]->Store,
|
||||
n->Children[1]->Swizzle);
|
||||
if (n->Children[1]->Store->File == PROGRAM_TEMPORARY) {
|
||||
free_temporary(gc, n->Children[1]->Store->Index);
|
||||
#if 1
|
||||
if (n->Children[0]->Store->Size > 4) {
|
||||
/* move matrix/struct etc */
|
||||
slang_ir_storage dstStore = *n->Children[0]->Store;
|
||||
slang_ir_storage srcStore = *n->Children[1]->Store;
|
||||
GLint size = srcStore.Size;
|
||||
ASSERT(n->Children[0]->Writemask == WRITEMASK_XYZW);
|
||||
ASSERT(n->Children[1]->Swizzle == SWIZZLE_NOOP);
|
||||
dstStore.Size = 4;
|
||||
srcStore.Size = 4;
|
||||
while (size >= 4) {
|
||||
inst = new_instruction(prog, OPCODE_MOV);
|
||||
inst->Comment = _mesa_strdup("IR_MOVE block");
|
||||
storage_to_dst_reg(&inst->DstReg, &dstStore, n->Writemask);
|
||||
storage_to_src_reg(&inst->SrcReg[0], &srcStore,
|
||||
n->Children[1]->Swizzle);
|
||||
srcStore.Index++;
|
||||
dstStore.Index++;
|
||||
size -= 4;
|
||||
}
|
||||
}
|
||||
inst->Comment = n->Comment;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
inst = new_instruction(prog, OPCODE_MOV);
|
||||
storage_to_dst_reg(&inst->DstReg, n->Children[0]->Store, n->Writemask);
|
||||
storage_to_src_reg(&inst->SrcReg[0], n->Children[1]->Store,
|
||||
n->Children[1]->Swizzle);
|
||||
}
|
||||
if (n->Children[1]->Store->File == PROGRAM_TEMPORARY) {
|
||||
free_temporary(gc, n->Children[1]->Store->Index,
|
||||
n->Children[1]->Store->Size);
|
||||
}
|
||||
/*inst->Comment = _mesa_strdup("IR_MOVE");*/
|
||||
n->Store = n->Children[0]->Store; /*XXX new */
|
||||
return inst;
|
||||
}
|
||||
|
|
@ -1012,14 +1066,24 @@ gen(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
|
|||
}
|
||||
|
||||
|
||||
slang_gen_context *
|
||||
_slang_new_codegen_context(void)
|
||||
{
|
||||
slang_gen_context *gc = (slang_gen_context *) _mesa_calloc(sizeof(*gc));
|
||||
return gc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
GLboolean
|
||||
_slang_emit_code(slang_ir_node *n, struct gl_program *prog)
|
||||
_slang_emit_code(slang_ir_node *n, slang_gen_context *gc,
|
||||
struct gl_program *prog)
|
||||
{
|
||||
slang_gen_context *gc;
|
||||
/*GET_CURRENT_CONTEXT(ctx);*/
|
||||
|
||||
gc = (slang_gen_context *) _mesa_calloc(sizeof(*gc));
|
||||
/*
|
||||
gc = _slang_new_codegen_context();
|
||||
*/
|
||||
|
||||
printf("************ Begin generate code\n");
|
||||
|
||||
|
|
|
|||
|
|
@ -32,9 +32,8 @@
|
|||
#include "mtypes.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
GLboolean TempUsed[MAX_PROGRAM_TEMPS];
|
||||
} slang_gen_context;
|
||||
extern slang_gen_context *
|
||||
_slang_new_codegen_context(void);
|
||||
|
||||
|
||||
extern void
|
||||
|
|
@ -45,12 +44,21 @@ extern slang_ir_storage *
|
|||
_slang_new_ir_storage(enum register_file file, GLint index, GLint size);
|
||||
|
||||
|
||||
extern slang_ir_storage *
|
||||
_slang_clone_ir_storage(slang_ir_storage *store);
|
||||
|
||||
|
||||
extern GLuint
|
||||
_slang_sizeof_type_specifier(const slang_type_specifier *spec);
|
||||
|
||||
|
||||
extern void
|
||||
slang_resolve_storage(slang_gen_context *gc, slang_ir_node *n,
|
||||
struct gl_program *prog);
|
||||
|
||||
extern GLboolean
|
||||
_slang_emit_code(slang_ir_node *n, struct gl_program *prog);
|
||||
_slang_emit_code(slang_ir_node *n, slang_gen_context *gc,
|
||||
struct gl_program *prog);
|
||||
|
||||
|
||||
#endif /* SLANG_EMIT_H */
|
||||
|
|
|
|||
|
|
@ -320,18 +320,6 @@ _slang_link2(GLcontext *ctx,
|
|||
linked->FragmentProgram = (struct gl_fragment_program *)
|
||||
_mesa_clone_program(ctx, &fragProg->Base);
|
||||
|
||||
#if 1
|
||||
printf("************** orig fragment program\n");
|
||||
_mesa_print_program(&fragProg->Base);
|
||||
_mesa_print_program_parameters(ctx, &fragProg->Base);
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
printf("************** orig vertex program\n");
|
||||
_mesa_print_program(&vertProg->Base);
|
||||
_mesa_print_program_parameters(ctx, &fragProg->Base);
|
||||
#endif
|
||||
|
||||
link_varying_vars(linked, &linked->VertexProgram->Base);
|
||||
link_varying_vars(linked, &linked->FragmentProgram->Base);
|
||||
|
||||
|
|
@ -345,10 +333,22 @@ _slang_link2(GLcontext *ctx,
|
|||
linked->FragmentProgram->Base.Parameters = linked->Uniforms;
|
||||
|
||||
#if 1
|
||||
printf("************** linked/cloned frag prog\n");
|
||||
printf("************** original fragment program\n");
|
||||
_mesa_print_program(&fragProg->Base);
|
||||
_mesa_print_program_parameters(ctx, &fragProg->Base);
|
||||
#endif
|
||||
#if 1
|
||||
printf("************** linked fragment prog\n");
|
||||
_mesa_print_program(&linked->FragmentProgram->Base);
|
||||
_mesa_print_program_parameters(ctx, &linked->FragmentProgram->Base);
|
||||
printf("************** linked/cloned vert prog\n");
|
||||
#endif
|
||||
#if 1
|
||||
printf("************** original vertex program\n");
|
||||
_mesa_print_program(&vertProg->Base);
|
||||
_mesa_print_program_parameters(ctx, &fragProg->Base);
|
||||
#endif
|
||||
#if 1
|
||||
printf("************** linked vertex prog\n");
|
||||
_mesa_print_program(&linked->VertexProgram->Base);
|
||||
_mesa_print_program_parameters(ctx, &linked->VertexProgram->Base);
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue