Add more i915 state packets.
authorKeith Whitwell <keith@tungstengraphics.com>
Thu, 9 Aug 2007 17:07:42 +0000 (18:07 +0100)
committerKeith Whitwell <keith@tungstengraphics.com>
Thu, 9 Aug 2007 17:09:09 +0000 (18:09 +0100)
These correspond to the dynamic indirect state, though they are
currently just pushed straight to the batch buffer.

src/mesa/pipe/i915simple/Makefile
src/mesa/pipe/i915simple/i915_batch.h
src/mesa/pipe/i915simple/i915_context.c
src/mesa/pipe/i915simple/i915_context.h
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_dynamic.c [new file with mode: 0644]
src/mesa/pipe/i915simple/i915_state_emit.c
src/mesa/pipe/i915simple/i915_state_immediate.c

index 1adffbbfe17cf6e7c6c1b2a9d9ef468fa19c9dbd..96e16a948f827b0449370cc4696c1edf73b1dcc6 100644 (file)
@@ -16,6 +16,7 @@ DRIVER_SOURCES = \
        i915_regions.c \
        i915_state.c \
        i915_state_immediate.c \
+       i915_state_dynamic.c \
        i915_state_derived.c \
        i915_state_emit.c \
        i915_state_fragprog.c \
index 8a35ff6a3aa5a102c4c31655cd4b81dbe5d99206..b11bbeedbdf5b576fcc48dd054d89a8b955420e1 100644 (file)
@@ -48,6 +48,7 @@
    i915_dump_batchbuffer( i915, i915->batch_start, BEGIN_BATCH(0, 0) );        \
    i915->winsys->batch_flush( i915->winsys );                          \
    i915->batch_start = BEGIN_BATCH(0, 0);                              \
+   i915->hardware_dirty = ~0;                          \
 } while (0)
 
 #endif 
index 3e8d1fbb333124d7070e9f76c0c13403e5a56055..eb7f3804d3b15c3b79935036717cd0f4e546940f 100644 (file)
@@ -173,11 +173,13 @@ struct pipe_context *i915_create( struct i915_winsys *winsys )
    i915_init_flush_functions(i915);
 
 
+   i915->dirty = ~0;
+   i915->hardware_dirty = ~0;
+
    /* Batch stream debugging is a bit hacked up at the moment:
     */
    i915->batch_start = winsys->batch_start( winsys, 0, 0 );
 
-
    /*
     * XXX we could plug GL selection/feedback into the drawing pipeline
     * by specifying a different setup/render stage.
index 0f0728cde0c50d04099484649e7864fdb4604b87..c9fd2e9a3f806d92d439035f5e9fc9c6a96b7930 100644 (file)
 #define I915_DYNAMIC_BFO_1        7
 #define I915_DYNAMIC_STP_0        8 
 #define I915_DYNAMIC_STP_1        9 
-#define I915_DYNAMIC_SC_0         10 
-#define I915_DYNAMIC_SC_1         11 
-#define I915_DYNAMIC_SC_2         12 
-#define I915_DYNAMIC_SC_3         13 
+#define I915_DYNAMIC_SC_ENA_0     10 
+#define I915_DYNAMIC_SC_RECT_0    11 
+#define I915_DYNAMIC_SC_RECT_1    12 
+#define I915_DYNAMIC_SC_RECT_2    13 
 #define I915_MAX_DYNAMIC          14
 
 
@@ -83,6 +83,7 @@ struct i915_cache_context;
 struct i915_state 
 {
    GLuint immediate[I915_MAX_IMMEDIATE];
+   GLuint dynamic[I915_MAX_DYNAMIC];
    
    GLuint id;                  /* track lost context events */
 };
@@ -147,8 +148,14 @@ struct i915_context
 
 /* Dirty flags for hardware emit
  */
