From d3fe7398e31d76f5d2fd36856bec7d4483b5efe7 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 8 Jan 2007 14:06:00 -0700 Subject: [PATCH] Move storage allocation functions from slang_emit.c to slang_codegen.c --- src/mesa/shader/slang/slang_codegen.c | 281 +++++++++++++++++++++ src/mesa/shader/slang/slang_emit.c | 345 +------------------------- src/mesa/shader/slang/slang_emit.h | 9 +- 3 files changed, 288 insertions(+), 347 deletions(-) diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 73ad20a73d9..df361fbb3db 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -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. */ diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 3ee583625d4..65a356050f2 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -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]); diff --git a/src/mesa/shader/slang/slang_emit.h b/src/mesa/shader/slang/slang_emit.h index 8ac17e6c824..50585a4a031 100644 --- a/src/mesa/shader/slang/slang_emit.h +++ b/src/mesa/shader/slang/slang_emit.h @@ -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, -- 2.30.2