mesa: Branch 'index-swtnl-0.1'

Keith Whitwell keithw at kemper.freedesktop.org
Tue Mar 20 17:52:32 UTC 2007


 src/mesa/drivers/dri/i915tex/i915_cache.c        |    2 
 src/mesa/drivers/dri/i915tex/i915_cache.h        |    3 
 src/mesa/drivers/dri/i915tex/i915_differencer.c  |    4 -
 src/mesa/drivers/dri/i915tex/i915_state_vertex.c |   71 +++++++++------------
 src/mesa/drivers/dri/i915tex/i915_vtbl.c         |   14 ++++
 src/mesa/drivers/dri/i915tex/intel_batchbuffer.c |    1 
 src/mesa/drivers/dri/i915tex/intel_blit.c        |    1 
 src/mesa/drivers/dri/i915tex/intel_buffers.c     |   10 --
 src/mesa/drivers/dri/i915tex/intel_context.c     |   12 +--
 src/mesa/drivers/dri/i915tex/intel_context.h     |    9 ++
 src/mesa/drivers/dri/i915tex/intel_idx_render.c  |   11 +--
 src/mesa/drivers/dri/i915tex/intel_render.c      |   77 +++++++++++++++++++++++
 src/mesa/drivers/dri/i915tex/intel_state.c       |   11 ++-
 src/mesa/drivers/dri/i915tex/intel_tris.c        |   12 ---
 14 files changed, 162 insertions(+), 76 deletions(-)

New commits:
diff-tree a8627ac19268df367c55d8f79f6e530af63e0e62 (from 527be7b2878f024f572a230b499f11ef1a62f8bf)
Author: Keith Whitwell <keith at tungstengraphics.com>
Date:   Tue Mar 20 17:52:28 2007 +0000

    Add a state-checking stage to the render pipeline for attribute size changes.
    
    Use this to correctly set the vertex format for texture coordinates.