-#define I915_HW_INDIRECT          (1<<0)
-#define I915_HW_IMMEDIATE         (1<<1)
+#define I915_HW_STATIC            (1<<I915_CACHE_STATIC)
+#define I915_HW_DYNAMIC           (1<<I915_CACHE_DYNAMIC)
+#define I915_HW_SAMPLER           (1<<I915_CACHE_SAMPLER)
+#define I915_HW_MAP               (1<<I915_CACHE_MAP)
+#define I915_HW_PROGRAM           (1<<I915_CACHE_PROGRAM)
+#define I915_HW_CONSTANTS         (1<<I915_CACHE_CONSTANTS)
+#define I915_HW_IMMEDIATE         (1<<(I915_MAX_CACHE+0))
+#define I915_HW_INVARIENT         (1<<(I915_MAX_CACHE+1))
 
 
 /***********************************************************************
index 18918459a8cd20fe140d40e4f800b58d8f94bcef..5173fc0b38e73c8e98a655a65cc8e4f83a025c53 100644 (file)
@@ -116,7 +116,6 @@ emit_prim( struct draw_stage *stage,
           unsigned nr )
 {
    struct i915_context *i915 = setup_stage(stage)->i915;
-   struct i915_winsys *winsys = i915->winsys;
    unsigned vertex_size = 4 * sizeof(int);
    unsigned *ptr;
    unsigned i;
@@ -127,10 +126,16 @@ emit_prim( struct draw_stage *stage,
    if (i915->hardware_dirty)
       i915_emit_hardware_state( i915 );
 
-   ptr = winsys->batch_start( winsys, nr * vertex_size, 0 );
+   ptr = BEGIN_BATCH( nr * vertex_size, 0 );
    if (ptr == 0) {
-      winsys->batch_flush( winsys );
-      ptr = winsys->batch_start( winsys, nr * vertex_size, 0 );
+      FLUSH_BATCH();
+
+      /* Make sure state is re-emitted after a flush: 
+       */
+      i915_update_derived( i915 );
+      i915_emit_hardware_state( i915 );
+
+      ptr = BEGIN_BATCH( nr * vertex_size, 0 );
       if (ptr == 0) {
         assert(0);
         return;
index e26e8f6b0b54c8d9b53e65c35f8330830e5484ea..794a251ad8860102880e6c9f2e81e8cd0f2b8132 100644 (file)
 
 struct i915_context;
 
+
+struct i915_tracked_state {
+   unsigned dirty;
+   void (*update)( struct i915_context * );
+};
+
 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_emit_hardware_state( struct i915_context *i915 );
index 32b8b6c808da10b5efd7360ae365fe4f14481695..7d03ed5567b8fe5efb9b421b0aef7661b17db089 100644 (file)
@@ -134,40 +134,6 @@ static void calculate_vertex_layout( struct i915_context *i915 )
 }
 
 
-/**
- * Recompute cliprect from scissor bounds, scissor enable and surface size.
- */
-static void
-compute_cliprect(struct i915_context *sp)
-{
-   GLint surfWidth, surfHeight;
-
-   if (sp->framebuffer.num_cbufs > 0) {
-      surfWidth = sp->framebuffer.cbufs[0]->width;
-      surfHeight = sp->framebuffer.cbufs[0]->height;
-   }
-   else {
-      /* no surface? */
-      surfWidth = sp->scissor.maxx;
-      surfHeight = sp->scissor.maxy;
-   }
-
-   if (sp->setup.scissor) {
-      /* clip to scissor rect */
-      sp->cliprect.minx = MAX2(sp->scissor.minx, 0);
-      sp->cliprect.miny = MAX2(sp->scissor.miny, 0);
-      sp->cliprect.maxx = MIN2(sp->scissor.maxx, surfWidth);
-      sp->cliprect.maxy = MIN2(sp->scissor.maxy, surfHeight);
-   }
-   else {
-      /* clip to surface bounds */
-      sp->cliprect.minx = 0;
-      sp->cliprect.miny = 0;
-      sp->cliprect.maxx = surfWidth;
-      sp->cliprect.maxy = surfHeight;
-   }
-}
-
 
 /* Hopefully this will remain quite simple, otherwise need to pull in
  * something like the state tracker mechanism.
@@ -177,18 +143,16 @@ 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_SCISSOR |
-                     I915_NEW_STENCIL |
-                     I915_NEW_FRAMEBUFFER))
-      compute_cliprect(i915);
-
    if (i915->dirty)
       i915_update_immediate( i915 );
 
+   if (i915->dirty)
+      i915_update_dynamic( i915 );
+
    /* HW emit currently references framebuffer state directly:
     */
    if (i915->dirty & I915_NEW_FRAMEBUFFER)
