Checkpoint: texture image and sampler state handling, plus better vertex format code.
authorBrian <brian.paul@tungstengraphics.com>
Thu, 23 Aug 2007 00:51:39 +0000 (18:51 -0600)
committerBrian <brian.paul@tungstengraphics.com>
Thu, 23 Aug 2007 00:52:40 +0000 (18:52 -0600)
Texture image/sampler state code should be working, but is disabled for now.
Need to fix outstanding issues with vertex formats and texcoords first...

src/mesa/pipe/i915simple/i915_context.h
src/mesa/pipe/i915simple/i915_fpc_emit.c
src/mesa/pipe/i915simple/i915_fpc_translate.c
src/mesa/pipe/i915simple/i915_prim_emit.c
src/mesa/pipe/i915simple/i915_state.h
src/mesa/pipe/i915simple/i915_state_derived.c
src/mesa/pipe/i915simple/i915_state_emit.c
src/mesa/pipe/i915simple/i915_state_immediate.c
src/mesa/pipe/i915simple/i915_state_sampler.c

index a037b20..849c3b0 100644 (file)
 
 #define I915_MAX_CONSTANT  32
 
+
+/**
+ * New vertex format stuff...
+ */
+#define MAX_VERT_ATTRIBS 12  /* OK? */
+
+#define FORMAT_OMIT 0
+#define FORMAT_1F   1
+#define FORMAT_2F   2
+#define FORMAT_3F   3
+#define FORMAT_4F   4
+#define FORMAT_4UB  5
+
+struct vertex_info
+{
+   uint num_attribs;
+   uint hwfmt[2];      /** hardware format info for this format */
+   uint attr_mask;     /** mask of VF_ATTR_ bits */
+   uint slot_to_attrib[MAX_VERT_ATTRIBS];
+   uint interp_mode[MAX_VERT_ATTRIBS];
+   uint format[MAX_VERT_ATTRIBS];   /**< FORMAT_x */
+};
+
+
+
+
 struct i915_cache_context;
 
 /* Use to calculate differences between state emitted to hardware and
@@ -95,10 +121,17 @@ struct i915_state
    uint *program;
    uint program_len;
 
+   /* texture sampler state */
    unsigned sampler[I915_TEX_UNITS][3];
    unsigned sampler_enable_flags;
    unsigned sampler_enable_nr;
-   
+
+   /* texture image buffers */
+   unsigned texbuffer[I915_TEX_UNITS][2];
+
+   /* vertex format registers */
+   struct vertex_info vertex_info;
+
    unsigned id;                        /* track lost context events */
 };
 
index dfbc5f1..235938a 100644 (file)
@@ -192,7 +192,8 @@ uint i915_emit_texld( struct i915_fp_compile *p,
                        uint coord,
                        uint op )
 {
-   if (coord != UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord))) {
+   uint k = UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord));
+   if (coord != k) {
       /* No real way to work around this in the general case - need to
        * allocate and declare a new temporary register (a utemp won't
        * do).  Will fallback for now.
index dcf0d18..cd2faa8 100644 (file)
@@ -153,8 +153,15 @@ src_vector(struct i915_fp_compile *p,
          src = i915_emit_decl(p, REG_TYPE_T, T_DIFFUSE, D0_CHANNEL_ALL);
          break;
       case FRAG_ATTRIB_COL1:
+#if 1
          src = i915_emit_decl(p, REG_TYPE_T, T_SPECULAR, D0_CHANNEL_XYZ);
          src = swizzle(src, X, Y, Z, ONE);
+#else
+         /* total hack to force texture mapping */
+         src = i915_emit_decl(p, REG_TYPE_T,
+                              T_TEX0/* + (index - FRAG_ATTRIB_TEX0)*/,
+                              D0_CHANNEL_ALL);
+#endif
          break;
       case FRAG_ATTRIB_FOGC:
          src = i915_emit_decl(p, REG_TYPE_T, T_FOG_W, D0_CHANNEL_W);
@@ -979,7 +986,7 @@ i915_fini_compile(struct i915_context *i915, struct i915_fp_compile *p)
 static void
 i915_find_wpos_space(struct i915_fp_compile *p)
 {
-   const uint inputs = p->shader->inputs_read;
+   const uint inputs = p->shader->inputs_read | FRAG_BIT_WPOS; /*XXX hack*/
    uint i;
 
    p->wpos_tex = -1;
index 2c5f11c..ff57d26 100644 (file)
@@ -71,13 +71,56 @@ emit_hw_vertex( struct i915_context *i915,
 
    /* colors are ARGB (MSB to LSB) */
    OUT_BATCH( pack_ub4(float_to_ubyte( vertex->data[1][2] ),
-                      float_to_ubyte( vertex->data[1][1] ),
-                      float_to_ubyte( vertex->data[1][0] ),
-                      float_to_ubyte( vertex->data[1][3] )) );
+                       float_to_ubyte( vertex->data[1][1] ),
+                       float_to_ubyte( vertex->data[1][0] ),
+                       float_to_ubyte( vertex->data[1][3] )) );
 }
                
                
 
