mesa: Branch 'glsl-compiler-1' - 4 commits

Brian Paul brianp at kemper.freedesktop.org
Wed Mar 21 21:42:39 UTC 2007


 src/mesa/shader/prog_instruction.h           |    1 
 src/mesa/shader/slang/slang_codegen.c        |   69 +++++--
 src/mesa/shader/slang/slang_compile_struct.c |  248 +++++++++++++--------------
 src/mesa/shader/slang/slang_emit.c           |   72 +++++++
 src/mesa/shader/slang/slang_ir.h             |    1 
 src/mesa/shader/slang/slang_storage.c        |    2 
 src/mesa/shader/slang/slang_storage.h        |    2 
 7 files changed, 250 insertions(+), 145 deletions(-)

New commits:
diff-tree 629ec2b06be40a32fa820a105e40e7b894acc84e (from 2500d82d0dc5015dc648067455231b7b963b54a5)
Author: Brian <brian at yutani.localnet.net>
Date:   Wed Mar 21 15:40:54 2007 -0600

    added SWIZZLE_XYZW

diff --git a/src/mesa/shader/prog_instruction.h b/src/mesa/shader/prog_instruction.h
index 66abb10..12e8480 100644
--- a/src/mesa/shader/prog_instruction.h
+++ b/src/mesa/shader/prog_instruction.h
@@ -57,6 +57,7 @@
 #define GET_SWZ(swz, idx)      (((swz) >> ((idx)*3)) & 0x7)
 #define GET_BIT(msk, idx)      (((msk) >> (idx)) & 0x1)
 
+#define SWIZZLE_XYZW MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W)
 #define SWIZZLE_XXXX MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X)
 #define SWIZZLE_YYYY MAKE_SWIZZLE4(SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y)
 #define SWIZZLE_ZZZZ MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z)
diff-tree 2500d82d0dc5015dc648067455231b7b963b54a5 (from 97c9b3ecc6da6058cf17840f6448617c7dc2be75)
Author: Brian <brian at yutani.localnet.net>
Date:   Wed Mar 21 15:40:39 2007 -0600

    Support for user-defined structures.
    
    struct == and != operators not finished yet.  Struct assignment works though.

diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 45868c7..89a8915 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -78,6 +78,35 @@ is_sampler_type(const slang_fully_specif
 }
 
 