diff --git a/src/mesa/drivers/dri/i915tex/i915_cache.c b/src/mesa/drivers/dri/i915tex/i915_cache.c
index 2a97e1c..330fbf8 100644
--- a/src/mesa/drivers/dri/i915tex/i915_cache.c
+++ b/src/mesa/drivers/dri/i915tex/i915_cache.c
@@ -73,7 +73,7 @@ static GLuint emit_packet( struct intel_
    GLuint offset = intel->batch->segment_finish_offset[segment];
    GLuint i;
 
-   /* XXX: 
+   /* This should not be possible:
     */
    assert(intel->batch->segment_finish_offset[segment] + size <
 	  intel->batch->segment_max_offset[segment]);
diff --git a/src/mesa/drivers/dri/i915tex/i915_cache.h b/src/mesa/drivers/dri/i915tex/i915_cache.h
index 41ee2a1..471f7ec 100644
--- a/src/mesa/drivers/dri/i915tex/i915_cache.h
+++ b/src/mesa/drivers/dri/i915tex/i915_cache.h
@@ -90,6 +90,9 @@ static inline void packet_init( struct i
 				GLuint nr_dwords, 
 				GLuint nr_relocs )
 {
+   assert(nr_dwords < PACKET_MAX_DWORDS);
+   assert(nr_relocs < PACKET_MAX_RELOCS);
+
    packet->nr_dwords = 0;
    packet->nr_relocs = 0;
    packet->reloc = (struct i915_cache_reloc *)&packet->dword[nr_dwords];
diff --git a/src/mesa/drivers/dri/i915tex/i915_differencer.c b/src/mesa/drivers/dri/i915tex/i915_differencer.c
index 5518d4a..d9e1d38 100644
--- a/src/mesa/drivers/dri/i915tex/i915_differencer.c
+++ b/src/mesa/drivers/dri/i915tex/i915_differencer.c
@@ -173,9 +173,9 @@ static void emit_dynamic_indirect( struc
 		 ((offset + size*4 - 4) | DIS0_BUFFER_VALID | flag) );
       ADVANCE_BATCH();
 
-      /* XXX:
+      /* This should not be possible:
        */
-      assert( offset + size*4 < intel->batch->segment_max_offset[segment]);      
+      assert( offset + size*4 < intel->batch->segment_max_offset[segment]);
       intel->batch->segment_finish_offset[segment] += size*4;
 
       ptr = (GLuint *)(intel->batch->map + offset);
diff --git a/src/mesa/drivers/dri/i915tex/i915_state_vertex.c b/src/mesa/drivers/dri/i915tex/i915_state_vertex.c
index 631352d..d4a268f 100644
--- a/src/mesa/drivers/dri/i915tex/i915_state_vertex.c
+++ b/src/mesa/drivers/dri/i915tex/i915_state_vertex.c
@@ -37,37 +37,6 @@
 #include "tnl/t_vertex.h"
 
 
-#if 0
-/* Scan the TNL VB struct and look at the size of each attribute
- * coming out.  
- *
- * The fragment program has been determined by this point, so it is ok
- * to restrict the list to the inputs referenced by the fragprog.
- *
- * This is not a 
- */
-void check_input_sizes( struct intel_context *intel )
-{
-   struct i915_context *i915 = i915_context( &intel->ctx );
-   GLcontext *ctx = &intel->ctx;
-   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
-   GLubyte old_sizes[8];
-   GLuint i;
-
-   memcpy(old_sizes, i915->fragprog.input_sizes, sizeof(old_sizes));
-
-   for (i = 0; i < FRAG_ATTRIB_MAX; i++) {
-      GLvector4f *attrib = VB->AttribPtr[i];
-      i915->fragprog.input_sizes[i] = attrib->size;
-   }
-
-   /* Raise statechanges if input sizes and varying have changed: 
-    */
-   if (memcmp(i915->fragprog.input_sizes, old_sizes, sizeof(old_sizes)) != 0)
-      intel->state.dirty.intel |= I915_NEW_INPUT_SIZES;
-}
-
-#endif
 
 
 /***********************************************************************
@@ -97,7 +66,10 @@ do {									\
 /***********************************************************************
  * 
  */
-
+static inline GLuint attr_size(GLuint sizes, GLuint attr)
+{
+   return ((sizes >> (attr*2)) & 0x3) + 1;
+}
 
 static void i915_calculate_vertex_format( struct intel_context *intel )
 {
@@ -105,10 +77,14 @@ static void i915_calculate_vertex_format
    struct i915_fragment_program *fp = 
       i915_fragment_program(intel->state.FragmentProgram->_Current);
    const GLuint inputsRead = fp->Base.Base.InputsRead;
+   const GLuint sizes = intel->frag_attrib_sizes;
    GLuint s2 = S2_TEXCOORD_NONE;
    GLuint s4 = 0;
    GLuint offset = 0;
    GLuint i;
+   GLboolean need_w = (inputsRead & FRAG_BITS_TEX_ANY);
+   GLboolean have_w = (attr_size(sizes, FRAG_ATTRIB_WPOS) == 4);
+   GLboolean have_z = (attr_size(sizes, FRAG_ATTRIB_WPOS) >= 3);
 
    intel->vertex_attr_count = 0;
    intel->wpos_offset = 0;
@@ -116,12 +92,21 @@ static void i915_calculate_vertex_format
    intel->coloroffset = 0;
    intel->specoffset = 0;
 
-   if (inputsRead & FRAG_BITS_TEX_ANY) {
+
+   if (have_w && need_w) {
       EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, S4_VFMT_XYZW, 16);
    }
-   else {
+   else if (1 || have_z) {
       EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, S4_VFMT_XYZ, 12);
    }
+   else {
+      /* Need to update default z values to whatever zero maps to in
+       * the current viewport.  Or figure out that we don't need z in
+       * the current state.
+       */
+      EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_2F_VIEWPORT, S4_VFMT_XY, 8);
+   }
+   
 
    if (inputsRead & FRAG_BIT_COL0) {
       intel->coloroffset = offset / 4;
@@ -135,18 +120,26 @@ static void i915_calculate_vertex_format
    }
 
    if (inputsRead & FRAG_BIT_FOGC) {
-      
       EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1F, S4_VFMT_FOG_PARAM, 4);
    }
 
    for (i = 0; i < I915_TEX_UNITS; i++) {
       if (inputsRead & (FRAG_BIT_TEX0 << i)) {
 
-	 /* _NEW_VB_OUTPUT_SIZES 
+	 /* INTEL_NEW_FRAG_ATTRIB_SIZES 
+	  *
+	  * Basically need to know whether or not to include the W
+	  * value.  This could be used to transform TXP->TEX
+	  * instructions in the fragment program, but so far haven't
+	  * seen much performance benefit from doing that.
+	  *
+	  * There could also be benefit in things like turning off
+	  * perspective interpolation for the texture coordinates when
+	  * it is detected that the application is really doing
+	  * 2d-type texture operations.
 	  */
-/*          int sz = VB->TexCoordPtr[i]->size; */
-	 int sz = 2;
-
+	 int sz = attr_size(sizes, FRAG_ATTRIB_TEX0+i); 
+	 
          s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK);
          s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(sz));
 
diff --git a/src/mesa/drivers/dri/i915tex/i915_vtbl.c b/src/mesa/drivers/dri/i915tex/i915_vtbl.c
index 5e215b0..e3eacae 100644
--- a/src/mesa/drivers/dri/i915tex/i915_vtbl.c
+++ b/src/mesa/drivers/dri/i915tex/i915_vtbl.c
@@ -236,6 +236,19 @@ static void i915_lost_hardware( struct i
 }
 
 
+static GLboolean i915_check_indirect_space( struct intel_context *intel )
+{
+   GLuint dynamic_space = 
+      intel_batchbuffer_space( intel->batch, 
+			       SEGMENT_DYNAMIC_INDIRECT);
+   GLuint cache_space = 
+      intel_batchbuffer_space( intel->batch, 
+			       SEGMENT_OTHER_INDIRECT);
+
+   return (dynamic_space > I915_MAX_DYNAMIC * sizeof(GLuint) &&
+	   cache_space > I915_MAX_CACHE * PACKET_MAX_DWORDS * sizeof(GLuint));
+}
+
 void
 i915InitVtbl(struct i915_context *i915)
 {
@@ -245,4 +258,5 @@ i915InitVtbl(struct i915_context *i915)
    i915->intel.vtbl.debug_packet = i915_debug_packet;
    i915->intel.vtbl.get_hardware_state_size = i915_get_hardware_state_size;
    i915->intel.vtbl.emit_hardware_state = i915_emit_hardware_state;
+   i915->intel.vtbl.check_indirect_space = i915_check_indirect_space;
 }
diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c
index dcc688e..361b220 100644
--- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c
@@ -438,3 +438,4 @@ intel_batchbuffer_data(struct intel_batc
    __memcpy(batch->map + batch->segment_finish_offset[segment], data, bytes);
    batch->segment_finish_offset[segment] += bytes;
 }
+
diff --git a/src/mesa/drivers/dri/i915tex/intel_blit.c b/src/mesa/drivers/dri/i915tex/intel_blit.c
index 550669a..bbd8274 100644
--- a/src/mesa/drivers/dri/i915tex/intel_blit.c
+++ b/src/mesa/drivers/dri/i915tex/intel_blit.c
@@ -430,7 +430,6 @@ intelClearWithBlit(GLcontext * ctx, GLbi
       skipBuffers = BUFFER_BIT_STENCIL;
    }
 
-   /* XXX Move this flush/lock into the following conditional? */
    intelFlush(&intel->ctx);
    LOCK_HARDWARE(intel);
 
diff --git a/src/mesa/drivers/dri/i915tex/intel_buffers.c b/src/mesa/drivers/dri/i915tex/intel_buffers.c
index a3f52f6..f5906e0 100644
--- a/src/mesa/drivers/dri/i915tex/intel_buffers.c
+++ b/src/mesa/drivers/dri/i915tex/intel_buffers.c
@@ -313,9 +313,6 @@ intelClearWithTris(struct intel_context 
          else
             intel_meta_no_depth_write(intel);
 
-         /* XXX: Using INTEL_BATCH_NO_CLIPRECTS here is dangerous as the
-          * drawing origin may not be correctly emitted.
-          */
          intel_meta_draw_quad(intel, 
 			      clear.x1, clear.x2, 
 			      clear.y1, clear.y2, 
@@ -343,10 +340,9 @@ intelClearWithTris(struct intel_context 
             intel_meta_color_mask(intel, GL_TRUE);
             intel_meta_draw_region(intel, irbColor->region, NULL);
 
-            /* XXX: Using INTEL_BATCH_NO_CLIPRECTS here is dangerous as the
-             * drawing origin may not be correctly emitted.
-             */
-            intel_meta_draw_quad(intel, clear.x1, clear.x2, clear.y1, clear.y2, 0,      /* depth clear val */
+            intel_meta_draw_quad(intel, 
+				 clear.x1, clear.x2, 
+				 clear.y1, clear.y2, 0,      /* depth clear val */
                                  color, 0, 0, 0, 0);    /* texcoords */
 
             mask &= ~bufBit;
diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c
index a7fd4f8..259863f 100644
--- a/src/mesa/drivers/dri/i915tex/intel_context.c
+++ b/src/mesa/drivers/dri/i915tex/intel_context.c
@@ -201,6 +201,7 @@ const struct dri_extension card_extensio
 };
 
 extern const struct tnl_pipeline_stage _intel_render_stage;
+extern const struct tnl_pipeline_stage _intel_check_frag_attrib_sizes;
 
 static const struct tnl_pipeline_stage *intel_pipeline[] = {
    &_tnl_vertex_transform_stage,
@@ -212,13 +213,10 @@ static const struct tnl_pipeline_stage *
    &_tnl_texture_transform_stage,
    &_tnl_point_attenuation_stage,
    &_tnl_arb_vertex_program_stage,
-   &_tnl_vertex_program_stage,
-#if 1
-   &_intel_render_stage,        /* ADD: unclipped rastersetup-to-dma */
-#endif
-#if 1
-   &_tnl_indexed_render_stage,        /* ADD: rastersetup-to-dma, indexed prims */
-#endif
+   &_tnl_vertex_program_stage,   
+   &_intel_check_frag_attrib_sizes,
+   &_intel_render_stage,       /* ADD: unclipped rastersetup-to-dma */
+   &_tnl_indexed_render_stage, /* ADD: rastersetup-to-dma, indexed prims */
    &_tnl_render_stage,
    0,
 };
diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h
index 24a154d..685d4f1 100644
--- a/src/mesa/drivers/dri/i915tex/intel_context.h
+++ b/src/mesa/drivers/dri/i915tex/intel_context.h
@@ -84,7 +84,7 @@ extern void intelFallback(struct intel_c
 #define INTEL_NEW_MESA                    0x1 /* Mesa state has changed */
 #define INTEL_NEW_FRAGMENT_PROGRAM        0x2
 #define INTEL_NEW_VERTEX_SIZE             0x4
-#define INTEL_NEW_INPUT_SIZES             0x8
+#define INTEL_NEW_FRAG_ATTRIB_SIZES       0x8
 #define INTEL_NEW_CONTEXT                 0x10 /* Lost hardware? */
 #define INTEL_NEW_REDUCED_PRIMITIVE       0x20
 #define INTEL_NEW_FALLBACK                0x40
@@ -189,6 +189,8 @@ struct intel_context
 
       void (*emit_hardware_state) (struct intel_context *intel);
 
+      GLboolean (*check_indirect_space) (struct intel_context *intel);
+
       
 
    } vtbl;
@@ -248,6 +250,11 @@ struct intel_context
     */
    GLuint program_id;
 
+   /* Track TNL attrib sizes:
+    */
+   GLuint frag_attrib_sizes;
+   GLuint frag_attrib_varying;
+
    /* State for intelvb.c and inteltris.c.
     */
    GLuint coloroffset;
diff --git a/src/mesa/drivers/dri/i915tex/intel_idx_render.c b/src/mesa/drivers/dri/i915tex/intel_idx_render.c
index c0e78c0..09b0a43 100644
--- a/src/mesa/drivers/dri/i915tex/intel_idx_render.c
+++ b/src/mesa/drivers/dri/i915tex/intel_idx_render.c
@@ -179,12 +179,11 @@ static void emit_prims( GLcontext *ctx,
       if (nr == 0)
 	 continue;
 
-      /* XXX: Need to ensure that both the state and the primitive
-       * command below end up in the same batchbuffer, otherwise there
-       * is a risk that another context might interpose a batchbuffer
-       * containing different statesetting commands.  Using logical
-       * contexts would fix this, as would the BRW scheme of only
-       * emitting batch commands while holding the lock.
+      /* The 'dwords' usage below ensures that both the state and the
+       * primitive command below end up in the same batchbuffer,
+       * otherwise there is a risk that another context might
+       * interpose a batchbuffer containing different statesetting
+       * commands.
        */
 /*       intelRenderPrimitive() */
       {
diff --git a/src/mesa/drivers/dri/i915tex/intel_render.c b/src/mesa/drivers/dri/i915tex/intel_render.c
index daee49a..f699fee 100644
--- a/src/mesa/drivers/dri/i915tex/intel_render.c
+++ b/src/mesa/drivers/dri/i915tex/intel_render.c
@@ -45,6 +45,7 @@
 #include "intel_tris.h"
 #include "intel_batchbuffer.h"
 #include "intel_reg.h"
+#include "intel_state.h"
 
 /*
  * Render unclipped vertex buffers by emitting vertices directly to
@@ -239,3 +240,79 @@ const struct tnl_pipeline_stage _intel_r
    NULL,
    intel_run_render             /* run */
 };
+
+static GLuint frag_attr_to_VB( GLuint attr )
+{
+   switch(attr) {
+   case FRAG_ATTRIB_WPOS: return VERT_ATTRIB_POS;
+   case FRAG_ATTRIB_COL0: return VERT_ATTRIB_COLOR0;
+   case FRAG_ATTRIB_COL1: return VERT_ATTRIB_COLOR1;
+   case FRAG_ATTRIB_FOGC: return VERT_ATTRIB_FOG;
+   case FRAG_ATTRIB_TEX0: return VERT_ATTRIB_TEX0;
+   case FRAG_ATTRIB_TEX1: return VERT_ATTRIB_TEX1;
+   case FRAG_ATTRIB_TEX2: return VERT_ATTRIB_TEX2;
+   case FRAG_ATTRIB_TEX3: return VERT_ATTRIB_TEX3;
+   case FRAG_ATTRIB_TEX4: return VERT_ATTRIB_TEX4;
+   case FRAG_ATTRIB_TEX5: return VERT_ATTRIB_TEX5;
+   case FRAG_ATTRIB_TEX6: return VERT_ATTRIB_TEX6;
+   case FRAG_ATTRIB_TEX7: return VERT_ATTRIB_TEX7;
+   default: return 0;
+   }
+}
+
+
+/* A mini stage just to update our state regarding the pipeline:
+ */
+static GLboolean frag_attrib_size_check( GLcontext * ctx, 
+					 struct tnl_pipeline_stage *stage )
+{
+   struct intel_context *intel = intel_context(ctx);
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   struct vertex_buffer *VB = &tnl->vb;
+   GLuint i;
+
+
+   /* Look at the size of each attribute coming out, and raise a
+    * statechange if different. 
+    */
+   GLuint sizes = 0;
+   GLuint varying = 0;
+
+   /* We need to do this first:
+    */
+   VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
+
+   for (i = 0; i < FRAG_ATTRIB_MAX; i++) {
+      GLvector4f *attrib = VB->AttribPtr[frag_attr_to_VB(i)];
+      sizes |= (attrib->size - 1) << (i * 2);
+      varying |= (attrib->stride != 0) << i;
+   }
+
+   /* Raise statechanges if input sizes and varying have changed: 
+    */
+   if (intel->frag_attrib_sizes != sizes ||
+       intel->frag_attrib_varying != varying) 
+   {
+      intel->state.dirty.intel |= INTEL_NEW_FRAG_ATTRIB_SIZES;
+      intel->frag_attrib_varying = varying;
+      intel->frag_attrib_sizes = sizes;
+
+      _mesa_printf("sizes: %x varying: %x\n", sizes, varying);
+   }
+
+
+   /* Catch any changes from the pipeline...
+    */
+   intel_update_software_state(intel);
+
+   return GL_TRUE;
+}
+
+const struct tnl_pipeline_stage _intel_check_frag_attrib_sizes = {
+   "intel check frag attrib sizes",
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   frag_attrib_size_check
+};
diff --git a/src/mesa/drivers/dri/i915tex/intel_state.c b/src/mesa/drivers/dri/i915tex/intel_state.c
index f52b79e..40be0d3 100644
--- a/src/mesa/drivers/dri/i915tex/intel_state.c
+++ b/src/mesa/drivers/dri/i915tex/intel_state.c
@@ -68,8 +68,11 @@ void intel_update_software_state( struct
    struct intel_state_flags *state = &intel->state.dirty;
    GLuint i;
 
-   if (state->intel == 0)
+   if (state->intel == 0) {
+      assert(state->mesa == 0);
+      assert(state->extra == 0);
       return;
+   }
 
    if (!intel->metaops.active) {
       intel->state.DrawBuffer = intel->ctx.DrawBuffer;
@@ -78,6 +81,9 @@ void intel_update_software_state( struct
       intel->state._ColorDrawBufferMask0 = intel->ctx.DrawBuffer->_ColorDrawBufferMask[0];
    }
 
+   if (!intel->vtbl.check_indirect_space( intel ))
+      intel_batchbuffer_flush( intel->batch );
+
    if (INTEL_DEBUG) {
       /* Debug version which enforces various sanity checks on the
        * state flags which are generated and checked to help ensure
@@ -131,8 +137,7 @@ void intel_emit_hardware_state( struct i
 
    for (i = 0; i < 2; i++)
    {
-      if (intel->state.dirty.intel)
-	 intel_update_software_state( intel );
+      intel_update_software_state( intel );
       
       if (intel_batchbuffer_space( intel->batch, SEGMENT_IMMEDIATE ) <
 	  intel->vtbl.get_hardware_state_size( intel ) +  dwords * sizeof(GLuint))
diff --git a/src/mesa/drivers/dri/i915tex/intel_tris.c b/src/mesa/drivers/dri/i915tex/intel_tris.c
index ec53ebd..6e61fc6 100644
--- a/src/mesa/drivers/dri/i915tex/intel_tris.c
+++ b/src/mesa/drivers/dri/i915tex/intel_tris.c
@@ -888,8 +888,10 @@ intelRunPipeline(GLcontext * ctx)
    if (ctx->NewState)
       _mesa_update_state_locked(ctx);
 
-   /* Want to update state but not emit: */
+#if 0
+   /* Maybe need this for fallbacks??? */
    intel_update_software_state( intel );
+#endif
 
    _tnl_run_pipeline(ctx);
 
@@ -899,14 +901,6 @@ intelRunPipeline(GLcontext * ctx)
 static void
 intelRenderStart(GLcontext * ctx)
 {
-   struct intel_context *intel = intel_context(ctx);
-   TNLcontext *tnl = TNL_CONTEXT(ctx);
-   struct vertex_buffer *VB = &tnl->vb;
-
-   VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
-
-   assert(!intel->state.dirty.intel);
-   intel_update_software_state(intel);
 }
 
 static void



More information about the mesa-commit mailing list