summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian <[email protected]>2007-01-10 13:33:38 -0700
committerBrian <[email protected]>2007-01-10 13:33:38 -0700
commit88e2dbfd10129eab2c7f4a935358a6ab2a18bf65 (patch)
tree11dd7ef5cbacf8e3792cbff6fefc0032619d7eef
parent8a48f3557424cfa67269ae5e4dca100ae2a0ddda (diff)
checkpoint: codegen for global vars w/ initializers
-rw-r--r--src/mesa/shader/shader_api.c3
-rw-r--r--src/mesa/shader/slang/slang_codegen.c365
-rw-r--r--src/mesa/shader/slang/slang_codegen.h7
-rw-r--r--src/mesa/shader/slang/slang_compile.c20
4 files changed, 228 insertions, 167 deletions
diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c
index 69314b225a4..c18bbcec4be 100644
--- a/src/mesa/shader/shader_api.c
+++ b/src/mesa/shader/shader_api.c
@@ -307,9 +307,10 @@ _mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index,
_slang_remap_attribute(&shProg->VertexProgram->Base, oldIndex, index);
}
+#if 0
printf("===== post BindAttrib:\n");
_mesa_print_program(&shProg->VertexProgram->Base);
-
+#endif
}
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 07ca8107c0a..12e9588579e 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -291,10 +291,12 @@ slang_allocate_storage(slang_gen_context *gc, slang_ir_node *n,
n->Store->Size = _slang_sizeof_type_specifier(&n->Var->type.specifier);
assert(n->Store->Size > 0);
n->Store->Index = _slang_alloc_temporary(gc, n->Store->Size);
+ /*
printf("alloc var %s storage at %d (size %d)\n",
(char *) n->Var->a_name,
n->Store->Index,
n->Store->Size);
+ */
assert(n->Store->Size > 0);
n->Var->declared = GL_TRUE;
return;
@@ -459,155 +461,6 @@ _slang_output_index(const char *name, GLenum target)
}
-/**
- * Called by compiler when a global variable has been parsed/compiled.
- * Here we examine the variable's type to determine what kind of register
- * storage will be used.
- *
- * A uniform such as "gl_Position" will become the register specification
- * (PROGRAM_OUTPUT, VERT_RESULT_HPOS). Or, uniform "gl_FogFragCoord"
- * will be (PROGRAM_INPUT, FRAG_ATTRIB_FOGC).
- *
- * Samplers are interesting. For "uniform sampler2D tex;" we'll specify
- * (PROGRAM_SAMPLER, index) where index is resolved at link-time to an
- * actual texture unit (as specified by the user calling glUniform1i()).
- */
-void
-_slang_codegen_global_variable(slang_variable *var, struct gl_program *prog,
- slang_unit_type type)
-{
- const char *varName = (char *) var->a_name;
- GLint texIndex;
- slang_ir_storage *store = NULL;
- int dbg = 0;
-
- texIndex = sampler_to_texture_index(var->type.specifier.type);
-
- if (texIndex != -1) {
- /* Texture sampler:
- * store->File = PROGRAM_SAMPLER
- * store->Index = sampler uniform location
- * store->Size = texture type index (1D, 2D, 3D, cube, etc)
- */
- GLint samplerUniform = _mesa_add_sampler(prog->Parameters, varName);
- store = _slang_new_ir_storage(PROGRAM_SAMPLER, samplerUniform, texIndex);
- if (dbg) printf("SAMPLER ");
- }
- else if (var->type.qualifier == slang_qual_uniform) {
- /* Uniform variable */
- const GLint size = _slang_sizeof_type_specifier(&var->type.specifier);
- if (prog) {
- /* user-defined uniform */
- GLint uniformLoc = _mesa_add_uniform(prog->Parameters, varName, size);
- store = _slang_new_ir_storage(PROGRAM_UNIFORM, uniformLoc, size);
- }
- else {
- /* pre-defined uniform, like gl_ModelviewMatrix */
- /* We know it's a uniform, but don't allocate storage unless
- * it's really used.
- */
-
- store = _slang_new_ir_storage(PROGRAM_STATE_VAR, -1, size);
-
- }
- if (dbg) printf("UNIFORM ");
- }
- else if (var->type.qualifier == slang_qual_varying) {
- const GLint size = 4; /* XXX fix */
- if (prog) {
- /* user-defined varying */
- GLint varyingLoc = _mesa_add_varying(prog->Varying, varName, size);
- store = _slang_new_ir_storage(PROGRAM_VARYING, varyingLoc, size);
- }
- else {
- /* pre-defined varying, like gl_Color or gl_TexCoord */
- if (type == slang_unit_fragment_builtin) {
- GLint index = _slang_input_index(varName, GL_FRAGMENT_PROGRAM_ARB);
- assert(index >= 0);
- store = _slang_new_ir_storage(PROGRAM_INPUT, index, size);
- assert(index < FRAG_ATTRIB_MAX);
- }
- else {
- GLint index = _slang_output_index(varName, GL_VERTEX_PROGRAM_ARB);
- assert(index >= 0);
- assert(type == slang_unit_vertex_builtin);
- store = _slang_new_ir_storage(PROGRAM_OUTPUT, index, size);
- assert(index < VERT_RESULT_MAX);
- }
- if (dbg) printf("V/F ");
- }
- if (dbg) printf("VARYING ");
- }
- else if (var->type.qualifier == slang_qual_const) {
- if (prog) {
- /* user-defined constant */
- const GLint size = _slang_sizeof_type_specifier(&var->type.specifier);
- /*
- const GLint index = _mesa_add_named_constant(prog->Parameters);
- */
- printf("Global user constant\n");
- abort(); /* XXX fix */
- }
- else {
- /* pre-defined global constant, like gl_MaxLights */
- GLint size = -1;
- store = _slang_new_ir_storage(PROGRAM_CONSTANT, -1, size);
- }
- if (dbg) printf("CONST ");
- }
- else if (var->type.qualifier == slang_qual_attribute) {
- if (prog) {
- /* user-defined vertex attribute */
- const GLint size = _slang_sizeof_type_specifier(&var->type.specifier);
- const GLint attr = -1; /* unknown */
- GLint index = _mesa_add_attribute(prog->Attributes, varName,
- size, attr);
- assert(index >= 0);
- store = _slang_new_ir_storage(PROGRAM_INPUT,
- VERT_ATTRIB_GENERIC0 + index, size);
- }
- else {
- /* pre-defined vertex attrib */
- GLint index = _slang_input_index(varName, GL_VERTEX_PROGRAM_ARB);
- GLint size = 4; /* XXX? */
- assert(index >= 0);
- store = _slang_new_ir_storage(PROGRAM_INPUT, index, size);
- }
- if (dbg) printf("ATTRIB ");
- }
- else if (var->type.qualifier == slang_qual_fixedinput) {
- GLint index = _slang_input_index(varName, GL_FRAGMENT_PROGRAM_ARB);
- GLint size = 4; /* XXX? */
- store = _slang_new_ir_storage(PROGRAM_INPUT, index, size);
- if (dbg) printf("INPUT ");
- }
- else if (var->type.qualifier == slang_qual_fixedoutput) {
- if (type == slang_unit_vertex_builtin) {
- GLint index = _slang_output_index(varName, GL_VERTEX_PROGRAM_ARB);
- GLint size = 4; /* XXX? */
- store = _slang_new_ir_storage(PROGRAM_OUTPUT, index, size);
- }
- else {
- assert(type == slang_unit_fragment_builtin);
- GLint index = _slang_output_index(varName, GL_FRAGMENT_PROGRAM_ARB);
- GLint size = 4; /* XXX? */
- store = _slang_new_ir_storage(PROGRAM_OUTPUT, index, size);
- }
- if (dbg) printf("OUTPUT ");
- }
- else {
- /* ordinary variable */
- assert(prog); /* shouldn't be any pre-defined, unqualified vars */
- if (dbg) printf("other ");
- abort();
- }
- if (dbg) printf("GLOBAL VAR %s idx %d\n", (char*) var->a_name, store?store->Index:-2);
-
- assert(!var->aux);
-
- var->aux = store;
-}
-
/**********************************************************************/
@@ -1023,10 +876,9 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
/* allocate the return var */
resultVar = slang_variable_scope_grow(commaSeq->locals);
/*
- printf("ALLOC __retVal from scope %p\n", (void*) commaSeq->locals);
- */
printf("Alloc __resultTemp in scope %p for retval of calling %s\n",
(void*)commaSeq->locals, (char *) fun->header.a_name);
+ */
resultVar->a_name = slang_atom_pool_atom(A->atoms, "__resultTmp");
resultVar->type = fun->header.type; /* XXX copy? */
@@ -1071,9 +923,11 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
substCount = 0;
for (i = 0; i < totalArgs; i++) {
slang_variable *p = &fun->parameters->variables[i];
+ /*
printf("Param %d: %s %s \n", i,
slang_type_qual_string(p->type.qualifier),
(char *) p->a_name);
+ */
if (p->type.qualifier == slang_qual_inout ||
p->type.qualifier == slang_qual_out) {
/* an output param */
@@ -2110,12 +1964,197 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper)
}
+
+/**
+ * Called by compiler when a global variable has been parsed/compiled.
+ * Here we examine the variable's type to determine what kind of register
+ * storage will be used.
+ *
+ * A uniform such as "gl_Position" will become the register specification
+ * (PROGRAM_OUTPUT, VERT_RESULT_HPOS). Or, uniform "gl_FogFragCoord"
+ * will be (PROGRAM_INPUT, FRAG_ATTRIB_FOGC).
+ *
+ * Samplers are interesting. For "uniform sampler2D tex;" we'll specify
+ * (PROGRAM_SAMPLER, index) where index is resolved at link-time to an
+ * actual texture unit (as specified by the user calling glUniform1i()).
+ */
+GLboolean
+_slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
+ slang_unit_type type)
+{
+ struct gl_program *prog = A->program;
+ const char *varName = (char *) var->a_name;
+ GLint texIndex;
+ slang_ir_storage *store = NULL;
+ int dbg = 0;
+ GLboolean codegen = GL_FALSE; /* generate code for this global? */
+
+ texIndex = sampler_to_texture_index(var->type.specifier.type);
+
+ if (texIndex != -1) {
+ /* Texture sampler:
+ * store->File = PROGRAM_SAMPLER
+ * store->Index = sampler uniform location
+ * store->Size = texture type index (1D, 2D, 3D, cube, etc)
+ */
+ GLint samplerUniform = _mesa_add_sampler(prog->Parameters, varName);
+ store = _slang_new_ir_storage(PROGRAM_SAMPLER, samplerUniform, texIndex);
+ if (dbg) printf("SAMPLER ");
+ }
+ else if (var->type.qualifier == slang_qual_uniform) {
+ /* Uniform variable */
+ const GLint size = _slang_sizeof_type_specifier(&var->type.specifier);
+ if (prog) {
+ /* user-defined uniform */
+ GLint uniformLoc = _mesa_add_uniform(prog->Parameters, varName, size);
+ store = _slang_new_ir_storage(PROGRAM_UNIFORM, uniformLoc, size);
+ }
+ else {
+ /* pre-defined uniform, like gl_ModelviewMatrix */
+ /* We know it's a uniform, but don't allocate storage unless
+ * it's really used.
+ */
+
+ store = _slang_new_ir_storage(PROGRAM_STATE_VAR, -1, size);
+
+ }
+ if (dbg) printf("UNIFORM ");
+ }
+ else if (var->type.qualifier == slang_qual_varying) {
+ const GLint size = 4; /* XXX fix */
+ if (prog) {
+ /* user-defined varying */
+ GLint varyingLoc = _mesa_add_varying(prog->Varying, varName, size);
+ store = _slang_new_ir_storage(PROGRAM_VARYING, varyingLoc, size);
+ }
+ else {
+ /* pre-defined varying, like gl_Color or gl_TexCoord */
+ if (type == slang_unit_fragment_builtin) {
+ GLint index = _slang_input_index(varName, GL_FRAGMENT_PROGRAM_ARB);
+ assert(index >= 0);
+ store = _slang_new_ir_storage(PROGRAM_INPUT, index, size);
+ assert(index < FRAG_ATTRIB_MAX);
+ }
+ else {
+ GLint index = _slang_output_index(varName, GL_VERTEX_PROGRAM_ARB);
+ assert(index >= 0);
+ assert(type == slang_unit_vertex_builtin);
+ store = _slang_new_ir_storage(PROGRAM_OUTPUT, index, size);
+ assert(index < VERT_RESULT_MAX);
+ }
+ if (dbg) printf("V/F ");
+ }
+ if (dbg) printf("VARYING ");
+ }
+ else if (var->type.qualifier == slang_qual_const) {
+ if (prog) {
+ /* user-defined constant */
+ /*
+ const GLint size = _slang_sizeof_type_specifier(&var->type.specifier);
+ const GLint index = _mesa_add_named_constant(prog->Parameters);
+ */
+ printf("Global user constant\n");
+ abort(); /* XXX fix */
+ }
+ else {
+ /* pre-defined global constant, like gl_MaxLights */
+ GLint size = -1;
+ store = _slang_new_ir_storage(PROGRAM_CONSTANT, -1, size);
+ }
+ if (dbg) printf("CONST ");
+ }
+ else if (var->type.qualifier == slang_qual_attribute) {
+ if (prog) {
+ /* user-defined vertex attribute */
+ const GLint size = _slang_sizeof_type_specifier(&var->type.specifier);
+ const GLint attr = -1; /* unknown */
+ GLint index = _mesa_add_attribute(prog->Attributes, varName,
+ size, attr);
+ assert(index >= 0);
+ store = _slang_new_ir_storage(PROGRAM_INPUT,
+ VERT_ATTRIB_GENERIC0 + index, size);
+ }
+ else {
+ /* pre-defined vertex attrib */
+ GLint index = _slang_input_index(varName, GL_VERTEX_PROGRAM_ARB);
+ GLint size = 4; /* XXX? */
+ assert(index >= 0);
+ store = _slang_new_ir_storage(PROGRAM_INPUT, index, size);
+ }
+ if (dbg) printf("ATTRIB ");
+ }
+ else if (var->type.qualifier == slang_qual_fixedinput) {
+ GLint index = _slang_input_index(varName, GL_FRAGMENT_PROGRAM_ARB);
+ GLint size = 4; /* XXX? */
+ store = _slang_new_ir_storage(PROGRAM_INPUT, index, size);
+ if (dbg) printf("INPUT ");
+ }
+ else if (var->type.qualifier == slang_qual_fixedoutput) {
+ if (type == slang_unit_vertex_builtin) {
+ GLint index = _slang_output_index(varName, GL_VERTEX_PROGRAM_ARB);
+ GLint size = 4; /* XXX? */
+ store = _slang_new_ir_storage(PROGRAM_OUTPUT, index, size);
+ }
+ else {
+ assert(type == slang_unit_fragment_builtin);
+ GLint index = _slang_output_index(varName, GL_FRAGMENT_PROGRAM_ARB);
+ GLint size = 4; /* XXX? */
+ store = _slang_new_ir_storage(PROGRAM_OUTPUT, index, size);
+ }
+ if (dbg) printf("OUTPUT ");
+ }
+ else {
+ /* ordinary variable */
+ const GLint size = _slang_sizeof_type_specifier(&var->type.specifier);
+ const GLint index = -1;
+ store = _slang_new_ir_storage(PROGRAM_TEMPORARY, index, size);
+ codegen = GL_TRUE;
+ assert(prog); /* shouldn't be any pre-defined, unqualified vars */
+ }
+ if (dbg) printf("GLOBAL VAR %s idx %d\n", (char*) var->a_name,
+ store ? store->Index : -2);
+
+ assert(!var->aux);
+ var->aux = store; /* save var's storage info */
+
+ if (codegen) {
+ slang_ir_node *n;
+
+ n = new_node(IR_VAR_DECL, NULL, NULL);
+ if (!n)
+ return GL_FALSE;
+ n->Var = var;
+ var->declared = GL_TRUE;
+ slang_allocate_storage(A->codegen, n, A->program);
+
+ if (var->initializer) {
+ slang_ir_node *lhs, *rhs, *init;
+
+ /* Generate IR_MOVE instruction to initialize the variable */
+ lhs = new_node(IR_VAR, NULL, NULL);
+ lhs->Var = var;
+ lhs->Swizzle = SWIZZLE_NOOP;
+ lhs->Store = store;
+
+ rhs = _slang_gen_operation(A, var->initializer);
+ init = new_node(IR_MOVE, lhs, rhs);
+ n = new_seq(n, init);
+ }
+
+ /* emit code (n) */
+
+ }
+
+ return GL_TRUE;
+}
+
+
/**
- * Produce an IR tree from a function AST.
+ * Produce an IR tree from a function AST (fun->body).
* Then call the code emitter to convert the IR tree into gl_program
* instructions.
*/
-struct slang_ir_node_ *
+GLboolean
_slang_codegen_function(slang_assemble_ctx * A, slang_function * fun)
{
slang_ir_node *n, *endLabel;
@@ -2125,11 +2164,13 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun)
/* we only really generate code for main, all other functions get
* inlined.
*/
- return 0;
+ return GL_TRUE; /* not an error */
}
#if 1
printf("\n*********** codegen_function %s\n", (char *) fun->header.a_name);
+#endif
+#if 0
slang_print_function(fun, 1);
#endif
@@ -2137,11 +2178,11 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun)
assert(A->program->Parameters );
assert(A->program->Varying);
- A->codegen = _slang_new_codegen_context();
+ assert(A->codegen);
+ /* A->codegen = _slang_new_codegen_context();*/
- /*printf("** Begin Simplify\n");*/
+ /* fold constant expressions, etc. */
slang_simplify(fun->body, &A->space, A->atoms);
- /*printf("** End Simplify\n");*/
CurFunction = fun;
@@ -2159,19 +2200,23 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun)
CurFunction = NULL;
-#if 1
+#if 0
printf("************* New AST for %s *****\n", (char*)fun->header.a_name);
slang_print_function(fun, 1);
+#endif
+#if 1
printf("************* IR for %s *******\n", (char*)fun->header.a_name);
slang_print_ir(n, 0);
- printf("************* End assemble function2 ************\n\n");
+ printf("************* End codegen function ************\n\n");
#endif
success = _slang_emit_code(n, A->codegen, A->program);
/* free codegen context */
+ /*
_mesa_free(A->codegen);
+ */
- return n;
+ return GL_TRUE;
}
diff --git a/src/mesa/shader/slang/slang_codegen.h b/src/mesa/shader/slang/slang_codegen.h
index ad8e2a4fd88..76d364237a3 100644
--- a/src/mesa/shader/slang/slang_codegen.h
+++ b/src/mesa/shader/slang/slang_codegen.h
@@ -29,14 +29,13 @@
#include "imports.h"
#include "slang_compile.h"
-#include "slang_ir.h"
-extern struct slang_ir_node_ *
+extern GLboolean
_slang_codegen_function(slang_assemble_ctx *A , struct slang_function_ *fun);
-extern void
-_slang_codegen_global_variable(slang_variable *var, struct gl_program *prog,
+extern GLboolean
+_slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
slang_unit_type type);
diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c
index 314c32f7077..bb1da271524 100644
--- a/src/mesa/shader/slang/slang_compile.c
+++ b/src/mesa/shader/slang/slang_compile.c
@@ -38,6 +38,7 @@
#include "slang_preprocess.h"
#include "slang_storage.h"
#include "slang_error.h"
+#include "slang_emit.h"
#include "slang_print.h"
@@ -247,6 +248,7 @@ typedef struct slang_output_ctx_
slang_var_pool *global_pool;
slang_machine *machine;
struct gl_program *program;
+ slang_gen_context *codegen;
} slang_output_ctx;
/* _slang_compile() */
@@ -1719,8 +1721,20 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O,
}
#if 1
- if (C->global_scope /*&& O->program*/)
- _slang_codegen_global_variable(var, O->program, C->type);
+ if (C->global_scope) {
+ 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;
+ A.codegen = O->codegen;
+ A.program = O->program;
+
+ _slang_codegen_global_variable(&A, var, C->type);
+ }
#endif
/* allocate global address space for a variable with a known size */
@@ -1880,6 +1894,7 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition,
A.space.structs = O->structs;
A.space.vars = O->vars;
A.program = O->program;
+ A.codegen = O->codegen;
_slang_reset_error();
@@ -1953,6 +1968,7 @@ parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit,
o.global_pool = &unit->object->varpool;
o.machine = &unit->object->machine;
o.program = program;
+ o.codegen = _slang_new_codegen_context();
/* parse individual functions and declarations */
while (*C->I != EXTERNAL_NULL) {