*/
#include "imports.h"
+#include "get.h"
#include "macros.h"
#include "slang_assemble.h"
#include "slang_codegen.h"
#include "program.h"
#include "prog_instruction.h"
#include "prog_parameter.h"
+#include "prog_statevars.h"
#include "slang_print.h"
_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.
*/
#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"
}
-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)
}
-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;
}
-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)
}
-/**
- * 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.
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)
{
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,
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]);