Move some code around, add some comments.

This commit is contained in:
Brian 2007-01-08 14:11:54 -07:00
parent d3fe7398e3
commit 483ca39bca

View file

@ -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.
*/
}