+/**
+ * Return the offset (in floats or ints) of the named field within
+ * the given struct.  Return -1 if field not found.
+ * If field is NULL, return the size of the struct instead.
+ */
+static GLint
+_slang_field_offset(const slang_type_specifier *spec, slang_atom field)
+{
+   GLint offset = 0;
+   GLuint i;
+   for (i = 0; i < spec->_struct->fields->num_variables; i++) {
+      const slang_variable *v = spec->_struct->fields->variables[i];
+      const GLuint sz = _slang_sizeof_type_specifier(&v->type.specifier);
+      if (sz > 1) {
+         /* types larger than 1 float are register (4-float) aligned */
+         offset = (offset + 3) & ~3;
+      }
+      if (field && v->a_name == field) {
+         return offset;
+      }
+      offset += sz;
+   }
+   if (field)
+      return -1; /* field not found */
+   else
+      return offset;  /* struct size */
+}
+
+
 GLuint
 _slang_sizeof_type_specifier(const slang_type_specifier *spec)
 {
@@ -122,20 +151,9 @@ _slang_sizeof_type_specifier(const slang
    case SLANG_SPEC_SAMPLER2DSHADOW:
    case SLANG_SPEC_SAMPLER2DRECT:
    case SLANG_SPEC_SAMPLER2DRECTSHADOW:
-      return 1; /* special case */
+      return 1; /* a sampler is basically just an integer index */
    case SLANG_SPEC_STRUCT:
-      {
-         GLuint sum = 0, i;
-         for (i = 0; i < spec->_struct->fields->num_variables; i++) {
-            slang_variable *v = spec->_struct->fields->variables[i];
-            GLuint sz = _slang_sizeof_type_specifier(&v->type.specifier);
-            /* XXX verify padding */
-            if (sz < 4)
-               sz = 4;
-            sum += sz;
-         }
-         return sum;
-      }
+      return _slang_field_offset(spec, 0); /* special use */
    case SLANG_SPEC_ARRAY:
       return _slang_sizeof_type_specifier(spec->_array);
    default:
@@ -2034,6 +2052,7 @@ _slang_gen_field(slang_assemble_ctx * A,
 {
    slang_typeinfo ti;
 
+   /* type of struct */
    slang_typeinfo_construct(&ti);
    _slang_typeof_operation(A, &oper->children[0], &ti);
 
@@ -2079,20 +2098,38 @@ _slang_gen_field(slang_assemble_ctx * A,
       /* oper->children[0] is the base */
       /* oper->a_id is the field name */
       slang_ir_node *base, *n;
-      GLint size = 4; /* XXX fix? */
+      slang_typeinfo field_ti;
+      GLint fieldSize, fieldOffset;
+      /* type of field */
+      slang_typeinfo_construct(&field_ti);
+      _slang_typeof_operation(A, oper, &field_ti);
+
+      fieldSize = _slang_sizeof_type_specifier(&field_ti.spec);
+      fieldOffset = _slang_field_offset(&ti.spec, oper->a_id);
+
+      if (fieldOffset < 0) {
+         slang_info_log_error(A->log,
+                              "\"%s\" is not a member of struct \"%s\"",
+                              (char *) oper->a_id,
+                              (char *) ti.spec._struct->a_name);
+         return NULL;
+      }
+      assert(fieldSize >= 0);
 
       base = _slang_gen_operation(A, &oper->children[0]);
       if (!base) {
-         /* error previously found */
+         /* error msg should have already been logged */
          return NULL;
       }
 
       n = new_node1(IR_FIELD, base);
       if (n) {
          n->Field = (char *) oper->a_id;
+         n->FieldOffset = fieldOffset;
+         assert(n->FieldOffset >= 0);
          n->Store = _slang_new_ir_storage(base->Store->File,
                                           base->Store->Index,
-                                          size);
+                                          fieldSize);
       }
       return n;
 
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 25c107d..e578c82 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -771,6 +771,53 @@ emit_arith(slang_emit_info *emitInfo, sl
 
 
 /**
+ * Emit code for == and != operators.  These could normally be handled
+ * by emit_arith() except we need to be able to handle structure comparisons.
+ */
+static struct prog_instruction *
+emit_compare(slang_emit_info *emitInfo, slang_ir_node *n)
+{
+   struct prog_instruction *inst;
+
+   assert(n->Opcode == IR_SEQUAL || n->Opcode == IR_SNEQUAL);
+
+   /* gen code for children */
+   emit(emitInfo, n->Children[0]);
+   emit(emitInfo, n->Children[1]);
+
+   assert(n->Children[0]->Store->Size == n->Children[1]->Store->Size);
+
+   /* gen this instruction and src registers */
+   inst = new_instruction(emitInfo,
+                          (n->Opcode == IR_SEQUAL) ? OPCODE_SEQ : OPCODE_SNE);
+   if (n->Children[0]->Store->Size > 4) {
+      /* struct compare */
+      _mesa_problem(NULL, "struct compare not implemented!");
+      return NULL;
+   }
+   else {
+      /* small/simple types */
+      storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store);
+      storage_to_src_reg(&inst->SrcReg[1], n->Children[1]->Store);
+   }
+
+   /* free temps */
+   free_temp_storage(emitInfo->vt, n->Children[0]);
+   free_temp_storage(emitInfo->vt, n->Children[1]);
+
+   /* result storage */
+   if (!n->Store) {
+      if (!alloc_temp_storage(emitInfo, n, 1))  /* 1 bool */
+         return NULL;
+   }
+   storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
+
+   return inst;
+}
+
+
+
+/**
  * Generate code for an IR_CLAMP instruction.
  */
 static struct prog_instruction *
@@ -1337,7 +1384,6 @@ emit_array_element(slang_emit_info *emit
       return NULL;
    }
 
-
    if (n->Children[1]->Opcode == IR_FLOAT) {
       /* Constant index */
       const GLint arrayAddr = n->Children[0]->Store->Index;
@@ -1365,7 +1411,16 @@ emit_struct_field(slang_emit_info *emitI
       n->Store->Index = _slang_alloc_statevar(n, emitInfo->prog->Parameters);
    }
    else {
-      _mesa_problem(NULL, "structs/fields not supported yet");
+      GLint offset = n->FieldOffset / 4;
+      assert(n->Children[0]->Store->Index >= 0);
+      n->Store->Index = n->Children[0]->Store->Index + offset;
+      if (n->Store->Size == 1) {
+         GLint swz = n->FieldOffset % 4;
+         n->Store->Swizzle = MAKE_SWIZZLE4(swz, swz, swz, swz);
+      }
+      else {
+         n->Store->Swizzle = SWIZZLE_XYZW;
+      }
    }
    return NULL; /* no instruction */
 }
@@ -1427,10 +1482,10 @@ emit(slang_emit_info *emitInfo, slang_ir
       if (emitInfo->EmitComments) {
          /* emit NOP with comment describing the variable's storage location */
          char s[1000];
-         sprintf(s, "TEMP[%d]%s = %s (size %d)",
+         sprintf(s, "TEMP[%d]%s = variable %s (size %d)",
                  n->Store->Index,
                  _mesa_swizzle_string(n->Store->Swizzle, 0, GL_FALSE), 
-                 (char *) n->Var->a_name,
+                 (n->Var ? (char *) n->Var->a_name : "anonymous"),
                  n->Store->Size);
          inst = new_instruction(emitInfo, OPCODE_NOP);
          inst->Comment = _mesa_strdup(s);
@@ -1503,8 +1558,6 @@ emit(slang_emit_info *emitInfo, slang_ir
    case IR_CROSS:
    case IR_MIN:
    case IR_MAX:
-   case IR_SEQUAL:
-   case IR_SNEQUAL:
    case IR_SGE:
    case IR_SGT:
    case IR_SLE:
@@ -1515,6 +1568,11 @@ emit(slang_emit_info *emitInfo, slang_ir
    /* trinary operators */
    case IR_LRP:
       return emit_arith(emitInfo, n);
+
+   case IR_SEQUAL:
+   case IR_SNEQUAL:
+      return emit_compare(emitInfo, n);
+
    case IR_CLAMP:
       return emit_clamp(emitInfo, n);
    case IR_TEX:
@@ -1600,7 +1658,7 @@ _slang_emit_code(slang_ir_node *n, slang
    emitInfo.prog = prog;
 
    emitInfo.EmitHighLevelInstructions = ctx->Shader.EmitHighLevelInstructions;
-   emitInfo.EmitComments = ctx->Shader.EmitComments;
+   emitInfo.EmitComments = 1+ctx->Shader.EmitComments;
 
    (void) emit(&emitInfo, n);
 
diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h
index b733d10..3c5526e 100644
--- a/src/mesa/shader/slang/slang_ir.h
+++ b/src/mesa/shader/slang/slang_ir.h
@@ -152,6 +152,7 @@ typedef struct slang_ir_node_
 
    /** special fields depending on Opcode: */
    const char *Field;  /**< If Opcode == IR_FIELD */
+   int FieldOffset;  /**< If Opcode == IR_FIELD */
    GLuint Writemask;  /**< If Opcode == IR_MOVE */
    GLfloat Value[4];    /**< If Opcode == IR_FLOAT */
    slang_variable *Var;  /**< If Opcode == IR_VAR or IR_VAR_DECL */
diff-tree 97c9b3ecc6da6058cf17840f6448617c7dc2be75 (from e02b989ff96cb706b9cbbea519034e3403b3ecfa)
Author: Brian <brian at yutani.localnet.net>
Date:   Wed Mar 21 15:38:46 2007 -0600

    disable apparently unused code

diff --git a/src/mesa/shader/slang/slang_storage.c b/src/mesa/shader/slang/slang_storage.c
index 04995aa..6d6a6d9 100644
--- a/src/mesa/shader/slang/slang_storage.c
+++ b/src/mesa/shader/slang/slang_storage.c
@@ -258,6 +258,7 @@ _slang_sizeof_aggregate(const slang_stor
 }
 
 
+#if 0
 GLboolean
 _slang_flatten_aggregate(slang_storage_aggregate * flat,
                          const slang_storage_aggregate * agg)
@@ -299,3 +300,4 @@ _slang_flatten_aggregate(slang_storage_a
    }
    return GL_TRUE;
 }
+#endif
diff --git a/src/mesa/shader/slang/slang_storage.h b/src/mesa/shader/slang/slang_storage.h
index b02931f..d3047ee 100644
--- a/src/mesa/shader/slang/slang_storage.h
+++ b/src/mesa/shader/slang/slang_storage.h
@@ -125,6 +125,7 @@ extern GLuint
 _slang_sizeof_aggregate (const slang_storage_aggregate *);
 
 
+#if 0
 /**
  * Converts structured aggregate to a flat one, with arrays of generic
  * type being one-element long.  Returns GL_TRUE on success.  Returns
@@ -134,5 +135,6 @@ extern GLboolean
 _slang_flatten_aggregate (slang_storage_aggregate *,
                           const slang_storage_aggregate *);
 
+#endif
 
 #endif /* SLANG_STORAGE_H */
diff-tree e02b989ff96cb706b9cbbea519034e3403b3ecfa (from 23d31efc167f09d47635352f697ffcb087d3ebbd)
Author: Brian <brian at yutani.localnet.net>
Date:   Wed Mar 21 14:45:34 2007 -0600

    indent

diff --git a/src/mesa/shader/slang/slang_compile_struct.c b/src/mesa/shader/slang/slang_compile_struct.c
index 5d876b2..89c79d4 100644
--- a/src/mesa/shader/slang/slang_compile_struct.c
+++ b/src/mesa/shader/slang/slang_compile_struct.c
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.5
+ * Version:  6.5.3
  *
- * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2005-2007  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -31,139 +31,143 @@
 #include "imports.h"
 #include "slang_compile.h"
 
-/*
- * slang_struct_scope
- */
 
 GLvoid
-_slang_struct_scope_ctr (slang_struct_scope *self)
+_slang_struct_scope_ctr(slang_struct_scope * self)
 {
    self->structs = NULL;
    self->num_structs = 0;
    self->outer_scope = NULL;
 }
 
-void slang_struct_scope_destruct (slang_struct_scope *scope)
+void
+slang_struct_scope_destruct(slang_struct_scope * scope)
 {
-	unsigned int i;
+   GLuint i;
 
-	for (i = 0; i < scope->num_structs; i++)
-		slang_struct_destruct (scope->structs + i);
-	slang_alloc_free (scope->structs);
-	/* do not free scope->outer_scope */
-}
-
-int slang_struct_scope_copy (slang_struct_scope *x, const slang_struct_scope *y)
-{
-	slang_struct_scope z;
-	unsigned int i;
-
-   _slang_struct_scope_ctr (&z);
-	z.structs = (slang_struct *) slang_alloc_malloc (y->num_structs * sizeof (slang_struct));
-	if (z.structs == NULL)
-	{
-		slang_struct_scope_destruct (&z);
-		return 0;
-	}
-	for (z.num_structs = 0; z.num_structs < y->num_structs; z.num_structs++)
-		if (!slang_struct_construct (&z.structs[z.num_structs]))
-		{
-			slang_struct_scope_destruct (&z);
-			return 0;
-		}
-	for (i = 0; i < z.num_structs; i++)
-		if (!slang_struct_copy (&z.structs[i], &y->structs[i]))
-		{
-			slang_struct_scope_destruct (&z);
-			return 0;
-		}
-	z.outer_scope = y->outer_scope;
-	slang_struct_scope_destruct (x);
-	*x = z;
-	return 1;
-}
-
-slang_struct *slang_struct_scope_find (slang_struct_scope *stru, slang_atom a_name, int all_scopes)
-{
-	unsigned int i;
-
-	for (i = 0; i < stru->num_structs; i++)
-		if (a_name == stru->structs[i].a_name)
-			return &stru->structs[i];
-	if (all_scopes && stru->outer_scope != NULL)
-		return slang_struct_scope_find (stru->outer_scope, a_name, 1);
-	return NULL;
+   for (i = 0; i < scope->num_structs; i++)
+      slang_struct_destruct(scope->structs + i);
+   slang_alloc_free(scope->structs);
+   /* do not free scope->outer_scope */
+}
+
+int
+slang_struct_scope_copy(slang_struct_scope * x, const slang_struct_scope * y)
+{
+   slang_struct_scope z;
+   GLuint i;
+
+   _slang_struct_scope_ctr(&z);
+   z.structs =
+      (slang_struct *) slang_alloc_malloc(y->num_structs *
+                                          sizeof(slang_struct));
+   if (z.structs == NULL) {
+      slang_struct_scope_destruct(&z);
+      return 0;
+   }
+   for (z.num_structs = 0; z.num_structs < y->num_structs; z.num_structs++)
+      if (!slang_struct_construct(&z.structs[z.num_structs])) {
+         slang_struct_scope_destruct(&z);
+         return 0;
+      }
+   for (i = 0; i < z.num_structs; i++)
+      if (!slang_struct_copy(&z.structs[i], &y->structs[i])) {
+         slang_struct_scope_destruct(&z);
+         return 0;
+      }
+   z.outer_scope = y->outer_scope;
+   slang_struct_scope_destruct(x);
+   *x = z;
+   return 1;
+}
+
+slang_struct *
+slang_struct_scope_find(slang_struct_scope * stru, slang_atom a_name,
+                        int all_scopes)
+{
+   GLuint i;
+
+   for (i = 0; i < stru->num_structs; i++)
+      if (a_name == stru->structs[i].a_name)
+         return &stru->structs[i];
+   if (all_scopes && stru->outer_scope != NULL)
+      return slang_struct_scope_find(stru->outer_scope, a_name, 1);
+   return NULL;
 }
 
 /* slang_struct */
 
-int slang_struct_construct (slang_struct *stru)
+int
+slang_struct_construct(slang_struct * stru)
 {
-	stru->a_name = SLANG_ATOM_NULL;
-	stru->fields = (slang_variable_scope *) slang_alloc_malloc (sizeof (slang_variable_scope));
-	if (stru->fields == NULL)
-		return 0;
-   _slang_variable_scope_ctr (stru->fields);
-	stru->structs = (slang_struct_scope *) slang_alloc_malloc (sizeof (slang_struct_scope));
-	if (stru->structs == NULL)
-	{
-		slang_variable_scope_destruct (stru->fields);
-		slang_alloc_free (stru->fields);
-		return 0;
-	}
-   _slang_struct_scope_ctr (stru->structs);
-	return 1;
-}
-
-void slang_struct_destruct (slang_struct *stru)
-{
-	slang_variable_scope_destruct (stru->fields);
-	slang_alloc_free (stru->fields);
-	slang_struct_scope_destruct (stru->structs);
-	slang_alloc_free (stru->structs);
-}
-
-int slang_struct_copy (slang_struct *x, const slang_struct *y)
-{
-	slang_struct z;
-
-	if (!slang_struct_construct (&z))
-		return 0;
-	z.a_name = y->a_name;
-	if (!slang_variable_scope_copy (z.fields, y->fields))
-	{
-		slang_struct_destruct (&z);
-		return 0;
-	}
-	if (!slang_struct_scope_copy (z.structs, y->structs))
-	{
-		slang_struct_destruct (&z);
-		return 0;
-	}
-	slang_struct_destruct (x);
-	*x = z;
-	return 1;
-}
-
-int slang_struct_equal (const slang_struct *x, const slang_struct *y)
-{
-	unsigned int i;
-
-	if (x->fields->num_variables != y->fields->num_variables)
-		return 0;
-	for (i = 0; i < x->fields->num_variables; i++)
-	{
-		slang_variable *varx = x->fields->variables[i];
-		slang_variable *vary = y->fields->variables[i];
-
-		if (varx->a_name != vary->a_name)
-			return 0;
-		if (!slang_type_specifier_equal (&varx->type.specifier, &vary->type.specifier))
-			return 0;
-		if (varx->type.specifier.type == SLANG_SPEC_ARRAY)
-			if (varx->array_len != vary->array_len)
-				return GL_FALSE;
-	}
-	return 1;
+   stru->a_name = SLANG_ATOM_NULL;
+   stru->fields = (slang_variable_scope *)
+      slang_alloc_malloc(sizeof(slang_variable_scope));
+   if (stru->fields == NULL)
+      return 0;
+   _slang_variable_scope_ctr(stru->fields);
+
+   stru->structs =
+      (slang_struct_scope *) slang_alloc_malloc(sizeof(slang_struct_scope));
+   if (stru->structs == NULL) {
+      slang_variable_scope_destruct(stru->fields);
+      slang_alloc_free(stru->fields);
+      return 0;
+   }
+   _slang_struct_scope_ctr(stru->structs);
+   return 1;
+}
+
+void
+slang_struct_destruct(slang_struct * stru)
+{
+   slang_variable_scope_destruct(stru->fields);
+   slang_alloc_free(stru->fields);
+   slang_struct_scope_destruct(stru->structs);
+   slang_alloc_free(stru->structs);
+}
+
+int
+slang_struct_copy(slang_struct * x, const slang_struct * y)
+{
+   slang_struct z;
+
+   if (!slang_struct_construct(&z))
+      return 0;
+   z.a_name = y->a_name;
+   if (!slang_variable_scope_copy(z.fields, y->fields)) {
+      slang_struct_destruct(&z);
+      return 0;
+   }
+   if (!slang_struct_scope_copy(z.structs, y->structs)) {
+      slang_struct_destruct(&z);
+      return 0;
+   }
+   slang_struct_destruct(x);
+   *x = z;
+   return 1;
+}
+
+int
+slang_struct_equal(const slang_struct * x, const slang_struct * y)
+{
+   GLuint i;
+
+   if (x->fields->num_variables != y->fields->num_variables)
+      return 0;
+
+   for (i = 0; i < x->fields->num_variables; i++) {
+      const slang_variable *varx = x->fields->variables[i];
+      const slang_variable *vary = y->fields->variables[i];
+
+      if (varx->a_name != vary->a_name)
+         return 0;
+      if (!slang_type_specifier_equal(&varx->type.specifier,
+                                      &vary->type.specifier))
+         return 0;
+      if (varx->type.specifier.type == SLANG_SPEC_ARRAY)
+         if (varx->array_len != vary->array_len)
+            return GL_FALSE;
+   }
+   return 1;
 }
-



More information about the mesa-commit mailing list