Reimplement code for swizzling so that expressions like (p+q).x for vectors p and q works correctly.
This commit is contained in:
@@ -57,11 +57,13 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper);
|
||||
/**
|
||||
* Lookup a named constant and allocate storage for the parameter in
|
||||
* the given parameter list.
|
||||
* \param swizzleOut returns swizzle mask for accessing the constant
|
||||
* \return position of the constant in the paramList.
|
||||
*/
|
||||
static GLint
|
||||
slang_lookup_constant(const char *name, GLint index,
|
||||
struct gl_program_parameter_list *paramList)
|
||||
struct gl_program_parameter_list *paramList,
|
||||
GLuint *swizzleOut)
|
||||
{
|
||||
struct constant_info {
|
||||
const char *Name;
|
||||
@@ -82,7 +84,6 @@ slang_lookup_constant(const char *name, GLint index,
|
||||
{ NULL, 0 }
|
||||
};
|
||||
GLuint i;
|
||||
GLuint swizzle; /* XXX use this */
|
||||
|
||||
for (i = 0; info[i].Name; i++) {
|
||||
if (strcmp(info[i].Name, name) == 0) {
|
||||
@@ -92,7 +93,7 @@ slang_lookup_constant(const char *name, GLint index,
|
||||
_mesa_GetFloatv(info[i].Token, &value);
|
||||
ASSERT(value >= 0.0); /* sanity check that glGetFloatv worked */
|
||||
/* XXX named constant! */
|
||||
pos = _mesa_add_unnamed_constant(paramList, &value, 1, &swizzle);
|
||||
pos = _mesa_add_unnamed_constant(paramList, &value, 1, swizzleOut);
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
@@ -299,8 +300,10 @@ slang_allocate_storage(slang_assemble_ctx *A, slang_ir_node *n)
|
||||
n->Store->Index = i;
|
||||
}
|
||||
else if (n->Store->File == PROGRAM_CONSTANT) {
|
||||
GLint i = slang_lookup_constant(varName, 0, prog->Parameters);
|
||||
GLint i = slang_lookup_constant(varName, 0, prog->Parameters,
|
||||
&n->Store->Swizzle);
|
||||
assert(i >= 0);
|
||||
assert(n->Store->Size == 1);
|
||||
n->Store->Index = i;
|
||||
}
|
||||
}
|
||||
@@ -518,7 +521,6 @@ new_node(slang_ir_opcode op, slang_ir_node *left, slang_ir_node *right)
|
||||
n->Opcode = op;
|
||||
n->Children[0] = left;
|
||||
n->Children[1] = right;
|
||||
n->Swizzle = SWIZZLE_NOOP;
|
||||
n->Writemask = WRITEMASK_XYZW;
|
||||
}
|
||||
return n;
|
||||
@@ -544,11 +546,14 @@ new_label(slang_atom labName)
|
||||
static slang_ir_node *
|
||||
new_float_literal(float x, float y, float z, float w)
|
||||
{
|
||||
GLuint size = 4; /* XXX fix */
|
||||
slang_ir_node *n = new_node(IR_FLOAT, NULL, NULL);
|
||||
n->Value[0] = x;
|
||||
n->Value[1] = y;
|
||||
n->Value[2] = z;
|
||||
n->Value[3] = w;
|
||||
/* allocate a storage object, but compute actual location (Index) later */
|
||||
n->Store = _slang_new_ir_storage(PROGRAM_CONSTANT, -1, size);
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -583,7 +588,6 @@ new_jump(slang_atom target)
|
||||
static slang_ir_node *
|
||||
new_var(slang_assemble_ctx *A, slang_operation *oper, slang_atom name)
|
||||
{
|
||||
GLuint swizzle = SWIZZLE_NOOP;
|
||||
slang_variable *v = _slang_locate_variable(oper->locals, name, GL_TRUE);
|
||||
slang_ir_node *n = new_node(IR_VAR, NULL, NULL);
|
||||
if (!v) {
|
||||
@@ -592,10 +596,7 @@ new_var(slang_assemble_ctx *A, slang_operation *oper, slang_atom name)
|
||||
}
|
||||
assert(!oper->var || oper->var == v);
|
||||
v->used = GL_TRUE;
|
||||
|
||||
n->Swizzle = swizzle;
|
||||
n->Var = v;
|
||||
|
||||
slang_allocate_storage(A, n);
|
||||
|
||||
return n;
|
||||
@@ -667,7 +668,9 @@ slang_inline_asm_function(slang_assemble_ctx *A,
|
||||
slang_operation *inlined = slang_operation_new(1);
|
||||
|
||||
/*assert(oper->type == slang_oper_call); or vec4_add, etc */
|
||||
/*
|
||||
printf("Inline asm %s\n", (char*) fun->header.a_name);
|
||||
*/
|
||||
inlined->type = fun->body->children[0].type;
|
||||
inlined->a_id = fun->body->children[0].a_id;
|
||||
inlined->num_children = numArgs;
|
||||
@@ -871,9 +874,11 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
|
||||
substNew = (slang_operation **)
|
||||
_mesa_calloc(totalArgs * sizeof(slang_operation *));
|
||||
|
||||
#if 0
|
||||
printf("Inline call to %s (total vars=%d nparams=%d)\n",
|
||||
(char *) fun->header.a_name,
|
||||
fun->parameters->num_variables, numArgs);
|
||||
#endif
|
||||
|
||||
if (haveRetValue && !returnOper) {
|
||||
/* Create 3-child comma sequence for inlined code:
|
||||
@@ -1022,7 +1027,9 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
|
||||
slang_operation *decl = slang_operation_insert(&inlined->num_children,
|
||||
&inlined->children,
|
||||
numCopyIn);
|
||||
/*
|
||||
printf("COPY_IN %s from expr\n", (char*)p->a_name);
|
||||
*/
|
||||
decl->type = slang_oper_variable_decl;
|
||||
assert(decl->locals);
|
||||
decl->locals = fun->parameters;
|
||||
@@ -1073,13 +1080,12 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
|
||||
_mesa_free(substOld);
|
||||
_mesa_free(substNew);
|
||||
|
||||
#if 0
|
||||
printf("Done Inline call to %s (total vars=%d nparams=%d)\n",
|
||||
(char *) fun->header.a_name,
|
||||
fun->parameters->num_variables, numArgs);
|
||||
|
||||
/*
|
||||
slang_print_tree(top, 0);
|
||||
*/
|
||||
#endif
|
||||
return top;
|
||||
}
|
||||
|
||||
@@ -1123,7 +1129,6 @@ _slang_gen_function_call(slang_assemble_ctx *A, slang_function *fun,
|
||||
assert(inlined->locals);
|
||||
printf("*** Inlined code for call to %s:\n",
|
||||
(char*) fun->header.a_name);
|
||||
|
||||
slang_print_tree(oper, 10);
|
||||
printf("\n");
|
||||
#endif
|
||||
@@ -1204,11 +1209,15 @@ _slang_gen_asm(slang_assemble_ctx *A, slang_operation *oper,
|
||||
assert(info->NumParams <= 2);
|
||||
|
||||
if (info->NumParams == oper->num_children) {
|
||||
/* storage for result not specified */
|
||||
/* Storage for result is not specified.
|
||||
* Children[0], [1] are the operands.
|
||||
*/
|
||||
firstOperand = 0;
|
||||
}
|
||||
else {
|
||||
/* storage for result (child[0]) is specified */
|
||||
/* Storage for result (child[0]) is specified.
|
||||
* Children[1], [2] are the operands.
|
||||
*/
|
||||
firstOperand = 1;
|
||||
}
|
||||
|
||||
@@ -1229,9 +1238,9 @@ _slang_gen_asm(slang_assemble_ctx *A, slang_operation *oper,
|
||||
slang_ir_node *n0;
|
||||
|
||||
dest_oper = &oper->children[0];
|
||||
if (dest_oper->type == slang_oper_field) {
|
||||
while /*if*/ (dest_oper->type == slang_oper_field) {
|
||||
/* writemask */
|
||||
writemask = make_writemask((char*) dest_oper->a_id);
|
||||
writemask &= /*=*/make_writemask((char*) dest_oper->a_id);
|
||||
dest_oper = &dest_oper->children[0];
|
||||
}
|
||||
|
||||
@@ -1829,6 +1838,20 @@ _slang_gen_assignment(slang_assemble_ctx * A, slang_operation *oper)
|
||||
}
|
||||
|
||||
|
||||
static slang_ir_node *
|
||||
_slang_gen_swizzle(slang_ir_node *child, GLuint swizzle)
|
||||
{
|
||||
slang_ir_node *n = new_node(IR_SWIZZLE, child, NULL);
|
||||
if (n) {
|
||||
n->Store = _slang_new_ir_storage(child->Store->File,
|
||||
child->Store->Index,
|
||||
child->Store->Size);
|
||||
n->Store->Swizzle = swizzle;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate IR tree for referencing a field in a struct (or basic vector type)
|
||||
*/
|
||||
@@ -1845,28 +1868,35 @@ _slang_gen_field(slang_assemble_ctx * A, slang_operation *oper)
|
||||
const GLuint rows = _slang_type_dim(ti.spec.type);
|
||||
slang_swizzle swz;
|
||||
slang_ir_node *n;
|
||||
GLuint swizzle;
|
||||
if (!_slang_is_swizzle((char *) oper->a_id, rows, &swz)) {
|
||||
RETURN_ERROR("Bad swizzle", 0);
|
||||
}
|
||||
swizzle = MAKE_SWIZZLE4(swz.swizzle[0],
|
||||
swz.swizzle[1],
|
||||
swz.swizzle[2],
|
||||
swz.swizzle[3]);
|
||||
|
||||
n = _slang_gen_operation(A, &oper->children[0]);
|
||||
n->Swizzle = MAKE_SWIZZLE4(swz.swizzle[0],
|
||||
swz.swizzle[1],
|
||||
swz.swizzle[2],
|
||||
swz.swizzle[3]);
|
||||
/* create new parent node with swizzle */
|
||||
n = _slang_gen_swizzle(n, swizzle);
|
||||
return n;
|
||||
}
|
||||
else if (ti.spec.type == slang_spec_float) {
|
||||
const GLuint rows = 1;
|
||||
slang_swizzle swz;
|
||||
slang_ir_node *n;
|
||||
GLuint swizzle;
|
||||
if (!_slang_is_swizzle((char *) oper->a_id, rows, &swz)) {
|
||||
RETURN_ERROR("Bad swizzle", 0);
|
||||
}
|
||||
swizzle = MAKE_SWIZZLE4(swz.swizzle[0],
|
||||
swz.swizzle[1],
|
||||
swz.swizzle[2],
|
||||
swz.swizzle[3]);
|
||||
n = _slang_gen_operation(A, &oper->children[0]);
|
||||
n->Swizzle = MAKE_SWIZZLE4(swz.swizzle[0],
|
||||
swz.swizzle[1],
|
||||
swz.swizzle[2],
|
||||
swz.swizzle[3]);
|
||||
/* create new parent node with swizzle */
|
||||
n = _slang_gen_swizzle(n, swizzle);
|
||||
return n;
|
||||
}
|
||||
else {
|
||||
@@ -1904,7 +1934,8 @@ _slang_gen_subscript(slang_assemble_ctx * A, slang_operation *oper)
|
||||
n = _slang_gen_operation(A, &oper->children[0]);
|
||||
if (n) {
|
||||
/* use swizzle to access the element */
|
||||
n->Swizzle = SWIZZLE_X + index;
|
||||
n = _slang_gen_swizzle(n, SWIZZLE_X + index);
|
||||
/*n->Store = _slang_clone_ir_storage_swz(n->Store, */
|
||||
n->Writemask = WRITEMASK_X << index;
|
||||
}
|
||||
return n;
|
||||
@@ -2372,7 +2403,6 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
|
||||
/* Generate IR_MOVE instruction to initialize the variable */
|
||||
lhs = new_node(IR_VAR, NULL, NULL);
|
||||
lhs->Var = var;
|
||||
lhs->Swizzle = SWIZZLE_NOOP;
|
||||
lhs->Store = n->Store;
|
||||
|
||||
/* constant folding, etc */
|
||||
|
||||
@@ -101,6 +101,7 @@ static slang_ir_info IrInfo[] = {
|
||||
{ IR_FLOAT, "IR_FLOAT", 0, 0, 0 },
|
||||
{ IR_FIELD, "IR_FIELD", 0, 0, 0 },
|
||||
{ IR_ELEMENT, "IR_ELEMENT", 0, 0, 0 },
|
||||
{ IR_SWIZZLE, "IR_SWIZZLE", 0, 0, 0 },
|
||||
{ IR_NOP, NULL, OPCODE_NOP, 0, 0 }
|
||||
};
|
||||
|
||||
@@ -124,6 +125,24 @@ slang_ir_name(slang_ir_opcode opcode)
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Swizzle a swizzle.
|
||||
*/
|
||||
static GLuint
|
||||
swizzle_compose(GLuint swz1, GLuint swz2)
|
||||
{
|
||||
GLuint i, swz, s[4];
|
||||
for (i = 0; i < 4; i++) {
|
||||
GLuint c = GET_SWZ(swz1, i);
|
||||
s[i] = GET_SWZ(swz2, c);
|
||||
}
|
||||
swz = MAKE_SWIZZLE4(s[0], s[1], s[2], s[3]);
|
||||
return swz;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
slang_ir_storage *
|
||||
_slang_new_ir_storage(enum register_file file, GLint index, GLint size)
|
||||
{
|
||||
@@ -133,20 +152,12 @@ _slang_new_ir_storage(enum register_file file, GLint index, GLint size)
|
||||
st->File = file;
|
||||
st->Index = index;
|
||||
st->Size = size;
|
||||
st->Swizzle = SWIZZLE_NOOP;
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -257,7 +268,7 @@ slang_print_ir(const slang_ir_node *n, int indent)
|
||||
break;
|
||||
case IR_VAR:
|
||||
printf("VAR %s%s at %s store %p\n",
|
||||
(char *) n->Var->a_name, swizzle_string(n->Swizzle),
|
||||
(char *) n->Var->a_name, swizzle_string(n->Store->Swizzle),
|
||||
storage_string(n->Store), (void*) n->Store);
|
||||
break;
|
||||
case IR_VAR_DECL:
|
||||
@@ -270,7 +281,7 @@ slang_print_ir(const slang_ir_node *n, int indent)
|
||||
slang_print_ir(n->Children[0], indent+3);
|
||||
break;
|
||||
case IR_CALL:
|
||||
printf("ASMCALL %s(%d args)\n", n->Target, n->Swizzle);
|
||||
printf("ASMCALL %s(%d args)\n", n->Target, 0/*XXX*/);
|
||||
break;
|
||||
case IR_FLOAT:
|
||||
printf("FLOAT %f %f %f %f\n",
|
||||
@@ -279,9 +290,14 @@ slang_print_ir(const slang_ir_node *n, int indent)
|
||||
case IR_I_TO_F:
|
||||
printf("INT_TO_FLOAT %d\n", (int) n->Value[0]);
|
||||
break;
|
||||
case IR_SWIZZLE:
|
||||
printf("SWIZZLE %s of (store %p) \n",
|
||||
swizzle_string(n->Store->Swizzle), (void*) n->Store);
|
||||
slang_print_ir(n->Children[0], indent + 3);
|
||||
break;
|
||||
default:
|
||||
printf("%s (%p, %p)\n", slang_ir_name(n->Opcode),
|
||||
(void*) n->Children[0], (void*) n->Children[1]);
|
||||
printf("%s (%p, %p) (store %p)\n", slang_ir_name(n->Opcode),
|
||||
(void*) n->Children[0], (void*) n->Children[1], (void*) n->Store);
|
||||
slang_print_ir(n->Children[0], indent+3);
|
||||
slang_print_ir(n->Children[1], indent+3);
|
||||
}
|
||||
@@ -322,37 +338,6 @@ free_temp_storage(slang_var_table *vt, slang_ir_node *n)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Allocate storage for a floating point constant.
|
||||
*/
|
||||
static slang_ir_storage *
|
||||
alloc_constant(const GLfloat v[], GLuint size, struct gl_program *prog)
|
||||
{
|
||||
GLuint swizzle;
|
||||
GLint ind = _mesa_add_unnamed_constant(prog->Parameters, v, size, &swizzle);
|
||||
slang_ir_storage *st = _slang_new_ir_storage(PROGRAM_CONSTANT, ind, size);
|
||||
return st;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Swizzle a swizzle.
|
||||
*/
|
||||
#if 0
|
||||
static GLuint
|
||||
swizzle_compose(GLuint swz1, GLuint swz2)
|
||||
{
|
||||
GLuint i, swz, s[4];
|
||||
for (i = 0; i < 4; i++) {
|
||||
GLuint c = GET_SWZ(swz1, i);
|
||||
s[i] = GET_SWZ(swz2, c);
|
||||
}
|
||||
swz = MAKE_SWIZZLE4(s[0], s[1], s[2], s[3]);
|
||||
return swz;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Convert IR storage to an instruction dst register.
|
||||
*/
|
||||
@@ -366,6 +351,7 @@ storage_to_dst_reg(struct prog_dst_register *dst, const slang_ir_storage *st,
|
||||
WRITEMASK_X | WRITEMASK_Y | WRITEMASK_Z,
|
||||
WRITEMASK_X | WRITEMASK_Y | WRITEMASK_Z | WRITEMASK_W
|
||||
};
|
||||
assert(st->Index >= 0 && st->Index <= 16);
|
||||
dst->File = st->File;
|
||||
dst->Index = st->Index;
|
||||
assert(st->File != PROGRAM_UNDEFINED);
|
||||
@@ -388,7 +374,7 @@ storage_to_src_reg(struct prog_src_register *src, const slang_ir_storage *st,
|
||||
MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W),
|
||||
MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W)
|
||||
};
|
||||
|
||||
assert(st->File >= 0 && st->File <= 16);
|
||||
src->File = st->File;
|
||||
src->Index = st->Index;
|
||||
assert(st->File != PROGRAM_UNDEFINED);
|
||||
@@ -396,8 +382,8 @@ storage_to_src_reg(struct prog_src_register *src, const slang_ir_storage *st,
|
||||
assert(st->Size <= 4);
|
||||
/* XXX swizzling logic here may need some work */
|
||||
/*src->Swizzle = swizzle_compose(swizzle, defaultSwizzle[st->Size - 1]);*/
|
||||
if (swizzle != SWIZZLE_NOOP)
|
||||
src->Swizzle = swizzle;
|
||||
if (st->Swizzle != SWIZZLE_NOOP)
|
||||
src->Swizzle = st->Swizzle;
|
||||
else
|
||||
src->Swizzle = defaultSwizzle[st->Size - 1];
|
||||
}
|
||||
@@ -448,9 +434,9 @@ emit_binop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
|
||||
/* gen this instruction */
|
||||
inst = new_instruction(prog, info->InstOpcode);
|
||||
storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store,
|
||||
n->Children[0]->Swizzle);
|
||||
/**n->Children[0]->Swizzle*/0);
|
||||
storage_to_src_reg(&inst->SrcReg[1], n->Children[1]->Store,
|
||||
n->Children[1]->Swizzle);
|
||||
/**n->Children[1]->Swizzle*/0);
|
||||
free_temp_storage(vt, n->Children[0]);
|
||||
free_temp_storage(vt, n->Children[1]);
|
||||
|
||||
@@ -480,7 +466,7 @@ emit_unop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
|
||||
/* gen this instruction */
|
||||
inst = new_instruction(prog, info->InstOpcode);
|
||||
storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store,
|
||||
n->Children[0]->Swizzle);
|
||||
/**n->Children[0]->Swizzle*/0);
|
||||
free_temp_storage(vt, n->Children[0]);
|
||||
|
||||
if (!n->Store) {
|
||||
@@ -511,7 +497,7 @@ emit_negation(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
|
||||
inst = new_instruction(prog, OPCODE_MOV);
|
||||
storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
|
||||
storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store,
|
||||
n->Children[0]->Swizzle);
|
||||
/**n->Children[0]->Swizzle*/0);
|
||||
inst->SrcReg[0].NegateBase = NEGATE_XYZW;
|
||||
inst->Comment = n->Comment;
|
||||
return inst;
|
||||
@@ -574,7 +560,7 @@ emit_tex(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
|
||||
|
||||
/* Child[1] is the coord */
|
||||
storage_to_src_reg(&inst->SrcReg[0], n->Children[1]->Store,
|
||||
n->Children[1]->Swizzle);
|
||||
/**n->Children[1]->Swizzle*/0);
|
||||
|
||||
/* Child[0] is the sampler (a uniform which'll indicate the texture unit) */
|
||||
assert(n->Children[0]->Store);
|
||||
@@ -598,6 +584,8 @@ emit_move(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
|
||||
assert(n->Children[1]);
|
||||
inst = emit(vt, n->Children[1], prog);
|
||||
|
||||
assert(n->Children[1]->Store->Index >= 0);
|
||||
|
||||
/* lhs */
|
||||
emit(vt, n->Children[0], prog);
|
||||
|
||||
@@ -611,6 +599,8 @@ emit_move(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
|
||||
n->Children[1]->Store->Size);
|
||||
*n->Children[1]->Store = *n->Children[0]->Store;
|
||||
/* fixup the prev (RHS) instruction */
|
||||
assert(n->Children[0]->Store->Index >= 0);
|
||||
assert(n->Children[0]->Store->Index < 16);
|
||||
storage_to_dst_reg(&inst->DstReg, n->Children[0]->Store, n->Writemask);
|
||||
return inst;
|
||||
}
|
||||
@@ -623,7 +613,7 @@ emit_move(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
|
||||
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);
|
||||
ASSERT(n->Children[1]->Store->Swizzle == SWIZZLE_NOOP);
|
||||
dstStore.Size = 4;
|
||||
srcStore.Size = 4;
|
||||
while (size >= 4) {
|
||||
@@ -631,7 +621,7 @@ emit_move(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
|
||||
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);
|
||||
/**n->Children[1]->Swizzle*/0);
|
||||
srcStore.Index++;
|
||||
dstStore.Index++;
|
||||
size -= 4;
|
||||
@@ -639,9 +629,11 @@ emit_move(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
|
||||
}
|
||||
else {
|
||||
inst = new_instruction(prog, OPCODE_MOV);
|
||||
assert(n->Children[0]->Store->Index >= 0);
|
||||
assert(n->Children[0]->Store->Index < 16);
|
||||
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);
|
||||
/**n->Children[1]->Swizzle*/0);
|
||||
}
|
||||
/* XXX is this test correct? */
|
||||
if (_slang_is_temp(vt, n->Children[1]->Store->Index)) {
|
||||
@@ -680,7 +672,7 @@ emit_cond(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
|
||||
inst->CondUpdate = GL_TRUE;
|
||||
storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
|
||||
storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store,
|
||||
n->Children[0]->Swizzle);
|
||||
/**n->Children[0]->Swizzle*/0);
|
||||
_slang_free_temp(vt, n->Store->Index, n->Store->Size);
|
||||
return inst; /* XXX or null? */
|
||||
}
|
||||
@@ -726,6 +718,11 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
|
||||
/* a regular variable */
|
||||
_slang_add_variable(vt, n->Var);
|
||||
n->Store->Index = _slang_alloc_var(vt, n->Store->Size);
|
||||
/*
|
||||
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;
|
||||
@@ -762,6 +759,17 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
|
||||
}
|
||||
return NULL; /* no instruction */
|
||||
|
||||
case IR_SWIZZLE:
|
||||
/* swizzled storage access */
|
||||
(void) emit(vt, n->Children[0], prog);
|
||||
/* "pull-up" the child's storage info, applying our swizzle info */
|
||||
n->Store->File = n->Children[0]->Store->File;
|
||||
n->Store->Index = n->Children[0]->Store->Index;
|
||||
n->Store->Size = n->Children[0]->Store->Size;
|
||||
assert(n->Store->Index >= 0);
|
||||
/* XXX compose swizzles here!!! */
|
||||
return NULL;
|
||||
|
||||
/* Simple binary operators */
|
||||
case IR_ADD:
|
||||
case IR_SUB:
|
||||
@@ -798,8 +806,11 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)
|
||||
case IR_NEG:
|
||||
return emit_negation(vt, n, prog);
|
||||
case IR_FLOAT:
|
||||
n->Store = alloc_constant(n->Value, 4, prog); /*XXX fix size */
|
||||
break;
|
||||
/* find storage location for this float */
|
||||
n->Store->Index = _mesa_add_unnamed_constant(prog->Parameters, n->Value,
|
||||
4, &n->Store->Swizzle);
|
||||
assert(n->Store->Index >= 0);
|
||||
return NULL;
|
||||
|
||||
case IR_MOVE:
|
||||
return emit_move(vt, n, prog);
|
||||
|
||||
@@ -40,10 +40,6 @@ 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 GLboolean
|
||||
_slang_emit_code(slang_ir_node *n, slang_var_table *vartable,
|
||||
struct gl_program *prog, GLboolean withEnd);
|
||||
|
||||
@@ -83,6 +83,7 @@ typedef enum
|
||||
IR_VAR, /* variable reference */
|
||||
IR_VAR_DECL,/* var declaration */
|
||||
IR_ELEMENT, /* array element */
|
||||
IR_SWIZZLE, /* swizzled storage access */
|
||||
IR_TEX, /* texture lookup */
|
||||
IR_TEXB, /* texture lookup with LOD bias */
|
||||
IR_TEXP, /* texture lookup with projection */
|
||||
@@ -101,6 +102,7 @@ typedef struct
|
||||
enum register_file File; /**< PROGRAM_TEMPORARY, PROGRAM_INPUT, etc */
|
||||
GLint Index; /**< -1 means unallocated */
|
||||
GLint Size; /**< number of floats */
|
||||
GLuint Swizzle;
|
||||
} slang_ir_storage;
|
||||
|
||||
|
||||
@@ -113,11 +115,10 @@ typedef struct slang_ir_node_
|
||||
struct slang_ir_node_ *Children[2];
|
||||
const char *Comment;
|
||||
const char *Target;
|
||||
GLuint Swizzle;
|
||||
GLuint Writemask; /**< If Opcode == IR_MOVE */
|
||||
GLfloat Value[4]; /**< If Opcode == IR_FLOAT */
|
||||
slang_variable *Var;
|
||||
slang_ir_storage *Store;
|
||||
slang_ir_storage *Store; /**< location of result of this operation */
|
||||
} slang_ir_node;
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user