-      i915->hardware_dirty = 1;
+      i915->hardware_dirty |= I915_HW_STATIC;
 
    i915->dirty = 0;
 }
diff --git a/src/mesa/pipe/i915simple/i915_state_dynamic.c b/src/mesa/pipe/i915simple/i915_state_dynamic.c
new file mode 100644 (file)
index 0000000..8d5a398
--- /dev/null
@@ -0,0 +1,429 @@
+/**************************************************************************
+ * 
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * 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"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+#include "glheader.h"
+#include "context.h"
+#include "macros.h"
+#include "enums.h"
+
+#include "i915_batch.h"
+#include "i915_state_inlines.h"
+#include "i915_context.h"
+#include "i915_reg.h"
+#include "i915_state.h"
+
+#define FILE_DEBUG_FLAG DEBUG_STATE
+
+/* State that we have chosen to store in the DYNAMIC segment of the
+ * i915 indirect state mechanism.  
+ *
+ * Can't cache these in the way we do the static state, as there is no
+ * start/size in the command packet, instead an 'end' value that gets
+ * incremented.
+ *
+ * Additionally, there seems to be a requirement to re-issue the full
+ * (active) state every time a 4kb boundary is crossed.
+ */
+
+static inline void set_dynamic_indirect( struct i915_context *i915,
+                                        GLuint offset,
+                                        const GLuint *src,
+                                        GLuint dwords )
+{
+   int i;
+
+   for (i = 0; i < dwords; i++)
+      i915->current.dynamic[offset + i] = src[i];
+
+   i915->hardware_dirty |= I915_HW_DYNAMIC;
+}
+
+
+/***********************************************************************
+ * Modes4: stencil masks and logicop 
+ */
+static void upload_MODES4( struct i915_context *i915 )
+{
+   GLuint modes4 = 0;
+
+   /* I915_NEW_STENCIL */
+   {
+      GLint testmask = i915->stencil.value_mask[0] & 0xff;
+      GLint writemask = i915->stencil.write_mask[0] & 0xff;
+
+      modes4 |= (_3DSTATE_MODES_4_CMD |
+                ENABLE_STENCIL_TEST_MASK |
+                STENCIL_TEST_MASK(testmask) |
+                ENABLE_STENCIL_WRITE_MASK |
+                STENCIL_WRITE_MASK(writemask));
+   }
+
+   /* I915_NEW_BLEND */
+   {
+      modes4 |= (_3DSTATE_MODES_4_CMD |
+                ENABLE_LOGIC_OP_FUNC |
+                LOGIC_OP_FUNC(i915_translate_logic_op(i915->blend.logicop_func)));
+   }
+   
+   /* Always, so that we know when state is in-active: 
+    */
+   set_dynamic_indirect( i915, 
+                        I915_DYNAMIC_MODES4,
+                        &modes4,
+                        1 );
+}
+
+const struct i915_tracked_state i915_upload_MODES4 = {
+   .dirty = I915_NEW_BLEND | I915_NEW_STENCIL,
+   .update = upload_MODES4
+};
+
+
+
+
+/***********************************************************************
+ */
+
+static void upload_BFO( struct i915_context *i915 )
+{
+   GLuint bf[2];
+
+   memset( bf, 0, sizeof(bf) );
+
+   /* _NEW_STENCIL 
+    */
+   if (i915->stencil.back_enabled) {
+      GLint test  = i915_translate_compare_func(i915->stencil.back_func);
+      GLint fop   = i915_translate_stencil_op(i915->stencil.back_fail_op);
+      GLint dfop  = i915_translate_stencil_op(i915->stencil.back_zfail_op);
+      GLint dpop  = i915_translate_stencil_op(i915->stencil.back_zpass_op);
+      GLint ref   = i915->stencil.ref_value[1] & 0xff;
+      GLint tmask = i915->stencil.value_mask[1] & 0xff;
+      GLint wmask = i915->stencil.write_mask[1] & 0xff;
+      
+      bf[0] = (_3DSTATE_BACKFACE_STENCIL_OPS |
+              BFO_ENABLE_STENCIL_FUNCS |
+              BFO_ENABLE_STENCIL_TWO_SIDE |
+              BFO_ENABLE_STENCIL_REF |
+              BFO_STENCIL_TWO_SIDE |
+              (ref  << BFO_STENCIL_REF_SHIFT) |
+              (test << BFO_STENCIL_TEST_SHIFT) |
+              (fop  << BFO_STENCIL_FAIL_SHIFT) |
+              (dfop << BFO_STENCIL_PASS_Z_FAIL_SHIFT) |
+              (dpop << BFO_STENCIL_PASS_Z_PASS_SHIFT));
+
+      bf[1] = (_3DSTATE_BACKFACE_STENCIL_MASKS |
+              BFM_ENABLE_STENCIL_TEST_MASK |
+              BFM_ENABLE_STENCIL_WRITE_MASK |
+              (tmask << BFM_STENCIL_TEST_MASK_SHIFT) |
+              (wmask << BFM_STENCIL_WRITE_MASK_SHIFT));
+   }
+   else {
+      /* This actually disables two-side stencil: The bit set is a
+       * modify-enable bit to indicate we are changing the two-side
+       * setting.  Then there is a symbolic zero to show that we are
+       * setting the flag to zero/off.
+       */
+      bf[0] = (_3DSTATE_BACKFACE_STENCIL_OPS |
+              BFO_ENABLE_STENCIL_TWO_SIDE |
+              0);
+      bf[1] = 0;
+   }      
+
+   set_dynamic_indirect( i915, 
+                        I915_DYNAMIC_BFO_0,
+                        &bf[0],
+                        2 );
+}
+
+const struct i915_tracked_state i915_upload_BFO = {
+   .dirty = I915_NEW_STENCIL,
+   .update = upload_BFO
+};
+
+
+/***********************************************************************
+ */
+
+
+static void upload_BLENDCOLOR( struct i915_context *i915 )
+{
+   GLuint bc[2];
+
+   memset( bc, 0, sizeof(bc) );
+
+   /* I915_NEW_BLEND {_COLOR} 
+    */
+   {
+      const GLfloat *color = i915->blend_color.color;
+      GLubyte r, g, b, a;
+
+      UNCLAMPED_FLOAT_TO_UBYTE(r, color[RCOMP]);
+      UNCLAMPED_FLOAT_TO_UBYTE(g, color[GCOMP]);
+      UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]);
+      UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]);
+
+      bc[0] = (_3DSTATE_CONST_BLEND_COLOR_CMD);
+      bc[1] = (a << 24) | (r << 16) | (g << 8) | b;
+   }
+
+   set_dynamic_indirect( i915, 
+                        I915_DYNAMIC_BC_0,
+                        bc,
+                        2 );
+}
+
+const struct i915_tracked_state i915_upload_BLENDCOLOR = {
+   .dirty = I915_NEW_BLEND,
+   .update = upload_BLENDCOLOR
+};
+
+/***********************************************************************
+ */
+
+
+static void upload_IAB( struct i915_context *i915 )
+{
+   GLuint iab = 0;
+
+   {
+      GLuint eqRGB  = i915->blend.rgb_func;
+      GLuint srcRGB = i915->blend.rgb_src_factor;
+      GLuint dstRGB = i915->blend.rgb_dst_factor;
+
+      GLuint eqA    = i915->blend.alpha_func;
+      GLuint srcA   = i915->blend.alpha_src_factor;
+      GLuint dstA   = i915->blend.alpha_dst_factor;
+
+      if (eqA == GL_MIN || eqA == GL_MAX) {
+        srcA = dstA = GL_ONE;
+      }
+
+      if (eqRGB == GL_MIN || eqRGB == GL_MAX) {
+        srcRGB = dstRGB = GL_ONE;
+      }
+      
+      if (srcA != srcRGB ||
+         dstA != dstRGB ||
+         eqA != eqRGB) {
+
+        iab = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD |    
+               IAB_MODIFY_ENABLE |
+               IAB_ENABLE |
+               IAB_MODIFY_FUNC | 
+               IAB_MODIFY_SRC_FACTOR | 
+               IAB_MODIFY_DST_FACTOR |
+               SRC_ABLND_FACT(i915_translate_blend_factor(srcA)) |
+               DST_ABLND_FACT(i915_translate_blend_factor(dstA)) |
+               (i915_translate_blend_func(eqA) << IAB_FUNC_SHIFT));
+      }         
+      else {
+        iab = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD |    
+               IAB_MODIFY_ENABLE |
+               0);
+      }
+   }
+
+
+   set_dynamic_indirect( i915, 
+                        I915_DYNAMIC_IAB,
+                        &iab,
+                        1 );
+}
+
+const struct i915_tracked_state i915_upload_IAB = {
+   .dirty = I915_NEW_BLEND,
+   .update = upload_IAB
+};
+
+
+/***********************************************************************
+ */
+
+
+
+static void upload_DEPTHSCALE( struct i915_context *i915 )
+{
+   union { GLfloat f; GLuint u; } ds[2];
+
+   memset( ds, 0, sizeof(ds) );
+   
+   /* I915_NEW_SETUP
+    */
+   ds[0].u = _3DSTATE_DEPTH_OFFSET_SCALE;
+   ds[1].f = i915->setup.offset_scale;
+
+   set_dynamic_indirect( i915, 
+                        I915_DYNAMIC_DEPTHSCALE_0,
+                        &ds[0].u,
+                        2 );
+}
+
+const struct i915_tracked_state i915_upload_DEPTHSCALE = {
+   .dirty = I915_NEW_SETUP,
+   .update = upload_DEPTHSCALE
+};
+
+
+
+/***********************************************************************
+ * Polygon stipple
+ *
+ * The i915 supports a 4x4 stipple natively, GL wants 32x32.
+ * Fortunately stipple is usually a repeating pattern.
+ *
+ * XXX: does stipple pattern need to be adjusted according to
+ * the window position?
+ *
+ * XXX: possibly need workaround for conform paths test. 
+ */
+
+static void upload_STIPPLE( struct i915_context *i915 )
+{
+   GLuint st[2];
+
+   st[0] = _3DSTATE_STIPPLE;
+   st[1] = 0;
+   
+   /* I915_NEW_SETUP 
+    */
+   if (i915->setup.poly_stipple_enable) {
+      st[1] |= ST1_ENABLE;
+   }
+
+
+   /* I915_NEW_STIPPLE
+    */
+   {
+      const GLubyte *mask = (const GLubyte *)i915->poly_stipple.stipple;
+      GLubyte p[4];
+
+      p[0] = mask[12] & 0xf;
+      p[1] = mask[8] & 0xf;
+      p[2] = mask[4] & 0xf;
+      p[3] = mask[0] & 0xf;
+
+      /* Not sure what to do about fallbacks, so for now just dont:
+       */
+      st[1] |= ((p[0] << 0) |
+               (p[1] << 4) |
+               (p[2] << 8) | 
+               (p[3] << 12));
+   }
+
+
+   set_dynamic_indirect( i915, 
+                        I915_DYNAMIC_STP_0,
+                        &st[0],
+                        2 );
+}
+
+
+const struct i915_tracked_state i915_upload_STIPPLE = {
+   .dirty = I915_NEW_SETUP | I915_NEW_STIPPLE,
+   .update = upload_STIPPLE
+};
+
+
+
+/***********************************************************************
+ * Scissor.  
+ */
+static void upload_SCISSOR_ENABLE( struct i915_context *i915 )
+{
+   unsigned sc[1];
+
+   if (i915->setup.scissor) 
+      sc[0] = _3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT;
+   else
+      sc[0] = _3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT;
+
+   set_dynamic_indirect( i915, 
+                        I915_DYNAMIC_SC_ENA_0,
+                        &sc[0],
+                        1 );
+}
+
+const struct i915_tracked_state i915_upload_SCISSOR_ENABLE = {
+   .dirty = I915_NEW_SETUP,
+   .update = upload_SCISSOR_ENABLE
+};
+
+
+
+static void upload_SCISSOR_RECT( struct i915_context *i915 )
+{
+   unsigned x1 = i915->scissor.minx;
+   unsigned y1 = i915->scissor.miny;
+   unsigned x2 = i915->scissor.maxx;
+   unsigned y2 = i915->scissor.maxy;
+   unsigned sc[3];
+   sc[0] = _3DSTATE_SCISSOR_RECT_0_CMD;
+   sc[1] = (y1 << 16) | (x1 & 0xffff);
+   sc[2] = (y2 << 16) | (x2 & 0xffff);
+
+   set_dynamic_indirect( i915, 
+                        I915_DYNAMIC_SC_RECT_0,
+                        &sc[0],
+                        3 );
+}
+
+
+const struct i915_tracked_state i915_upload_SCISSOR_RECT = {
+   .dirty = I915_NEW_SCISSOR,
+   .update = upload_SCISSOR_RECT
+};
+
+
+
+
+
+
+static const struct i915_tracked_state *atoms[] = {
+   &i915_upload_MODES4,
+   &i915_upload_BFO,
+   &i915_upload_BLENDCOLOR,
+   &i915_upload_IAB,
+   &i915_upload_DEPTHSCALE,
+   &i915_upload_STIPPLE,
+   &i915_upload_SCISSOR_ENABLE,
+   &i915_upload_SCISSOR_RECT
+};
+
+/* These will be dynamic indirect state commands, but for now just end
+ * up on the batch buffer with everything else.
+ */
+void i915_update_dynamic( struct i915_context *i915 )
+{
+   int i;
+
+   for (i = 0; i < Elements(atoms); i++)
+      if (i915->dirty & atoms[i]->dirty)
+        atoms[i]->update( i915 );
+}
+
index 1a50470fbdaf6ae85c1904a87b554e39690ac119..2ce079fbaaea0ef2709e00199db7106b516e097c 100644 (file)
@@ -66,14 +66,13 @@ i915_emit_hardware_state(struct i915_context *i915 )
 {
    BEGIN_BATCH(100, 10);
 
+   if (i915->hardware_dirty & I915_HW_INVARIENT)
    {
       OUT_BATCH(_3DSTATE_AA_CMD |
                AA_LINE_ECAAR_WIDTH_ENABLE |
                AA_LINE_ECAAR_WIDTH_1_0 |
                AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0);
-   }
 
-   {
       OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD);
       OUT_BATCH(0);
 
@@ -82,10 +81,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
       
       OUT_BATCH(_3DSTATE_DFLT_Z_CMD);
       OUT_BATCH(0);
-   }
 