+static INLINE void
+emit_hw_vertex2( struct i915_context *i915,
+                 const struct vertex_header *vertex)
+{
+   const struct vertex_info *vinfo = &i915->current.vertex_info;
+   uint i;
+
+   for (i = 0; i < vinfo->num_attribs; i++) {
+      switch (vinfo->format[i]) {
+      case FORMAT_OMIT:
+         /* no-op */
+         break;
+      case FORMAT_1F:
+         OUT_BATCH( fui(vertex->data[i][0]) );
+         break;
+      case FORMAT_2F:
+         OUT_BATCH( fui(vertex->data[i][0]) );
+         OUT_BATCH( fui(vertex->data[i][1]) );
+         break;
+      case FORMAT_3F:
+         OUT_BATCH( fui(vertex->data[i][0]) );
+         OUT_BATCH( fui(vertex->data[i][1]) );
+         OUT_BATCH( fui(vertex->data[i][2]) );
+         break;
+      case FORMAT_4F:
+         OUT_BATCH( fui(vertex->data[i][0]) );
+         OUT_BATCH( fui(vertex->data[i][1]) );
+         OUT_BATCH( fui(vertex->data[i][2]) );
+         OUT_BATCH( fui(vertex->data[i][3]) );
+         break;
+      case FORMAT_4UB:
+         OUT_BATCH( pack_ub4(float_to_ubyte( vertex->data[i][2] ),
+                             float_to_ubyte( vertex->data[i][1] ),
+                             float_to_ubyte( vertex->data[i][0] ),
+                             float_to_ubyte( vertex->data[i][3] )) );
+         break;
+      default:
+         assert(0);
+      }
+   }
+}
+
+
 
 static INLINE void 
 emit_prim( struct draw_stage *stage, 
@@ -120,7 +163,7 @@ emit_prim( struct draw_stage *stage,
             ((4 + vertex_size * nr)/4 - 2));
 
    for (i = 0; i < nr; i++) {
-      emit_hw_vertex(i915, prim->v[i]);
+      emit_hw_vertex2(i915, prim->v[i]);
       ptr += vertex_size / sizeof(int);
    }
 }
index 4305845..86c6b00 100644 (file)
@@ -43,6 +43,7 @@ void i915_update_immediate( struct i915_context *i915 );
 void i915_update_dynamic( struct i915_context *i915 );
 void i915_update_derived( struct i915_context *i915 );
 void i915_update_samplers( struct i915_context *i915 );
+void i915_update_textures(struct i915_context *i915);
 
 void i915_emit_hardware_state( struct i915_context *i915 );
 
index 5a493cc..bd952cc 100644 (file)
 #include "pipe/draw/draw_context.h"
 #include "i915_context.h"
 #include "i915_state.h"
+#include "i915_reg.h"
 
 /* XXX should include i915_fpc.h but that causes some trouble atm */
 extern void i915_translate_fragment_program( struct i915_context *i915 );
 
 
 
-#define EMIT_ATTR( VF_ATTR, FRAG_ATTR, INTERP )        \
-do {                                           \
-   slot_to_vf_attr[nr_attrs] = VF_ATTR;                \
-   nr_attrs++;                                 \
-   attr_mask |= (1 << (VF_ATTR));              \
-} while (0)
-
-
 static const unsigned frag_to_vf[FRAG_ATTRIB_MAX] = 
 {
    VF_ATTRIB_POS,
@@ -68,6 +61,19 @@ static const unsigned frag_to_vf[FRAG_ATTRIB_MAX] =
 };
 
 
