mesa: Branch 'glsl-compiler-1' - 4 commits
Brian Paul
brianp at kemper.freedesktop.org
Sat Mar 24 22:02:29 UTC 2007
src/mesa/shader/slang/slang_codegen.c | 22 -
src/mesa/shader/slang/slang_emit.c | 315 ---------------------------
src/mesa/shader/slang/slang_ir.c | 387 ++++++++++++++++++++++++++++++++++
src/mesa/shader/slang/slang_ir.h | 27 ++
src/mesa/sources | 1
src/mesa/tnl/t_context.c | 21 -
6 files changed, 429 insertions(+), 344 deletions(-)
New commits:
diff-tree 0e71d08e8df7f59da74e78212fe8433ceb7c7315 (from b50b036ffb795a12106bd59b1a08b0287a8b3388)
Author: Brian <brian at yutani.localnet.net>
Date: Sat Mar 24 10:18:14 2007 -0600
Properly free the slang_ir_node->Store data (use ref counting).
diff --git a/src/mesa/shader/slang/slang_ir.c b/src/mesa/shader/slang/slang_ir.c
index 5790d0a..11c09d3 100644
--- a/src/mesa/shader/slang/slang_ir.c
+++ b/src/mesa/shader/slang/slang_ir.c
@@ -106,33 +106,65 @@ _slang_ir_info(slang_ir_opcode opcode)
return NULL;
}
+
static const char *
-slang_ir_name(slang_ir_opcode opcode)
+_slang_ir_name(slang_ir_opcode opcode)
{
return _slang_ir_info(opcode)->IrName;
}
-
/**
- * Recursively free an IR tree.
+ * Since many IR nodes might point to the same IR storage info, we need
+ * to be careful when deleting things.
+ * Before deleting an IR tree, traverse it and do refcounting on the
+ * IR storage nodes. Use the refcount info during delete to free things
+ * properly.
*/
-void
-_slang_free_ir_tree(slang_ir_node *n)
+static void
+_slang_refcount_storage(slang_ir_node *n)
{
-#if 1
GLuint i;
if (!n)
return;
+ if (n->Store)
+ n->Store->RefCount++;
+ for (i = 0; i < 3; i++)
+ _slang_refcount_storage(n->Children[i]);
+}
+
+
+static void
+_slang_free_ir(slang_ir_node *n)
+{
+ GLuint i;
+ if (!n)
+ return;
+
+ if (n->Store) {
+ n->Store->RefCount--;
+ if (n->Store->RefCount == 0) {
+ free(n->Store);
+ n->Store = NULL;
+ }
+ }
+
for (i = 0; i < 3; i++)
_slang_free_ir_tree(n->Children[i]);
/* Do not free n->List since it's a child elsewhere */
free(n);
-#endif
}
-
+/**
+ * Recursively free an IR tree.
+ */
+void
+_slang_free_ir_tree(slang_ir_node *n)
+{
+ _slang_refcount_storage(n);
+ _slang_free_ir(n);
+}
@@ -149,6 +181,7 @@ swizzle_string(GLuint swizzle)
return s;
}
+
static const char *
writemask_string(GLuint writemask)
{
@@ -163,6 +196,7 @@ writemask_string(GLuint writemask)
return s;
}
+
static const char *
storage_string(const slang_ir_storage *st)
{
@@ -204,12 +238,11 @@ spaces(int n)
}
-#define IND 0
-
-
void
_slang_print_ir_tree(const slang_ir_node *n, int indent)
{
+#define IND 0
+
if (!n)
return;
#if !IND
@@ -346,7 +379,7 @@ _slang_print_ir_tree(const slang_ir_node
_slang_print_ir_tree(n->Children[0], indent + 3);
break;
default:
- printf("%s (%p, %p) (store %p)\n", slang_ir_name(n->Opcode),
+ 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_tree(n->Children[0], indent+3);
_slang_print_ir_tree(n->Children[1], indent+3);
diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h
index 2b7d822..2e90409 100644
--- a/src/mesa/shader/slang/slang_ir.h
+++ b/src/mesa/shader/slang/slang_ir.h
@@ -147,6 +147,7 @@ struct _slang_ir_storage
GLint Index; /**< -1 means unallocated */
GLint Size; /**< number of floats */
GLuint Swizzle;
+ GLint RefCount; /**< Used during IR tree delete */
};
typedef struct _slang_ir_storage slang_ir_storage;
diff-tree b50b036ffb795a12106bd59b1a08b0287a8b3388 (from dc3015f1574f26704c3498c56915b5570d777da4)
Author: Brian <brian at yutani.localnet.net>
Date: Sat Mar 24 10:16:49 2007 -0600
When computing render_inputs_bitset, omit primary color if we have a fragment program and it doesn't need FRAG_ATTRIB_COL0. Silences valgrind warnings.
diff --git a/src/mesa/tnl/t_context.c b/src/mesa/tnl/t_context.c
index f665485..fa42a3d 100644
--- a/src/mesa/tnl/t_context.c
+++ b/src/mesa/tnl/t_context.c
@@ -102,6 +102,8 @@ void
_tnl_InvalidateState( GLcontext *ctx, GLuint new_state )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
+ const struct gl_vertex_program *vp = ctx->VertexProgram._Current;
+ const struct gl_fragment_program *fp = ctx->FragmentProgram._Current;
if (new_state & (_NEW_HINT)) {
ASSERT(tnl->AllowVertexFog || tnl->AllowPixelFog);
@@ -118,7 +120,9 @@ _tnl_InvalidateState( GLcontext *ctx, GL
RENDERINPUTS_ZERO( tnl->render_inputs_bitset );
RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_POS );
- RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_COLOR0 );
+ if (!fp || fp->Base.InputsRead & FRAG_BIT_COL0) {
+ RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_COLOR0 );
+ }
for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
if (ctx->Texture._EnabledCoordUnits & (1 << i)) {
RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_TEX(i) );
@@ -151,15 +155,12 @@ _tnl_InvalidateState( GLcontext *ctx, GL
RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_POINTSIZE );
/* check for varying vars which are written by the vertex program */
- {
- struct gl_vertex_program *vp = ctx->VertexProgram._Current;
- if (vp) {
- GLuint i;
- for (i = 0; i < MAX_VARYING; i++) {
- if (vp->Base.OutputsWritten & (1 << (VERT_RESULT_VAR0 + i))) {
- RENDERINPUTS_SET(tnl->render_inputs_bitset,
- _TNL_ATTRIB_GENERIC(i));
- }
+ if (vp) {
+ GLuint i;
+ for (i = 0; i < MAX_VARYING; i++) {
+ if (vp->Base.OutputsWritten & (1 << (VERT_RESULT_VAR0 + i))) {
+ RENDERINPUTS_SET(tnl->render_inputs_bitset,
+ _TNL_ATTRIB_GENERIC(i));
}
}
}
diff-tree dc3015f1574f26704c3498c56915b5570d777da4 (from b2bc563142c93fd9bfa503f7b9e5e99c7d450ccc)
Author: Brian <brian at yutani.localnet.net>
Date: Sat Mar 24 09:40:20 2007 -0600
move some code into new slang_ir.c file
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 2eb509b..2210b95 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -402,24 +402,6 @@ static slang_asm_info AsmInfo[] = {
};
-/**
- * Recursively free an IR tree.
- */
-static void
-_slang_free_ir_tree(slang_ir_node *n)
-{
-#if 1
- GLuint i;
- if (!n)
- return;
- for (i = 0; i < 3; i++)
- _slang_free_ir_tree(n->Children[i]);
- /* Do not free n->List since it's a child elsewhere */
- free(n);
-#endif
-}
-
-
static slang_ir_node *
new_node3(slang_ir_opcode op,
slang_ir_node *c0, slang_ir_node *c1, slang_ir_node *c2)
@@ -1639,7 +1621,7 @@ _slang_gen_select(slang_assemble_ctx *A,
tree = new_seq(ifNode, tmpVar);
tree = new_seq(tmpDecl, tree);
- slang_print_ir(tree, 10);
+ /*_slang_print_ir_tree(tree, 10);*/
return tree;
}
@@ -2835,7 +2817,7 @@ _slang_codegen_function(slang_assemble_c
#endif
#if 0
printf("************* IR for %s *******\n", (char*)fun->header.a_name);
- slang_print_ir(n, 0);
+ _slang_print_ir_tree(n, 0);
#endif
#if 0
printf("************* End codegen function ************\n\n");
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 6ec20da..ace68d1 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -66,102 +66,6 @@ typedef struct
} slang_emit_info;
-/**
- * Assembly and IR info
- */
-typedef struct
-{
- slang_ir_opcode IrOpcode;
- const char *IrName;
- gl_inst_opcode InstOpcode;
- GLuint ResultSize, NumParams;
-} slang_ir_info;
-
-
-
-static const slang_ir_info IrInfo[] = {
- /* binary ops */
- { IR_ADD, "IR_ADD", OPCODE_ADD, 4, 2 },
- { IR_SUB, "IR_SUB", OPCODE_SUB, 4, 2 },
- { IR_MUL, "IR_MUL", OPCODE_MUL, 4, 2 },
- { IR_DIV, "IR_DIV", OPCODE_NOP, 0, 2 }, /* XXX broke */
- { IR_DOT4, "IR_DOT_4", OPCODE_DP4, 1, 2 },
- { IR_DOT3, "IR_DOT_3", OPCODE_DP3, 1, 2 },
- { IR_CROSS, "IR_CROSS", OPCODE_XPD, 3, 2 },
- { IR_LRP, "IR_LRP", OPCODE_LRP, 4, 3 },
- { IR_MIN, "IR_MIN", OPCODE_MIN, 4, 2 },
- { IR_MAX, "IR_MAX", OPCODE_MAX, 4, 2 },
- { IR_CLAMP, "IR_CLAMP", OPCODE_NOP, 4, 3 }, /* special case: emit_clamp() */
- { IR_SEQUAL, "IR_SEQUAL", OPCODE_SEQ, 4, 2 },
- { IR_SNEQUAL, "IR_SNEQUAL", OPCODE_SNE, 4, 2 },
- { IR_SGE, "IR_SGE", OPCODE_SGE, 4, 2 },
- { IR_SGT, "IR_SGT", OPCODE_SGT, 4, 2 },
- { IR_SLE, "IR_SLE", OPCODE_SLE, 4, 2 },
- { IR_SLT, "IR_SLT", OPCODE_SLT, 4, 2 },
- { IR_POW, "IR_POW", OPCODE_POW, 1, 2 },
- /* unary ops */
- { IR_I_TO_F, "IR_I_TO_F", OPCODE_NOP, 1, 1 },
- { IR_F_TO_I, "IR_F_TO_I", OPCODE_INT, 4, 1 }, /* 4 floats to 4 ints */
- { IR_EXP, "IR_EXP", OPCODE_EXP, 1, 1 },
- { IR_EXP2, "IR_EXP2", OPCODE_EX2, 1, 1 },
- { IR_LOG2, "IR_LOG2", OPCODE_LG2, 1, 1 },
- { IR_RSQ, "IR_RSQ", OPCODE_RSQ, 1, 1 },
- { IR_RCP, "IR_RCP", OPCODE_RCP, 1, 1 },
- { IR_FLOOR, "IR_FLOOR", OPCODE_FLR, 4, 1 },
- { IR_FRAC, "IR_FRAC", OPCODE_FRC, 4, 1 },
- { IR_ABS, "IR_ABS", OPCODE_ABS, 4, 1 },
- { IR_NEG, "IR_NEG", OPCODE_NOP, 4, 1 }, /* special case: emit_negation() */
- { IR_DDX, "IR_DDX", OPCODE_DDX, 4, 1 },
- { IR_DDX, "IR_DDY", OPCODE_DDX, 4, 1 },
- { IR_SIN, "IR_SIN", OPCODE_SIN, 1, 1 },
- { IR_COS, "IR_COS", OPCODE_COS, 1, 1 },
- { IR_NOISE1, "IR_NOISE1", OPCODE_NOISE1, 1, 1 },
- { IR_NOISE2, "IR_NOISE2", OPCODE_NOISE2, 1, 1 },
- { IR_NOISE3, "IR_NOISE3", OPCODE_NOISE3, 1, 1 },
- { IR_NOISE4, "IR_NOISE4", OPCODE_NOISE4, 1, 1 },
-
- /* other */
- { IR_SEQ, "IR_SEQ", OPCODE_NOP, 0, 0 },
- { IR_SCOPE, "IR_SCOPE", OPCODE_NOP, 0, 0 },
- { IR_LABEL, "IR_LABEL", OPCODE_NOP, 0, 0 },
- { IR_JUMP, "IR_JUMP", OPCODE_NOP, 0, 0 },
- { IR_IF, "IR_IF", OPCODE_NOP, 0, 0 },
- { IR_KILL, "IR_KILL", OPCODE_NOP, 0, 0 },
- { IR_COND, "IR_COND", OPCODE_NOP, 0, 0 },
- { IR_CALL, "IR_CALL", OPCODE_NOP, 0, 0 },
- { IR_MOVE, "IR_MOVE", OPCODE_NOP, 0, 1 },
- { IR_NOT, "IR_NOT", OPCODE_NOP, 1, 1 },
- { IR_VAR, "IR_VAR", OPCODE_NOP, 0, 0 },
- { IR_VAR_DECL, "IR_VAR_DECL", OPCODE_NOP, 0, 0 },
- { IR_TEX, "IR_TEX", OPCODE_TEX, 4, 1 },
- { IR_TEXB, "IR_TEXB", OPCODE_TXB, 4, 1 },
- { IR_TEXP, "IR_TEXP", OPCODE_TXP, 4, 1 },
- { IR_FLOAT, "IR_FLOAT", OPCODE_NOP, 0, 0 }, /* float literal */
- { IR_FIELD, "IR_FIELD", OPCODE_NOP, 0, 0 },
- { IR_ELEMENT, "IR_ELEMENT", OPCODE_NOP, 0, 0 },
- { IR_SWIZZLE, "IR_SWIZZLE", OPCODE_NOP, 0, 0 },
- { IR_NOP, NULL, OPCODE_NOP, 0, 0 }
-};
-
-
-static const slang_ir_info *
-slang_find_ir_info(slang_ir_opcode opcode)
-{
- GLuint i;
- for (i = 0; IrInfo[i].IrName; i++) {
- if (IrInfo[i].IrOpcode == opcode) {
- return IrInfo + i;
- }
- }
- return NULL;
-}
-
-static const char *
-slang_ir_name(slang_ir_opcode opcode)
-{
- return slang_find_ir_info(opcode)->IrName;
-}
-
/**
* Swizzle a swizzle. That is, return swz2(swz1)
@@ -194,221 +98,6 @@ _slang_new_ir_storage(enum register_file
}
-static const char *
-swizzle_string(GLuint swizzle)
-{
- static char s[6];
- GLuint i;
- s[0] = '.';
- for (i = 1; i < 5; i++) {
- s[i] = "xyzw"[GET_SWZ(swizzle, i-1)];
- }
- s[i] = 0;
- return s;
-}
-
-static const char *
-writemask_string(GLuint writemask)
-{
- static char s[6];
- GLuint i, j = 0;
- s[j++] = '.';
- for (i = 0; i < 4; i++) {
- if (writemask & (1 << i))
- s[j++] = "xyzw"[i];
- }
- s[j] = 0;
- return s;
-}
-
-static const char *
-storage_string(const slang_ir_storage *st)
-{
- static const char *files[] = {
- "TEMP",
- "LOCAL_PARAM",
- "ENV_PARAM",
- "STATE",
- "INPUT",
- "OUTPUT",
- "NAMED_PARAM",
- "CONSTANT",
- "UNIFORM",
- "WRITE_ONLY",
- "ADDRESS",
- "SAMPLER",
- "UNDEFINED"
- };
- static char s[100];
-#if 0
- if (st->Size == 1)
- sprintf(s, "%s[%d]", files[st->File], st->Index);
- else
- sprintf(s, "%s[%d..%d]", files[st->File], st->Index,
- st->Index + st->Size - 1);
-#endif
- assert(st->File < (GLint) (sizeof(files) / sizeof(files[0])));
- sprintf(s, "%s[%d]", files[st->File], st->Index);
- return s;
-}
-
-
-static void
-spaces(int n)
-{
- while (n-- > 0) {
- printf(" ");
- }
-}
-
-#define IND 0
-void
-slang_print_ir(const slang_ir_node *n, int indent)
-{
- if (!n)
- return;
-#if !IND
- if (n->Opcode != IR_SEQ)
-#else
- printf("%3d:", indent);
-#endif
- spaces(indent);
-
- switch (n->Opcode) {
- case IR_SEQ:
-#if IND
- printf("SEQ at %p\n", (void*) n);
-#endif
- assert(n->Children[0]);
- assert(n->Children[1]);
- slang_print_ir(n->Children[0], indent + IND);
- slang_print_ir(n->Children[1], indent + IND);
- break;
- case IR_SCOPE:
- printf("NEW SCOPE\n");
- assert(!n->Children[1]);
- slang_print_ir(n->Children[0], indent + 3);
- break;
- case IR_MOVE:
- printf("MOVE (writemask = %s)\n", writemask_string(n->Writemask));
- slang_print_ir(n->Children[0], indent+3);
- slang_print_ir(n->Children[1], indent+3);
- break;
- case IR_LABEL:
- printf("LABEL: %s\n", n->Label->Name);
- break;
- case IR_COND:
- printf("COND\n");
- slang_print_ir(n->Children[0], indent + 3);
- break;
- case IR_JUMP:
- printf("JUMP %s\n", n->Label->Name);
- break;
-
- case IR_IF:
- printf("IF \n");
- slang_print_ir(n->Children[0], indent+3);
- spaces(indent);
- printf("THEN\n");
- slang_print_ir(n->Children[1], indent+3);
- if (n->Children[2]) {
- spaces(indent);
- printf("ELSE\n");
- slang_print_ir(n->Children[2], indent+3);
- }
- spaces(indent);
- printf("ENDIF\n");
- break;
-
- case IR_BEGIN_SUB:
- printf("BEGIN_SUB\n");
- break;
- case IR_END_SUB:
- printf("END_SUB\n");
- break;
- case IR_RETURN:
- printf("RETURN\n");
- break;
- case IR_CALL:
- printf("CALL\n");
- break;
-
- case IR_LOOP:
- printf("LOOP\n");
- slang_print_ir(n->Children[0], indent+3);
- if (n->Children[1]) {
- spaces(indent);
- printf("TAIL:\n");
- slang_print_ir(n->Children[1], indent+3);
- }
- spaces(indent);
- printf("ENDLOOP\n");
- break;
- case IR_CONT:
- printf("CONT\n");
- break;
- case IR_BREAK:
- printf("BREAK\n");
- break;
- case IR_BREAK_IF_FALSE:
- printf("BREAK_IF_FALSE\n");
- slang_print_ir(n->Children[0], indent+3);
- break;
- case IR_BREAK_IF_TRUE:
- printf("BREAK_IF_TRUE\n");
- slang_print_ir(n->Children[0], indent+3);
- break;
- case IR_CONT_IF_FALSE:
- printf("CONT_IF_FALSE\n");
- slang_print_ir(n->Children[0], indent+3);
- break;
- case IR_CONT_IF_TRUE:
- printf("CONT_IF_TRUE\n");
- slang_print_ir(n->Children[0], indent+3);
- break;
-
- case IR_VAR:
- printf("VAR %s%s at %s store %p\n",
- (n->Var ? (char *) n->Var->a_name : "TEMP"),
- swizzle_string(n->Store->Swizzle),
- storage_string(n->Store), (void*) n->Store);
- break;
- case IR_VAR_DECL:
- printf("VAR_DECL %s (%p) at %s store %p\n",
- (n->Var ? (char *) n->Var->a_name : "TEMP"),
- (void*) n->Var, storage_string(n->Store),
- (void*) n->Store);
- break;
- case IR_FIELD:
- printf("FIELD %s of\n", n->Field);
- slang_print_ir(n->Children[0], indent+3);
- break;
- case IR_FLOAT:
- printf("FLOAT %g %g %g %g\n",
- n->Value[0], n->Value[1], n->Value[2], n->Value[3]);
- break;
- case IR_I_TO_F:
- printf("INT_TO_FLOAT\n");
- slang_print_ir(n->Children[0], indent+3);
- break;
- case IR_F_TO_I:
- printf("FLOAT_TO_INT\n");
- slang_print_ir(n->Children[0], indent+3);
- 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) (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);
- }
-}
-
-
/**
* Allocate temporary storage for an intermediate result (such as for
* a multiply or add, etc.
@@ -713,7 +402,7 @@ static struct prog_instruction *
emit_arith(slang_emit_info *emitInfo, slang_ir_node *n)
{
struct prog_instruction *inst;
- const slang_ir_info *info = slang_find_ir_info(n->Opcode);
+ const slang_ir_info *info = _slang_ir_info(n->Opcode);
char *srcAnnot[3], *dstAnnot;
GLuint i;
@@ -1347,8 +1036,6 @@ emit_loop(slang_emit_info *emitInfo, sla
GLuint beginInstLoc, tailInstLoc, endInstLoc;
slang_ir_node *ir;
- slang_print_ir(n, 10);
-
/* emit OPCODE_BGNLOOP */
beginInstLoc = prog->NumInstructions;
if (emitInfo->EmitHighLevelInstructions) {
diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h
index 37dd38e..2b7d822 100644
--- a/src/mesa/shader/slang/slang_ir.h
+++ b/src/mesa/shader/slang/slang_ir.h
@@ -175,4 +175,30 @@ typedef struct slang_ir_node_
} slang_ir_node;
+
+/**
+ * Assembly and IR info
+ */
+typedef struct
+{
+ slang_ir_opcode IrOpcode;
+ const char *IrName;
+ gl_inst_opcode InstOpcode;
+ GLuint ResultSize, NumParams;
+} slang_ir_info;
+
+
+
+extern const slang_ir_info *
+_slang_ir_info(slang_ir_opcode opcode);
+
+
+extern void
+_slang_free_ir_tree(slang_ir_node *n);
+
+
+extern void
+_slang_print_ir_tree(const slang_ir_node *n, int indent);
+
+
#endif /* SLANG_IR_H */
diff --git a/src/mesa/sources b/src/mesa/sources
index 628599c..73fd581 100644
--- a/src/mesa/sources
+++ b/src/mesa/sources
@@ -179,6 +179,7 @@ SLANG_SOURCES = \
shader/slang/slang_compile_struct.c \
shader/slang/slang_compile_variable.c \
shader/slang/slang_emit.c \
+ shader/slang/slang_ir.c \
shader/slang/slang_label.c \
shader/slang/slang_library_noise.c \
shader/slang/slang_link.c \
diff-tree b2bc563142c93fd9bfa503f7b9e5e99c7d450ccc (from 8f9db0f81c13c3244f07333f33a15bfe098e0f31)
Author: Brian <brian at yutani.localnet.net>
Date: Sat Mar 24 09:39:24 2007 -0600
IR utility functions
diff --git a/src/mesa/shader/slang/slang_ir.c b/src/mesa/shader/slang/slang_ir.c
new file mode 100644
index 0000000..5790d0a
--- /dev/null
+++ b/src/mesa/shader/slang/slang_ir.c
@@ -0,0 +1,354 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5.3
+ *
+ * Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "imports.h"
+#include "context.h"
+#include "slang_ir.h"
+#include "prog_print.h"
+
+
+static const slang_ir_info IrInfo[] = {
+ /* binary ops */
+ { IR_ADD, "IR_ADD", OPCODE_ADD, 4, 2 },
+ { IR_SUB, "IR_SUB", OPCODE_SUB, 4, 2 },
+ { IR_MUL, "IR_MUL", OPCODE_MUL, 4, 2 },
+ { IR_DIV, "IR_DIV", OPCODE_NOP, 0, 2 }, /* XXX broke */
+ { IR_DOT4, "IR_DOT_4", OPCODE_DP4, 1, 2 },
+ { IR_DOT3, "IR_DOT_3", OPCODE_DP3, 1, 2 },
+ { IR_CROSS, "IR_CROSS", OPCODE_XPD, 3, 2 },
+ { IR_LRP, "IR_LRP", OPCODE_LRP, 4, 3 },
+ { IR_MIN, "IR_MIN", OPCODE_MIN, 4, 2 },
+ { IR_MAX, "IR_MAX", OPCODE_MAX, 4, 2 },
+ { IR_CLAMP, "IR_CLAMP", OPCODE_NOP, 4, 3 }, /* special case: emit_clamp() */
+ { IR_SEQUAL, "IR_SEQUAL", OPCODE_SEQ, 4, 2 },
+ { IR_SNEQUAL, "IR_SNEQUAL", OPCODE_SNE, 4, 2 },
+ { IR_SGE, "IR_SGE", OPCODE_SGE, 4, 2 },
+ { IR_SGT, "IR_SGT", OPCODE_SGT, 4, 2 },
+ { IR_SLE, "IR_SLE", OPCODE_SLE, 4, 2 },
+ { IR_SLT, "IR_SLT", OPCODE_SLT, 4, 2 },
+ { IR_POW, "IR_POW", OPCODE_POW, 1, 2 },
+ /* unary ops */
+ { IR_I_TO_F, "IR_I_TO_F", OPCODE_NOP, 1, 1 },
+ { IR_F_TO_I, "IR_F_TO_I", OPCODE_INT, 4, 1 }, /* 4 floats to 4 ints */
+ { IR_EXP, "IR_EXP", OPCODE_EXP, 1, 1 },
+ { IR_EXP2, "IR_EXP2", OPCODE_EX2, 1, 1 },
+ { IR_LOG2, "IR_LOG2", OPCODE_LG2, 1, 1 },
+ { IR_RSQ, "IR_RSQ", OPCODE_RSQ, 1, 1 },
+ { IR_RCP, "IR_RCP", OPCODE_RCP, 1, 1 },
+ { IR_FLOOR, "IR_FLOOR", OPCODE_FLR, 4, 1 },
+ { IR_FRAC, "IR_FRAC", OPCODE_FRC, 4, 1 },
+ { IR_ABS, "IR_ABS", OPCODE_ABS, 4, 1 },
+ { IR_NEG, "IR_NEG", OPCODE_NOP, 4, 1 }, /* special case: emit_negation() */
+ { IR_DDX, "IR_DDX", OPCODE_DDX, 4, 1 },
+ { IR_DDX, "IR_DDY", OPCODE_DDX, 4, 1 },
+ { IR_SIN, "IR_SIN", OPCODE_SIN, 1, 1 },
+ { IR_COS, "IR_COS", OPCODE_COS, 1, 1 },
+ { IR_NOISE1, "IR_NOISE1", OPCODE_NOISE1, 1, 1 },
+ { IR_NOISE2, "IR_NOISE2", OPCODE_NOISE2, 1, 1 },
+ { IR_NOISE3, "IR_NOISE3", OPCODE_NOISE3, 1, 1 },
+ { IR_NOISE4, "IR_NOISE4", OPCODE_NOISE4, 1, 1 },
+
+ /* other */
+ { IR_SEQ, "IR_SEQ", OPCODE_NOP, 0, 0 },
+ { IR_SCOPE, "IR_SCOPE", OPCODE_NOP, 0, 0 },
+ { IR_LABEL, "IR_LABEL", OPCODE_NOP, 0, 0 },
+ { IR_JUMP, "IR_JUMP", OPCODE_NOP, 0, 0 },
+ { IR_IF, "IR_IF", OPCODE_NOP, 0, 0 },
+ { IR_KILL, "IR_KILL", OPCODE_NOP, 0, 0 },
+ { IR_COND, "IR_COND", OPCODE_NOP, 0, 0 },
+ { IR_CALL, "IR_CALL", OPCODE_NOP, 0, 0 },
+ { IR_MOVE, "IR_MOVE", OPCODE_NOP, 0, 1 },
+ { IR_NOT, "IR_NOT", OPCODE_NOP, 1, 1 },
+ { IR_VAR, "IR_VAR", OPCODE_NOP, 0, 0 },
+ { IR_VAR_DECL, "IR_VAR_DECL", OPCODE_NOP, 0, 0 },
+ { IR_TEX, "IR_TEX", OPCODE_TEX, 4, 1 },
+ { IR_TEXB, "IR_TEXB", OPCODE_TXB, 4, 1 },
+ { IR_TEXP, "IR_TEXP", OPCODE_TXP, 4, 1 },
+ { IR_FLOAT, "IR_FLOAT", OPCODE_NOP, 0, 0 }, /* float literal */
+ { IR_FIELD, "IR_FIELD", OPCODE_NOP, 0, 0 },
+ { IR_ELEMENT, "IR_ELEMENT", OPCODE_NOP, 0, 0 },
+ { IR_SWIZZLE, "IR_SWIZZLE", OPCODE_NOP, 0, 0 },
+ { IR_NOP, NULL, OPCODE_NOP, 0, 0 }
+};
+
+
+const slang_ir_info *
+_slang_ir_info(slang_ir_opcode opcode)
+{
+ GLuint i;
+ for (i = 0; IrInfo[i].IrName; i++) {
+ if (IrInfo[i].IrOpcode == opcode) {
+ return IrInfo + i;
+ }
+ }
+ return NULL;
+}
+
+static const char *
+slang_ir_name(slang_ir_opcode opcode)
+{
+ return _slang_ir_info(opcode)->IrName;
+}
+
+
+
+/**
+ * Recursively free an IR tree.
+ */
+void
+_slang_free_ir_tree(slang_ir_node *n)
+{
+#if 1
+ GLuint i;
+ if (!n)
+ return;
+ for (i = 0; i < 3; i++)
+ _slang_free_ir_tree(n->Children[i]);
+ /* Do not free n->List since it's a child elsewhere */
+ free(n);
+#endif
+}
+
+
+
+
+
+
+static const char *
+swizzle_string(GLuint swizzle)
+{
+ static char s[6];
+ GLuint i;
+ s[0] = '.';
+ for (i = 1; i < 5; i++) {
+ s[i] = "xyzw"[GET_SWZ(swizzle, i-1)];
+ }
+ s[i] = 0;
+ return s;
+}
+
+static const char *
+writemask_string(GLuint writemask)
+{
+ static char s[6];
+ GLuint i, j = 0;
+ s[j++] = '.';
+ for (i = 0; i < 4; i++) {
+ if (writemask & (1 << i))
+ s[j++] = "xyzw"[i];
+ }
+ s[j] = 0;
+ return s;
+}
+
+static const char *
+storage_string(const slang_ir_storage *st)
+{
+ static const char *files[] = {
+ "TEMP",
+ "LOCAL_PARAM",
+ "ENV_PARAM",
+ "STATE",
+ "INPUT",
+ "OUTPUT",
+ "NAMED_PARAM",
+ "CONSTANT",
+ "UNIFORM",
+ "WRITE_ONLY",
+ "ADDRESS",
+ "SAMPLER",
+ "UNDEFINED"
+ };
+ static char s[100];
+#if 0
+ if (st->Size == 1)
+ sprintf(s, "%s[%d]", files[st->File], st->Index);
+ else
+ sprintf(s, "%s[%d..%d]", files[st->File], st->Index,
+ st->Index + st->Size - 1);
+#endif
+ assert(st->File < (GLint) (sizeof(files) / sizeof(files[0])));
+ sprintf(s, "%s[%d]", files[st->File], st->Index);
+ return s;
+}
+
+
+static void
+spaces(int n)
+{
+ while (n-- > 0) {
+ printf(" ");
+ }
+}
+
+
+#define IND 0
+
+
+void
+_slang_print_ir_tree(const slang_ir_node *n, int indent)
+{
+ if (!n)
+ return;
+#if !IND
+ if (n->Opcode != IR_SEQ)
+#else
+ printf("%3d:", indent);
+#endif
+ spaces(indent);
+
+ switch (n->Opcode) {
+ case IR_SEQ:
+#if IND
+ printf("SEQ at %p\n", (void*) n);
+#endif
+ assert(n->Children[0]);
+ assert(n->Children[1]);
+ _slang_print_ir_tree(n->Children[0], indent + IND);
+ _slang_print_ir_tree(n->Children[1], indent + IND);
+ break;
+ case IR_SCOPE:
+ printf("NEW SCOPE\n");
+ assert(!n->Children[1]);
+ _slang_print_ir_tree(n->Children[0], indent + 3);
+ break;
+ case IR_MOVE:
+ printf("MOVE (writemask = %s)\n", writemask_string(n->Writemask));
+ _slang_print_ir_tree(n->Children[0], indent+3);
+ _slang_print_ir_tree(n->Children[1], indent+3);
+ break;
+ case IR_LABEL:
+ printf("LABEL: %s\n", n->Label->Name);
+ break;
+ case IR_COND:
+ printf("COND\n");
+ _slang_print_ir_tree(n->Children[0], indent + 3);
+ break;
+ case IR_JUMP:
+ printf("JUMP %s\n", n->Label->Name);
+ break;
+
+ case IR_IF:
+ printf("IF \n");
+ _slang_print_ir_tree(n->Children[0], indent+3);
+ spaces(indent);
+ printf("THEN\n");
+ _slang_print_ir_tree(n->Children[1], indent+3);
+ if (n->Children[2]) {
+ spaces(indent);
+ printf("ELSE\n");
+ _slang_print_ir_tree(n->Children[2], indent+3);
+ }
+ spaces(indent);
+ printf("ENDIF\n");
+ break;
+
+ case IR_BEGIN_SUB:
+ printf("BEGIN_SUB\n");
+ break;
+ case IR_END_SUB:
+ printf("END_SUB\n");
+ break;
+ case IR_RETURN:
+ printf("RETURN\n");
+ break;
+ case IR_CALL:
+ printf("CALL\n");
+ break;
+
+ case IR_LOOP:
+ printf("LOOP\n");
+ _slang_print_ir_tree(n->Children[0], indent+3);
+ if (n->Children[1]) {
+ spaces(indent);
+ printf("TAIL:\n");
+ _slang_print_ir_tree(n->Children[1], indent+3);
+ }
+ spaces(indent);
+ printf("ENDLOOP\n");
+ break;
+ case IR_CONT:
+ printf("CONT\n");
+ break;
+ case IR_BREAK:
+ printf("BREAK\n");
+ break;
+ case IR_BREAK_IF_FALSE:
+ printf("BREAK_IF_FALSE\n");
+ _slang_print_ir_tree(n->Children[0], indent+3);
+ break;
+ case IR_BREAK_IF_TRUE:
+ printf("BREAK_IF_TRUE\n");
+ _slang_print_ir_tree(n->Children[0], indent+3);
+ break;
+ case IR_CONT_IF_FALSE:
+ printf("CONT_IF_FALSE\n");
+ _slang_print_ir_tree(n->Children[0], indent+3);
+ break;
+ case IR_CONT_IF_TRUE:
+ printf("CONT_IF_TRUE\n");
+ _slang_print_ir_tree(n->Children[0], indent+3);
+ break;
+
+ case IR_VAR:
+ printf("VAR %s%s at %s store %p\n",
+ (n->Var ? (char *) n->Var->a_name : "TEMP"),
+ swizzle_string(n->Store->Swizzle),
+ storage_string(n->Store), (void*) n->Store);
+ break;
+ case IR_VAR_DECL:
+ printf("VAR_DECL %s (%p) at %s store %p\n",
+ (n->Var ? (char *) n->Var->a_name : "TEMP"),
+ (void*) n->Var, storage_string(n->Store),
+ (void*) n->Store);
+ break;
+ case IR_FIELD:
+ printf("FIELD %s of\n", n->Field);
+ _slang_print_ir_tree(n->Children[0], indent+3);
+ break;
+ case IR_FLOAT:
+ printf("FLOAT %g %g %g %g\n",
+ n->Value[0], n->Value[1], n->Value[2], n->Value[3]);
+ break;
+ case IR_I_TO_F:
+ printf("INT_TO_FLOAT\n");
+ _slang_print_ir_tree(n->Children[0], indent+3);
+ break;
+ case IR_F_TO_I:
+ printf("FLOAT_TO_INT\n");
+ _slang_print_ir_tree(n->Children[0], indent+3);
+ break;
+ case IR_SWIZZLE:
+ printf("SWIZZLE %s of (store %p) \n",
+ swizzle_string(n->Store->Swizzle), (void*) n->Store);
+ _slang_print_ir_tree(n->Children[0], indent + 3);
+ break;
+ default:
+ 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_tree(n->Children[0], indent+3);
+ _slang_print_ir_tree(n->Children[1], indent+3);
+ }
+}
More information about the mesa-commit
mailing list