-
-   {
       OUT_BATCH(_3DSTATE_COORD_SET_BINDINGS |
                CSB_TCB(0, 0) |
                CSB_TCB(1, 1) |
@@ -95,9 +91,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
                CSB_TCB(5, 5) | 
                CSB_TCB(6, 6) | 
                CSB_TCB(7, 7));
-   }
 
-   {
       OUT_BATCH(_3DSTATE_RASTER_RULES_CMD |
                ENABLE_POINT_RASTER_RULE |
                OGL_POINT_RASTER_RULE |
@@ -107,42 +101,25 @@ i915_emit_hardware_state(struct i915_context *i915 )
                TRI_FAN_PROVOKE_VRTX(2) | 
                ENABLE_TEXKILL_3D_4D | 
                TEXKILL_4D);
-   }
 
-   /* Need to initialize this to zero.
-    */
-   {
+      /* Need to initialize this to zero.
+       */
       OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | (0));
       OUT_BATCH(0);
-   }
 
-   
-   {
-      OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT);
-      
-      OUT_BATCH(_3DSTATE_SCISSOR_RECT_0_CMD);
-      OUT_BATCH(0);
-      OUT_BATCH(0);
-   }
-
-   {      
       OUT_BATCH(_3DSTATE_DEPTH_SUBRECT_DISABLE);
-   }
 