+static INLINE void
+emit_vertex_attr(struct vertex_info *vinfo, uint vfAttr, uint format)
+{
+   const uint n = vinfo->num_attribs;
+   vinfo->attr_mask |= (1 << vfAttr);
+   vinfo->slot_to_attrib[n] = vfAttr;
+   /*vinfo->interp_mode[n] = interpMode;*/
+   vinfo->format[n] = format;
+   vinfo->num_attribs++;
+}
+
+
+
 /**
  * Determine which post-transform / pre-rasterization vertex attributes
  * we need.
@@ -75,19 +81,17 @@ static const unsigned frag_to_vf[FRAG_ATTRIB_MAX] =
  */
 static void calculate_vertex_layout( struct i915_context *i915 )
 {
-//   const unsigned inputsRead = i915->fs.inputs_read;
-   const unsigned inputsRead = (FRAG_BIT_WPOS | FRAG_BIT_COL0);
-   unsigned slot_to_vf_attr[VF_ATTRIB_MAX];
-   unsigned attr_mask = 0x0;
-   unsigned nr_attrs = 0;
+   const unsigned inputsRead = i915->fs.inputs_read;
+//   const unsigned inputsRead = (FRAG_BIT_WPOS | FRAG_BIT_COL0);
    unsigned i;
+   struct vertex_info *vinfo = &i915->current.vertex_info;
 
-   memset(slot_to_vf_attr, 0, sizeof(slot_to_vf_attr));
-
+   memset(vinfo, 0, sizeof(*vinfo));
 
    /* TODO - Figure out if we need to do perspective divide, etc.
     */
-   EMIT_ATTR(VF_ATTRIB_POS, FRAG_ATTRIB_WPOS, INTERP_LINEAR);
+   emit_vertex_attr(vinfo, VF_ATTRIB_POS, FORMAT_3F);
+   vinfo->hwfmt[0] |= S4_VFMT_XYZ;
       
    /* Pull in the rest of the attributes.  They are all in float4
     * format.  Future optimizations could be to keep some attributes
@@ -95,20 +99,29 @@ static void calculate_vertex_layout( struct i915_context *i915 )
     */
    for (i = 1; i < FRAG_ATTRIB_TEX0; i++) {
       if (inputsRead & (1 << i)) {
-         assert(i < sizeof(frag_to_vf) / sizeof(frag_to_vf[0]));
+         assert(i < Elements(frag_to_vf));
          if (i915->setup.flatshade
-             && (i == FRAG_ATTRIB_COL0 || i == FRAG_ATTRIB_COL1))
-            EMIT_ATTR(frag_to_vf[i], i, INTERP_CONSTANT);
-         else
-            EMIT_ATTR(frag_to_vf[i], i, INTERP_LINEAR);
+             && (i == FRAG_ATTRIB_COL0 || i == FRAG_ATTRIB_COL1)) {
+            emit_vertex_attr(vinfo, frag_to_vf[i], FORMAT_4UB);
+         }   
+         else {
+            emit_vertex_attr(vinfo, frag_to_vf[i], FORMAT_4UB);
+         }
+         vinfo->hwfmt[0] |= S4_VFMT_COLOR;
       }
    }
 
    for (i = FRAG_ATTRIB_TEX0; i < FRAG_ATTRIB_MAX; i++) {
+      uint hwtc;
       if (inputsRead & (1 << i)) {
+         hwtc = TEXCOORDFMT_4D;
          assert(i < sizeof(frag_to_vf) / sizeof(frag_to_vf[0]));
-         EMIT_ATTR(frag_to_vf[i], i, INTERP_PERSPECTIVE);
+         emit_vertex_attr(vinfo, frag_to_vf[i], FORMAT_4F);
+      }
+      else {
+         hwtc = TEXCOORDFMT_NOT_PRESENT;
       }
+      vinfo->hwfmt[1] |= hwtc << ((i - FRAG_ATTRIB_TEX0) * 4);
    }
 
    /* Additional attributes required for setup: Just twosided
@@ -117,24 +130,31 @@ static void calculate_vertex_layout( struct i915_context *i915 )
     */
    if (i915->setup.light_twoside) {
       if (inputsRead & FRAG_BIT_COL0) {
-        EMIT_ATTR(VF_ATTRIB_BFC0, FRAG_ATTRIB_MAX, 0); /* XXX: mark as discarded after setup */
+         /* XXX: mark as discarded after setup */
+         emit_vertex_attr(vinfo, VF_ATTRIB_BFC0, FORMAT_OMIT);
       }
            
       if (inputsRead & FRAG_BIT_COL1) {
-        EMIT_ATTR(VF_ATTRIB_BFC1, FRAG_ATTRIB_MAX, 0); /* XXX: discard after setup */
+         /* XXX: discard after setup */
+         emit_vertex_attr(vinfo, VF_ATTRIB_BFC1, FORMAT_OMIT);
       }
    }
 
