[Mesa-dev] [PATCH] i965: Add support for GL_FIXED vertex attributes.

Eric Anholt eric at anholt.net
Wed Jun 8 15:20:03 PDT 2011


This sadly requires work in the VS to rescale them, because the
hardware doesn't support this format natively.

Fixes arb_es2_compatibility-fixed-type and gtf/fixed_data_type.
---
 src/mesa/drivers/dri/i965/brw_draw_upload.c |    5 +++++
 src/mesa/drivers/dri/i965/brw_vs.c          |   11 ++++++++++-
 src/mesa/drivers/dri/i965/brw_vs.h          |    4 ++++
 src/mesa/drivers/dri/i965/brw_vs_emit.c     |   22 ++++++++++++++++++++++
 4 files changed, 41 insertions(+), 1 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c
index 3cc3372..c6e5395 100644
--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
@@ -207,6 +207,10 @@ static GLuint get_surface_type( GLenum type, GLuint size,
       case GL_UNSIGNED_INT: return uint_types_scale[size];
       case GL_UNSIGNED_SHORT: return ushort_types_scale[size];
       case GL_UNSIGNED_BYTE: return ubyte_types_scale[size];
+      /* This produces GL_FIXED inputs as values between INT32_MIN and
+       * INT32_MAX, which will be scaled down by 1/65536 by the VS.
+       */
+      case GL_FIXED: return int_types_scale[size];
       default: assert(0); return 0;
       }
    }
@@ -225,6 +229,7 @@ static GLuint get_size( GLenum type )
    case GL_UNSIGNED_INT: return sizeof(GLuint);
    case GL_UNSIGNED_SHORT: return sizeof(GLushort);
    case GL_UNSIGNED_BYTE: return sizeof(GLubyte);
+   case GL_FIXED: return sizeof(GLuint);
    default: assert(0); return 0;
    }
 }
diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c
index d6a5399..80d5e78 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.c
+++ b/src/mesa/drivers/dri/i965/brw_vs.c
@@ -145,6 +145,14 @@ static void brw_upload_vs_prog(struct brw_context *brw)
       }
    }
 
+   /* BRW_NEW_VERTICES */
+   for (i = 0; i < VERT_ATTRIB_MAX; i++) {
+      if (vp->program.Base.InputsRead & (1 << i) &&
+	  brw->vb.inputs[i].glarray->Type == GL_FIXED) {
+	 key.gl_fixed_input_size[i] = brw->vb.inputs[i].glarray->Size;
+      }
+   }
+
    /* Make an early check for the key.
     */
    drm_intel_bo_unreference(brw->vs.prog_bo);
@@ -164,7 +172,8 @@ const struct brw_tracked_state brw_vs_prog = {
    .dirty = {
       .mesa  = (_NEW_TRANSFORM | _NEW_POLYGON | _NEW_POINT | _NEW_LIGHT |
 		_NEW_BUFFERS),
-      .brw   = BRW_NEW_VERTEX_PROGRAM,
+      .brw   = (BRW_NEW_VERTEX_PROGRAM |
+		BRW_NEW_VERTICES),
       .cache = 0
    },
    .prepare = brw_upload_vs_prog
diff --git a/src/mesa/drivers/dri/i965/brw_vs.h b/src/mesa/drivers/dri/i965/brw_vs.h
index 7ca84a5..432994a 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.h
+++ b/src/mesa/drivers/dri/i965/brw_vs.h
@@ -41,6 +41,10 @@
 
 struct brw_vs_prog_key {
    GLuint program_string_id;
+   /**
+    * Number of channels of the vertex attribute that need GL_FIXED rescaling
+    */
+   uint8_t gl_fixed_input_size[VERT_ATTRIB_MAX];
    GLuint nr_userclip:4;
    GLuint copy_edgeflag:1;
    GLuint point_coord_replace:8;
diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index 7d5eb35..b6c9e5a 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -1878,6 +1878,26 @@ get_predicate(const struct prog_instruction *inst)
    }
 }
 
+static void
+brw_vs_rescale_gl_fixed(struct brw_vs_compile *c)
+{
+   struct brw_compile *p = &c->func;
+   int i;
+
+   for (i = 0; i < VERT_ATTRIB_MAX; i++) {
+      if (!(c->prog_data.inputs_read & (1 << i)))
+	 continue;
+
+      if (c->key.gl_fixed_input_size[i] != 0) {
+	 struct brw_reg reg = c->regs[PROGRAM_INPUT][i];
+
+	 brw_MUL(p,
+		 brw_writemask(reg, (1 << c->key.gl_fixed_input_size[i]) - 1),
+		 reg, brw_imm_f(1.0 / 65536.0));
+      }
+   }
+}
+
 /* Emit the vertex program instructions here.
  */
 void brw_vs_emit(struct brw_vs_compile *c )
@@ -1937,6 +1957,8 @@ void brw_vs_emit(struct brw_vs_compile *c )
     */
    brw_vs_alloc_regs(c);
 
+   brw_vs_rescale_gl_fixed(c);
+
    if (c->needs_stack)
       brw_MOV(p, get_addr_reg(stack_index), brw_address(c->stack));
 
-- 
1.7.5.3



More information about the mesa-dev mailing list