-   {
-      OUT_BATCH(_3DSTATE_LOAD_INDIRECT | 0);       /* disable indirect state */
+      /* disable indirect state for now
+       */
+      OUT_BATCH(_3DSTATE_LOAD_INDIRECT | 0);
       OUT_BATCH(0);
    }
-
    
-   {
-      /* Don't support twosided stencil yet */
-      OUT_BATCH(_3DSTATE_BACKFACE_STENCIL_OPS | BFO_ENABLE_STENCIL_TWO_SIDE | 0);
-      OUT_BATCH(0);
-   }
 
 
 
+
+   if (i915->hardware_dirty & I915_HW_IMMEDIATE)
    {
       OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | 
                I1_LOAD_S(2) |
@@ -156,93 +133,76 @@ i915_emit_hardware_state(struct i915_context *i915 )
       OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S5]);
       OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S6]);
    }
-
-   {
-      OUT_BATCH(_3DSTATE_MODES_4_CMD |
-               ENABLE_LOGIC_OP_FUNC |
-               LOGIC_OP_FUNC(LOGICOP_COPY) |
-               ENABLE_STENCIL_TEST_MASK |
-               STENCIL_TEST_MASK(0xff) |
-               ENABLE_STENCIL_WRITE_MASK |
-               STENCIL_WRITE_MASK(0xff));
-   }
    
