Move storage allocation functions from slang_emit.c to slang_codegen.c

This commit is contained in:
Brian 2007-01-08 14:06:00 -07:00
parent 27cc9068ce
commit d3fe7398e3
3 changed files with 288 additions and 347 deletions

View file

@ -29,6 +29,7 @@
*/
#include "imports.h"
#include "get.h"
#include "macros.h"
#include "slang_assemble.h"
#include "slang_codegen.h"
@ -42,6 +43,7 @@
#include "program.h"
#include "prog_instruction.h"
#include "prog_parameter.h"
#include "prog_statevars.h"
#include "slang_print.h"
@ -57,6 +59,285 @@ static slang_ir_node *
_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.
* \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 constant_info {
const char *Name;
const GLenum Token;
};
static const struct constant_info info[] = {
{ "gl_MaxLights", GL_MAX_LIGHTS },
{ "gl_MaxClipPlanes", GL_MAX_CLIP_PLANES },
{ "gl_MaxTextureUnits", GL_MAX_TEXTURE_UNITS },
{ "gl_MaxTextureCoords", GL_MAX_TEXTURE_COORDS },
{ "gl_MaxVertexAttribs", GL_MAX_VERTEX_ATTRIBS },
{ "gl_MaxVertexUniformComponents", GL_MAX_VERTEX_UNIFORM_COMPONENTS },
{ "gl_MaxVaryingFloats", GL_MAX_VARYING_FLOATS },
{ "gl_MaxVertexTextureImageUnits", GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS },
{ "gl_MaxTextureImageUnits", GL_MAX_TEXTURE_IMAGE_UNITS },
{ "gl_MaxFragmentUniformComponents", GL_MAX_FRAGMENT_UNIFORM_COMPONENTS },
{ "gl_MaxCombinedTextureImageUnits", GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS },
{ NULL, 0 }
};
GLuint i;
GLuint swizzle; /* XXX use this */
for (i = 0; info[i].Name; i++) {
if (strcmp(info[i].Name, name) == 0) {
/* found */
GLfloat value = -1.0;
GLint pos;
_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);
return pos;
}
}
return -1;
}
/**
* Determine if 'name' is a state variable. If so, create a new program
* parameter for it, and return the param's index. Else, return -1.
*/
static GLint
slang_lookup_statevar(const char *name, GLint index,
struct gl_program_parameter_list *paramList)
{
struct state_info {
const char *Name;
const GLuint NumRows; /** for matrices */
const GLuint Swizzle;
const GLint Indexes[6];
};
static const struct state_info state[] = {
{ "gl_ModelViewMatrix", 4, SWIZZLE_NOOP,
{ STATE_MATRIX, STATE_MODELVIEW, 0, 0, 0, 0 } },
{ "gl_NormalMatrix", 3, SWIZZLE_NOOP,
{ STATE_MATRIX, STATE_MODELVIEW, 0, 0, 0, 0 } },
{ "gl_ProjectionMatrix", 4, SWIZZLE_NOOP,
{ STATE_MATRIX, STATE_PROJECTION, 0, 0, 0, 0 } },
{ "gl_ModelViewProjectionMatrix", 4, SWIZZLE_NOOP,
{ STATE_MATRIX, STATE_MVP, 0, 0, 0, 0 } },
{ "gl_TextureMatrix", 4, SWIZZLE_NOOP,
{ STATE_MATRIX, STATE_TEXTURE, 0, 0, 0, 0 } },
{ NULL, 0, 0, {0, 0, 0, 0, 0, 0} }
};
GLuint i;
for (i = 0; state[i].Name; i++) {
if (strcmp(state[i].Name, name) == 0) {
/* found */
if (paramList) {
if (state[i].NumRows > 1) {
/* a matrix */
GLuint j;
GLint pos[4], indexesCopy[6];
/* make copy of state tokens */
for (j = 0; j < 6; j++)
indexesCopy[j] = state[i].Indexes[j];
/* load rows */
for (j = 0; j < state[i].NumRows; j++) {
indexesCopy[3] = indexesCopy[4] = j; /* jth row of matrix */
pos[j] = _mesa_add_state_reference(paramList, indexesCopy);
assert(pos[j] >= 0);
}
return pos[0];
}
else {
/* non-matrix state */
GLint pos
= _mesa_add_state_reference(paramList, state[i].Indexes);
assert(pos >= 0);
return pos;
}
}
}
}
return -1;
}
static GLboolean
is_sampler_type(const slang_fully_specified_type *t)
{
switch (t->specifier.type) {
case slang_spec_sampler1D:
case slang_spec_sampler2D:
case slang_spec_sampler3D:
case slang_spec_samplerCube:
case slang_spec_sampler1DShadow:
case slang_spec_sampler2DShadow:
return GL_TRUE;
default:
return GL_FALSE;
}
}
static GLuint
_slang_sizeof_struct(const slang_struct *s)
{
return 0;
}
static GLuint
_slang_sizeof_type_specifier(const slang_type_specifier *spec)
{
switch (spec->type) {
case slang_spec_void:
abort();
return 0;
case slang_spec_bool:
return 1;
case slang_spec_bvec2:
return 2;
case slang_spec_bvec3:
return 3;
case slang_spec_bvec4:
return 4;
case slang_spec_int:
return 1;
case slang_spec_ivec2:
return 2;
case slang_spec_ivec3:
return 3;
case slang_spec_ivec4:
return 4;
case slang_spec_float:
return 1;
case slang_spec_vec2:
return 2;
case slang_spec_vec3:
return 3;
case slang_spec_vec4:
return 4;
case slang_spec_mat2:
return 2 * 2;
case slang_spec_mat3:
return 3 * 3;
case slang_spec_mat4:
return 4 * 4;
case slang_spec_sampler1D:
case slang_spec_sampler2D:
case slang_spec_sampler3D:
case slang_spec_samplerCube:
case slang_spec_sampler1DShadow:
case slang_spec_sampler2DShadow:
return 1; /* special case */
case slang_spec_struct:
return _slang_sizeof_struct(spec->_struct);
case slang_spec_array:
return 1; /* XXX */
default:
abort();
return 0;
}
return 0;
}
/**
* Allocate storage info for an IR node (n->Store).
* We may do any of the following:
* 1. Compute Store->File/Index for program inputs/outputs/uniforms/etc.
* 2. Allocate storage for user-declared variables.
* 3. Allocate intermediate/unnamed storage for complex expressions.
* 4. other?
*/
static void
slang_resolve_storage(slang_gen_context *gc, slang_ir_node *n,
struct gl_program *prog)
{
assert(gc);
assert(n);
assert(n->Opcode == IR_VAR_DECL || n->Opcode == IR_VAR);
assert(prog);
if (!n->Store) {
/* allocate storage info for this node */
if (n->Var && n->Var->aux) {
/* node storage info = var storage info */
n->Store = (slang_ir_storage *) n->Var->aux;
}
else {
/* alloc new storage info */
n->Store = _slang_new_ir_storage(PROGRAM_UNDEFINED, -1, -5);
if (n->Var)
n->Var->aux = n->Store;
}
}
if (n->Opcode == IR_VAR_DECL) {
/* variable declaration */
assert(n->Var);
assert(!is_sampler_type(&n->Var->type));
assert(n->Store->Index < 0);
n->Store->File = PROGRAM_TEMPORARY;
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;
}
assert(n->Store->File != PROGRAM_UNDEFINED);
if (n->Store->Index < 0) {
/* determine storage location for this var */
assert(n->Var);
assert(n->Store->Size > 0);
if (n->Store->File == PROGRAM_STATE_VAR) {
GLint i = slang_lookup_statevar((char *) n->Var->a_name, 0,
prog->Parameters);
assert(i >= 0);
if (i >= 0) {
assert(n->Store->File == PROGRAM_STATE_VAR /*||
n->Store->File == PROGRAM_UNIFORM*/);
n->Store->File = PROGRAM_STATE_VAR;
n->Store->Index = i;
return;
}
}
else if (n->Store->File == PROGRAM_CONSTANT) {
GLint i = slang_lookup_constant((char *) n->Var->a_name, 0,
prog->Parameters);
assert(i >= 0);
if (i >= 0) {
n->Store->File = PROGRAM_CONSTANT;
n->Store->Index = i;
return;
}
}
else {
/* what's this??? */
abort();
}
}
}
/**
* Map "_asm foo" to IR_FOO, etc.
*/

