summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Whitwell <keith@tungstengraphics.com>2007-08-09 18:07:42 +0100
committerKeith Whitwell <keith@tungstengraphics.com>2007-08-09 18:09:09 +0100
commit7c9a1357beabd6d0df88142d31cd5d77a012e85a (patch)
treec9b098a7c3de4bf44858de4d72cbead8d59bafcf
parentb3efc75f1a3496cbd0b93b5eff497a92fa31dc3b (diff)
Add more i915 state packets.
These correspond to the dynamic indirect state, though they are currently just pushed straight to the batch buffer.
-rw-r--r--src/mesa/pipe/i915simple/Makefile1
-rw-r--r--src/mesa/pipe/i915simple/i915_batch.h1
-rw-r--r--src/mesa/pipe/i915simple/i915_context.c4
-rw-r--r--src/mesa/pipe/i915simple/i915_context.h19
-rw-r--r--src/mesa/pipe/i915simple/i915_prim_emit.c13
-rw-r--r--src/mesa/pipe/i915simple/i915_state.h7
-rw-r--r--src/mesa/pipe/i915simple/i915_state_derived.c44
-rw-r--r--src/mesa/pipe/i915simple/i915_state_dynamic.c429
-rw-r--r--src/mesa/pipe/i915simple/i915_state_emit.c160
-rw-r--r--src/mesa/pipe/i915simple/i915_state_immediate.c5
10 files changed, 527 insertions, 156 deletions
diff --git a/src/mesa/pipe/i915simple/Makefile b/src/mesa/pipe/i915simple/Makefile
index 1adffbbfe1..96e16a948f 100644
--- a/src/mesa/pipe/i915simple/Makefile
+++ b/src/mesa/pipe/i915simple/Makefile
@@ -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 \
diff --git a/src/mesa/pipe/i915simple/i915_batch.h b/src/mesa/pipe/i915simple/i915_batch.h
index 8a35ff6a3a..b11bbeedbd 100644
--- a/src/mesa/pipe/i915simple/i915_batch.h
+++ b/src/mesa/pipe/i915simple/i915_batch.h
@@ -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
diff --git a/src/mesa/pipe/i915simple/i915_context.c b/src/mesa/pipe/i915simple/i915_context.c
index 3e8d1fbb33..eb7f3804d3 100644
--- a/src/mesa/pipe/i915simple/i915_context.c
+++ b/src/mesa/pipe/i915simple/i915_context.c
@@ -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.
diff --git a/src/mesa/pipe/i915simple/i915_context.h b/src/mesa/pipe/i915simple/i915_context.h
index 0f0728cde0..c9fd2e9a3f 100644
--- a/src/mesa/pipe/i915simple/i915_context.h
+++ b/src/mesa/pipe/i915simple/i915_context.h
@@ -46,10 +46,10 @@
#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))
/***********************************************************************
diff --git a/src/mesa/pipe/i915simple/i915_prim_emit.c b/src/mesa/pipe/i915simple/i915_prim_emit.c
index 18918459a8..5173fc0b38 100644
--- a/src/mesa/pipe/i915simple/i915_prim_emit.c
+++ b/src/mesa/pipe/i915simple/i915_prim_emit.c
@@ -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;
diff --git a/src/mesa/pipe/i915simple/i915_state.h b/src/mesa/pipe/i915simple/i915_state.h
index e26e8f6b0b..794a251ad8 100644
--- a/src/mesa/pipe/i915simple/i915_state.h
+++ b/src/mesa/pipe/i915simple/i915_state.h
@@ -33,7 +33,14 @@
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 );
diff --git a/src/mesa/pipe/i915simple/i915_state_derived.c b/src/mesa/pipe/i915simple/i915_state_derived.c
index 32b8b6c808..7d03ed5567 100644
--- a/src/mesa/pipe/i915simple/i915_state_derived.c
+++ b/src/mesa/pipe/i915simple/i915_state_derived.c
@@ -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
index 0000000000..8d5a398890
--- /dev/null
+++ b/src/mesa/pipe/i915simple/i915_state_dynamic.c
@@ -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 );
+}
+
diff --git a/src/mesa/pipe/i915simple/i915_state_emit.c b/src/mesa/pipe/i915simple/i915_state_emit.c
index 1a50470fbd..2ce079fbaa 100644
--- a/src/mesa/pipe/i915simple/i915_state_emit.c
+++ b/src/mesa/pipe/i915simple/i915_state_emit.c
@@ -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 );
diff --git a/src/mesa/pipe/i915simple/i915_state_immediate.c b/src/mesa/pipe/i915simple/i915_state_immediate.c
index 8b93ca7f62..2f64d9dd90 100644
--- a/src/mesa/pipe/i915simple/i915_state_immediate.c
+++ b/src/mesa/pipe/i915simple/i915_state_immediate.c
@@ -44,11 +44,6 @@
*/
-struct i915_tracked_state {
- unsigned dirty;
- void (*update)( struct i915_context * );
-};
-
/***********************************************************************