-   /* If the attributes have changed, tell the draw module (which in turn
-    * tells the vf module) about the new vertex layout.
+   /* If the attributes have changed, tell the draw module about the new
+    * vertex layout.  We'll also update the hardware vertex format info.
     */
    draw_set_vertex_attributes( i915->draw,
-                              slot_to_vf_attr,
-                              nr_attrs );
+                               vinfo->slot_to_attrib,
+                              vinfo->num_attribs);
+#if 0
+   printf("VERTEX_FORMAT LIS2: 0x%x  LIS4: 0x%x\n",
+          vinfo->hwfmt[1], vinfo->hwfmt[0]);
+#endif
 }
 
 
 
+
 /* Hopefully this will remain quite simple, otherwise need to pull in
  * something like the state tracker mechanism.
  */
@@ -143,6 +163,12 @@ void i915_update_derived( struct i915_context *i915 )
    if (i915->dirty & (I915_NEW_SETUP | I915_NEW_FS))
       calculate_vertex_layout( i915 );
 
+   if (i915->dirty & I915_NEW_SAMPLER)
+      i915_update_samplers(i915);
+
+   if (i915->dirty & I915_NEW_TEXTURE)
+      i915_update_textures(i915);
+
    if (i915->dirty)
       i915_update_immediate( i915 );
 
index dff9d40..ceb9628 100644 (file)
@@ -180,7 +180,6 @@ i915_emit_hardware_state(struct i915_context *i915 )
            zformat = translate_depth_format( i915->framebuffer.zbuf->format );
 
         OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD);
-
         OUT_BATCH(DSTORG_HORT_BIAS(0x8) | /* .5 */
                   DSTORG_VERT_BIAS(0x8) | /* .5 */
                   LOD_PRECLAMP_OGL |
@@ -190,6 +189,38 @@ i915_emit_hardware_state(struct i915_context *i915 )
       }
    }
 
+
+#if 0
+      /* texture images */
+      if (i915->hardware_dirty & I915_HW_MAP)
+      {
+         const uint nr = i915->current.sampler_enable_nr;
+         const uint enabled = i915->current.sampler_enable_flags;
+         uint unit;
+         uint count = 0;
+         OUT_BATCH(_3DSTATE_MAP_STATE | (3 * nr));
+         OUT_BATCH(enabled);
+         for (unit = 0; unit < I915_TEX_UNITS; unit++) {
+            if (enabled & (1 << unit)) {
+               struct pipe_buffer_handle *buf =
+                  i915->texture[unit]->region->buffer;
+               uint offset = 0;
+               assert(buf);
+
+               count++;
+
+               OUT_RELOC(buf,
+                         I915_BUFFER_ACCESS_READ,
+                         offset);
+               OUT_BATCH(i915->current.texbuffer[unit][0]); /* MS3 */
+               OUT_BATCH(i915->current.texbuffer[unit][1]); /* MS4 */
+            }
+         }
+         assert(count == nr);
+      }
+#endif
+
+#if 0
    /* samplers */
    if (i915->hardware_dirty & I915_HW_SAMPLER) 
    {
@@ -210,8 +241,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
         }
       }
    }
-   
-
+#endif
 
    /* constants */
    if (i915->hardware_dirty & I915_HW_PROGRAM)
index 1cd1866..c6f1f59 100644 (file)
@@ -53,8 +53,16 @@ static void upload_S2S4(struct i915_context *i915)
    unsigned LIS2, LIS4;
    
    /* I915_NEW_VERTEX_FORMAT */
+#if 01
    LIS2 = 0xffffffff;
    LIS4 = (S4_VFMT_XYZ | S4_VFMT_COLOR);
+#else
+   assert(LIS2 == i915->current.vertex_info.hwfmt[1]);
+   assert(LIS4 == i915->current.vertex_info.hwfmt[0]);
+   LIS2 = i915->current.vertex_info.hwfmt[1];
+   LIS4 = i915->current.vertex_info.hwfmt[0];
+   printf("UPLOAD FORMAT LIS2: 0x%x  LIS4: 0x%x\n", LIS2, LIS4);
+#endif
 
 
    /* I915_NEW_SETUP */
index 591e368..e23e4bd 100644 (file)
@@ -39,6 +39,7 @@
 #include "i915_state_inlines.h"
 #include "i915_context.h"
 #include "i915_reg.h"
+#include "i915_state.h"
 //#include "i915_cache.h"
 
 
@@ -283,3 +284,136 @@ void i915_update_samplers( struct i915_context *i915 )
 
    i915->hardware_dirty |= I915_HW_SAMPLER;
 }