View file

@ -30,12 +30,10 @@
#include "imports.h"
#include "context.h"
#include "get.h"
#include "macros.h"
#include "program.h"
#include "prog_instruction.h"
#include "prog_parameter.h"
#include "prog_statevars.h"
#include "slang_emit.h"
@ -201,93 +199,6 @@ storage_string(const slang_ir_storage *st)
}
static GLuint
sizeof_struct(const slang_struct *s)
{
return 0;
}
GLuint
_slang_sizeof_type_specifier(const slang_type_specifier *spec)
{
switch (spec->type) {
case slang_spec_void:
abort();
return 0;
case slang_spec_bool:
return 1;
case slang_spec_bvec2:
return 2;
case slang_spec_bvec3:
return 3;
case slang_spec_bvec4:
return 4;
case slang_spec_int:
return 1;
case slang_spec_ivec2:
return 2;
case slang_spec_ivec3:
return 3;
case slang_spec_ivec4:
return 4;
case slang_spec_float:
return 1;
case slang_spec_vec2:
return 2;
case slang_spec_vec3:
return 3;
case slang_spec_vec4:
return 4;
case slang_spec_mat2:
return 2 * 2;
case slang_spec_mat3:
return 3 * 3;
case slang_spec_mat4:
return 4 * 4;
case slang_spec_sampler1D:
case slang_spec_sampler2D:
case slang_spec_sampler3D:
case slang_spec_samplerCube:
case slang_spec_sampler1DShadow:
case slang_spec_sampler2DShadow:
return 1; /* special case */
case slang_spec_struct:
return sizeof_struct(spec->_struct);
case slang_spec_array:
return 1; /* XXX */
default:
abort();
return 0;
}
return 0;
}
static GLuint
sizeof_type(const slang_fully_specified_type *t)
{
return _slang_sizeof_type_specifier(&t->specifier);
}
static GLboolean
is_sampler_type(const slang_fully_specified_type *t)
{
switch (t->specifier.type) {
case slang_spec_sampler1D:
case slang_spec_sampler2D:
case slang_spec_sampler3D:
case slang_spec_samplerCube:
case slang_spec_sampler1DShadow:
case slang_spec_sampler2DShadow:
return GL_TRUE;
default:
return GL_FALSE;
}
}
#define IND 0
void
slang_print_ir(const slang_ir_node *n, int indent)
@ -365,8 +276,8 @@ slang_print_ir(const slang_ir_node *n, int indent)
}
static GLint
alloc_temporary(slang_gen_context *gc, GLint size)
GLint
_slang_alloc_temporary(slang_gen_context *gc, GLint size)
{
const GLuint sz4 = (size + 3) / 4;
GLuint i, j;
@ -389,14 +300,6 @@ alloc_temporary(slang_gen_context *gc, GLint size)
}
static GLint
alloc_sampler(slang_gen_context *gc)
{
GLint sampler = gc->NumSamplers;
gc->NumSamplers++;
return sampler;
}
static GLboolean
is_temporary(const slang_gen_context *gc, const slang_ir_storage *st)
@ -420,123 +323,6 @@ free_temporary(slang_gen_context *gc, GLuint r, GLint size)
}
/**
* Lookup a named constant and allocate storage for the parameter in
* the given parameter list.
* \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 constant_info {
const char *Name;
const GLenum Token;
};
static const struct constant_info info[] = {
{ "gl_MaxLights", GL_MAX_LIGHTS },
{ "gl_MaxClipPlanes", GL_MAX_CLIP_PLANES },
{ "gl_MaxTextureUnits", GL_MAX_TEXTURE_UNITS },
{ "gl_MaxTextureCoords", GL_MAX_TEXTURE_COORDS },
{ "gl_MaxVertexAttribs", GL_MAX_VERTEX_ATTRIBS },
{ "gl_MaxVertexUniformComponents", GL_MAX_VERTEX_UNIFORM_COMPONENTS },
{ "gl_MaxVaryingFloats", GL_MAX_VARYING_FLOATS },
{ "gl_MaxVertexTextureImageUnits", GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS },
{ "gl_MaxTextureImageUnits", GL_MAX_TEXTURE_IMAGE_UNITS },
{ "gl_MaxFragmentUniformComponents", GL_MAX_FRAGMENT_UNIFORM_COMPONENTS },
{ "gl_MaxCombinedTextureImageUnits", GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS },
{ NULL, 0 }
};
GLuint i;
GLuint swizzle; /* XXX use this */
for (i = 0; info[i].Name; i++) {
if (strcmp(info[i].Name, name) == 0) {
/* found */
GLfloat value = -1.0;
GLint pos;
_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);
return pos;
}
}
return -1;
}
/**
* Determine if 'name' is a state variable. If so, create a new program
* parameter for it, and return the param's index. Else, return -1.
*/
static GLint
slang_lookup_statevar(const char *name, GLint index,
struct gl_program_parameter_list *paramList)
{
struct state_info {
const char *Name;
const GLuint NumRows; /** for matrices */
const GLuint Swizzle;
const GLint Indexes[6];
};
static const struct state_info state[] = {
{ "gl_ModelViewMatrix", 4, SWIZZLE_NOOP,
{ STATE_MATRIX, STATE_MODELVIEW, 0, 0, 0, 0 } },
{ "gl_NormalMatrix", 3, SWIZZLE_NOOP,
{ STATE_MATRIX, STATE_MODELVIEW, 0, 0, 0, 0 } },
{ "gl_ProjectionMatrix", 4, SWIZZLE_NOOP,
{ STATE_MATRIX, STATE_PROJECTION, 0, 0, 0, 0 } },
{ "gl_ModelViewProjectionMatrix", 4, SWIZZLE_NOOP,
{ STATE_MATRIX, STATE_MVP, 0, 0, 0, 0 } },
{ "gl_TextureMatrix", 4, SWIZZLE_NOOP,
{ STATE_MATRIX, STATE_TEXTURE, 0, 0, 0, 0 } },
{ NULL, 0, 0, {0, 0, 0, 0, 0, 0} }
};
GLuint i;
for (i = 0; state[i].Name; i++) {
if (strcmp(state[i].Name, name) == 0) {
/* found */
if (paramList) {
if (state[i].NumRows > 1) {
/* a matrix */
GLuint j;
GLint pos[4], indexesCopy[6];
/* make copy of state tokens */
for (j = 0; j < 6; j++)
indexesCopy[j] = state[i].Indexes[j];
/* load rows */
for (j = 0; j < state[i].NumRows; j++) {
indexesCopy[3] = indexesCopy[4] = j; /* jth row of matrix */
pos[j] = _mesa_add_state_reference(paramList, indexesCopy);
assert(pos[j] >= 0);
}
return pos[0];
}
else {
/* non-matrix state */
GLint pos
= _mesa_add_state_reference(paramList, state[i].Indexes);
assert(pos >= 0);
return pos;
}
}
}
}
return -1;
}
static GLint
slang_alloc_uniform(struct gl_program *prog, const char *name, GLuint size)
{
GLint i = _mesa_add_uniform(prog->Parameters, name, size);
return i;
}
/**
* Allocate temporary storage for an intermediate result (such as for
* a multiply or add, etc.
@ -548,112 +334,11 @@ slang_alloc_temp_storage(slang_gen_context *gc, slang_ir_node *n, GLint size)
assert(!n->Var);
assert(!n->Store);
assert(size > 0);
indx = alloc_temporary(gc, size);
indx = _slang_alloc_temporary(gc, size);
n->Store = _slang_new_ir_storage(PROGRAM_TEMPORARY, indx, size);
}
/**
* Allocate storage info for an IR node (n->Store).
* We may do any of the following:
* 1. Compute Store->File/Index for program inputs/outputs/uniforms/etc.
* 2. Allocate storage for user-declared variables.
* 3. Allocate intermediate/unnamed storage for complex expressions.
* 4. other?
*/
void
slang_resolve_storage(slang_gen_context *gc, slang_ir_node *n,
struct gl_program *prog)
{
assert(gc);
assert(n);
assert(prog);
if (!n->Store) {
/* allocate storage info for this node */
if (n->Var && n->Var->aux) {
/* node storage info = var storage info */
n->Store = (slang_ir_storage *) n->Var->aux;
}
else {
/* alloc new storage info */
n->Store = _slang_new_ir_storage(PROGRAM_UNDEFINED, -1, -5);
if (n->Var)
n->Var->aux = n->Store;
}
}
if (n->Opcode == IR_VAR_DECL) {
/* storage declaration */
assert(n->Var);
assert(!is_sampler_type(&n->Var->type));
assert(n->Store->Index < 0);
if (n->Store->Index < 0) { /* XXX assert this? */
assert(gc);
n->Store->File = PROGRAM_TEMPORARY;
n->Store->Size = sizeof_type(&n->Var->type);
n->Store->Index = 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;
}
assert(n->Store->Size > 0);
return;
}
/*
assert(!is_sampler_type(&n->Var->type));
*/
assert(n->Opcode == IR_VAR);
assert(n->Store->File != PROGRAM_UNDEFINED);
if (n->Store->Index < 0) {
/* determine storage location for this var */
GLint i;
assert(n->Var);
assert(n->Store->Size > 0);
if (n->Store->Size < 0) {
/* determine var/storage size now */
abort();
n->Store->Size = sizeof_type(&n->Var->type);
assert(n->Store->Size > 0);
}
if (n->Store->File == PROGRAM_STATE_VAR) {
i = slang_lookup_statevar((char *) n->Var->a_name, 0, prog->Parameters);
assert(i >= 0);
if (i >= 0) {
assert(n->Store->File == PROGRAM_STATE_VAR /*||
n->Store->File == PROGRAM_UNIFORM*/);
n->Store->File = PROGRAM_STATE_VAR;
n->Store->Index = i;
return;
}
}
else if (n->Store->File == PROGRAM_CONSTANT) {
i = slang_lookup_constant((char *) n->Var->a_name, 0,
prog->Parameters);
assert(i >= 0);
if (i >= 0) {
n->Store->File = PROGRAM_CONSTANT;
n->Store->Index = i;
return;
}
}
else {
/* what's this??? */
abort();
}
}
}
static slang_ir_storage *
alloc_constant(const GLfloat v[], GLuint size, struct gl_program *prog)
{
@ -775,11 +460,7 @@ emit_binop(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
inst = new_instruction(prog, info->InstOpcode);
/* alloc temp storage for the result: */
if (!n->Store || n->Store->File == PROGRAM_UNDEFINED) {
#if 1
slang_alloc_temp_storage(gc, n, info->ResultSize);
#else
slang_resolve_storage(gc, n, prog);
#endif
}
storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store,
@ -927,29 +608,13 @@ emit(slang_gen_context *gc, slang_ir_node *n, struct gl_program *prog)
return inst;
break;
case IR_VAR_DECL:
#if 0000
slang_resolve_storage(gc, n, prog);
#endif
case IR_VAR:
/* Storage should have already been resolved/allocated */
assert(n->Store);
assert(n->Store->File != PROGRAM_UNDEFINED);
assert(n->Store->Index >= 0);
assert(n->Store->Size > 0);
break;
case IR_VAR:
/*printf("Gen: var ref\n");*/
{
assert(n->Store);
assert(n->Store->File != PROGRAM_UNDEFINED);
assert(n->Store->Index >= 0);
#if 00
int b = !n->Store || n->Store->Index < 0;
if (b)
slang_resolve_storage(gc, n, prog);
/*assert(n->Store->Index >= 0);*/
#endif
assert(n->Store->Size > 0);
}
break;
case IR_MOVE:
/* rhs */
assert(n->Children[1]);

View file

@ -48,13 +48,8 @@ extern slang_ir_storage *
_slang_clone_ir_storage(slang_ir_storage *store);
extern GLuint
_slang_sizeof_type_specifier(const slang_type_specifier *spec);
extern void
slang_resolve_storage(slang_gen_context *gc, slang_ir_node *n,
struct gl_program *prog);
extern GLint
_slang_alloc_temporary(slang_gen_context *gc, GLint size);
extern GLboolean
_slang_emit_code(slang_ir_node *n, slang_gen_context *gc,