summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/shader/slang/slang_codegen.c498
1 files changed, 256 insertions, 242 deletions
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index df361fbb3db..239f6a5e759 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -258,7 +258,7 @@ _slang_sizeof_type_specifier(const slang_type_specifier *spec)
* 4. other?
*/
static void
-slang_resolve_storage(slang_gen_context *gc, slang_ir_node *n,
+slang_allocate_storage(slang_gen_context *gc, slang_ir_node *n,
struct gl_program *prog)
{
assert(gc);
@@ -337,6 +337,259 @@ slang_resolve_storage(slang_gen_context *gc, slang_ir_node *n,
}
+/**
+ * Return the TEXTURE_*_INDEX value that corresponds to a sampler type,
+ * or -1 if the type is not a sampler.
+ */
+static GLint
+sampler_to_texture_index(const slang_type_specifier_type type)
+{
+ switch (type) {
+ case slang_spec_sampler1D:
+ return TEXTURE_1D_INDEX;
+ case slang_spec_sampler2D:
+ return TEXTURE_2D_INDEX;
+ case slang_spec_sampler3D:
+ return TEXTURE_3D_INDEX;
+ case slang_spec_samplerCube:
+ return TEXTURE_CUBE_INDEX;
+ case slang_spec_sampler1DShadow:
+ return TEXTURE_1D_INDEX; /* XXX fix */
+ case slang_spec_sampler2DShadow:
+ return TEXTURE_2D_INDEX; /* XXX fix */
+ default:
+ return -1;
+ }
+}
+
+
+/**
+ * Return the VERT_ATTRIB_* or FRAG_ATTRIB_* value that corresponds to
+ * a vertex or fragment program input variable. Return -1 if the input
+ * name is invalid.
+ * XXX return size too
+ */
+static GLint
+_slang_input_index(const char *name, GLenum target)
+{
+ struct input_info {
+ const char *Name;
+ GLuint Attrib;
+ };
+ static const struct input_info vertInputs[] = {
+ { "gl_Vertex", VERT_ATTRIB_POS },
+ { "gl_Normal", VERT_ATTRIB_NORMAL },
+ { "gl_Color", VERT_ATTRIB_COLOR0 },
+ { "gl_SecondaryColor", VERT_ATTRIB_COLOR1 },
+ { "gl_FogCoord", VERT_ATTRIB_FOG },
+ { "gl_MultiTexCoord0", VERT_ATTRIB_TEX0 },
+ { "gl_MultiTexCoord1", VERT_ATTRIB_TEX1 },
+ { "gl_MultiTexCoord2", VERT_ATTRIB_TEX2 },
+ { "gl_MultiTexCoord3", VERT_ATTRIB_TEX3 },
+ { "gl_MultiTexCoord4", VERT_ATTRIB_TEX4 },
+ { "gl_MultiTexCoord5", VERT_ATTRIB_TEX5 },
+ { "gl_MultiTexCoord6", VERT_ATTRIB_TEX6 },
+ { "gl_MultiTexCoord7", VERT_ATTRIB_TEX7 },
+ { NULL, 0 }
+ };
+ static const struct input_info fragInputs[] = {
+ { "gl_FragCoord", FRAG_ATTRIB_WPOS },
+ { "gl_Color", FRAG_ATTRIB_COL0 },
+ { "gl_SecondaryColor", FRAG_ATTRIB_COL1 },
+ { "gl_FogFragCoord", FRAG_ATTRIB_FOGC },
+ { "gl_TexCoord", FRAG_ATTRIB_TEX0 },
+ { NULL, 0 }
+ };
+ GLuint i;
+ const struct input_info *inputs
+ = (target == GL_VERTEX_PROGRAM_ARB) ? vertInputs : fragInputs;
+
+ for (i = 0; inputs[i].Name; i++) {
+ if (strcmp(inputs[i].Name, name) == 0) {
+ /* found */
+ return inputs[i].Attrib;
+ }
+ }
+ return -1;
+}
+
+
+/**
+ * Return the VERT_RESULT_* or FRAG_RESULT_* value that corresponds to
+ * a vertex or fragment program output variable. Return -1 for an invalid
+ * output name.
+ */
+static GLint
+_slang_output_index(const char *name, GLenum target)
+{
+ struct output_info {
+ const char *Name;
+ GLuint Attrib;
+ };
+ static const struct output_info vertOutputs[] = {
+ { "gl_Position", VERT_RESULT_HPOS },
+ { "gl_FrontColor", VERT_RESULT_COL0 },
+ { "gl_BackColor", VERT_RESULT_BFC0 },
+ { "gl_FrontSecondaryColor", VERT_RESULT_COL1 },
+ { "gl_BackSecondaryColor", VERT_RESULT_BFC1 },
+ { "gl_TexCoord", VERT_RESULT_TEX0 }, /* XXX indexed */
+ { "gl_FogFragCoord", VERT_RESULT_FOGC },
+ { "gl_PointSize", VERT_RESULT_PSIZ },
+ { NULL, 0 }
+ };
+ static const struct output_info fragOutputs[] = {
+ { "gl_FragColor", FRAG_RESULT_COLR },
+ { "gl_FragDepth", FRAG_RESULT_DEPR },
+ { NULL, 0 }
+ };
+ GLuint i;
+ const struct output_info *outputs
+ = (target == GL_VERTEX_PROGRAM_ARB) ? vertOutputs : fragOutputs;
+
+ for (i = 0; outputs[i].Name; i++) {
+ if (strcmp(outputs[i].Name, name) == 0) {
+ /* found */
+ return outputs[i].Attrib;
+ }
+ }
+ return -1;
+}
+
+
+/**
+ * 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;
+
+ 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);
+ 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);
+
+ }
+ 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);
+ }
+ printf("V/F ");
+ }
+ printf("VARYING ");
+ }
+ else if (var->type.qualifier == slang_qual_const) {
+ if (prog) {
+ abort();
+ }
+ else {
+ /* pre-defined global constant, like gl_MaxLights */
+ GLint size = -1;
+ store = _slang_new_ir_storage(PROGRAM_CONSTANT, -1, size);
+ }
+ printf("CONST ");
+ }
+ else if (var->type.qualifier == slang_qual_attribute) {
+ /* Vertex attribute */
+ 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);
+ 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);
+ 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);
+ }
+ printf("OUTPUT ");
+ }
+ else {
+ printf("other ");
+ }
+ printf("GLOBAL VAR %s idx %d\n", (char*) var->a_name, store?store->Index:-2);
+
+ assert(!var->aux);
+#if 1
+ var->aux = store;
+#endif
+ /**
+ XXX allocate variable storage (aux), at least the register file.
+ */
+}
+
+
+/**********************************************************************/
+
/**
* Map "_asm foo" to IR_FOO, etc.
@@ -479,7 +732,7 @@ new_var(slang_assemble_ctx *A, slang_operation *oper,
oper->var = v;
n->Swizzle = swizzle;
n->Var = v;
- slang_resolve_storage(A->codegen, n, A->program);
+ slang_allocate_storage(A->codegen, n, A->program);
return n;
}
@@ -1408,7 +1661,7 @@ _slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper)
varDecl->Var = v;
v->declared = GL_TRUE;
- slang_resolve_storage(A->codegen, varDecl, A->program);
+ slang_allocate_storage(A->codegen, varDecl, A->program);
if (oper->num_children > 0) {
/* child is initializer */
@@ -1888,242 +2141,3 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun)
return n;
}
-
-static GLint
-sampler_to_texture_index(const slang_type_specifier_type type)
-{
- switch (type) {
- case slang_spec_sampler1D:
- return TEXTURE_1D_INDEX;
- case slang_spec_sampler2D:
- return TEXTURE_2D_INDEX;
- case slang_spec_sampler3D:
- return TEXTURE_3D_INDEX;
- case slang_spec_samplerCube:
- return TEXTURE_CUBE_INDEX;
- case slang_spec_sampler1DShadow:
- return TEXTURE_1D_INDEX; /* XXX fix */
- case slang_spec_sampler2DShadow:
- return TEXTURE_2D_INDEX; /* XXX fix */
- default:
- return -1;
- }
-}
-
-
-/**
- * XXX return size too
- */
-static GLint
-_slang_input_index(const char *name, GLenum target)
-{
- struct input_info {
- const char *Name;
- GLuint Attrib;
- };
- static const struct input_info vertInputs[] = {
- { "gl_Vertex", VERT_ATTRIB_POS },
- { "gl_Normal", VERT_ATTRIB_NORMAL },
- { "gl_Color", VERT_ATTRIB_COLOR0 },
- { "gl_SecondaryColor", VERT_ATTRIB_COLOR1 },
- { "gl_FogCoord", VERT_ATTRIB_FOG },
- { "gl_MultiTexCoord0", VERT_ATTRIB_TEX0 },
- { "gl_MultiTexCoord1", VERT_ATTRIB_TEX1 },
- { "gl_MultiTexCoord2", VERT_ATTRIB_TEX2 },
- { "gl_MultiTexCoord3", VERT_ATTRIB_TEX3 },
- { "gl_MultiTexCoord4", VERT_ATTRIB_TEX4 },
- { "gl_MultiTexCoord5", VERT_ATTRIB_TEX5 },
- { "gl_MultiTexCoord6", VERT_ATTRIB_TEX6 },
- { "gl_MultiTexCoord7", VERT_ATTRIB_TEX7 },
- { NULL, 0 }
- };
- static const struct input_info fragInputs[] = {
- { "gl_FragCoord", FRAG_ATTRIB_WPOS },
- { "gl_Color", FRAG_ATTRIB_COL0 },
- { "gl_SecondaryColor", FRAG_ATTRIB_COL1 },
- { "gl_FogFragCoord", FRAG_ATTRIB_FOGC },
- { "gl_TexCoord", FRAG_ATTRIB_TEX0 },
- { NULL, 0 }
- };
- GLuint i;
- const struct input_info *inputs
- = (target == GL_VERTEX_PROGRAM_ARB) ? vertInputs : fragInputs;
-
- for (i = 0; inputs[i].Name; i++) {
- if (strcmp(inputs[i].Name, name) == 0) {
- /* found */
- return inputs[i].Attrib;
- }
- }
- return -1;
-}
-
-
-
-static GLint
-_slang_output_index(const char *name, GLenum target)
-{
- struct output_info {
- const char *Name;
- GLuint Attrib;
- };
- static const struct output_info vertOutputs[] = {
- { "gl_Position", VERT_RESULT_HPOS },
- { "gl_FrontColor", VERT_RESULT_COL0 },
- { "gl_BackColor", VERT_RESULT_BFC0 },
- { "gl_FrontSecondaryColor", VERT_RESULT_COL1 },
- { "gl_BackSecondaryColor", VERT_RESULT_BFC1 },
- { "gl_TexCoord", VERT_RESULT_TEX0 }, /* XXX indexed */
- { "gl_FogFragCoord", VERT_RESULT_FOGC },
- { "gl_PointSize", VERT_RESULT_PSIZ },
- { NULL, 0 }
- };
- static const struct output_info fragOutputs[] = {
- { "gl_FragColor", FRAG_RESULT_COLR },
- { "gl_FragDepth", FRAG_RESULT_DEPR },
- { NULL, 0 }
- };
- GLuint i;
- const struct output_info *outputs
- = (target == GL_VERTEX_PROGRAM_ARB) ? vertOutputs : fragOutputs;
-
- for (i = 0; outputs[i].Name; i++) {
- if (strcmp(outputs[i].Name, name) == 0) {
- /* found */
- return outputs[i].Attrib;
- }
- }
- return -1;
-}
-
-
-/**
- * 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;
-
- 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);
- 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);
-
- }
- 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);
- }
- printf("V/F ");
- }
- printf("VARYING ");
- }
- else if (var->type.qualifier == slang_qual_const) {
- if (prog) {
- abort();
- }
- else {
- /* pre-defined global constant, like gl_MaxLights */
- GLint size = -1;
- store = _slang_new_ir_storage(PROGRAM_CONSTANT, -1, size);
- }
- printf("CONST ");
- }
- else if (var->type.qualifier == slang_qual_attribute) {
- /* Vertex attribute */
- 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);
- 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);
- 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);
- }
- printf("OUTPUT ");
- }
- else {
- printf("other ");
- }
- printf("GLOBAL VAR %s idx %d\n", (char*) var->a_name, store?store->Index:-2);
-
- assert(!var->aux);
-#if 1
- var->aux = store;
-#endif
- /**
- XXX allocate variable storage (aux), at least the register file.
- */
-}