+
+
+
+
+static uint
+translate_texture_format(uint pipeFormat)
+{
+   switch (pipeFormat) {
+   case PIPE_FORMAT_U_L8:
+      return MAPSURF_8BIT | MT_8BIT_L8;
+   case PIPE_FORMAT_U_I8:
+      return MAPSURF_8BIT | MT_8BIT_I8;
+   case PIPE_FORMAT_U_A8:
+      return MAPSURF_8BIT | MT_8BIT_A8;
+   case PIPE_FORMAT_U_L8_A8:
+      return MAPSURF_16BIT | MT_16BIT_AY88;
+   case PIPE_FORMAT_U_R5_G6_B5:
+      return MAPSURF_16BIT | MT_16BIT_RGB565;
+   case PIPE_FORMAT_U_A1_R5_G5_B5:
+      return MAPSURF_16BIT | MT_16BIT_ARGB1555;
+   case PIPE_FORMAT_U_A4_R4_G4_B4:
+      return MAPSURF_16BIT | MT_16BIT_ARGB4444;
+   case PIPE_FORMAT_U_A8_R8_G8_B8:
+      return MAPSURF_32BIT | MT_32BIT_ARGB8888;
+   case PIPE_FORMAT_YCBCR_REV:
+      return (MAPSURF_422 | MT_422_YCRCB_NORMAL);
+   case PIPE_FORMAT_YCBCR:
+      return (MAPSURF_422 | MT_422_YCRCB_SWAPY);
+#if 0
+   case PIPE_FORMAT_RGB_FXT1:
+   case PIPE_FORMAT_RGBA_FXT1:
+      return (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1);
+#endif
+   case PIPE_FORMAT_U_Z16:
+      return (MAPSURF_16BIT | MT_16BIT_L16);
+#if 0
+   case PIPE_FORMAT_RGBA_DXT1:
+   case PIPE_FORMAT_RGB_DXT1:
+      return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1);
+   case PIPE_FORMAT_RGBA_DXT3:
+      return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3);
+   case PIPE_FORMAT_RGBA_DXT5:
+      return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5);
+#endif
+   case PIPE_FORMAT_S8_Z24:
+      return (MAPSURF_32BIT | MT_32BIT_xL824);
+   default:
+      fprintf(stderr, "i915: translate_texture_format() bad image format %x\n",
+              pipeFormat);
+      assert(0);
+      return 0;
+   }
+}
+
+
+#define I915_TEXREG_MS3        1
+#define I915_TEXREG_MS4        2
+
+
+static void
+i915_update_texture(struct i915_context *i915, uint unit,
+                    uint state[6])
+{
+   const struct pipe_mipmap_tree *mt = i915->texture[unit];
+   uint format, pitch;
+   const uint width = mt->width0, height = mt->height0, depth = mt->depth0;
+   const uint num_levels = mt->last_level - mt->first_level;
+
+   assert(mt);
+   assert(width);
+   assert(height);
+   assert(depth);
+
+#if 0
+   if (i915->state.tex_buffer[unit] != NULL) {
+       driBOUnReference(i915->state.tex_buffer[unit]);
+       i915->state.tex_buffer[unit] = NULL;
+   }
+#endif
+
+
+   {
+      struct pipe_buffer_handle *p = driBOReference(mt->region->buffer);
+   }
+
+#if 0
+   i915->state.tex_buffer[unit] = driBOReference(intelObj->mt->region->
+                                                 buffer);
+   i915->state.tex_offset[unit] =  intel_miptree_image_offset(intelObj->mt,
+                                                              0, intelObj->
+                                                              firstLevel);
+#endif
+
+   format = translate_texture_format(mt->format);
+   pitch = mt->pitch * mt->cpp;
+
+   assert(format);
+   assert(pitch);
+
+   printf("texture format = 0x%x\n", format);
+
+   /* MS3 state */
+   state[0] =
+      (((height - 1) << MS3_HEIGHT_SHIFT)
+       | ((width - 1) << MS3_WIDTH_SHIFT)
+       | format
+       | MS3_USE_FENCE_REGS);
+
+   /* MS4 state */
+   state[1] =
+      ((((pitch / 4) - 1) << MS4_PITCH_SHIFT)
+       | MS4_CUBE_FACE_ENA_MASK
+       | ((num_levels * 4) << MS4_MAX_LOD_SHIFT)
+       | ((depth - 1) << MS4_VOLUME_DEPTH_SHIFT));
+}
+
+
+
+void
+i915_update_textures(struct i915_context *i915)
+{
+   uint unit;
+
+   for (unit = 0; unit < I915_TEX_UNITS; unit++) {
+      /* determine unit enable/disable by looking for a bound mipmap tree */
+      /* could also examine the fragment program? */
+      if (i915->texture[unit]) {
+         i915_update_texture(i915, unit, i915->current.texbuffer[unit]);
+      }
+   }
+
+   i915->hardware_dirty |= I915_HW_MAP;
+}