-   if (0) {
-      OUT_BATCH(_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD |
-               IAB_MODIFY_ENABLE |
-               IAB_MODIFY_FUNC |
-               IAB_MODIFY_SRC_FACTOR |
-               IAB_MODIFY_DST_FACTOR);
-   }
 
+   if (i915->hardware_dirty & I915_HW_DYNAMIC) 
    {
-      //3DSTATE_INDEPENDENT_ALPHA_BLEND (1 dwords):
-      OUT_BATCH(0x6ba008a1);
-
-      //3DSTATE_CONSTANT_BLEND_COLOR (2 dwords):
-      OUT_BATCH(0x7d880000);
-      OUT_BATCH(0x00000000);
+      int i;
+      for (i = 0; i < I915_MAX_DYNAMIC; i++) {
+        OUT_BATCH(i915->current.dynamic[i]);
+      }
    }
 
 
 
-   if (i915->framebuffer.cbufs[0]) {
-      struct pipe_region *cbuf_region = i915->framebuffer.cbufs[0]->region;
-      unsigned pitch = (cbuf_region->pitch *
-                       cbuf_region->cpp);
-
-      OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
-
-      OUT_BATCH(BUF_3D_ID_COLOR_BACK | 
-               BUF_3D_PITCH(pitch) |  /* pitch in bytes */
-               BUF_3D_USE_FENCE);
-
-      OUT_RELOC(cbuf_region->buffer,
-               I915_BUFFER_ACCESS_WRITE,
-               0);
-   }
-
-   /* What happens if no zbuf??
-    */
-   if (i915->framebuffer.zbuf) {
-      struct pipe_region *depth_region = i915->framebuffer.zbuf->region;
-      unsigned zpitch = (depth_region->pitch *
-                        depth_region->cpp);
+   if (i915->hardware_dirty & I915_HW_STATIC)
+   {
+      if (i915->framebuffer.cbufs[0]) {
+        struct pipe_region *cbuf_region = i915->framebuffer.cbufs[0]->region;
+        unsigned pitch = (cbuf_region->pitch *
+                          cbuf_region->cpp);
+
+        OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
+
+        OUT_BATCH(BUF_3D_ID_COLOR_BACK | 
+                  BUF_3D_PITCH(pitch) |  /* pitch in bytes */
+                  BUF_3D_USE_FENCE);
+
+        OUT_RELOC(cbuf_region->buffer,
+                  I915_BUFFER_ACCESS_WRITE,
+                  0);
+      }
+
+      /* What happens if no zbuf??
+       */
+      if (i915->framebuffer.zbuf) {
+        struct pipe_region *depth_region = i915->framebuffer.zbuf->region;
+        unsigned zpitch = (depth_region->pitch *
+                           depth_region->cpp);
                         
-      OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
+        OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
 
-      OUT_BATCH(BUF_3D_ID_DEPTH |
-               BUF_3D_PITCH(zpitch) |  /* pitch in bytes */
-               BUF_3D_USE_FENCE);
+        OUT_BATCH(BUF_3D_ID_DEPTH |
+                  BUF_3D_PITCH(zpitch) |  /* pitch in bytes */
+                  BUF_3D_USE_FENCE);
 
-      OUT_RELOC(depth_region->buffer,
-               I915_BUFFER_ACCESS_WRITE,
-               0);
-   }
+        OUT_RELOC(depth_region->buffer,
+                  I915_BUFFER_ACCESS_WRITE,
+                  0);
+      }
 
    
-   {
-      unsigned cformat = translate_format( i915->framebuffer.cbufs[0]->format );
-      unsigned zformat = 0;
+      {
+        unsigned cformat = translate_format( i915->framebuffer.cbufs[0]->format );
+        unsigned zformat = 0;
       
-      if (i915->framebuffer.zbuf) 
-        zformat = translate_depth_format( i915->framebuffer.zbuf->format );
+        if (i915->framebuffer.zbuf) 
+           zformat = translate_depth_format( i915->framebuffer.zbuf->format );
 
-      OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD);
+        OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD);
 
-      OUT_BATCH(DSTORG_HORT_BIAS(0x8) | /* .5 */
-               DSTORG_VERT_BIAS(0x8) | /* .5 */
-               LOD_PRECLAMP_OGL |
-               TEX_DEFAULT_COLOR_OGL |
-               cformat |
-               zformat );
-   }
+        OUT_BATCH(DSTORG_HORT_BIAS(0x8) | /* .5 */
+                  DSTORG_VERT_BIAS(0x8) | /* .5 */
+                  LOD_PRECLAMP_OGL |
+                  TEX_DEFAULT_COLOR_OGL |
+                  cformat |
+                  zformat );
+      }
 
-   {
-      OUT_BATCH(_3DSTATE_STIPPLE);
-      OUT_BATCH(0);
    }
 
+
+
    {
       GLuint i, dwords;
       GLuint *prog = i915_passthrough_program( &dwords );
index 8b93ca7f62872689a8b184a412e7ba23cf901b2c..2f64d9dd901d2a9b70b5528b5aaeec22bf3a502e 100644 (file)
  */
 
 
-struct i915_tracked_state {
-   unsigned dirty;
-   void (*update)( struct i915_context * );
-};
-
 
 
 /***********************************************************************