summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Whitwell <keith@tungstengraphics.com>2007-03-08 10:40:47 +0000
committerKeith Whitwell <keith@tungstengraphics.com>2007-03-08 10:40:47 +0000
commitc11f0148aca6bb8c03b8715c58eb2d4d2da8cc6c (patch)
treec8c9a1e045c6d798f1eac56c15dbeeff5b222beb
parent682fdd9462485562e3534293a12ccebc41d3c3ed (diff)
Beginnings of i915 state rework. Won't compile.
-rw-r--r--src/mesa/drivers/dri/i915tex/Makefile26
-rw-r--r--src/mesa/drivers/dri/i915tex/i830_vtbl.c1
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_context.c22
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_context.h69
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_fp.c295
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_fp.h44
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_fp_debug.c (renamed from src/mesa/drivers/dri/i915tex/i915_debug.c)0
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_fp_emit.c487
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_fp_emit.h (renamed from src/mesa/drivers/dri/i915tex/i915_program.h)0
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_fp_translate.c (renamed from src/mesa/drivers/dri/i915tex/i915_fragprog.c)325
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_program.c590
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_state.c1086
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_state.h25
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_state_constants.c136
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_state_fp.c (renamed from src/mesa/drivers/dri/i915tex/i915_tex.c)84
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_state_fp_inputs.c150
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_state_immediate.c315
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_state_indirect.c61
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_state_map.c201
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_state_misc.c560
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_state_sampler.c (renamed from src/mesa/drivers/dri/i915tex/i915_texstate.c)130
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_vtbl.c388
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_context.h5
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_idx_render.c91
24 files changed, 2761 insertions, 2330 deletions
diff --git a/src/mesa/drivers/dri/i915tex/Makefile b/src/mesa/drivers/dri/i915tex/Makefile
index 9bd1d33507..89fd30de82 100644
--- a/src/mesa/drivers/dri/i915tex/Makefile
+++ b/src/mesa/drivers/dri/i915tex/Makefile
@@ -7,6 +7,22 @@ LIBNAME = i915tex_dri.so
MINIGLX_SOURCES = server/intel_dri.c
DRIVER_SOURCES = \
+ i915_context.c \
+ i915_fp.c \
+ i915_fp_debug.c \
+ i915_fp_emit.c \
+ i915_fp_state.c \
+ i915_fp_translate.c \
+ i915_metaops.c \
+ i915_program.c \
+ i915_state.c \
+ i915_state_immediate.c \
+ i915_state_indirect.c \
+ i915_state_misc.c \
+ i915_tex.c \
+ i915_tex_layout.c \
+ i915_tex_state.c \
+ i915_vtbl.c \
i830_context.c \
i830_metaops.c \
i830_state.c \
@@ -20,7 +36,6 @@ DRIVER_SOURCES = \
intel_buffer_objects.c \
intel_batchbuffer.c \
intel_mipmap_tree.c \
- i915_tex_layout.c \
intel_tex_layout.c \
intel_tex_image.c \
intel_tex_subimage.c \
@@ -34,15 +49,6 @@ DRIVER_SOURCES = \
intel_pixel_draw.c \
intel_buffers.c \
intel_blit.c \
- i915_tex.c \
- i915_texstate.c \
- i915_context.c \
- i915_debug.c \
- i915_fragprog.c \
- i915_metaops.c \
- i915_program.c \
- i915_state.c \
- i915_vtbl.c \
intel_context.c \
intel_ioctl.c \
intel_rotate.c \
diff --git a/src/mesa/drivers/dri/i915tex/i830_vtbl.c b/src/mesa/drivers/dri/i915tex/i830_vtbl.c
index dd0670dec3..5f1363caef 100644
--- a/src/mesa/drivers/dri/i915tex/i830_vtbl.c
+++ b/src/mesa/drivers/dri/i915tex/i830_vtbl.c
@@ -646,7 +646,6 @@ i830_assert_not_dirty( struct intel_context *intel )
void
i830InitVtbl(struct i830_context *i830)
{
- i830->intel.vtbl.check_vertex_size = i830_check_vertex_size;
i830->intel.vtbl.destroy = i830_destroy_context;
i830->intel.vtbl.emit_state = i830_emit_state;
i830->intel.vtbl.lost_hardware = i830_lost_hardware;
diff --git a/src/mesa/drivers/dri/i915tex/i915_context.c b/src/mesa/drivers/dri/i915tex/i915_context.c
index 9b4d72eab3..fd2943e4e1 100644
--- a/src/mesa/drivers/dri/i915tex/i915_context.c
+++ b/src/mesa/drivers/dri/i915tex/i915_context.c
@@ -52,6 +52,7 @@ static const struct dri_extension i915_extensions[] = {
{"GL_ARB_fragment_program", NULL},
{"GL_ARB_shadow", NULL},
{"GL_ARB_texture_env_crossbar", NULL},
+ {"GL_EXT_stencil_two_side", NULL},
{"GL_ARB_texture_non_power_of_two", NULL},
{"GL_EXT_shadow_funcs", NULL},
/* ARB extn won't work if not enabled */
@@ -70,20 +71,6 @@ i915InvalidateState(GLcontext * ctx, GLuint new_state)
_tnl_InvalidateState(ctx, new_state);
_tnl_invalidate_vertex_state(ctx, new_state);
intel_context(ctx)->NewGLState |= new_state;
-
- /* Todo: gather state values under which tracked parameters become
- * invalidated, add callbacks for things like
- * ProgramLocalParameters, etc.
- */
- {
- struct i915_fragment_program *p =
- (struct i915_fragment_program *) ctx->FragmentProgram._Current;
- if (p && p->nr_params)
- p->params_uptodate = 0;
- }
-
- if (new_state & (_NEW_FOG | _NEW_HINT | _NEW_PROGRAM))
- i915_update_fog(ctx);
}
@@ -91,8 +78,6 @@ static void
i915InitDriverFunctions(struct dd_function_table *functions)
{
intelInitDriverFunctions(functions);
- i915InitStateFunctions(functions);
- i915InitTextureFuncs(functions);
i915InitFragProgFuncs(functions);
functions->UpdateState = i915InvalidateState;
}
@@ -162,6 +147,11 @@ i915CreateContext(const __GLcontextModes * mesaVis,
driInitExtensions(ctx, i915_extensions, GL_FALSE);
+ /* always enbale pixel fog. vertex fog uses precaculted fog coord
+ * will conflict with appended fog program
+ */
+ _tnl_allow_vertex_fog( ctx, 0 );
+ _tnl_allow_pixel_fog( ctx, 1 );
_tnl_init_vertices(ctx, ctx->Const.MaxArrayLockSize + 12,
36 * sizeof(GLfloat));
diff --git a/src/mesa/drivers/dri/i915tex/i915_context.h b/src/mesa/drivers/dri/i915tex/i915_context.h
index d2713e88f9..3dc0f9d81c 100644
--- a/src/mesa/drivers/dri/i915tex/i915_context.h
+++ b/src/mesa/drivers/dri/i915tex/i915_context.h
@@ -119,8 +119,6 @@ struct i915_fragment_program
struct gl_fragment_program FragProg;
GLboolean translated;
- GLboolean params_uptodate;
- GLboolean on_hardware;
GLboolean error; /* If program is malformed for any reason. */
GLuint nr_tex_indirect;
@@ -129,43 +127,15 @@ struct i915_fragment_program
GLuint nr_decl_insn;
-
-
- /* TODO: split between the stored representation of a program and
- * the state used to build that representation.
- */
- GLcontext *ctx;
-
- GLuint declarations[I915_PROGRAM_SIZE];
- GLuint program[I915_PROGRAM_SIZE];
-
GLfloat constant[I915_MAX_CONSTANT][4];
GLuint constant_flags[I915_MAX_CONSTANT];
GLuint nr_constants;
- GLuint *csr; /* Cursor, points into program.
- */
-
- GLuint *decl; /* Cursor, points into declarations.
- */
-
- GLuint decl_s; /* flags for which s regs need to be decl'd */
- GLuint decl_t; /* flags for which t regs need to be decl'd */
-
- GLuint temp_flag; /* Tracks temporary regs which are in
- * use.
- */
-
- GLuint utemp_flag; /* Tracks TYPE_U temporary regs which are in
- * use.
- */
-
/* Helpers for i915_fragprog.c:
*/
GLuint wpos_tex;
- GLboolean depth_written;
struct
{
@@ -174,20 +144,6 @@ struct i915_fragment_program
} param[I915_MAX_CONSTANT];
GLuint nr_params;
-
- /* Helpers for i915_texprog.c:
- */
- GLuint src_texture; /* Reg containing sampled texture color,
- * else UREG_BAD.
- */
-
- GLuint src_previous; /* Reg containing color from previous
- * stage. May need to be decl'd.
- */
-
- GLuint last_tex_stage; /* Number of last enabled texture unit */
-
- struct vertex_buffer *VB;
};
@@ -216,7 +172,6 @@ struct i915_hw_state
*/
struct intel_region *draw_region;
struct intel_region *depth_region;
-/* struct intel_region *tex_region[I915_TEX_UNITS]; */
/* Regions aren't actually that appropriate here as the memory may
* be from a PBO or FBO. Just use the buffer id. Will have to do
@@ -230,40 +185,18 @@ struct i915_hw_state
GLuint emitted; /* I915_UPLOAD_* */
};
-#define I915_FOG_PIXEL 2
-#define I915_FOG_VERTEX 1
-#define I915_FOG_NONE 0
+
struct i915_context
{
struct intel_context intel;
- GLuint last_ReallyEnabled;
- GLuint vertex_fog;
- GLuint lodbias_ss2[MAX_TEXTURE_UNITS];
-
-
struct i915_fragment_program *current_program;
struct i915_hw_state meta, initial, state, *current;
};
-#define I915_STATECHANGE(i915, flag) \
-do { \
- INTEL_FIREVERTICES( &(i915)->intel ); \
- (i915)->state.emitted &= ~(flag); \
-} while (0)
-
-#define I915_ACTIVESTATE(i915, flag, mode) \
-do { \
- INTEL_FIREVERTICES( &(i915)->intel ); \
- if (mode) \
- (i915)->state.active |= (flag); \
- else \
- (i915)->state.active &= ~(flag); \
-} while (0)
-
/*======================================================================
* i915_vtbl.c
diff --git a/src/mesa/drivers/dri/i915tex/i915_fp.c b/src/mesa/drivers/dri/i915tex/i915_fp.c
new file mode 100644
index 0000000000..5b2ccda191
--- /dev/null
+++ b/src/mesa/drivers/dri/i915tex/i915_fp.c
@@ -0,0 +1,295 @@
+/**************************************************************************
+ *
+ * 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 "macros.h"
+#include "enums.h"
+
+#include "tnl/tnl.h"
+#include "tnl/t_context.h"
+#include "intel_batchbuffer.h"
+
+#include "i915_reg.h"
+#include "i915_context.h"
+#include "i915_program.h"
+
+#include "program_instruction.h"
+#include "program.h"
+#include "programopt.h"
+
+
+
+static void
+track_params(struct i915_fragment_program *p)
+{
+ GLint i;
+
+ if (p->nr_params)
+ _mesa_load_state_parameters(p->ctx, p->FragProg.Base.Parameters);
+
+ for (i = 0; i < p->nr_params; i++) {
+ GLint reg = p->param[i].reg;
+ COPY_4V(p->constant[reg], p->param[i].values);
+ }
+}
+
+
+static void
+i915BindProgram(GLcontext * ctx, GLenum target, struct gl_program *prog)
+{
+ if (target == GL_FRAGMENT_PROGRAM_ARB) {
+ struct i915_context *i915 = I915_CONTEXT(ctx);
+ struct i915_fragment_program *p = (struct i915_fragment_program *) prog;
+
+ if (i915->current_program == p)
+ return;
+
+ i915->current_program = p;
+
+ assert(p->on_hardware == 0);
+ assert(p->params_uptodate == 0);
+
+ /* Hack: make sure fog is correctly enabled according to this
+ * fragment program's fog options.
+ */
+ ctx->Driver.Enable(ctx, GL_FRAGMENT_PROGRAM_ARB,
+ ctx->FragmentProgram.Enabled);
+ }
+}
+
+static struct gl_program *
+i915NewProgram(GLcontext * ctx, GLenum target, GLuint id)
+{
+ switch (target) {
+ case GL_VERTEX_PROGRAM_ARB:
+ return _mesa_init_vertex_program(ctx, CALLOC_STRUCT(gl_vertex_program),
+ target, id);
+
+ case GL_FRAGMENT_PROGRAM_ARB:{
+ struct i915_fragment_program *prog =
+ CALLOC_STRUCT(i915_fragment_program);
+ if (prog) {
+ i915_init_program(I915_CONTEXT(ctx), prog);
+
+ return _mesa_init_fragment_program(ctx, &prog->FragProg,
+ target, id);
+ }
+ else
+ return NULL;
+ }
+
+ default:
+ /* Just fallback:
+ */
+ return _mesa_new_program(ctx, target, id);
+ }
+}
+
+static void
+i915DeleteProgram(GLcontext * ctx, struct gl_program *prog)
+{
+ if (prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
+ struct i915_context *i915 = I915_CONTEXT(ctx);
+ struct i915_fragment_program *p = (struct i915_fragment_program *) prog;
+
+ if (i915->current_program == p)
+ i915->current_program = 0;
+ }
+
+ _mesa_delete_program(ctx, prog);
+}
+
+
+static GLboolean
+i915IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog)
+{
+ if (target == GL_FRAGMENT_PROGRAM_ARB) {
+ struct i915_fragment_program *p = (struct i915_fragment_program *) prog;
+
+ if (!p->translated)
+ translate_program(p);
+
+ return !p->error;
+ }
+ else
+ return GL_TRUE;
+}
+
+static void
+i915ProgramStringNotify(GLcontext * ctx,
+ GLenum target, struct gl_program *prog)
+{
+ if (target == GL_FRAGMENT_PROGRAM_ARB) {
+ struct i915_fragment_program *p = (struct i915_fragment_program *) prog;
+ p->translated = 0;
+
+ /* Hack: make sure fog is correctly enabled according to this
+ * fragment program's fog options.
+ */
+ ctx->Driver.Enable(ctx, GL_FRAGMENT_PROGRAM_ARB,
+ ctx->FragmentProgram.Enabled);
+
+ if (p->FragProg.FogOption) {
+ /* add extra instructions to do fog, then turn off FogOption field */
+ _mesa_append_fog_code(ctx, &p->FragProg);
+ p->FragProg.FogOption = GL_NONE;
+ }
+ }
+
+ _tnl_program_string(ctx, target, prog);
+}
+
+
+void
+i915ValidateFragmentProgram(struct i915_context *i915)
+{
+ GLcontext *ctx = &i915->intel.ctx;
+ struct intel_context *intel = intel_context(ctx);
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct vertex_buffer *VB = &tnl->vb;
+
+ struct i915_fragment_program *p =
+ (struct i915_fragment_program *) ctx->FragmentProgram._Current;
+
+ const GLuint inputsRead = p->FragProg.Base.InputsRead;
+ GLuint s4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_VFMT_MASK;
+ GLuint s2 = S2_TEXCOORD_NONE;
+ int i, offset = 0;
+
+ if (i915->current_program != p) {
+ i915->current_program = p;
+ }
+
+
+ /* Important:
+ */
+ VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
+
+ if (!p->translated)
+ translate_program(p);
+
+ intel->vertex_attr_count = 0;
+ intel->wpos_offset = 0;
+ intel->wpos_size = 0;
+ intel->coloroffset = 0;
+ intel->specoffset = 0;
+
+ if (inputsRead & FRAG_BITS_TEX_ANY) {
+ EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, S4_VFMT_XYZW, 16);
+ }
+ else {
+ EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, S4_VFMT_XYZ, 12);
+ }
+
+ if (inputsRead & FRAG_BIT_COL0) {
+ intel->coloroffset = offset / 4;
+ EMIT_ATTR(_TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, S4_VFMT_COLOR, 4);
+ }
+
+ if ((inputsRead & (FRAG_BIT_COL1 | FRAG_BIT_FOGC)) ||
+ i915->vertex_fog != I915_FOG_NONE) {
+
+ if (inputsRead & FRAG_BIT_COL1) {
+ intel->specoffset = offset / 4;
+ EMIT_ATTR(_TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, S4_VFMT_SPEC_FOG, 3);
+ }
+ else
+ EMIT_PAD(3);
+
+ if ((inputsRead & FRAG_BIT_FOGC) || i915->vertex_fog != I915_FOG_NONE)
+ EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1UB_1F, S4_VFMT_SPEC_FOG, 1);
+ else
+ EMIT_PAD(1);
+ }
+
+ /* XXX this was disabled, but enabling this code helped fix the Glean
+ * tfragprog1 fog tests.
+ */
+ if ((inputsRead & FRAG_BIT_FOGC) || i915->vertex_fog != I915_FOG_NONE) {
+ EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1F, S4_VFMT_FOG_PARAM, 4);
+ }
+
+ for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) {
+ if (inputsRead & FRAG_BIT_TEX(i)) {
+ int sz = VB->TexCoordPtr[i]->size;
+
+ s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK);
+ s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(sz));
+
+ EMIT_ATTR(_TNL_ATTRIB_TEX0 + i, EMIT_SZ(sz), 0, sz * 4);
+ }
+ else if (i == p->wpos_tex) {
+
+ /* If WPOS is required, duplicate the XYZ position data in an
+ * unused texture coordinate:
+ */
+ s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK);
+ s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(3));
+
+ intel->wpos_offset = offset;
+ intel->wpos_size = 3 * sizeof(GLuint);
+
+ EMIT_PAD(intel->wpos_size);
+ }
+ }
+
+ if (s2 != i915->state.Ctx[I915_CTXREG_LIS2] ||
+ s4 != i915->state.Ctx[I915_CTXREG_LIS4]) {
+ int k;
+
+ I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+
+ /* Must do this *after* statechange, so as not to affect
+ * buffered vertices reliant on the old state:
+ */
+ intel->vertex_size = _tnl_install_attrs(&intel->ctx,
+ intel->vertex_attrs,
+ intel->vertex_attr_count,
+ intel->ViewportMatrix.m, 0);
+
+ intel->vertex_size >>= 2;
+
+ i915->state.Ctx[I915_CTXREG_LIS2] = s2;
+ i915->state.Ctx[I915_CTXREG_LIS4] = s4;
+ }
+
+ if (!p->params_uptodate)
+ track_params(p);
+
+
+ i915_upload_program(i915, p);
+}
+
+void
+i915InitFragProgFuncs(struct dd_function_table *functions)
+{
+ functions->BindProgram = i915BindProgram;
+ functions->NewProgram = i915NewProgram;
+ functions->DeleteProgram = i915DeleteProgram;
+ functions->IsProgramNative = i915IsProgramNative;
+ functions->ProgramStringNotify = i915ProgramStringNotify;
+}
diff --git a/src/mesa/drivers/dri/i915tex/i915_fp.h b/src/mesa/drivers/dri/i915tex/i915_fp.h
new file mode 100644
index 0000000000..8af92c82be
--- /dev/null
+++ b/src/mesa/drivers/dri/i915tex/i915_fp.h
@@ -0,0 +1,44 @@
+
+struct i915_fp_compile {
+ GLcontext *ctx;
+
+ struct i915_fragment_program *fp;
+
+ GLuint declarations[I915_PROGRAM_SIZE];
+ GLuint program[I915_PROGRAM_SIZE];
+
+ GLfloat constant[I915_MAX_CONSTANT][4];
+ GLuint constant_flags[I915_MAX_CONSTANT];
+ GLuint nr_constants;
+
+ GLuint *csr; /* Cursor, points into program.
+ */
+
+ GLuint *decl; /* Cursor, points into declarations.
+ */
+
+ GLuint decl_s; /* flags for which s regs need to be decl'd */
+ GLuint decl_t; /* flags for which t regs need to be decl'd */
+
+ GLuint temp_flag; /* Tracks temporary regs which are in
+ * use.
+ */
+
+ GLuint utemp_flag; /* Tracks TYPE_U temporary regs which are in
+ * use.
+ */
+
+
+
+ /* Helpers for i915_fragprog.c:
+ */
+ GLuint wpos_tex;
+
+ struct
+ {
+ GLuint reg; /* Hardware constant idx */
+ const GLfloat *values; /* Pointer to tracked values */
+ } param[I915_MAX_CONSTANT];
+ GLuint nr_params;
+
+};
diff --git a/src/mesa/drivers/dri/i915tex/i915_debug.c b/src/mesa/drivers/dri/i915tex/i915_fp_debug.c
index 974527e14c..974527e14c 100644
--- a/src/mesa/drivers/dri/i915tex/i915_debug.c
+++ b/src/mesa/drivers/dri/i915tex/i915_fp_debug.c
diff --git a/src/mesa/drivers/dri/i915tex/i915_fp_emit.c b/src/mesa/drivers/dri/i915tex/i915_fp_emit.c
new file mode 100644
index 0000000000..9e4d598942
--- /dev/null
+++ b/src/mesa/drivers/dri/i915tex/i915_fp_emit.c
@@ -0,0 +1,487 @@
+/**************************************************************************
+ *
+ * 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 <strings.h>
+
+#include "glheader.h"
+#include "macros.h"
+#include "enums.h"
+
+#include "tnl/t_context.h"
+#include "intel_batchbuffer.h"
+
+#include "i915_reg.h"
+#include "i915_context.h"
+#include "i915_program.h"
+
+
+#define A0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT)
+#define D0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT)
+#define T0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT)
+#define A0_SRC0( reg ) (((reg)&UREG_MASK)>>UREG_A0_SRC0_SHIFT_LEFT)
+#define A1_SRC0( reg ) (((reg)&UREG_MASK)<<UREG_A1_SRC0_SHIFT_RIGHT)
+#define A1_SRC1( reg ) (((reg)&UREG_MASK)>>UREG_A1_SRC1_SHIFT_LEFT)
+#define A2_SRC1( reg ) (((reg)&UREG_MASK)<<UREG_A2_SRC1_SHIFT_RIGHT)
+#define A2_SRC2( reg ) (((reg)&UREG_MASK)>>UREG_A2_SRC2_SHIFT_LEFT)
+
+/* These are special, and don't have swizzle/negate bits.
+ */
+#define T0_SAMPLER( reg ) (GET_UREG_NR(reg)<<T0_SAMPLER_NR_SHIFT)
+#define T1_ADDRESS_REG( reg ) ((GET_UREG_NR(reg)<<T1_ADDRESS_REG_NR_SHIFT) | \
+ (GET_UREG_TYPE(reg)<<T1_ADDRESS_REG_TYPE_SHIFT))
+
+
+/* Macros for translating UREG's into the various register fields used
+ * by the I915 programmable unit.
+ */
+#define UREG_A0_DEST_SHIFT_LEFT (UREG_TYPE_SHIFT - A0_DEST_TYPE_SHIFT)
+#define UREG_A0_SRC0_SHIFT_LEFT (UREG_TYPE_SHIFT - A0_SRC0_TYPE_SHIFT)
+#define UREG_A1_SRC0_SHIFT_RIGHT (A1_SRC0_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT)
+#define UREG_A1_SRC1_SHIFT_LEFT (UREG_TYPE_SHIFT - A1_SRC1_TYPE_SHIFT)
+#define UREG_A2_SRC1_SHIFT_RIGHT (A2_SRC1_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT)
+#define UREG_A2_SRC2_SHIFT_LEFT (UREG_TYPE_SHIFT - A2_SRC2_TYPE_SHIFT)
+
+#define UREG_MASK 0xffffff00
+#define UREG_TYPE_NR_MASK ((REG_TYPE_MASK << UREG_TYPE_SHIFT) | \
+ (REG_NR_MASK << UREG_NR_SHIFT))
+
+
+#define I915_CONSTFLAG_PARAM 0x1f
+
+GLuint
+i915_get_temp(struct i915_fragment_program *p)
+{
+ int bit = ffs(~p->temp_flag);
+ if (!bit) {
+ fprintf(stderr, "%s: out of temporaries\n", __FILE__);
+ exit(1);
+ }
+
+ p->temp_flag |= 1 << (bit - 1);
+ return UREG(REG_TYPE_R, (bit - 1));
+}
+
+
+GLuint
+i915_get_utemp(struct i915_fragment_program * p)
+{
+ int bit = ffs(~p->utemp_flag);
+ if (!bit) {
+ fprintf(stderr, "%s: out of temporaries\n", __FILE__);
+ exit(1);
+ }
+
+ p->utemp_flag |= 1 << (bit - 1);
+ return UREG(REG_TYPE_U, (bit - 1));
+}
+
+void
+i915_release_utemps(struct i915_fragment_program *p)
+{
+ p->utemp_flag = ~0x7;
+}
+
+
+GLuint
+i915_emit_decl(struct i915_fragment_program *p,
+ GLuint type, GLuint nr, GLuint d0_flags)
+{
+ GLuint reg = UREG(type, nr);
+
+ if (type == REG_TYPE_T) {
+ if (p->decl_t & (1 << nr))
+ return reg;
+
+ p->decl_t |= (1 << nr);
+ }
+ else if (type == REG_TYPE_S) {
+ if (p->decl_s & (1 << nr))
+ return reg;
+
+ p->decl_s |= (1 << nr);
+ }
+ else
+ return reg;
+
+ *(p->decl++) = (D0_DCL | D0_DEST(reg) | d0_flags);
+ *(p->decl++) = D1_MBZ;
+ *(p->decl++) = D2_MBZ;
+
+ p->nr_decl_insn++;
+ return reg;
+}
+
+GLuint
+i915_emit_arith(struct i915_fragment_program * p,
+ GLuint op,
+ GLuint dest,
+ GLuint mask,
+ GLuint saturate, GLuint src0, GLuint src1, GLuint src2)
+{
+ GLuint c[3];
+ GLuint nr_const = 0;
+
+ assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST);
+ dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
+ assert(dest);
+
+ if (GET_UREG_TYPE(src0) == REG_TYPE_CONST)
+ c[nr_const++] = 0;
+ if (GET_UREG_TYPE(src1) == REG_TYPE_CONST)
+ c[nr_const++] = 1;
+ if (GET_UREG_TYPE(src2) == REG_TYPE_CONST)
+ c[nr_const++] = 2;
+
+ /* Recursively call this function to MOV additional const values
+ * into temporary registers. Use utemp registers for this -
+ * currently shouldn't be possible to run out, but keep an eye on
+ * this.
+ */
+ if (nr_const > 1) {
+ GLuint s[3], first, i, old_utemp_flag;
+
+ s[0] = src0;
+ s[1] = src1;
+ s[2] = src2;
+ old_utemp_flag = p->utemp_flag;
+
+ first = GET_UREG_NR(s[c[0]]);
+ for (i = 1; i < nr_const; i++) {
+ if (GET_UREG_NR(s[c[i]]) != first) {
+ GLuint tmp = i915_get_utemp(p);
+
+ i915_emit_arith(p, A0_MOV, tmp, A0_DEST_CHANNEL_ALL, 0,
+ s[c[i]], 0, 0);
+ s[c[i]] = tmp;
+ }
+ }
+
+ src0 = s[0];
+ src1 = s[1];
+ src2 = s[2];
+ p->utemp_flag = old_utemp_flag; /* restore */
+ }
+
+ *(p->csr++) = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0));
+ *(p->csr++) = (A1_SRC0(src0) | A1_SRC1(src1));
+ *(p->csr++) = (A2_SRC1(src1) | A2_SRC2(src2));
+
+ p->nr_alu_insn++;
+ return dest;
+}
+
+GLuint i915_emit_texld( struct i915_fragment_program *p,
+ GLuint dest,
+ GLuint destmask,
+ GLuint sampler,
+ GLuint coord,
+ GLuint op )
+{
+ if (coord != UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord))) {
+ /* 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.
+ */
+ i915_program_error(p, "Can't (yet) swizzle TEX arguments");
+ return 0;
+ }
+
+ /* Don't worry about saturate as we only support
+ */
+ if (destmask != A0_DEST_CHANNEL_ALL) {
+ GLuint tmp = i915_get_utemp(p);
+ i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, op );
+ i915_emit_arith( p, A0_MOV, dest, destmask, 0, tmp, 0, 0 );
+ return dest;
+ }
+ else {
+ assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST);
+ assert(dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)));
+
+ if (GET_UREG_TYPE(coord) != REG_TYPE_T) {
+ p->nr_tex_indirect++;
+ }
+
+ *(p->csr++) = (op |
+ T0_DEST( dest ) |
+ T0_SAMPLER( sampler ));
+
+ *(p->csr++) = T1_ADDRESS_REG( coord );
+ *(p->csr++) = T2_MBZ;
+
+ p->nr_tex_insn++;
+ return dest;
+ }
+}
+
+
+GLuint
+i915_emit_const1f(struct i915_fragment_program * p, GLfloat c0)
+{
+ GLint reg, idx;
+
+ if (c0 == 0.0)
+ return swizzle(UREG(REG_TYPE_R, 0), ZERO, ZERO, ZERO, ZERO);
+ if (c0 == 1.0)
+ return swizzle(UREG(REG_TYPE_R, 0), ONE, ONE, ONE, ONE);
+
+ for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
+ if (p->constant_flags[reg] == I915_CONSTFLAG_PARAM)
+ continue;
+ for (idx = 0; idx < 4; idx++) {
+ if (!(p->constant_flags[reg] & (1 << idx)) ||
+ p->constant[reg][idx] == c0) {
+ p->constant[reg][idx] = c0;
+ p->constant_flags[reg] |= 1 << idx;
+ if (reg + 1 > p->nr_constants)
+ p->nr_constants = reg + 1;
+ return swizzle(UREG(REG_TYPE_CONST, reg), idx, ZERO, ZERO, ONE);
+ }
+ }
+ }
+
+ fprintf(stderr, "%s: out of constants\n", __FUNCTION__);
+ p->error = 1;
+ return 0;
+}
+
+GLuint
+i915_emit_const2f(struct i915_fragment_program * p, GLfloat c0, GLfloat c1)
+{
+ GLint reg, idx;
+
+ if (c0 == 0.0)
+ return swizzle(i915_emit_const1f(p, c1), ZERO, X, Z, W);
+ if (c0 == 1.0)
+ return swizzle(i915_emit_const1f(p, c1), ONE, X, Z, W);
+
+ if (c1 == 0.0)
+ return swizzle(i915_emit_const1f(p, c0), X, ZERO, Z, W);
+ if (c1 == 1.0)
+ return swizzle(i915_emit_const1f(p, c0), X, ONE, Z, W);
+
+ for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
+ if (p->constant_flags[reg] == 0xf ||
+ p->constant_flags[reg] == I915_CONSTFLAG_PARAM)
+ continue;
+ for (idx = 0; idx < 3; idx++) {
+ if (!(p->constant_flags[reg] & (3 << idx))) {
+ p->constant[reg][idx] = c0;
+ p->constant[reg][idx + 1] = c1;
+ p->constant_flags[reg] |= 3 << idx;
+ if (reg + 1 > p->nr_constants)
+ p->nr_constants = reg + 1;
+ return swizzle(UREG(REG_TYPE_CONST, reg), idx, idx + 1, ZERO,
+ ONE);
+ }
+ }
+ }
+
+ fprintf(stderr, "%s: out of constants\n", __FUNCTION__);
+ p->error = 1;
+ return 0;
+}
+
+
+
+GLuint
+i915_emit_const4f(struct i915_fragment_program * p,
+ GLfloat c0, GLfloat c1, GLfloat c2, GLfloat c3)
+{
+ GLint reg;
+
+ for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
+ if (p->constant_flags[reg] == 0xf &&
+ p->constant[reg][0] == c0 &&
+ p->constant[reg][1] == c1 &&
+ p->constant[reg][2] == c2 && p->constant[reg][3] == c3) {
+ return UREG(REG_TYPE_CONST, reg);
+ }
+ else if (p->constant_flags[reg] == 0) {
+ p->constant[reg][0] = c0;
+ p->constant[reg][1] = c1;
+ p->constant[reg][2] = c2;
+ p->constant[reg][3] = c3;
+ p->constant_flags[reg] = 0xf;
+ if (reg + 1 > p->nr_constants)
+ p->nr_constants = reg + 1;
+ return UREG(REG_TYPE_CONST, reg);
+ }
+ }
+
+ fprintf(stderr, "%s: out of constants\n", __FUNCTION__);
+ p->error = 1;
+ return 0;
+}
+
+
+GLuint
+i915_emit_const4fv(struct i915_fragment_program * p, const GLfloat * c)
+{
+ return i915_emit_const4f(p, c[0], c[1], c[2], c[3]);
+}
+
+
+GLuint
+i915_emit_param4fv(struct i915_fragment_program * p, const GLfloat * values)
+{
+ GLint reg, i;
+
+ for (i = 0; i < p->nr_params; i++) {
+ if (p->param[i].values == values)
+ return UREG(REG_TYPE_CONST, p->param[i].reg);
+ }
+
+
+ for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
+ if (p->constant_flags[reg] == 0) {
+ p->constant_flags[reg] = I915_CONSTFLAG_PARAM;
+ i = p->nr_params++;
+
+ p->param[i].values = values;
+ p->param[i].reg = reg;
+ p->params_uptodate = 0;
+
+ if (reg + 1 > p->nr_constants)
+ p->nr_constants = reg + 1;
+ return UREG(REG_TYPE_CONST, reg);
+ }
+ }
+
+ fprintf(stderr, "%s: out of constants\n", __FUNCTION__);
+ p->error = 1;
+ return 0;
+}
+
+
+
+void
+i915_program_error(struct i915_fragment_program *p, const char *msg)
+{
+ _mesa_problem(NULL, "i915_program_error: %s", msg);
+ p->error = 1;
+}
+
+
+void
+i915_init_program(struct i915_context *i915, struct i915_fragment_program *p)
+{
+ GLcontext *ctx = &i915->intel.ctx;
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+
+ p->translated = 0;
+ p->params_uptodate = 0;
+ p->error = 0;
+
+ p->nr_tex_indirect = 1; /* correct? */
+ p->nr_tex_insn = 0;
+ p->nr_alu_insn = 0;
+ p->nr_decl_insn = 0;
+
+ p->ctx = ctx;
+ memset(p->constant_flags, 0, sizeof(p->constant_flags));
+
+ p->nr_constants = 0;
+ p->csr = p->program;
+ p->decl = p->declarations;
+ p->decl_s = 0;
+ p->decl_t = 0;
+ p->temp_flag = 0xffff000;
+ p->utemp_flag = ~0x7;
+ p->wpos_tex = -1;
+ p->nr_params = 0;
+
+ p->src_texture = UREG_BAD;
+ p->src_previous = UREG(REG_TYPE_T, T_DIFFUSE);
+ p->last_tex_stage = 0;
+ p->VB = &tnl->vb;
+
+ *(p->decl++) = _3DSTATE_PIXEL_SHADER_PROGRAM;
+}
+
+
+void
+i915_fini_program(struct i915_fragment_program *p)
+{
+ GLuint program_size = p->csr - p->program;
+ GLuint decl_size = p->decl - p->declarations;
+
+ if (p->nr_tex_indirect > I915_MAX_TEX_INDIRECT)
+ i915_program_error(p, "Exceeded max nr indirect texture lookups");
+
+ if (p->nr_tex_insn > I915_MAX_TEX_INSN)
+ i915_program_error(p, "Exceeded max TEX instructions");
+
+ if (p->nr_alu_insn > I915_MAX_ALU_INSN)
+ i915_program_error(p, "Exceeded max ALU instructions");
+
+ if (p->nr_decl_insn > I915_MAX_DECL_INSN)
+ i915_program_error(p, "Exceeded max DECL instructions");
+
+ if (p->error) {
+ p->FragProg.Base.NumNativeInstructions = 0;
+ p->FragProg.NumNativeAluInstructions = 0;
+ p->FragProg.NumNativeTexInstructions = 0;
+ p->FragProg.NumNativeTexIndirections = 0;
+ }
+ else {
+ p->FragProg.Base.NumNativeInstructions = (p->nr_alu_insn +
+ p->nr_tex_insn +
+ p->nr_decl_insn);
+ p->FragProg.NumNativeAluInstructions = p->nr_alu_insn;
+ p->FragProg.NumNativeTexInstructions = p->nr_tex_insn;
+ p->FragProg.NumNativeTexIndirections = p->nr_tex_indirect;
+ }
+
+ p->declarations[0] |= program_size + decl_size - 2;
+}
+
+void
+i915_upload_program(struct i915_context *i915,
+ struct i915_fragment_program *p)
+{
+ GLuint program_size = p->csr - p->program;
+ GLuint decl_size = p->decl - p->declarations;
+
+ FALLBACK(&i915->intel, I915_FALLBACK_PROGRAM, p->error);
+
+ /* Could just go straight to the batchbuffer from here:
+ */
+ if (i915->state.ProgramSize != (program_size + decl_size) ||
+ memcmp(i915->state.Program + decl_size, p->program,
+ program_size * sizeof(int)) != 0) {
+ I915_STATECHANGE(i915, I915_UPLOAD_PROGRAM);
+ memcpy(i915->state.Program, p->declarations, decl_size * sizeof(int));
+ memcpy(i915->state.Program + decl_size, p->program,
+ program_size * sizeof(int));
+ i915->state.ProgramSize = decl_size + program_size;
+ }
+
+
+ /* Set dependent state variables
+ */
+}
diff --git a/src/mesa/drivers/dri/i915tex/i915_program.h b/src/mesa/drivers/dri/i915tex/i915_fp_emit.h
index 3c12b34f16..3c12b34f16 100644
--- a/src/mesa/drivers/dri/i915tex/i915_program.h
+++ b/src/mesa/drivers/dri/i915tex/i915_fp_emit.h
diff --git a/src/mesa/drivers/dri/i915tex/i915_fragprog.c b/src/mesa/drivers/dri/i915tex/i915_fp_translate.c
index 8772e70230..bbcca2ef37 100644
--- a/src/mesa/drivers/dri/i915tex/i915_fragprog.c
+++ b/src/mesa/drivers/dri/i915tex/i915_fp_translate.c
@@ -80,6 +80,15 @@ src_vector(struct i915_fragment_program *p,
src = UREG(REG_TYPE_R, source->Index);
break;
case PROGRAM_INPUT:
+ /* XXX: Packing COL1, FOGC into a single attribute works for
+ * texenv programs, but will fail for real fragment programs
+ * that use these attributes and expect them to be a full 4
+ * components wide. Could use a texcoord to pass these
+ * attributes if necessary, but that won't work in the general
+ * case.
+ *
+ * We also use a texture coordinate to pass wpos when possible.
+ */
switch (source->Index) {
case FRAG_ATTRIB_WPOS:
src = i915_emit_decl(p, REG_TYPE_T, p->wpos_tex, D0_CHANNEL_ALL);
@@ -122,19 +131,15 @@ src_vector(struct i915_fragment_program *p,
break;
case PROGRAM_ENV_PARAM:
- src =
- i915_emit_param4fv(p,
- p->ctx->FragmentProgram.Parameters[source->
- Index]);
+ src = i915_emit_param4fv(
+ p, p->ctx->FragmentProgram.Parameters[source->Index]);
break;
case PROGRAM_CONSTANT:
case PROGRAM_STATE_VAR:
case PROGRAM_NAMED_PARAM:
- src =
- i915_emit_param4fv(p,
- program->Base.Parameters->ParameterValues[source->
- Index]);
+ src = i915_emit_param4fv(
+ p, program->Base.Parameters->ParameterValues[source->Index]);
break;
default:
@@ -168,7 +173,6 @@ get_result_vector(struct i915_fragment_program *p,
case FRAG_RESULT_COLR:
return UREG(REG_TYPE_OC, 0);
case FRAG_RESULT_DEPR:
- p->depth_written = 1;
return UREG(REG_TYPE_OD, 0);
default:
i915_program_error(p, "Bad inst->DstReg.Index");
@@ -761,7 +765,7 @@ upload_program(struct i915_fragment_program *p)
static void
fixup_depth_write(struct i915_fragment_program *p)
{
- if (p->depth_written) {
+ if (p->fp->Base.OutputsWritten & (1<<FRAG_RESULT_DEPR)) {
GLuint depth = UREG(REG_TYPE_OD, 0);
i915_emit_arith(p,
@@ -775,309 +779,24 @@ fixup_depth_write(struct i915_fragment_program *p)
#define FRAG_BIT_TEX(n) (FRAG_BIT_TEX0 << (n))
-static void
-check_wpos(struct i915_fragment_program *p)
-{
- GLuint inputs = p->FragProg.Base.InputsRead;
- GLint i;
-
- p->wpos_tex = -1;
-
- for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) {
- if (inputs & FRAG_BIT_TEX(i))
- continue;
- else if (inputs & FRAG_BIT_WPOS) {
- p->wpos_tex = i;
- inputs &= ~FRAG_BIT_WPOS;
- }
- }
-
- if (inputs & FRAG_BIT_WPOS) {
- i915_program_error(p, "No free texcoord for wpos value");
- }
-}
-
-
-static void
-translate_program(struct i915_fragment_program *p)
-{
- struct i915_context *i915 = I915_CONTEXT(p->ctx);
-
- i915_init_program(i915, p);
- check_wpos(p);
- upload_program(p);
- fixup_depth_write(p);
- i915_fini_program(p);
-
- p->translated = 1;
-}
-
-
-static void
-track_params(struct i915_fragment_program *p)
-{
- GLint i;
-
- if (p->nr_params)
- _mesa_load_state_parameters(p->ctx, p->FragProg.Base.Parameters);
-
- for (i = 0; i < p->nr_params; i++) {
- GLint reg = p->param[i].reg;
- COPY_4V(p->constant[reg], p->param[i].values);
- }
-
- p->params_uptodate = 1;
- p->on_hardware = 0; /* overkill */
-}
-
-
-static void
-i915BindProgram(GLcontext * ctx, GLenum target, struct gl_program *prog)
-{
- if (target == GL_FRAGMENT_PROGRAM_ARB) {
- struct i915_context *i915 = I915_CONTEXT(ctx);
- struct i915_fragment_program *p = (struct i915_fragment_program *) prog;
-
- if (i915->current_program == p)
- return;
-
- if (i915->current_program) {
- i915->current_program->on_hardware = 0;
- i915->current_program->params_uptodate = 0;
- }
-
- i915->current_program = p;
-
- assert(p->on_hardware == 0);
- assert(p->params_uptodate == 0);
-
- /* Hack: make sure fog is correctly enabled according to this
- * fragment program's fog options.
- */
- ctx->Driver.Enable(ctx, GL_FRAGMENT_PROGRAM_ARB,
- ctx->FragmentProgram.Enabled);
- }
-}
-
-static struct gl_program *
-i915NewProgram(GLcontext * ctx, GLenum target, GLuint id)
-{
- switch (target) {
- case GL_VERTEX_PROGRAM_ARB:
- return _mesa_init_vertex_program(ctx, CALLOC_STRUCT(gl_vertex_program),
- target, id);
-
- case GL_FRAGMENT_PROGRAM_ARB:{
- struct i915_fragment_program *prog =
- CALLOC_STRUCT(i915_fragment_program);
- if (prog) {
- i915_init_program(I915_CONTEXT(ctx), prog);
-
- return _mesa_init_fragment_program(ctx, &prog->FragProg,
- target, id);
- }
- else
- return NULL;
- }
-
- default:
- /* Just fallback:
- */
- return _mesa_new_program(ctx, target, id);
- }
-}
-
-static void
-i915DeleteProgram(GLcontext * ctx, struct gl_program *prog)
-{
- if (prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
- struct i915_context *i915 = I915_CONTEXT(ctx);
- struct i915_fragment_program *p = (struct i915_fragment_program *) prog;
-
- if (i915->current_program == p)
- i915->current_program = 0;
- }
-
- _mesa_delete_program(ctx, prog);
-}
-
-
-static GLboolean
-i915IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog)
-{
- if (target == GL_FRAGMENT_PROGRAM_ARB) {
- struct i915_fragment_program *p = (struct i915_fragment_program *) prog;
-
- if (!p->translated)
- translate_program(p);
-
- return !p->error;
- }
- else
- return GL_TRUE;
-}
-
-static void
-i915ProgramStringNotify(GLcontext * ctx,
- GLenum target, struct gl_program *prog)
-{
- if (target == GL_FRAGMENT_PROGRAM_ARB) {
- struct i915_fragment_program *p = (struct i915_fragment_program *) prog;
- p->translated = 0;
-
- /* Hack: make sure fog is correctly enabled according to this
- * fragment program's fog options.
- */
- ctx->Driver.Enable(ctx, GL_FRAGMENT_PROGRAM_ARB,
- ctx->FragmentProgram.Enabled);
-
- if (p->FragProg.FogOption) {
- /* add extra instructions to do fog, then turn off FogOption field */
- _mesa_append_fog_code(ctx, &p->FragProg);
- p->FragProg.FogOption = GL_NONE;
- }
- }
-
- _tnl_program_string(ctx, target, prog);
-}
void
-i915ValidateFragmentProgram(struct i915_context *i915)
+i915EmitFragmentProgram(struct i915_context *i915)
{
GLcontext *ctx = &i915->intel.ctx;
struct intel_context *intel = intel_context(ctx);
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- struct vertex_buffer *VB = &tnl->vb;
-
struct i915_fragment_program *p =
(struct i915_fragment_program *) ctx->FragmentProgram._Current;
- const GLuint inputsRead = p->FragProg.Base.InputsRead;
- GLuint s4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_VFMT_MASK;
- GLuint s2 = S2_TEXCOORD_NONE;
- int i, offset = 0;
-
- if (i915->current_program != p) {
- if (i915->current_program) {
- i915->current_program->on_hardware = 0;
- i915->current_program->params_uptodate = 0;
- }
-
- i915->current_program = p;
- }
-
-
- /* Important:
- */
- VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
-
- if (!p->translated)
- translate_program(p);
-
- intel->vertex_attr_count = 0;
- intel->wpos_offset = 0;
- intel->wpos_size = 0;
- intel->coloroffset = 0;
- intel->specoffset = 0;
-
- if (inputsRead & FRAG_BITS_TEX_ANY) {
- EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, S4_VFMT_XYZW, 16);
- }
- else {
- EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, S4_VFMT_XYZ, 12);
- }
-
- if (inputsRead & FRAG_BIT_COL0) {
- intel->coloroffset = offset / 4;
- EMIT_ATTR(_TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, S4_VFMT_COLOR, 4);
- }
-
- if ((inputsRead & (FRAG_BIT_COL1 | FRAG_BIT_FOGC)) ||
- i915->vertex_fog != I915_FOG_NONE) {
-
- if (inputsRead & FRAG_BIT_COL1) {
- intel->specoffset = offset / 4;
- EMIT_ATTR(_TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, S4_VFMT_SPEC_FOG, 3);
- }
- else
- EMIT_PAD(3);
-
- if ((inputsRead & FRAG_BIT_FOGC) || i915->vertex_fog != I915_FOG_NONE)
- EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1UB_1F, S4_VFMT_SPEC_FOG, 1);
- else
- EMIT_PAD(1);
- }
+ if (!p->translated) {
+ i915_init_program(i915, p);
+ check_wpos(p);
+ upload_program(p);
+ fixup_depth_write(p);
+ i915_fini_program(p);
- /* XXX this was disabled, but enabling this code helped fix the Glean
- * tfragprog1 fog tests.
- */
-#if 1
- if ((inputsRead & FRAG_BIT_FOGC) || i915->vertex_fog != I915_FOG_NONE) {
- EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1F, S4_VFMT_FOG_PARAM, 4);
+ p->translated = 1;
}
-#endif
-
- for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) {
- if (inputsRead & FRAG_BIT_TEX(i)) {
- int sz = VB->TexCoordPtr[i]->size;
-
- s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK);
- s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(sz));
-
- EMIT_ATTR(_TNL_ATTRIB_TEX0 + i, EMIT_SZ(sz), 0, sz * 4);
- }
- else if (i == p->wpos_tex) {
-
- /* If WPOS is required, duplicate the XYZ position data in an
- * unused texture coordinate:
- */
- s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK);
- s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(3));
-
- intel->wpos_offset = offset;
- intel->wpos_size = 3 * sizeof(GLuint);
-
- EMIT_PAD(intel->wpos_size);
- }
- }
-
- if (s2 != i915->state.Ctx[I915_CTXREG_LIS2] ||
- s4 != i915->state.Ctx[I915_CTXREG_LIS4]) {
- int k;
-
- I915_STATECHANGE(i915, I915_UPLOAD_CTX);
-
- /* Must do this *after* statechange, so as not to affect
- * buffered vertices reliant on the old state:
- */
- intel->vertex_size = _tnl_install_attrs(&intel->ctx,
- intel->vertex_attrs,
- intel->vertex_attr_count,
- intel->ViewportMatrix.m, 0);
-
- intel->vertex_size >>= 2;
-
- i915->state.Ctx[I915_CTXREG_LIS2] = s2;
- i915->state.Ctx[I915_CTXREG_LIS4] = s4;
-
- k = intel->vtbl.check_vertex_size(intel, intel->vertex_size);
- assert(k);
- }
-
- if (!p->params_uptodate)
- track_params(p);
-
- if (!p->on_hardware)
- i915_upload_program(i915, p);
}
-void
-i915InitFragProgFuncs(struct dd_function_table *functions)
-{
- functions->BindProgram = i915BindProgram;
- functions->NewProgram = i915NewProgram;
- functions->DeleteProgram = i915DeleteProgram;
- functions->IsProgramNative = i915IsProgramNative;
- functions->ProgramStringNotify = i915ProgramStringNotify;
-}
diff --git a/src/mesa/drivers/dri/i915tex/i915_program.c b/src/mesa/drivers/dri/i915tex/i915_program.c
index 0be89d3320..1ae065b10d 100644
--- a/src/mesa/drivers/dri/i915tex/i915_program.c
+++ b/src/mesa/drivers/dri/i915tex/i915_program.c
@@ -1,515 +1,147 @@
-/**************************************************************************
- *
- * 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 <strings.h>
-
-#include "glheader.h"
-#include "macros.h"
+/*
+ Copyright (C) Intel Corp. 2006. All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+
+ **********************************************************************/
+ /*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+
+#include "brw_context.h"
+#include "brw_aub.h"
+#include "brw_util.h"
+#include "program.h"
+#include "imports.h"
#include "enums.h"
+#include "tnl/tnl.h"
-#include "tnl/t_context.h"
-#include "intel_batchbuffer.h"
-
-#include "i915_reg.h"
-#include "i915_context.h"
-#include "i915_program.h"
-
-
-#define A0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT)
-#define D0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT)
-#define T0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT)
-#define A0_SRC0( reg ) (((reg)&UREG_MASK)>>UREG_A0_SRC0_SHIFT_LEFT)
-#define A1_SRC0( reg ) (((reg)&UREG_MASK)<<UREG_A1_SRC0_SHIFT_RIGHT)
-#define A1_SRC1( reg ) (((reg)&UREG_MASK)>>UREG_A1_SRC1_SHIFT_LEFT)
-#define A2_SRC1( reg ) (((reg)&UREG_MASK)<<UREG_A2_SRC1_SHIFT_RIGHT)
-#define A2_SRC2( reg ) (((reg)&UREG_MASK)>>UREG_A2_SRC2_SHIFT_LEFT)
-
-/* These are special, and don't have swizzle/negate bits.
- */
-#define T0_SAMPLER( reg ) (GET_UREG_NR(reg)<<T0_SAMPLER_NR_SHIFT)
-#define T1_ADDRESS_REG( reg ) ((GET_UREG_NR(reg)<<T1_ADDRESS_REG_NR_SHIFT) | \
- (GET_UREG_TYPE(reg)<<T1_ADDRESS_REG_TYPE_SHIFT))
-
-
-/* Macros for translating UREG's into the various register fields used
- * by the I915 programmable unit.
- */
-#define UREG_A0_DEST_SHIFT_LEFT (UREG_TYPE_SHIFT - A0_DEST_TYPE_SHIFT)
-#define UREG_A0_SRC0_SHIFT_LEFT (UREG_TYPE_SHIFT - A0_SRC0_TYPE_SHIFT)
-#define UREG_A1_SRC0_SHIFT_RIGHT (A1_SRC0_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT)
-#define UREG_A1_SRC1_SHIFT_LEFT (UREG_TYPE_SHIFT - A1_SRC1_TYPE_SHIFT)
-#define UREG_A2_SRC1_SHIFT_RIGHT (A2_SRC1_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT)
-#define UREG_A2_SRC2_SHIFT_LEFT (UREG_TYPE_SHIFT - A2_SRC2_TYPE_SHIFT)
-#define UREG_MASK 0xffffff00
-#define UREG_TYPE_NR_MASK ((REG_TYPE_MASK << UREG_TYPE_SHIFT) | \
- (REG_NR_MASK << UREG_NR_SHIFT))
-
-
-#define I915_CONSTFLAG_PARAM 0x1f
-
-GLuint
-i915_get_temp(struct i915_fragment_program *p)
+static void brwBindProgram( GLcontext *ctx,
+ GLenum target,
+ struct gl_program *prog )
{
- int bit = ffs(~p->temp_flag);
- if (!bit) {
- fprintf(stderr, "%s: out of temporaries\n", __FILE__);
- exit(1);
- }
-
- p->temp_flag |= 1 << (bit - 1);
- return UREG(REG_TYPE_R, (bit - 1));
-}
-
+ struct brw_context *brw = brw_context(ctx);
-GLuint
-i915_get_utemp(struct i915_fragment_program * p)
-{
- int bit = ffs(~p->utemp_flag);
- if (!bit) {
- fprintf(stderr, "%s: out of temporaries\n", __FILE__);
- exit(1);
+ switch (target) {
+ case GL_VERTEX_PROGRAM_ARB:
+ brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM;
+ break;
+ case GL_FRAGMENT_PROGRAM_ARB:
+ brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM;
+ break;
}
-
- p->utemp_flag |= 1 << (bit - 1);
- return UREG(REG_TYPE_U, (bit - 1));
-}
-
-void
-i915_release_utemps(struct i915_fragment_program *p)
-{
- p->utemp_flag = ~0x7;
}
-
-GLuint
-i915_emit_decl(struct i915_fragment_program *p,
- GLuint type, GLuint nr, GLuint d0_flags)
+static struct gl_program *brwNewProgram( GLcontext *ctx,
+ GLenum target,
+ GLuint id )
{
- GLuint reg = UREG(type, nr);
+ struct brw_context *brw = brw_context(ctx);
- if (type == REG_TYPE_T) {
- if (p->decl_t & (1 << nr))
- return reg;
-
- p->decl_t |= (1 << nr);
- }
- else if (type == REG_TYPE_S) {
- if (p->decl_s & (1 << nr))
- return reg;
-
- p->decl_s |= (1 << nr);
- }
- else
- return reg;
-
- *(p->decl++) = (D0_DCL | D0_DEST(reg) | d0_flags);
- *(p->decl++) = D1_MBZ;
- *(p->decl++) = D2_MBZ;
-
- p->nr_decl_insn++;
- return reg;
-}
-
-GLuint
-i915_emit_arith(struct i915_fragment_program * p,
- GLuint op,
- GLuint dest,
- GLuint mask,
- GLuint saturate, GLuint src0, GLuint src1, GLuint src2)
-{
- GLuint c[3];
- GLuint nr_const = 0;
+ switch (target) {
+ case GL_VERTEX_PROGRAM_ARB: {
+ struct brw_vertex_program *prog = CALLOC_STRUCT(brw_vertex_program);
+ if (prog) {
+ prog->id = brw->program_id++;
- assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST);
- dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
- assert(dest);
-
- if (GET_UREG_TYPE(src0) == REG_TYPE_CONST)
- c[nr_const++] = 0;
- if (GET_UREG_TYPE(src1) == REG_TYPE_CONST)
- c[nr_const++] = 1;
- if (GET_UREG_TYPE(src2) == REG_TYPE_CONST)
- c[nr_const++] = 2;
-
- /* Recursively call this function to MOV additional const values
- * into temporary registers. Use utemp registers for this -
- * currently shouldn't be possible to run out, but keep an eye on
- * this.
- */
- if (nr_const > 1) {
- GLuint s[3], first, i, old_utemp_flag;
-
- s[0] = src0;
- s[1] = src1;
- s[2] = src2;
- old_utemp_flag = p->utemp_flag;
-
- first = GET_UREG_NR(s[c[0]]);
- for (i = 1; i < nr_const; i++) {
- if (GET_UREG_NR(s[c[i]]) != first) {
- GLuint tmp = i915_get_utemp(p);
-
- i915_emit_arith(p, A0_MOV, tmp, A0_DEST_CHANNEL_ALL, 0,
- s[c[i]], 0, 0);
- s[c[i]] = tmp;
- }
+ return _mesa_init_vertex_program( ctx, &prog->program,
+ target, id );
}
-
- src0 = s[0];
- src1 = s[1];
- src2 = s[2];
- p->utemp_flag = old_utemp_flag; /* restore */
+ else
+ return NULL;
}
- *(p->csr++) = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0));
- *(p->csr++) = (A1_SRC0(src0) | A1_SRC1(src1));
- *(p->csr++) = (A2_SRC1(src1) | A2_SRC2(src2));
-
- p->nr_alu_insn++;
- return dest;
-}
+ case GL_FRAGMENT_PROGRAM_ARB: {
+ struct brw_fragment_program *prog = CALLOC_STRUCT(brw_fragment_program);
+ if (prog) {
+ prog->id = brw->program_id++;
-GLuint i915_emit_texld( struct i915_fragment_program *p,
- GLuint dest,
- GLuint destmask,
- GLuint sampler,
- GLuint coord,
- GLuint op )
-{
- if (coord != UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord))) {
- /* 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.
- */
- i915_program_error(p, "Can't (yet) swizzle TEX arguments");
- return 0;
- }
-
- /* Don't worry about saturate as we only support
- */
- if (destmask != A0_DEST_CHANNEL_ALL) {
- GLuint tmp = i915_get_utemp(p);
- i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, op );
- i915_emit_arith( p, A0_MOV, dest, destmask, 0, tmp, 0, 0 );
- return dest;
- }
- else {
- assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST);
- assert(dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)));
-
- if (GET_UREG_TYPE(coord) != REG_TYPE_T) {
- p->nr_tex_indirect++;
+ return _mesa_init_fragment_program( ctx, &prog->program,
+ target, id );
}
-
- *(p->csr++) = (op |
- T0_DEST( dest ) |
- T0_SAMPLER( sampler ));
-
- *(p->csr++) = T1_ADDRESS_REG( coord );
- *(p->csr++) = T2_MBZ;
-
- p->nr_tex_insn++;
- return dest;
+ else
+ return NULL;
}
-}
-
-
-GLuint
-i915_emit_const1f(struct i915_fragment_program * p, GLfloat c0)
-{
- GLint reg, idx;
-
- if (c0 == 0.0)
- return swizzle(UREG(REG_TYPE_R, 0), ZERO, ZERO, ZERO, ZERO);
- if (c0 == 1.0)
- return swizzle(UREG(REG_TYPE_R, 0), ONE, ONE, ONE, ONE);
- for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
- if (p->constant_flags[reg] == I915_CONSTFLAG_PARAM)
- continue;
- for (idx = 0; idx < 4; idx++) {
- if (!(p->constant_flags[reg] & (1 << idx)) ||
- p->constant[reg][idx] == c0) {
- p->constant[reg][idx] = c0;
- p->constant_flags[reg] |= 1 << idx;
- if (reg + 1 > p->nr_constants)
- p->nr_constants = reg + 1;
- return swizzle(UREG(REG_TYPE_CONST, reg), idx, ZERO, ZERO, ONE);
- }
- }
+ default:
+ return _mesa_new_program(ctx, target, id);
}
-
- fprintf(stderr, "%s: out of constants\n", __FUNCTION__);
- p->error = 1;
- return 0;
}
-GLuint
-i915_emit_const2f(struct i915_fragment_program * p, GLfloat c0, GLfloat c1)
+static void brwDeleteProgram( GLcontext *ctx,
+ struct gl_program *prog )
{
- GLint reg, idx;
-
- if (c0 == 0.0)
- return swizzle(i915_emit_const1f(p, c1), ZERO, X, Z, W);
- if (c0 == 1.0)
- return swizzle(i915_emit_const1f(p, c1), ONE, X, Z, W);
-
- if (c1 == 0.0)
- return swizzle(i915_emit_const1f(p, c0), X, ZERO, Z, W);
- if (c1 == 1.0)
- return swizzle(i915_emit_const1f(p, c0), X, ONE, Z, W);
-
- for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
- if (p->constant_flags[reg] == 0xf ||
- p->constant_flags[reg] == I915_CONSTFLAG_PARAM)
- continue;
- for (idx = 0; idx < 3; idx++) {
- if (!(p->constant_flags[reg] & (3 << idx))) {
- p->constant[reg][idx] = c0;
- p->constant[reg][idx + 1] = c1;
- p->constant_flags[reg] |= 3 << idx;
- if (reg + 1 > p->nr_constants)
- p->nr_constants = reg + 1;
- return swizzle(UREG(REG_TYPE_CONST, reg), idx, idx + 1, ZERO,
- ONE);
- }
- }
- }
-
- fprintf(stderr, "%s: out of constants\n", __FUNCTION__);
- p->error = 1;
- return 0;
+
+ _mesa_delete_program( ctx, prog );
}
-
-GLuint
-i915_emit_const4f(struct i915_fragment_program * p,
- GLfloat c0, GLfloat c1, GLfloat c2, GLfloat c3)
+static GLboolean brwIsProgramNative( GLcontext *ctx,
+ GLenum target,
+ struct gl_program *prog )
{
- GLint reg;
-
- for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
- if (p->constant_flags[reg] == 0xf &&
- p->constant[reg][0] == c0 &&
- p->constant[reg][1] == c1 &&
- p->constant[reg][2] == c2 && p->constant[reg][3] == c3) {
- return UREG(REG_TYPE_CONST, reg);
- }
- else if (p->constant_flags[reg] == 0) {
- p->constant[reg][0] = c0;
- p->constant[reg][1] = c1;
- p->constant[reg][2] = c2;
- p->constant[reg][3] = c3;
- p->constant_flags[reg] = 0xf;
- if (reg + 1 > p->nr_constants)
- p->nr_constants = reg + 1;
- return UREG(REG_TYPE_CONST, reg);
- }
- }
-
- fprintf(stderr, "%s: out of constants\n", __FUNCTION__);
- p->error = 1;
- return 0;
+ return GL_TRUE;
}
-
-GLuint
-i915_emit_const4fv(struct i915_fragment_program * p, const GLfloat * c)
+static void brwProgramStringNotify( GLcontext *ctx,
+ GLenum target,
+ struct gl_program *prog )
{
- return i915_emit_const4f(p, c[0], c[1], c[2], c[3]);
-}
-
-
-GLuint
-i915_emit_param4fv(struct i915_fragment_program * p, const GLfloat * values)
-{
- GLint reg, i;
-
- for (i = 0; i < p->nr_params; i++) {
- if (p->param[i].values == values)
- return UREG(REG_TYPE_CONST, p->param[i].reg);
- }
-
-
- for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
- if (p->constant_flags[reg] == 0) {
- p->constant_flags[reg] = I915_CONSTFLAG_PARAM;
- i = p->nr_params++;
-
- p->param[i].values = values;
- p->param[i].reg = reg;
- p->params_uptodate = 0;
-
- if (reg + 1 > p->nr_constants)
- p->nr_constants = reg + 1;
- return UREG(REG_TYPE_CONST, reg);
- }
+ if (target == GL_FRAGMENT_PROGRAM_ARB) {
+ struct brw_context *brw = brw_context(ctx);
+ struct brw_fragment_program *p = (struct brw_fragment_program *)prog;
+ struct brw_fragment_program *fp = (struct brw_fragment_program *)brw->fragment_program;
+ if (p == fp)
+ brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM;
+ p->id = brw->program_id++;
+ p->param_state = brw_parameter_list_state_flags(p->program.Base.Parameters);
+ }
+ else if (target == GL_VERTEX_PROGRAM_ARB) {
+ struct brw_context *brw = brw_context(ctx);
+ struct brw_vertex_program *p = (struct brw_vertex_program *)prog;
+ struct brw_vertex_program *vp = (struct brw_vertex_program *)brw->vertex_program;
+ if (p == vp)
+ brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM;
+ p->id = brw->program_id++;
+ p->param_state = brw_parameter_list_state_flags(p->program.Base.Parameters);
+
+ /* Also tell tnl about it:
+ */
+ _tnl_program_string(ctx, target, prog);
}
-
- fprintf(stderr, "%s: out of constants\n", __FUNCTION__);
- p->error = 1;
- return 0;
-}
-
-
-
-void
-i915_program_error(struct i915_fragment_program *p, const char *msg)
-{
- _mesa_problem(NULL, "i915_program_error: %s", msg);
- p->error = 1;
-}
-
-
-void
-i915_init_program(struct i915_context *i915, struct i915_fragment_program *p)
-{
- GLcontext *ctx = &i915->intel.ctx;
- TNLcontext *tnl = TNL_CONTEXT(ctx);
-
- p->translated = 0;
- p->params_uptodate = 0;
- p->on_hardware = 0;
- p->error = 0;
-
- p->nr_tex_indirect = 1; /* correct? */
- p->nr_tex_insn = 0;
- p->nr_alu_insn = 0;
- p->nr_decl_insn = 0;
-
- p->ctx = ctx;
- memset(p->constant_flags, 0, sizeof(p->constant_flags));
-
- p->nr_constants = 0;
- p->csr = p->program;
- p->decl = p->declarations;
- p->decl_s = 0;
- p->decl_t = 0;
- p->temp_flag = 0xffff000;
- p->utemp_flag = ~0x7;
- p->wpos_tex = -1;
- p->depth_written = 0;
- p->nr_params = 0;
-
- p->src_texture = UREG_BAD;
- p->src_previous = UREG(REG_TYPE_T, T_DIFFUSE);
- p->last_tex_stage = 0;
- p->VB = &tnl->vb;
-
- *(p->decl++) = _3DSTATE_PIXEL_SHADER_PROGRAM;
}
-
-void
-i915_fini_program(struct i915_fragment_program *p)
+void brwInitFragProgFuncs( struct dd_function_table *functions )
{
- GLuint program_size = p->csr - p->program;
- GLuint decl_size = p->decl - p->declarations;
-
- if (p->nr_tex_indirect > I915_MAX_TEX_INDIRECT)
- i915_program_error(p, "Exceeded max nr indirect texture lookups");
-
- if (p->nr_tex_insn > I915_MAX_TEX_INSN)
- i915_program_error(p, "Exceeded max TEX instructions");
-
- if (p->nr_alu_insn > I915_MAX_ALU_INSN)
- i915_program_error(p, "Exceeded max ALU instructions");
-
- if (p->nr_decl_insn > I915_MAX_DECL_INSN)
- i915_program_error(p, "Exceeded max DECL instructions");
-
- if (p->error) {
- p->FragProg.Base.NumNativeInstructions = 0;
- p->FragProg.NumNativeAluInstructions = 0;
- p->FragProg.NumNativeTexInstructions = 0;
- p->FragProg.NumNativeTexIndirections = 0;
- }
- else {
- p->FragProg.Base.NumNativeInstructions = (p->nr_alu_insn +
- p->nr_tex_insn +
- p->nr_decl_insn);
- p->FragProg.NumNativeAluInstructions = p->nr_alu_insn;
- p->FragProg.NumNativeTexInstructions = p->nr_tex_insn;
- p->FragProg.NumNativeTexIndirections = p->nr_tex_indirect;
- }
+ assert(functions->ProgramStringNotify == _tnl_program_string);
- p->declarations[0] |= program_size + decl_size - 2;
+ functions->BindProgram = brwBindProgram;
+ functions->NewProgram = brwNewProgram;
+ functions->DeleteProgram = brwDeleteProgram;
+ functions->IsProgramNative = brwIsProgramNative;
+ functions->ProgramStringNotify = brwProgramStringNotify;
}
-void
-i915_upload_program(struct i915_context *i915,
- struct i915_fragment_program *p)
-{
- GLuint program_size = p->csr - p->program;
- GLuint decl_size = p->decl - p->declarations;
-
- FALLBACK(&i915->intel, I915_FALLBACK_PROGRAM, p->error);
-
- /* Could just go straight to the batchbuffer from here:
- */
- if (i915->state.ProgramSize != (program_size + decl_size) ||
- memcmp(i915->state.Program + decl_size, p->program,
- program_size * sizeof(int)) != 0) {
- I915_STATECHANGE(i915, I915_UPLOAD_PROGRAM);
- memcpy(i915->state.Program, p->declarations, decl_size * sizeof(int));
- memcpy(i915->state.Program + decl_size, p->program,
- program_size * sizeof(int));
- i915->state.ProgramSize = decl_size + program_size;
- }
-
- /* Always seemed to get a failure if I used memcmp() to
- * shortcircuit this state upload. Needs further investigation?
- */
- if (p->nr_constants) {
- GLuint nr = p->nr_constants;
-
- I915_ACTIVESTATE(i915, I915_UPLOAD_CONSTANTS, 1);
- I915_STATECHANGE(i915, I915_UPLOAD_CONSTANTS);
-
- i915->state.Constant[0] = _3DSTATE_PIXEL_SHADER_CONSTANTS | ((nr) * 4);
- i915->state.Constant[1] = (1 << (nr - 1)) | ((1 << (nr - 1)) - 1);
-
- memcpy(&i915->state.Constant[2], p->constant, 4 * sizeof(int) * (nr));
- i915->state.ConstantSize = 2 + (nr) * 4;
-
- if (0) {
- GLuint i;
- for (i = 0; i < nr; i++) {
- fprintf(stderr, "const[%d]: %f %f %f %f\n", i,
- p->constant[i][0],
- p->constant[i][1], p->constant[i][2], p->constant[i][3]);
- }
- }
- }
- else {
- I915_ACTIVESTATE(i915, I915_UPLOAD_CONSTANTS, 0);
- }
-
- p->on_hardware = 1;
-}
diff --git a/src/mesa/drivers/dri/i915tex/i915_state.c b/src/mesa/drivers/dri/i915tex/i915_state.c
index 78ae4bdb5f..93e41245b3 100644
--- a/src/mesa/drivers/dri/i915tex/i915_state.c
+++ b/src/mesa/drivers/dri/i915tex/i915_state.c
@@ -45,965 +45,263 @@
#define FILE_DEBUG_FLAG DEBUG_STATE
-static void
-i915StencilFuncSeparate(GLcontext * ctx, GLenum face, GLenum func, GLint ref,
- GLuint mask)
-{
- struct i915_context *i915 = I915_CONTEXT(ctx);
- int test = intel_translate_compare_func(func);
-
- mask = mask & 0xff;
-
- DBG("%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__,
- _mesa_lookup_enum_by_nr(func), ref, mask);
-
-
- I915_STATECHANGE(i915, I915_UPLOAD_CTX);
- i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK;
- i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK |
- STENCIL_TEST_MASK(mask));
-
- i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_REF_MASK |
- S5_STENCIL_TEST_FUNC_MASK);
- i915->state.Ctx[I915_CTXREG_LIS5] |= ((ref << S5_STENCIL_REF_SHIFT) |
- (test <<
- S5_STENCIL_TEST_FUNC_SHIFT));
-}
-
-static void
-i915StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask)
-{
- struct i915_context *i915 = I915_CONTEXT(ctx);
-
- DBG("%s : mask 0x%x\n", __FUNCTION__, mask);
-
- mask = mask & 0xff;
-
- I915_STATECHANGE(i915, I915_UPLOAD_CTX);
- i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK;
- i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK |
- STENCIL_WRITE_MASK(mask));
-}
-
-
-static void
-i915StencilOpSeparate(GLcontext * ctx, GLenum face, GLenum fail, GLenum zfail,
- GLenum zpass)
-{
- struct i915_context *i915 = I915_CONTEXT(ctx);
- int fop = intel_translate_stencil_op(fail);
- int dfop = intel_translate_stencil_op(zfail);
- int dpop = intel_translate_stencil_op(zpass);
-
-
- DBG("%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__,
- _mesa_lookup_enum_by_nr(fail),
- _mesa_lookup_enum_by_nr(zfail), _mesa_lookup_enum_by_nr(zpass));
-
- I915_STATECHANGE(i915, I915_UPLOAD_CTX);
-
- i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK |
- S5_STENCIL_PASS_Z_FAIL_MASK |
- S5_STENCIL_PASS_Z_PASS_MASK);
-
- i915->state.Ctx[I915_CTXREG_LIS5] |= ((fop << S5_STENCIL_FAIL_SHIFT) |
- (dfop <<
- S5_STENCIL_PASS_Z_FAIL_SHIFT) |
- (dpop <<
- S5_STENCIL_PASS_Z_PASS_SHIFT));
-}
-
-static void
-i915AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref)
-{
- struct i915_context *i915 = I915_CONTEXT(ctx);
- int test = intel_translate_compare_func(func);
- GLubyte refByte;
-
- UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref);
-
- I915_STATECHANGE(i915, I915_UPLOAD_CTX);
- i915->state.Ctx[I915_CTXREG_LIS6] &= ~(S6_ALPHA_TEST_FUNC_MASK |
- S6_ALPHA_REF_MASK);
- i915->state.Ctx[I915_CTXREG_LIS6] |= ((test << S6_ALPHA_TEST_FUNC_SHIFT) |
- (((GLuint) refByte) <<
- S6_ALPHA_REF_SHIFT));
-}
+/*
+ Copyright (C) Intel Corp. 2006. All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+
+ **********************************************************************/
+ /*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+
+
+#include "brw_context.h"
+#include "brw_state.h"
+#include "bufmgr.h"
+#include "intel_batchbuffer.h"
-/* This function makes sure that the proper enables are
- * set for LogicOp, Independant Alpha Blend, and Blending.
- * It needs to be called from numerous places where we
- * could change the LogicOp or Independant Alpha Blend without subsequent
- * calls to glEnable.
+/* This is used to initialize brw->state.atoms[]. We could use this
+ * list directly except for a single atom, brw_constant_buffer, which
+ * has a .dirty value which changes according to the parameters of the
+ * current fragment and vertex programs, and so cannot be a static
+ * value.
*/
-static void
-i915EvalLogicOpBlendState(GLcontext * ctx)
+const struct brw_tracked_state *atoms[] =
{
- struct i915_context *i915 = I915_CONTEXT(ctx);
-
- I915_STATECHANGE(i915, I915_UPLOAD_CTX);
-
- if (RGBA_LOGICOP_ENABLED(ctx)) {
- i915->state.Ctx[I915_CTXREG_LIS5] |= S5_LOGICOP_ENABLE;
- i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE;
- }
- else {
- i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_LOGICOP_ENABLE;
-
- if (ctx->Color.BlendEnabled) {
- i915->state.Ctx[I915_CTXREG_LIS6] |= S6_CBUF_BLEND_ENABLE;
- }
- else {
- i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE;
- }
- }
-}
-
-static void
-i915BlendColor(GLcontext * ctx, const GLfloat color[4])
-{
- struct i915_context *i915 = I915_CONTEXT(ctx);
- GLubyte r, g, b, a;
-
- DBG("%s\n", __FUNCTION__);
-
- 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]);
-
- I915_STATECHANGE(i915, I915_UPLOAD_CTX);
- i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] =
- (a << 24) | (r << 16) | (g << 8) | b;
-}
-
-
-#define DST_BLND_FACT(f) ((f)<<S6_CBUF_DST_BLEND_FACT_SHIFT)
-#define SRC_BLND_FACT(f) ((f)<<S6_CBUF_SRC_BLEND_FACT_SHIFT)
-#define DST_ABLND_FACT(f) ((f)<<IAB_DST_FACTOR_SHIFT)
-#define SRC_ABLND_FACT(f) ((f)<<IAB_SRC_FACTOR_SHIFT)
+ &i915_check_fallback,
+ &i915_invarient_state,
+ /*
+ */
+ &i915_fp_choose_prog_get_inputs,
-static GLuint
-translate_blend_equation(GLenum mode)
-{
- switch (mode) {
- case GL_FUNC_ADD:
- return BLENDFUNC_ADD;
- case GL_MIN:
- return BLENDFUNC_MIN;
- case GL_MAX:
- return BLENDFUNC_MAX;
- case GL_FUNC_SUBTRACT:
- return BLENDFUNC_SUBTRACT;
- case GL_FUNC_REVERSE_SUBTRACT:
- return BLENDFUNC_REVERSE_SUBTRACT;
- default:
- return 0;
- }
-}
+ /* Scan VB:
+ */
+ &i915_fp_input_sizes,
+
+ /* Get compiled version of the fragment program which is mildly
+ * optimized according to input sizes. This will be cached, but
+ * for now recompile on all changes.
+ *
+ * Also calculate vertex layout, immediate (S2,S4) state, vertex
+ * size.
+ */
+ &i915_fp_compile,
-static void
-i915UpdateBlendState(GLcontext * ctx)
-{
- struct i915_context *i915 = I915_CONTEXT(ctx);
- GLuint iab = (i915->state.Ctx[I915_CTXREG_IAB] &
- ~(IAB_SRC_FACTOR_MASK |
- IAB_DST_FACTOR_MASK |
- (BLENDFUNC_MASK << IAB_FUNC_SHIFT) | IAB_ENABLE));
-
- GLuint lis6 = (i915->state.Ctx[I915_CTXREG_LIS6] &
- ~(S6_CBUF_SRC_BLEND_FACT_MASK |
- S6_CBUF_DST_BLEND_FACT_MASK | S6_CBUF_BLEND_FUNC_MASK));
-
- GLuint eqRGB = ctx->Color.BlendEquationRGB;
- GLuint eqA = ctx->Color.BlendEquationA;
- GLuint srcRGB = ctx->Color.BlendSrcRGB;
- GLuint dstRGB = ctx->Color.BlendDstRGB;
- GLuint srcA = ctx->Color.BlendSrcA;
- GLuint dstA = ctx->Color.BlendDstA;
-
- if (eqRGB == GL_MIN || eqRGB == GL_MAX) {
- srcRGB = dstRGB = GL_ONE;
- }
+ /* Emit compiled version of the fragment program.
+ */
+ &i915_upload_fp,
- if (eqA == GL_MIN || eqA == GL_MAX) {
- srcA = dstA = GL_ONE;
- }
+ /* Immediate state. Don't make any effort to combine packets yet.
+ */
+ &i915_upload_S0S1,
+ &i915_upload_S2,
+ &i915_upload_S4,
+ &i915_upload_S5,
+ &i915_upload_S6,
+
+ /* Other state. This will eventually be able to emit itself either
+ * to the batchbuffer directly, or as indirect state. Indirect
+ * state will be subject to caching so that we get something like
+ * constant state objects from the i965 driver.
+ */
+ &i915_upload_maps, /* must do before samplers */
+ &i915_upload_samplers,
- lis6 |= SRC_BLND_FACT(intel_translate_blend_factor(srcRGB));
- lis6 |= DST_BLND_FACT(intel_translate_blend_factor(dstRGB));
- lis6 |= translate_blend_equation(eqRGB) << S6_CBUF_BLEND_FUNC_SHIFT;
+ &i915_upload_MODES4,
+ &i915_upload_BFO,
+ &i915_upload_BLENDCOLOR,
+ &i915_upload_IAB,
- iab |= SRC_ABLND_FACT(intel_translate_blend_factor(srcA));
- iab |= DST_ABLND_FACT(intel_translate_blend_factor(dstA));
- iab |= translate_blend_equation(eqA) << IAB_FUNC_SHIFT;
+ &i915_upload_colorbuffer,
+ &i915_upload_depthbuffer,
- if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB)
- iab |= IAB_ENABLE;
+ /* Note this packet has a dependency on the current primitive:
+ */
+ &i915_upload_polygon_stipple,
- if (iab != i915->state.Ctx[I915_CTXREG_IAB] ||
- lis6 != i915->state.Ctx[I915_CTXREG_LIS6]) {
- I915_STATECHANGE(i915, I915_UPLOAD_CTX);
- i915->state.Ctx[I915_CTXREG_IAB] = iab;
- i915->state.Ctx[I915_CTXREG_LIS6] = lis6;
- }
+ &i915_upload_scissor,
- /* This will catch a logicop blend equation */
- i915EvalLogicOpBlendState(ctx);
-}
+ NULL, /* i915_constant_buffer */
+};
-static void
-i915BlendFuncSeparate(GLcontext * ctx, GLenum srcRGB,
- GLenum dstRGB, GLenum srcA, GLenum dstA)
+void i915_init_state( struct i915_context *i915 )
{
- i915UpdateBlendState(ctx);
-}
+ GLuint i;
+ i915_init_pools(i915);
+ i915_init_caches(i915);
-static void
-i915BlendEquationSeparate(GLcontext * ctx, GLenum eqRGB, GLenum eqA)
-{
- i915UpdateBlendState(ctx);
-}
+ i915->state.atoms = _mesa_malloc(sizeof(atoms));
+ i915->state.nr_atoms = sizeof(atoms)/sizeof(*atoms);
+ _mesa_memcpy(i915->state.atoms, atoms, sizeof(atoms));
+ /* Patch in a pointer to the dynamic state atom:
+ */
+ for (i = 0; i < i915->state.nr_atoms; i++)
+ if (i915->state.atoms[i] == NULL)
+ i915->state.atoms[i] = &i915->curbe.tracked_state;
-static void
-i915DepthFunc(GLcontext * ctx, GLenum func)
-{
- struct i915_context *i915 = I915_CONTEXT(ctx);
- int test = intel_translate_compare_func(func);
-
- DBG("%s\n", __FUNCTION__);
-
- I915_STATECHANGE(i915, I915_UPLOAD_CTX);
- i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_FUNC_MASK;
- i915->state.Ctx[I915_CTXREG_LIS6] |= test << S6_DEPTH_TEST_FUNC_SHIFT;
+ _mesa_memcpy(&i915->curbe.tracked_state,
+ &i915_constant_buffer,
+ sizeof(i915_constant_buffer));
}
-static void
-i915DepthMask(GLcontext * ctx, GLboolean flag)
-{
- struct i915_context *i915 = I915_CONTEXT(ctx);
-
- DBG("%s flag (%d)\n", __FUNCTION__, flag);
-
- I915_STATECHANGE(i915, I915_UPLOAD_CTX);
- if (flag && ctx->Depth.Test)
- i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_WRITE_ENABLE;
- else
- i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_WRITE_ENABLE;
-}
-
-/* =============================================================
- * Polygon stipple
- *
- * The i915 supports a 4x4 stipple natively, GL wants 32x32.
- * Fortunately stipple is usually a repeating pattern.
- */
-static void
-i915PolygonStipple(GLcontext * ctx, const GLubyte * mask)
+void i915_destroy_state( struct i915_context *i915 )
{
- struct i915_context *i915 = I915_CONTEXT(ctx);
- const GLubyte *m = mask;
- GLubyte p[4];
- int i, j, k;
- int active = (ctx->Polygon.StippleFlag &&
- i915->intel.reduced_primitive == GL_TRIANGLES);
- GLuint newMask;
-
- if (active) {
- I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE);
- i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE;
+ if (i915->state.atoms) {
+ _mesa_free(i915->state.atoms);
+ i915->state.atoms = NULL;
}
- p[0] = mask[12] & 0xf;
- p[0] |= p[0] << 4;
- p[1] = mask[8] & 0xf;
- p[1] |= p[1] << 4;
- p[2] = mask[4] & 0xf;
- p[2] |= p[2] << 4;
- p[3] = mask[0] & 0xf;
- p[3] |= p[3] << 4;
-
- for (k = 0; k < 8; k++)
- for (j = 3; j >= 0; j--)
- for (i = 0; i < 4; i++, m++)
- if (*m != p[j]) {
- i915->intel.hw_stipple = 0;
- return;
- }
-
- newMask = (((p[0] & 0xf) << 0) |
- ((p[1] & 0xf) << 4) |
- ((p[2] & 0xf) << 8) | ((p[3] & 0xf) << 12));
-
-
- if (newMask == 0xffff || newMask == 0x0) {
- /* this is needed to make conform pass */
- i915->intel.hw_stipple = 0;
- return;
- }
-
- i915->state.Stipple[I915_STPREG_ST1] &= ~0xffff;
- i915->state.Stipple[I915_STPREG_ST1] |= newMask;
- i915->intel.hw_stipple = 1;
-
- if (active)
- i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE;
+ i915_destroy_caches(i915);
+ i915_destroy_batch_cache(i915);
+ i915_destroy_pools(i915);
}
-
-/* =============================================================
- * Hardware clipping
+/***********************************************************************
*/
-static void
-i915Scissor(GLcontext * ctx, GLint x, GLint y, GLsizei w, GLsizei h)
-{
- struct i915_context *i915 = I915_CONTEXT(ctx);
- int x1, y1, x2, y2;
-
- if (!ctx->DrawBuffer)
- return;
-
- DBG("%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h);
-
- if (ctx->DrawBuffer->Name == 0) {
- x1 = x;
- y1 = ctx->DrawBuffer->Height - (y + h);
- x2 = x + w - 1;
- y2 = y1 + h - 1;
- DBG("%s %d..%d,%d..%d (inverted)\n", __FUNCTION__, x1, x2, y1, y2);
- }
- else {
- /* FBO - not inverted
- */
- x1 = x;
- y1 = y;
- x2 = x + w - 1;
- y2 = y + h - 1;
- DBG("%s %d..%d,%d..%d (not inverted)\n", __FUNCTION__, x1, x2, y1, y2);
- }
-
- x1 = CLAMP(x1, 0, ctx->DrawBuffer->Width - 1);
- y1 = CLAMP(y1, 0, ctx->DrawBuffer->Height - 1);
- x2 = CLAMP(x2, 0, ctx->DrawBuffer->Width - 1);
- y2 = CLAMP(y2, 0, ctx->DrawBuffer->Height - 1);
-
- DBG("%s %d..%d,%d..%d (clamped)\n", __FUNCTION__, x1, x2, y1, y2);
-
- I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS);
- i915->state.Buffer[I915_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff);
- i915->state.Buffer[I915_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff);
-}
-static void
-i915LogicOp(GLcontext * ctx, GLenum opcode)
+static GLboolean check_state( const struct i915_state_flags *a,
+ const struct i915_state_flags *b )
{
- struct i915_context *i915 = I915_CONTEXT(ctx);
- int tmp = intel_translate_logic_op(opcode);
-
- DBG("%s\n", __FUNCTION__);
-
- I915_STATECHANGE(i915, I915_UPLOAD_CTX);
- i915->state.Ctx[I915_CTXREG_STATE4] &= ~LOGICOP_MASK;
- i915->state.Ctx[I915_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp);
+ return ((a->mesa & b->mesa) ||
+ (a->i915 & b->i915) ||
+ (a->cache & b->cache));
}
-
-
-static void
-i915CullFaceFrontFace(GLcontext * ctx, GLenum unused)
+static void accumulate_state( struct i915_state_flags *a,
+ const struct i915_state_flags *b )
{
- struct i915_context *i915 = I915_CONTEXT(ctx);
- GLuint mode;
-
- DBG("%s %d\n", __FUNCTION__,
- ctx->DrawBuffer ? ctx->DrawBuffer->Name : 0);
-
- if (!ctx->Polygon.CullFlag) {
- mode = S4_CULLMODE_NONE;
- }
- else if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) {
- mode = S4_CULLMODE_CW;
-
- if (ctx->DrawBuffer && ctx->DrawBuffer->Name != 0)
- mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW);
- if (ctx->Polygon.CullFaceMode == GL_FRONT)
- mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW);
- if (ctx->Polygon.FrontFace != GL_CCW)
- mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW);
- }
- else {
- mode = S4_CULLMODE_BOTH;
- }
-
- I915_STATECHANGE(i915, I915_UPLOAD_CTX);
- i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_CULLMODE_MASK;
- i915->state.Ctx[I915_CTXREG_LIS4] |= mode;
+ a->mesa |= b->mesa;
+ a->i915 |= b->i915;
+ a->cache |= b->cache;
}
-static void
-i915LineWidth(GLcontext * ctx, GLfloat widthf)
-{
- struct i915_context *i915 = I915_CONTEXT(ctx);
- int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_LINE_WIDTH_MASK;
- int width;
-
- DBG("%s\n", __FUNCTION__);
-
- width = (int) (widthf * 2);
- CLAMP_SELF(width, 1, 0xf);
- lis4 |= width << S4_LINE_WIDTH_SHIFT;
-
- if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) {
- I915_STATECHANGE(i915, I915_UPLOAD_CTX);
- i915->state.Ctx[I915_CTXREG_LIS4] = lis4;
- }
-}
-static void
-i915PointSize(GLcontext * ctx, GLfloat size)
+static void xor_states( struct i915_state_flags *result,
+ const struct i915_state_flags *a,
+ const struct i915_state_flags *b )
{
- struct i915_context *i915 = I915_CONTEXT(ctx);
- int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_POINT_WIDTH_MASK;
- GLint point_size = (int) size;
-
- DBG("%s\n", __FUNCTION__);
-
- CLAMP_SELF(point_size, 1, 255);
- lis4 |= point_size << S4_POINT_WIDTH_SHIFT;
-
- if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) {
- I915_STATECHANGE(i915, I915_UPLOAD_CTX);
- i915->state.Ctx[I915_CTXREG_LIS4] = lis4;
- }
+ result->mesa = a->mesa ^ b->mesa;
+ result->i915 = a->i915 ^ b->i915;
+ result->cache = a->cache ^ b->cache;
}
-/* =============================================================
- * Color masks
+/***********************************************************************
+ * Emit all state:
*/
-
-static void
-i915ColorMask(GLcontext * ctx,
- GLboolean r, GLboolean g, GLboolean b, GLboolean a)
-{
- struct i915_context *i915 = I915_CONTEXT(ctx);
- GLuint tmp = i915->state.Ctx[I915_CTXREG_LIS5] & ~S5_WRITEDISABLE_MASK;
-
- DBG("%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, r, g, b,
- a);
-
- if (!r)
- tmp |= S5_WRITEDISABLE_RED;
- if (!g)
- tmp |= S5_WRITEDISABLE_GREEN;
- if (!b)
- tmp |= S5_WRITEDISABLE_BLUE;
- if (!a)
- tmp |= S5_WRITEDISABLE_ALPHA;
-
- if (tmp != i915->state.Ctx[I915_CTXREG_LIS5]) {
- I915_STATECHANGE(i915, I915_UPLOAD_CTX);
- i915->state.Ctx[I915_CTXREG_LIS5] = tmp;
- }
-}
-
-static void
-update_specular(GLcontext * ctx)
-{
- /* A hack to trigger the rebuild of the fragment program.
- */
- intel_context(ctx)->NewGLState |= _NEW_TEXTURE;
-}
-
-static void
-i915LightModelfv(GLcontext * ctx, GLenum pname, const GLfloat * param)
+void i915_validate_state( struct i915_context *i915 )
{
- DBG("%s\n", __FUNCTION__);
-
- if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) {
- update_specular(ctx);
- }
-}
-
-static void
-i915ShadeModel(GLcontext * ctx, GLenum mode)
-{
- struct i915_context *i915 = I915_CONTEXT(ctx);
- I915_STATECHANGE(i915, I915_UPLOAD_CTX);
-
- if (mode == GL_SMOOTH) {
- i915->state.Ctx[I915_CTXREG_LIS4] &= ~(S4_FLATSHADE_ALPHA |
- S4_FLATSHADE_COLOR |
- S4_FLATSHADE_SPECULAR);
- }
- else {
- i915->state.Ctx[I915_CTXREG_LIS4] |= (S4_FLATSHADE_ALPHA |
- S4_FLATSHADE_COLOR |
- S4_FLATSHADE_SPECULAR);
- }
-}
-
-/* =============================================================
- * Fog
- */
-void
-i915_update_fog(GLcontext * ctx)
-{
- struct i915_context *i915 = I915_CONTEXT(ctx);
- GLenum mode;
- GLboolean enabled;
- GLboolean try_pixel_fog;
-
- if (ctx->FragmentProgram._Active) {
- /* Pull in static fog state from program */
+ struct i915_state_flags *state = &i915->state.dirty;
+ GLuint i;
- mode = ctx->FragmentProgram._Current->FogOption;
- enabled = (mode != GL_NONE);
- try_pixel_fog = 0;
- }
- else {
- enabled = ctx->Fog.Enabled;
- mode = ctx->Fog.Mode;
-
- try_pixel_fog = (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT && ctx->Hint.Fog == GL_NICEST && 0); /* XXX - DISABLE -- Need ortho fallback */
- }
-
- if (!enabled) {
- i915->vertex_fog = I915_FOG_NONE;
- }
- else if (try_pixel_fog) {
-
- I915_STATECHANGE(i915, I915_UPLOAD_FOG);
- i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_FOGFUNC_MASK;
- i915->vertex_fog = I915_FOG_PIXEL;
-
- switch (mode) {
- case GL_LINEAR:
- if (ctx->Fog.End <= ctx->Fog.Start) {
- /* XXX - this won't work with fragment programs. Need to
- * either fallback or append fog instructions to end of
- * program in the case of linear fog.
- */
- i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_VERTEX;
- i915->vertex_fog = I915_FOG_VERTEX;
- }
- else {
- GLfloat c1 = ctx->Fog.End / (ctx->Fog.End - ctx->Fog.Start);
- GLfloat c2 = 1.0 / (ctx->Fog.End - ctx->Fog.Start);
-
- i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_C1_MASK;
- i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_LINEAR;
- i915->state.Fog[I915_FOGREG_MODE1] |=
- ((GLuint) (c1 * FMC1_C1_ONE)) & FMC1_C1_MASK;
-
- if (i915->state.Fog[I915_FOGREG_MODE1] & FMC1_FOGINDEX_Z) {
- i915->state.Fog[I915_FOGREG_MODE2] =
- (GLuint) (c2 * FMC2_C2_ONE);
- }
- else {
- union
- {
- float f;
- int i;
- } fi;
- fi.f = c2;
- i915->state.Fog[I915_FOGREG_MODE2] = fi.i;
- }
- }
- break;
- case GL_EXP:
- i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_EXP;
- break;
- case GL_EXP2:
- i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_EXP2;
- break;
- default:
- break;
- }
- }
- else { /* if (i915->vertex_fog != I915_FOG_VERTEX) */
+ state->mesa |= i915->intel.NewGLState;
+ i915->intel.NewGLState = 0;
- I915_STATECHANGE(i915, I915_UPLOAD_FOG);
- i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_FOGFUNC_MASK;
- i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_VERTEX;
- i915->vertex_fog = I915_FOG_VERTEX;
- }
+ if (i915->wrap)
+ state->i915 |= I915_NEW_CONTEXT;
- {
- I915_STATECHANGE(i915, I915_UPLOAD_CTX);
- I915_ACTIVESTATE(i915, I915_UPLOAD_FOG, enabled);
- if (enabled)
- i915->state.Ctx[I915_CTXREG_LIS5] |= S5_FOG_ENABLE;
- else
- i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_FOG_ENABLE;
+ if (i915->emit_state_always) {
+ state->mesa |= ~0;
+ state->i915 |= ~0;
}
- /* always enbale pixel fog
- * vertex fog use precaculted fog coord will conflict with appended
- * fog program
+ /* texenv program needs to notify us somehow when this happens:
+ * Some confusion about which state flag should represent this change.
*/
- _tnl_allow_vertex_fog( ctx, 0 );
- _tnl_allow_pixel_fog( ctx, 1 );
-}
-
-static void
-i915Fogfv(GLcontext * ctx, GLenum pname, const GLfloat * param)
-{
- struct i915_context *i915 = I915_CONTEXT(ctx);
-
- switch (pname) {
- case GL_FOG_COORDINATE_SOURCE_EXT:
- case GL_FOG_MODE:
- case GL_FOG_START:
- case GL_FOG_END:
- break;
-
- case GL_FOG_DENSITY:
- I915_STATECHANGE(i915, I915_UPLOAD_FOG);
-
- if (i915->state.Fog[I915_FOGREG_MODE1] & FMC1_FOGINDEX_Z) {
- i915->state.Fog[I915_FOGREG_MODE3] = (GLuint) (ctx->Fog.Density *
- FMC3_D_ONE);
- }
- else {
- union
- {
- float f;
- int i;
- } fi;
- fi.f = ctx->Fog.Density;
- i915->state.Fog[I915_FOGREG_MODE3] = fi.i;
- }
- break;
-
- case GL_FOG_COLOR:
- I915_STATECHANGE(i915, I915_UPLOAD_FOG);
- i915->state.Fog[I915_FOGREG_COLOR] =
- (_3DSTATE_FOG_COLOR_CMD |
- ((GLubyte) (ctx->Fog.Color[0] * 255.0F) << 16) |
- ((GLubyte) (ctx->Fog.Color[1] * 255.0F) << 8) |
- ((GLubyte) (ctx->Fog.Color[2] * 255.0F) << 0));
- break;
-
- default:
- break;
+ if (i915->fragment_program != i915->attribs.FragmentProgram->_Current) {
+ i915->fragment_program = i915->attribs.FragmentProgram->_Current;
+ i915->state.dirty.mesa |= _NEW_PROGRAM;
+ i915->state.dirty.i915 |= I915_NEW_FRAGMENT_PROGRAM;
}
-}
-static void
-i915Hint(GLcontext * ctx, GLenum target, GLenum state)
-{
- switch (target) {
- case GL_FOG_HINT:
- break;
- default:
- break;
- }
-}
-
-/* =============================================================
- */
-static void
-i915Enable(GLcontext * ctx, GLenum cap, GLboolean state)
-{
- struct i915_context *i915 = I915_CONTEXT(ctx);
-
- switch (cap) {
- case GL_TEXTURE_2D:
- break;
-
- case GL_LIGHTING:
- case GL_COLOR_SUM:
- update_specular(ctx);
- break;
-
- case GL_ALPHA_TEST:
- I915_STATECHANGE(i915, I915_UPLOAD_CTX);
- if (state)
- i915->state.Ctx[I915_CTXREG_LIS6] |= S6_ALPHA_TEST_ENABLE;
- else
- i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_ALPHA_TEST_ENABLE;
- break;
+ if (state->mesa == 0 &&
+ state->cache == 0 &&
+ state->i915 == 0)
+ return;
- case GL_BLEND:
- i915EvalLogicOpBlendState(ctx);
- break;
+ if (i915->state.dirty.i915 & I915_NEW_CONTEXT)
+ i915_clear_batch_cache_flush(i915);
- case GL_COLOR_LOGIC_OP:
- i915EvalLogicOpBlendState(ctx);
- /* Logicop doesn't seem to work at 16bpp:
- */
- if (i915->intel.intelScreen->cpp == 2) /* XXX FBO fix */
- FALLBACK(&i915->intel, I915_FALLBACK_LOGICOP, state);
- break;
-
- case GL_FRAGMENT_PROGRAM_ARB:
- break;
-
- case GL_DITHER:
- I915_STATECHANGE(i915, I915_UPLOAD_CTX);
- if (state)
- i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE;
- else
- i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_COLOR_DITHER_ENABLE;
- break;
-
- case GL_DEPTH_TEST:
- I915_STATECHANGE(i915, I915_UPLOAD_CTX);
- if (state)
- i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_TEST_ENABLE;
- else
- i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_ENABLE;
-
- i915DepthMask(ctx, ctx->Depth.Mask);
- break;
-
- case GL_SCISSOR_TEST:
- I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS);
- if (state)
- i915->state.Buffer[I915_DESTREG_SENABLE] =
- (_3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT);
- else
- i915->state.Buffer[I915_DESTREG_SENABLE] =
- (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT);
- break;
-
- case GL_LINE_SMOOTH:
- I915_STATECHANGE(i915, I915_UPLOAD_CTX);
- if (state)
- i915->state.Ctx[I915_CTXREG_LIS4] |= S4_LINE_ANTIALIAS_ENABLE;
- else
- i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_LINE_ANTIALIAS_ENABLE;
- break;
-
- case GL_FOG:
- break;
-
- case GL_CULL_FACE:
- i915CullFaceFrontFace(ctx, 0);
- break;
-
- case GL_STENCIL_TEST:
- {
- GLboolean hw_stencil = GL_FALSE;
- if (ctx->DrawBuffer) {
- struct intel_renderbuffer *irbStencil
- = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL);
- hw_stencil = (irbStencil && irbStencil->region);
- }
- if (hw_stencil) {
- I915_STATECHANGE(i915, I915_UPLOAD_CTX);
- if (state)
- i915->state.Ctx[I915_CTXREG_LIS5] |= (S5_STENCIL_TEST_ENABLE |
- S5_STENCIL_WRITE_ENABLE);
- else
- i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_TEST_ENABLE |
- S5_STENCIL_WRITE_ENABLE);
- }
- else {
- FALLBACK(&i915->intel, I915_FALLBACK_STENCIL, state);
- }
- }
- break;
- case GL_POLYGON_STIPPLE:
- /* The stipple command worked on my 855GM box, but not my 845G.
- * I'll do more testing later to find out exactly which hardware
- * supports it. Disabled for now.
+ if (INTEL_DEBUG) {
+ /* Debug version which enforces various sanity checks on the
+ * state flags which are generated and checked to help ensure
+ * state atoms are ordered correctly in the list.
*/
- if (i915->intel.hw_stipple &&
- i915->intel.reduced_primitive == GL_TRIANGLES) {
- I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE);
- if (state)
- i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE;
- else
- i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE;
+ struct i915_state_flags examined, prev;
+ _mesa_memset(&examined, 0, sizeof(examined));
+ prev = *state;
+
+ for (i = 0; i < i915->state.nr_atoms; i++) {
+ const struct i915_tracked_state *atom = i915->state.atoms[i];
+ struct i915_state_flags generated;
+
+ assert(atom->dirty.mesa ||
+ atom->dirty.i915 ||
+ atom->dirty.cache);
+ assert(atom->update);
+
+ if (check_state(state, &atom->dirty)) {
+ i915->state.atoms[i]->update( i915 );
+
+/* emit_foo(i915); */
+ }
+
+ accumulate_state(&examined, &atom->dirty);
+
+ /* generated = (prev ^ state)
+ * if (examined & generated)
+ * fail;
+ */
+ xor_states(&generated, &prev, state);
+ assert(!check_state(&examined, &generated));
+ prev = *state;
}
- break;
-
- case GL_POLYGON_SMOOTH:
- break;
-
- case GL_POINT_SMOOTH:
- break;
-
- default:
- ;
}
-}
-
-
-static void
-i915_init_packets(struct i915_context *i915)
-{
- intelScreenPrivate *screen = i915->intel.intelScreen;
-
- /* Zero all state */
- memset(&i915->state, 0, sizeof(i915->state));
-
-
- {
- I915_STATECHANGE(i915, I915_UPLOAD_CTX);
- /* Probably don't want to upload all this stuff every time one
- * piece changes.
- */
- i915->state.Ctx[I915_CTXREG_LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
- I1_LOAD_S(2) |
- I1_LOAD_S(4) |
- I1_LOAD_S(5) | I1_LOAD_S(6) | (4));
- i915->state.Ctx[I915_CTXREG_LIS2] = 0;
- i915->state.Ctx[I915_CTXREG_LIS4] = 0;
- i915->state.Ctx[I915_CTXREG_LIS5] = 0;
-
- if (screen->cpp == 2) /* XXX FBO fix */
- i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE;
-
-
- i915->state.Ctx[I915_CTXREG_LIS6] = (S6_COLOR_WRITE_ENABLE |
- (2 << S6_TRISTRIP_PV_SHIFT));
-
- i915->state.Ctx[I915_CTXREG_STATE4] = (_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));
-
- i915->state.Ctx[I915_CTXREG_IAB] =
- (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | IAB_MODIFY_ENABLE |
- IAB_MODIFY_FUNC | IAB_MODIFY_SRC_FACTOR | IAB_MODIFY_DST_FACTOR);
-
- i915->state.Ctx[I915_CTXREG_BLENDCOLOR0] =
- _3DSTATE_CONST_BLEND_COLOR_CMD;
- i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = 0;
-
- }
-
- {
- I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE);
- i915->state.Stipple[I915_STPREG_ST0] = _3DSTATE_STIPPLE;
- }
-
-
- {
- I915_STATECHANGE(i915, I915_UPLOAD_FOG);
- i915->state.Fog[I915_FOGREG_MODE0] = _3DSTATE_FOG_MODE_CMD;
- i915->state.Fog[I915_FOGREG_MODE1] = (FMC1_FOGFUNC_MODIFY_ENABLE |
- FMC1_FOGFUNC_VERTEX |
- FMC1_FOGINDEX_MODIFY_ENABLE |
- FMC1_FOGINDEX_W |
- FMC1_C1_C2_MODIFY_ENABLE |
- FMC1_DENSITY_MODIFY_ENABLE);
- i915->state.Fog[I915_FOGREG_COLOR] = _3DSTATE_FOG_COLOR_CMD;
- }
-
-
- {
- I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS);
- /* color buffer offset/stride */
- i915->state.Buffer[I915_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD;
- /* XXX FBO: remove this? Also get set in i915_set_draw_region() */
- i915->state.Buffer[I915_DESTREG_CBUFADDR1] = (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(screen->front.pitch) | /* pitch in bytes */
- BUF_3D_USE_FENCE);
-
- i915->state.Buffer[I915_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD;
- /* XXX FBO: remove this? Also get set in i915_set_draw_region() */
- i915->state.Buffer[I915_DESTREG_DBUFADDR1] = (BUF_3D_ID_DEPTH | BUF_3D_PITCH(screen->depth.pitch) | /* pitch in bytes */
- BUF_3D_USE_FENCE);
-
- i915->state.Buffer[I915_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD;
-
- /* XXX FBO: remove this? Also get set in i915_set_draw_region() */
-#if 0 /* seems we don't need this */
- switch (screen->fbFormat) {
- case DV_PF_565:
- i915->state.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
- DSTORG_VERT_BIAS(0x8) | /* .5 */
- LOD_PRECLAMP_OGL |
- TEX_DEFAULT_COLOR_OGL |
- DITHER_FULL_ALWAYS |
- screen->fbFormat |
- DEPTH_FRMT_16_FIXED);
- break;
- case DV_PF_8888:
- i915->state.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
- DSTORG_VERT_BIAS(0x8) | /* .5 */
- LOD_PRECLAMP_OGL |
- TEX_DEFAULT_COLOR_OGL |
- screen->fbFormat |
- DEPTH_FRMT_24_FIXED_8_OTHER);
- break;
+ else {
+ for (i = 0; i < Elements(atoms); i++) {
+ if (check_state(state, &i915->state.atoms[i]->dirty))
+ i915->state.atoms[i]->update( i915 );
}
-#endif
-
-
- /* scissor */
- i915->state.Buffer[I915_DESTREG_SENABLE] =
- (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT);
- i915->state.Buffer[I915_DESTREG_SR0] = _3DSTATE_SCISSOR_RECT_0_CMD;
- i915->state.Buffer[I915_DESTREG_SR1] = 0;
- i915->state.Buffer[I915_DESTREG_SR2] = 0;
- }
-
-
-#if 0
- {
- I915_STATECHANGE(i915, I915_UPLOAD_DEFAULTS);
- i915->state.Default[I915_DEFREG_C0] = _3DSTATE_DEFAULT_DIFFUSE;
- i915->state.Default[I915_DEFREG_C1] = 0;
- i915->state.Default[I915_DEFREG_S0] = _3DSTATE_DEFAULT_SPECULAR;
- i915->state.Default[I915_DEFREG_S1] = 0;
- i915->state.Default[I915_DEFREG_Z0] = _3DSTATE_DEFAULT_Z;
- i915->state.Default[I915_DEFREG_Z1] = 0;
}
-#endif
-
- /* These will be emitted every at the head of every buffer, unless
- * we get hardware contexts working.
- */
- i915->state.active = (I915_UPLOAD_PROGRAM |
- I915_UPLOAD_STIPPLE |
- I915_UPLOAD_CTX |
- I915_UPLOAD_BUFFERS | I915_UPLOAD_INVARIENT);
+ memset(state, 0, sizeof(*state));
}
-void
-i915InitStateFunctions(struct dd_function_table *functions)
-{
- functions->AlphaFunc = i915AlphaFunc;
- functions->BlendColor = i915BlendColor;
- functions->BlendEquationSeparate = i915BlendEquationSeparate;
- functions->BlendFuncSeparate = i915BlendFuncSeparate;
- functions->ColorMask = i915ColorMask;
- functions->CullFace = i915CullFaceFrontFace;
- functions->DepthFunc = i915DepthFunc;
- functions->DepthMask = i915DepthMask;
- functions->Enable = i915Enable;
- functions->Fogfv = i915Fogfv;
- functions->FrontFace = i915CullFaceFrontFace;
- functions->Hint = i915Hint;
- functions->LightModelfv = i915LightModelfv;
- functions->LineWidth = i915LineWidth;
- functions->LogicOpcode = i915LogicOp;
- functions->PointSize = i915PointSize;
- functions->PolygonStipple = i915PolygonStipple;
- functions->Scissor = i915Scissor;
- functions->ShadeModel = i915ShadeModel;
- functions->StencilFuncSeparate = i915StencilFuncSeparate;
- functions->StencilMaskSeparate = i915StencilMaskSeparate;
- functions->StencilOpSeparate = i915StencilOpSeparate;
-}
+/*
+ */
void
diff --git a/src/mesa/drivers/dri/i915tex/i915_state.h b/src/mesa/drivers/dri/i915tex/i915_state.h
new file mode 100644
index 0000000000..80e692f915
--- /dev/null
+++ b/src/mesa/drivers/dri/i915tex/i915_state.h
@@ -0,0 +1,25 @@
+#define DST_BLND_FACT(f) ((f)<<S6_CBUF_DST_BLEND_FACT_SHIFT)
+#define SRC_BLND_FACT(f) ((f)<<S6_CBUF_SRC_BLEND_FACT_SHIFT)
+#define DST_ABLND_FACT(f) ((f)<<IAB_DST_FACTOR_SHIFT)
+#define SRC_ABLND_FACT(f) ((f)<<IAB_SRC_FACTOR_SHIFT)
+
+
+
+static GLuint
+translate_blend_equation(GLenum mode)
+{
+ switch (mode) {
+ case GL_FUNC_ADD:
+ return BLENDFUNC_ADD;
+ case GL_MIN:
+ return BLENDFUNC_MIN;
+ case GL_MAX:
+ return BLENDFUNC_MAX;
+ case GL_FUNC_SUBTRACT:
+ return BLENDFUNC_SUBTRACT;
+ case GL_FUNC_REVERSE_SUBTRACT:
+ return BLENDFUNC_REVERSE_SUBTRACT;
+ default:
+ return 0;
+ }
+}
diff --git a/src/mesa/drivers/dri/i915tex/i915_state_constants.c b/src/mesa/drivers/dri/i915tex/i915_state_constants.c
new file mode 100644
index 0000000000..8faac6b891
--- /dev/null
+++ b/src/mesa/drivers/dri/i915tex/i915_state_constants.c
@@ -0,0 +1,136 @@
+/**************************************************************************
+ *
+ * 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 "macros.h"
+#include "enums.h"
+
+#include "tnl/tnl.h"
+#include "tnl/t_context.h"
+#include "intel_batchbuffer.h"
+
+#include "i915_reg.h"
+#include "i915_context.h"
+#include "i915_program.h"
+
+#include "program_instruction.h"
+#include "program.h"
+#include "programopt.h"
+
+
+
+static void
+upload_params(struct i915_fragment_program *p)
+{
+ GLint i;
+
+
+ /* Always seemed to get a failure if I used memcmp() to
+ * shortcircuit this state upload. Needs further investigation?
+ */
+ if (p->nr_constants) {
+ GLuint nr = p->nr_constants;
+
+ I915_ACTIVESTATE(i915, I915_UPLOAD_CONSTANTS, 1);
+ I915_STATECHANGE(i915, I915_UPLOAD_CONSTANTS);
+
+ i915->state.Constant[0] = _3DSTATE_PIXEL_SHADER_CONSTANTS | ((nr) * 4);
+ i915->state.Constant[1] = (1 << (nr - 1)) | ((1 << (nr - 1)) - 1);
+
+ memcpy(&i915->state.Constant[2], p->constant, 4 * sizeof(int) * (nr));
+ i915->state.ConstantSize = 2 + (nr) * 4;
+
+ if (0) {
+ GLuint i;
+ for (i = 0; i < nr; i++) {
+ fprintf(stderr, "const[%d]: %f %f %f %f\n", i,
+ p->constant[i][0],
+ p->constant[i][1], p->constant[i][2], p->constant[i][3]);
+ }
+ }
+ }
+ else {
+ I915_ACTIVESTATE(i915, I915_UPLOAD_CONSTANTS, 0);
+ }
+
+
+///////////////////////
+ if (p->nr_params)
+ _mesa_load_state_parameters(p->ctx, p->FragProg.Base.Parameters);
+
+ for (i = 0; i < p->nr_params; i++) {
+ GLint reg = p->param[i].reg;
+ COPY_4V(p->constant[reg], p->param[i].values);
+ }
+
+ p->params_uptodate = 1;
+
+
+/////////////////
+
+ /* Allocate state in the indirect buffer and upload constants:
+ */
+
+
+}
+
+
+
+
+
+static void
+track_params(struct i915_fragment_program *p)
+{
+ GLint i;
+
+ if (p->nr_params)
+ _mesa_load_state_parameters(p->ctx, p->FragProg.Base.Parameters);
+
+ for (i = 0; i < p->nr_params; i++) {
+ GLint reg = p->param[i].reg;
+ COPY_4V(p->constant[reg], p->param[i].values);
+ }
+
+ p->params_uptodate = 1;
+}
+
+
+/* This tracked state is unique in that the state it monitors varies
+ * dynamically depending on the parameters tracked by the fragment and
+ * vertex programs. This is the template used as a starting point,
+ * each context will maintain a copy of this internally and update as
+ * required.
+ */
+const struct i915_tracked_state i915_constant_buffer = {
+ .dirty = {
+ .mesa = 0, /* plus fp flags */
+ .intel = (I915_NEW_FRAGMENT_PROGRAM),
+ .cache = (CACHE_NEW_PROGRAM) /* ?? */
+ },
+ .update = upload_params
+};
+
diff --git a/src/mesa/drivers/dri/i915tex/i915_tex.c b/src/mesa/drivers/dri/i915tex/i915_state_fp.c
index 59e148ca04..6711bf2fcc 100644
--- a/src/mesa/drivers/dri/i915tex/i915_tex.c
+++ b/src/mesa/drivers/dri/i915tex/i915_state_fp.c
@@ -26,53 +26,67 @@
**************************************************************************/
#include "glheader.h"
-#include "mtypes.h"
-#include "imports.h"
-#include "simple_list.h"
+#include "macros.h"
#include "enums.h"
-#include "image.h"
-#include "texstore.h"
-#include "texformat.h"
-#include "texmem.h"
-#include "swrast/swrast.h"
-#include "mm.h"
+#include "tnl/tnl.h"
+#include "tnl/t_context.h"
+#include "intel_batchbuffer.h"
-#include "intel_ioctl.h"
-
-#include "i915_context.h"
#include "i915_reg.h"
+#include "i915_context.h"
+#include "i915_program.h"
+#include "program_instruction.h"
+#include "program.h"
+#include "programopt.h"
-static void
-i915TexEnv(GLcontext * ctx, GLenum target,
- GLenum pname, const GLfloat * param)
+
+void
+i915_upload_program()
{
- struct i915_context *i915 = I915_CONTEXT(ctx);
-
- switch (pname) {
- case GL_TEXTURE_LOD_BIAS:{
- GLuint unit = ctx->Texture.CurrentUnit;
- GLint b = (int) ((*param) * 16.0);
- if (b > 255)
- b = 255;
- if (b < -256)
- b = -256;
- I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit));
- i915->lodbias_ss2[unit] =
- ((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK);
- break;
- }
-
- default:
- break;
+ if (dirty & I915_UPLOAD_PROGRAM) {
+ if (INTEL_DEBUG & DEBUG_STATE)
+ fprintf(stderr, "I915_UPLOAD_PROGRAM:\n");
+
+ assert((state->Program[0] & 0x1ff) + 2 == state->ProgramSize);
+
+ emit(intel, state->Program, state->ProgramSize * sizeof(GLuint));
+ if (INTEL_DEBUG & DEBUG_STATE)
+ i915_disassemble_program(state->Program, state->ProgramSize);
}
}
+
+
void
-i915InitTextureFuncs(struct dd_function_table *functions)
+i915ValidateFragmentProgram(struct i915_context *i915)
{
- functions->TexEnv = i915TexEnv;
+ GLcontext *ctx = &i915->intel.ctx;
+ struct intel_context *intel = intel_context(ctx);
+
+ struct i915_fragment_program *p =
+ (struct i915_fragment_program *) ctx->FragmentProgram._Current;
+
+ int i, offset = 0;
+
+ if (i915->current_program != p) {
+
+
+ i915->current_program = p;
+ }
+
+
+ /* Important:
+ */
+ VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
+
+ if (!p->translated)
+ translate_program(p);
+
+
+ i915_upload_program(i915, p);
}
+
diff --git a/src/mesa/drivers/dri/i915tex/i915_state_fp_inputs.c b/src/mesa/drivers/dri/i915tex/i915_state_fp_inputs.c
new file mode 100644
index 0000000000..d7ec11500a
--- /dev/null
+++ b/src/mesa/drivers/dri/i915tex/i915_state_fp_inputs.c
@@ -0,0 +1,150 @@
+
+static void
+check_wpos(struct i915_fragment_program *p)
+{
+ GLuint inputs = p->FragProg.Base.InputsRead;
+ GLint i;
+
+ p->wpos_tex = -1;
+
+ for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) {
+ if (inputs & FRAG_BIT_TEX(i))
+ continue;
+ else if (inputs & FRAG_BIT_WPOS) {
+ p->wpos_tex = i;
+ inputs &= ~FRAG_BIT_WPOS;
+ }
+ }
+
+ if (inputs & FRAG_BIT_WPOS) {
+ i915_program_error(p, "No free texcoord for wpos value");
+ }
+}
+
+
+static void brw_merge_inputs( struct brw_context *brw,
+ const struct gl_client_array *arrays[])
+{
+ struct brw_vertex_element *inputs = brw->vb.inputs;
+ struct brw_vertex_info old = brw->vb.info;
+ GLuint i;
+
+ memset(inputs, 0, sizeof(*inputs));
+ memset(&brw->vb.info, 0, sizeof(brw->vb.info));
+
+ for (i = 0; i < VERT_ATTRIB_MAX; i++) {
+ brw->vb.inputs[i].glarray = arrays[i];
+
+ /* XXX: metaops passes null arrays */
+ if (arrays[i]) {
+ if (arrays[i]->StrideB != 0)
+ brw->vb.info.varying |= 1 << i;
+
+ brw->vb.info.sizes[i/16] |= (inputs[i].glarray->Size - 1) << ((i%16) * 2);
+ }
+ }
+
+ /* Raise statechanges if input sizes and varying have changed:
+ */
+ if (memcmp(brw->vb.info.sizes, old.sizes, sizeof(old.sizes)) != 0)
+ brw->state.dirty.brw |= BRW_NEW_INPUT_DIMENSIONS;
+
+ if (brw->vb.info.varying != old.varying)
+ brw->state.dirty.brw |= BRW_NEW_INPUT_VARYING;
+}
+
+
+
+
+
+
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct vertex_buffer *VB = &tnl->vb;
+ const GLuint inputsRead = p->FragProg.Base.InputsRead;
+
+
+
+ intel->vertex_attr_count = 0;
+ intel->wpos_offset = 0;
+ intel->wpos_size = 0;
+ intel->coloroffset = 0;
+ intel->specoffset = 0;
+
+ if (inputsRead & FRAG_BITS_TEX_ANY) {
+ EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, S4_VFMT_XYZW, 16);
+ }
+ else {
+ EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, S4_VFMT_XYZ, 12);
+ }
+
+ if (inputsRead & FRAG_BIT_COL0) {
+ intel->coloroffset = offset / 4;
+ EMIT_ATTR(_TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, S4_VFMT_COLOR, 4);
+ }
+
+ if (inputsRead & (FRAG_BIT_COL1 | FRAG_BIT_FOGC)) {
+
+ if (inputsRead & FRAG_BIT_COL1) {
+ intel->specoffset = offset / 4;
+ EMIT_ATTR(_TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, S4_VFMT_SPEC_FOG, 3);
+ }
+ else
+ EMIT_PAD(3);
+
+ if (inputsRead & FRAG_BIT_FOGC)
+ EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1UB_1F, S4_VFMT_SPEC_FOG, 1);
+ else
+ EMIT_PAD(1);
+ }
+
+ if (inputsRead & FRAG_BIT_FOGC) {
+ EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1F, S4_VFMT_FOG_PARAM, 4);
+ }
+
+ for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) {
+ if (inputsRead & FRAG_BIT_TEX(i)) {
+ int sz = VB->TexCoordPtr[i]->size;
+
+ s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK);
+ s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(sz));
+
+ EMIT_ATTR(_TNL_ATTRIB_TEX0 + i, EMIT_SZ(sz), 0, sz * 4);
+ }
+ else if (i == p->wpos_tex) {
+
+ /* If WPOS is required, duplicate the XYZ position data in an
+ * unused texture coordinate:
+ */
+ s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK);
+ s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(3));
+
+ intel->wpos_offset = offset;
+ intel->wpos_size = 3 * sizeof(GLuint);
+
+ EMIT_PAD(intel->wpos_size);
+ }
+ }
+
+
+
+ GLuint s4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_VFMT_MASK;
+ GLuint s2 = S2_TEXCOORD_NONE;
+ if (s2 != i915->state.Ctx[I915_CTXREG_LIS2] ||
+ s4 != i915->state.Ctx[I915_CTXREG_LIS4]) {
+ int k;
+
+ I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+
+ /* Must do this *after* statechange, so as not to affect
+ * buffered vertices reliant on the old state:
+ */
+ intel->vertex_size = _tnl_install_attrs(&intel->ctx,
+ intel->vertex_attrs,
+ intel->vertex_attr_count,
+ intel->ViewportMatrix.m, 0);
+
+ intel->vertex_size >>= 2;
+
+ i915->state.Ctx[I915_CTXREG_LIS2] = s2;
+ i915->state.Ctx[I915_CTXREG_LIS4] = s4;
+ }
diff --git a/src/mesa/drivers/dri/i915tex/i915_state_immediate.c b/src/mesa/drivers/dri/i915tex/i915_state_immediate.c
new file mode 100644
index 0000000000..e3090eb743
--- /dev/null
+++ b/src/mesa/drivers/dri/i915tex/i915_state_immediate.c
@@ -0,0 +1,315 @@
+/*
+ Copyright (C) Intel Corp. 2006. All Rights Reserved.
+ Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
+ develop this 3D driver.
+
+ 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, sublicense, 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 NONINFRINGEMENT.
+ IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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.
+
+ **********************************************************************/
+ /*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+
+
+#include "intel_batchbuffer.h"
+#include "intel_regions.h"
+
+#include "brw_context.h"
+#include "brw_state.h"
+#include "brw_defines.h"
+
+/***********************************************************************
+ * S0,S1: Vertex buffer state.
+ */
+static void upload_S0S1( struct i915_context *i915 )
+{
+ struct intel_context *intel = &i915->intel;
+
+ /* INTEL_NEW_VBO */
+ if (intel->vb->state.current_vbo) {
+
+ BEGIN_BATCH(3, 0);
+
+ OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
+ I1_LOAD_S(0) |
+ I1_LOAD_S(1) |
+ 2);
+
+ /* INTEL_NEW_VBO, INTEL_NEW_RELOC */
+ OUT_RELOC(intel->vb->state.current_vbo->buffer,
+ DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
+ DRM_BO_MASK_MEM | DRM_BO_FLAG_READ,
+ intel->vb->state.hw_vbo_offset);
+
+ /* INTEL_NEW_VERTEX_SIZE */
+ OUT_BATCH((intel->vertex_size << 24) |
+ (intel->vertex_size << 16));
+
+ ADVANCE_BATCH();
+ }
+}
+
+const struct i915_tracked_state i915_upload_S0S1 = {
+ .dirty = {
+ .mesa = 0,
+ .intel = INTEL_NEW_VBO | INTEL_NEW_VERTEX_SIZE | INTEL_NEW_RELOC,
+ .indirect = 0
+ },
+ .update = upload_S0S1
+};
+
+
+/***********************************************************************
+ * S2: Vertex format
+ */
+static void upload_S2( struct i915_context *i915 )
+{
+ /* I915_NEW_FRAGPROG */
+ i915->state.Ctx[I915_CTXREG_LIS2] = i915->state.fragprog.LIS2;
+}
+
+const struct i915_tracked_state i915_upload_S2 = {
+ .dirty = {
+ .mesa = 0,
+ .intel = I915_NEW_FRAGPROG,
+ .indirect = 0
+ },
+ .update = upload_S2
+};
+
+
+
+/***********************************************************************
+ * S4: Vertex format, rasterization state
+ */
+static void upload_S4(struct brw_context *brw)
+{
+
+ /* I915_NEW_FRAGPROG */
+ i915->state.Ctx[I915_CTXREG_LIS4] |= i915->state.fragprog.LIS4;
+
+
+ /* _NEW_POLYGON, _NEW_BUFFERS */
+ {
+ GLuint mode;
+
+ if (!ctx->Polygon.CullFlag) {
+ mode = S4_CULLMODE_NONE;
+ }
+ else if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) {
+ mode = S4_CULLMODE_CW;
+
+ if (ctx->DrawBuffer && ctx->DrawBuffer->Name != 0)
+ mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW);
+ if (ctx->Polygon.CullFaceMode == GL_FRONT)
+ mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW);
+ if (ctx->Polygon.FrontFace != GL_CCW)
+ mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW);
+ }
+ else {
+ mode = S4_CULLMODE_BOTH;
+ }
+ i915->state.Ctx[I915_CTXREG_LIS4] |= mode;
+ }
+
+
+ /* _NEW_LINE */
+ {
+ GLint width = (GLint) (ctx->Line.Width * 2);
+
+ CLAMP_SELF(width, 1, 0xf);
+ i915->state.Ctx[I915_CTXREG_LIS4] |= width << S4_LINE_WIDTH_SHIFT;
+
+ if (ctx->Line.Smooth)
+ i915->state.Ctx[I915_CTXREG_LIS4] |= S4_LINE_ANTIALIAS_ENABLE;
+ }
+
+ /* _NEW_POINT */
+ {
+ GLint point_size = (int) ctx->Point._Size;
+
+ CLAMP_SELF(point_size, 1, 255);
+ i915->state.Ctx[I915_CTXREG_LIS4] |= point_size << S4_POINT_WIDTH_SHIFT;
+ }
+
+ /* _NEW_LIGHT */
+ if (ctx->Light.ShadeModel == GL_FLAT) {
+ i915->state.Ctx[I915_CTXREG_LIS4] |= (S4_FLATSHADE_ALPHA |
+ S4_FLATSHADE_COLOR |
+ S4_FLATSHADE_SPECULAR);
+ }
+
+
+ I915_SET_STATE_IMMEDIATE(i915, , &bcc);
+}
+
+
+const struct i915_tracked_state i915_upload_S4 = {
+ .dirty = {
+ .mesa = (_NEW_POLYGON |
+ _NEW_BUFFERS |
+ _NEW_LINE |
+ _NEW_POINT |
+ _NEW_LIGHT),
+
+ .intel = I915_NEW_FRAGPROG,
+ .indirect = 0
+ },
+ .update = upload_S4
+};
+
+
+
+/***********************************************************************
+ *
+ */
+static void upload_S5( struct i915_context *i915 )
+{
+ /* _NEW_STENCIL */
+ if (ctx->Stencil.Enabled) {
+ GLint test = intel_translate_compare_func(ctx->Stencil.Function[0]);
+ GLint fop = intel_translate_stencil_op(fail);
+ GLint dfop = intel_translate_stencil_op(zfail);
+ GLint dpop = intel_translate_stencil_op(zpass);
+
+ i915->state.Ctx[I915_CTXREG_LIS5] |= (S5_STENCIL_TEST_ENABLE |
+ S5_STENCIL_WRITE_ENABLE);
+
+ i915->state.Ctx[I915_CTXREG_LIS5] |= ((ref << S5_STENCIL_REF_SHIFT) |
+ (test <<
+ S5_STENCIL_TEST_FUNC_SHIFT));
+
+
+
+ i915->state.Ctx[I915_CTXREG_LIS5] |= ((fop << S5_STENCIL_FAIL_SHIFT) |
+ (dfop <<
+ S5_STENCIL_PASS_Z_FAIL_SHIFT) |
+ (dpop <<
+ S5_STENCIL_PASS_Z_PASS_SHIFT));
+
+ }
+
+ /* _NEW_COLOR */
+ if (RGBA_LOGICOP_ENABLED(ctx)) {
+ i915->state.Ctx[I915_CTXREG_LIS5] |= S5_LOGICOP_ENABLE;
+ }
+
+ if (ctx->Color.DitherFlag) {
+ i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE;
+ }
+
+ {
+ const GLubyte *mask = ctx->Color.ColorMask;
+
+ if (!mask[0])
+ i915->state.Ctx[I915_CTXREG_LIS5] |= S5_WRITEDISABLE_RED;
+
+ if (!mask[1])
+ i915->state.Ctx[I915_CTXREG_LIS5] |= S5_WRITEDISABLE_GREEN;
+
+ if (!mask[2])
+ i915->state.Ctx[I915_CTXREG_LIS5] |= S5_WRITEDISABLE_BLUE;
+
+ if (!mask[3])
+ i915->state.Ctx[I915_CTXREG_LIS5] |= S5_WRITEDISABLE_ALPHA;
+ }
+}
+
+const struct i915_tracked_state i915_upload_S5 = {
+ .dirty = {
+ .mesa = (_NEW_STENCIL | _NEW_COLOR),
+ .intel = 0,
+ .indirect = 0
+ },
+ .update = upload_S5
+};
+
+
+/***********************************************************************
+ */
+static void upload_S6( struct i915_context *i915 )
+{
+ struct i915_context *i915 = I915_CONTEXT(ctx);
+
+
+ i915->state.Ctx[I915_CTXREG_LIS6] = (S6_COLOR_WRITE_ENABLE |
+ (2 << S6_TRISTRIP_PV_SHIFT));
+
+ /* _NEW_COLOR
+ */
+ if (ctx->Color.AlphaTest) {
+ int test = intel_translate_compare_func(ctx->Color.AlphaFunc);
+ GLubyte refByte;
+
+ CLAMPED_FLOAT_TO_UBYTE(refByte, ctx->Color.AlphaRef);
+
+ i915->state.Ctx[I915_CTXREG_LIS6] |= S6_ALPHA_TEST_ENABLE;
+
+ i915->state.Ctx[I915_CTXREG_LIS6] |= ((test << S6_ALPHA_TEST_FUNC_SHIFT) |
+ (((GLuint) refByte) << S6_ALPHA_REF_SHIFT));
+ }
+
+ /* _NEW_COLOR
+ */
+ if (ctx->Color.BlendEnabled && !RGBA_LOGICOP_ENABLED(ctx)) {
+
+ GLuint eqRGB = ctx->Color.BlendEquationRGB;
+ GLuint eqA = ctx->Color.BlendEquationA;
+ GLuint srcRGB = ctx->Color.BlendSrcRGB;
+ GLuint dstRGB = ctx->Color.BlendDstRGB;
+ GLuint srcA = ctx->Color.BlendSrcA;
+ GLuint dstA = ctx->Color.BlendDstA;
+
+ if (eqRGB == GL_MIN || eqRGB == GL_MAX) {
+ srcRGB = dstRGB = GL_ONE;
+ }
+
+ i915->state.Ctx[I915_CTXREG_LIS6] |= S6_CBUF_BLEND_ENABLE;
+
+ lis6 |= SRC_BLND_FACT(intel_translate_blend_factor(srcRGB));
+ lis6 |= DST_BLND_FACT(intel_translate_blend_factor(dstRGB));
+ lis6 |= translate_blend_equation(eqRGB) << S6_CBUF_BLEND_FUNC_SHIFT;
+ }
+
+ /* _NEW_DEPTH
+ */
+ if (ctx->Depth.Test) {
+ GLint func = intel_translate_compare_func(ctx->Depth.Func);
+
+ i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_TEST_ENABLE;
+ i915->state.Ctx[I915_CTXREG_LIS6] |= func << S6_DEPTH_TEST_FUNC_SHIFT;
+
+ if (ctx->Depth.Mask)
+ i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_WRITE_ENABLE;
+ }
+}
+
+const struct i915_tracked_state i915_upload_S6 = {
+ .dirty = {
+ .mesa = (_NEW_COLOR | _NEW_DEPTH),
+ .intel = 0,
+ .indirect = 0
+ },
+ .update = upload_S6
+};
+
diff --git a/src/mesa/drivers/dri/i915tex/i915_state_indirect.c b/src/mesa/drivers/dri/i915tex/i915_state_indirect.c
new file mode 100644
index 0000000000..4d199a139a
--- /dev/null
+++ b/src/mesa/drivers/dri/i915tex/i915_state_indirect.c
@@ -0,0 +1,61 @@
+/* Emit packets to preserved batch buffers, which can then be
+ * referenced by the LOAD_INDIRECT command.
+ *
+ * Need to figure out what STATIC vs DYNAMIC state is supposed to be.
+ */
+
+/* "constant state", or constant-ish??
+ */
+static void emit_static_indirect_state()
+{
+}
+
+/* "slow state", compared probably to the state in
+ * LOAD_STATE_IMMEDIATE.
+ */
+static void emit_dynamic_indirect_state()
+{
+}
+
+/* Need to figure out how to do driBO relocations on addresses in the
+ * indirect state buffers. When do the relocations become invalid?
+ */
+
+static void emit_sampler_state()
+{
+}
+
+static void emit_map_state()
+{
+}
+
+static void emit_program()
+{
+}
+
+static void emit_constants()
+{
+}
+
+void emit_indirect_state()
+{
+ /* Just emit the packet straight to batch:
+ */
+
+ /* Look at the dirty flags and figure out what needs to be sent.
+ */
+}
+
+const struct i915_tracked_state i915_indirect_state = {
+ .dirty = {
+ .mesa = 0,
+ .i915 = I915_NEW_STATE_MODE,
+ .indirect = (INDIRECT_NEW_STATIC |
+ INDIRECT_NEW_DYNAMIC |
+ INDIRECT_NEW_SAMPLER |
+ INDIRECT_NEW_MAP |
+ INDIRECT_NEW_PROGRAM |
+ INDIRECT_NEW_CONSTANTS);
+ },
+ .update = upload_indirect_state
+};
diff --git a/src/mesa/drivers/dri/i915tex/i915_state_map.c b/src/mesa/drivers/dri/i915tex/i915_state_map.c
new file mode 100644
index 0000000000..df85a8c344
--- /dev/null
+++ b/src/mesa/drivers/dri/i915tex/i915_state_map.c
@@ -0,0 +1,201 @@
+/**************************************************************************
+ *
+ * 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 "mtypes.h"
+#include "enums.h"
+#include "texformat.h"
+#include "dri_bufmgr.h"
+
+#include "intel_mipmap_tree.h"
+#include "intel_tex.h"
+
+#include "i915_context.h"
+#include "i915_reg.h"
+
+
+static GLuint
+translate_texture_format(GLuint mesa_format)
+{
+ switch (mesa_format) {
+ case MESA_FORMAT_L8:
+ return MAPSURF_8BIT | MT_8BIT_L8;
+ case MESA_FORMAT_I8:
+ return MAPSURF_8BIT | MT_8BIT_I8;
+ case MESA_FORMAT_A8:
+ return MAPSURF_8BIT | MT_8BIT_A8;
+ case MESA_FORMAT_AL88:
+ return MAPSURF_16BIT | MT_16BIT_AY88;
+ case MESA_FORMAT_RGB565:
+ return MAPSURF_16BIT | MT_16BIT_RGB565;
+ case MESA_FORMAT_ARGB1555:
+ return MAPSURF_16BIT | MT_16BIT_ARGB1555;
+ case MESA_FORMAT_ARGB4444:
+ return MAPSURF_16BIT | MT_16BIT_ARGB4444;
+ case MESA_FORMAT_ARGB8888:
+ return MAPSURF_32BIT | MT_32BIT_ARGB8888;
+ case MESA_FORMAT_YCBCR_REV:
+ return (MAPSURF_422 | MT_422_YCRCB_NORMAL);
+ case MESA_FORMAT_YCBCR:
+ return (MAPSURF_422 | MT_422_YCRCB_SWAPY);
+ case MESA_FORMAT_RGB_FXT1:
+ case MESA_FORMAT_RGBA_FXT1:
+ return (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1);
+ case MESA_FORMAT_Z16:
+ return (MAPSURF_16BIT | MT_16BIT_L16);
+ case MESA_FORMAT_RGBA_DXT1:
+ case MESA_FORMAT_RGB_DXT1:
+ return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1);
+ case MESA_FORMAT_RGBA_DXT3:
+ return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3);
+ case MESA_FORMAT_RGBA_DXT5:
+ return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5);
+ case MESA_FORMAT_Z24_S8:
+ return (MAPSURF_32BIT | MT_32BIT_xL824);
+ default:
+ assert(0);
+ return 0;
+ }
+}
+
+
+
+
+
+static void
+upload_maps( struct i915_context *i915 )
+{
+ GLcontext *ctx = &i915->intel.ctx;
+
+ for (unit = 0; unit < I915_TEX_UNITS; unit++) {
+ switch (ctx.Texture.Unit[unit]._ReallyEnabled) {
+
+ struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
+ struct intel_texture_object *intelObj = intel_texture_object(tObj);
+ struct gl_texture_image *firstImage;
+ GLuint *state = i915->state.Tex[unit];
+
+ memset(state, 0, sizeof(state));
+
+ /*We need to refcount these. */
+
+ if (i915->state.tex_buffer[unit] != NULL) {
+ driBOUnReference(i915->state.tex_buffer[unit]);
+ i915->state.tex_buffer[unit] = NULL;
+ }
+
+ if (!intel_finalize_mipmap_tree(intel, unit))
+ return GL_FALSE;
+
+ /* Get first image here, since intelObj->firstLevel will get set in
+ * the intel_finalize_mipmap_tree() call above.
+ */
+ firstImage = tObj->Image[0][intelObj->firstLevel];
+
+ i915->state.tex_buffer[unit] = driBOReference(intelObj->mt->region->buffer);
+ i915->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, 0,
+ intelObj->
+ firstLevel);
+
+ state[I915_TEXREG_MS3] =
+ (((firstImage->Height - 1) << MS3_HEIGHT_SHIFT) |
+ ((firstImage->Width - 1) << MS3_WIDTH_SHIFT) |
+ translate_texture_format(firstImage->TexFormat->MesaFormat) |
+ MS3_USE_FENCE_REGS);
+
+ state[I915_TEXREG_MS4] =
+ (((((intelObj->mt->pitch * intelObj->mt->cpp) / 4) - 1) << MS4_PITCH_SHIFT) |
+ MS4_CUBE_FACE_ENA_MASK |
+ ((((intelObj->lastLevel - intelObj->firstLevel) * 4)) << MS4_MAX_LOD_SHIFT) |
+ ((firstImage->Depth - 1) << MS4_VOLUME_DEPTH_SHIFT));
+
+
+ DBG(TEXTURE, "state[I915_TEXREG_MS2] = 0x%x\n", state[I915_TEXREG_MS2]);
+ DBG(TEXTURE, "state[I915_TEXREG_MS3] = 0x%x\n", state[I915_TEXREG_MS3]);
+ DBG(TEXTURE, "state[I915_TEXREG_MS4] = 0x%x\n", state[I915_TEXREG_MS4]);
+
+ }
+ }
+ else {
+ if (i915->state.active & I915_UPLOAD_TEX(i))
+ I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(i), GL_FALSE);
+
+ if (i915->state.tex_buffer[i] != NULL) {
+ driBOUnReference(i915->state.tex_buffer[i]);
+ i915->state.tex_buffer[i] = NULL;
+ }
+
+ break;
+ }
+
+
+ {
+ int nr = 0;
+
+ for (i = 0; i < I915_TEX_UNITS; i++)
+ if (dirty & I915_UPLOAD_TEX(i))
+ nr++;
+
+ BEGIN_BATCH(2 + nr * 3, 0);
+ OUT_BATCH(_3DSTATE_MAP_STATE | (3 * nr));
+ OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT);
+ for (i = 0; i < I915_TEX_UNITS; i++) {
+ if (dirty & I915_UPLOAD_TEX(i)) {
+
+ if (state->tex_buffer[i]) {
+ OUT_RELOC(state->tex_buffer[i],
+ DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
+ DRM_BO_MASK_MEM | DRM_BO_FLAG_READ,
+ state->tex_offset[i]);
+ }
+ else {
+ assert(i == 0);
+ assert(state == &i915->meta);
+ OUT_BATCH(0);
+ }
+
+ OUT_BATCH(state->Tex[i][I915_TEXREG_MS3]);
+ OUT_BATCH(state->Tex[i][I915_TEXREG_MS4]);
+ }
+ }
+ ADVANCE_BATCH();
+ }
+
+ return GL_TRUE;
+}
+
+
+
+
+
+const struct i915_tracked_state i915_upload_maps = {
+ .dirty = {
+ .mesa = (_NEW_TEXTURE),
+ .intel = 0,
+ .indirect = 0
+ },
+ .update = upload_maps
+};
diff --git a/src/mesa/drivers/dri/i915tex/i915_state_misc.c b/src/mesa/drivers/dri/i915tex/i915_state_misc.c
new file mode 100644
index 0000000000..8dbed0092f
--- /dev/null
+++ b/src/mesa/drivers/dri/i915tex/i915_state_misc.c
@@ -0,0 +1,560 @@
+/**************************************************************************
+ *
+ * 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 "dd.h"
+#include "tnl/tnl.h"
+#include "tnl/t_context.h"
+
+#include "texmem.h"
+
+#include "intel_fbo.h"
+#include "intel_screen.h"
+#include "intel_batchbuffer.h"
+
+#include "i915_context.h"
+#include "i915_reg.h"
+
+#define FILE_DEBUG_FLAG DEBUG_STATE
+
+/***********************************************************************
+ * Modes4: stencil masks and logicop
+ */
+static void upload_MODES4( struct i915_context *i915 )
+{
+ i915->state.Ctx[I915_CTXREG_MODES4] = _3DSTATE_MODES_4_CMD;
+
+ /* _NEW_STENCIL */
+ if (ctx->Stencil.Enabled) {
+ GLint testmask = ctx->Stencil.ValueMask[0] & 0xff;
+ GLint writemask = ctx->Stencil.WriteMask[0] & 0xff;
+
+ i915->state.Ctx[I915_CTXREG_MODES4] |= (ENABLE_STENCIL_TEST_MASK |
+ STENCIL_TEST_MASK(mask) |
+ ENABLE_STENCIL_WRITE_MASK |
+ STENCIL_WRITE_MASK(writemask));
+ }
+
+ /* _NEW_COLOR */
+ if (ctx->Color._LogicOpEnabled)
+ {
+ int tmp = intel_translate_logic_op(ctx->Color.LogicOp);
+
+ i915->state.Ctx[I915_CTXREG_MODES4] |= (ENABLE_LOGIC_OP_FUNC |
+ LOGIC_OP_FUNC(tmp));
+ }
+ else {
+ /* This seems to be the only way to turn off logicop. The
+ * ENABLE_LOGIC_OP_FUNC is just a modify-enable bit to say this
+ * field is present in the instruction.
+ */
+ i915->state.Ctx[I915_CTXREG_MODES4] |= (ENABLE_LOGIC_OP_FUNC |
+ LOGICOP_COPY);
+ }
+}
+
+const struct i915_tracked_state i915_upload_MODES4 = {
+ .dirty = {
+ .mesa = _NEW_STENCIL | _NEW_COLOR,
+ .intel = 0,
+ .indirect = 0
+ },
+ .update = upload_MODES4
+};
+
+
+/***********************************************************************
+ * BFO: Backface stencil
+ */
+
+static void upload_BFO( struct i915_context *i915 )
+{
+ i915->state.Ctx[I915_CTXREG_BFO] = _3DSTATE_BACKFACE_STENCIL_OPS;
+
+ /* _NEW_STENCIL
+ */
+ if (ctx->Stencil.Enabled) {
+ GLint test = intel_translate_compare_func(ctx->Stencil.Function[1]);
+ GLint fop = intel_translate_stencil_op(fail);
+ GLint dfop = intel_translate_stencil_op(zfail);
+ GLint dpop = intel_translate_stencil_op(zpass);
+
+ i915->state.Ctx[I915_CTXREG_BFO] |=
+ (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_FUNC_SHIFT) |
+ (fop << BFO_STENCIL_FAIL_SHIFT) |
+ (dfop << BFO_STENCIL_PASS_Z_FAIL_SHIFT) |
+ (dpop << BFO_STENCIL_PASS_Z_PASS_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.
+ */
+ i915->state.Ctx[I915_CTXREG_BFO] |= (BFO_ENABLE_STENCIL_TWO_SIDE |
+ 0);
+ }
+}
+
+const struct i915_tracked_state i915_upload_BFO = {
+ .dirty = {
+ .mesa = _NEW_STENCIL,
+ .intel = 0,
+ .indirect = 0
+ },
+ .update = upload_MODES4
+};
+
+
+/***********************************************************************
+ * BLENDCOLOR
+ */
+static void upload_BLENDCOLOR( struct i915_context *i915 )
+{
+ struct i915_context *i915 = I915_CONTEXT(ctx);
+
+ /* _NEW_COLOR
+ */
+ if (ctx->Color.BlendEnabled) {
+ const GLfloat *color = ctx->Color.BlendColor;
+ 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]);
+
+ BEGIN_BATCH(2, 0);
+ OUT_BATCH(_3DSTATE_CONST_BLEND_COLOR_CMD);
+ OUT_BATCH( (a << 24) | (r << 16) | (g << 8) | b );
+ ADVANCE_BATCH();
+ }
+}
+
+const struct i915_tracked_state i915_upload_BLENDCOLOR = {
+ .dirty = {
+ .mesa = _NEW_COLOR,
+ .i915 = 0,
+ .cache = 0
+ },
+ .update = upload_BLENDCOLOR
+};
+
+
+/***********************************************************************
+ * IAB: Independent Alpha Blend
+ */
+static void upload_IAB( struct i915_context *i915 )
+{
+ struct i915_context *i915 = I915_CONTEXT(ctx);
+
+
+ i915->state.Ctx[I915_CTXREG_IAB] =
+
+
+ if (ctx->Color.BlendEnabled) {
+
+ GLuint eqRGB = ctx->Color.BlendEquationRGB;
+ GLuint eqA = ctx->Color.BlendEquationA;
+ GLuint srcRGB = ctx->Color.BlendSrcRGB;
+ GLuint dstRGB = ctx->Color.BlendDstRGB;
+ GLuint srcA = ctx->Color.BlendSrcA;
+ GLuint dstA = ctx->Color.BlendDstA;
+
+ if (srcA != srcRGB ||
+ dstA != dstRGB ||
+ eqA != eqRGB) {
+
+ if (eqA == GL_MIN || eqA == GL_MAX) {
+ srcA = dstA = GL_ONE;
+ }
+
+ BEGIN_BATCH(1, 0);
+
+ OUT_BATCH( _3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD |
+ IAB_MODIFY_ENABLE |
+ IAB_MODIFY_FUNC |
+ IAB_MODIFY_SRC_FACTOR |
+ IAB_MODIFY_DST_FACTOR |
+ SRC_ABLND_FACT(intel_translate_blend_factor(srcA)) |
+ DST_ABLND_FACT(intel_translate_blend_factor(dstA)) |
+ (translate_blend_equation(eqA) << IAB_FUNC_SHIFT) |
+ IAB_ENABLE );
+
+ ADVANCE_BATCH();
+ }
+ }
+}
+
+const struct i915_tracked_state i915_upload_IAB = {
+ .dirty = {
+ .mesa = _NEW_COLOR,
+ .i915 = 0,
+ .cache = 0
+ },
+ .update = upload_IAB
+};
+
+
+/***********************************************************************
+ * Depthbuffer - currently constant, but rotation would change that.
+ */
+
+static void emit_buffers( struct i915_context *i915 )
+{
+ if (INTEL_DEBUG & DEBUG_STATE)
+ fprintf(stderr, "I915_UPLOAD_BUFFERS:\n");
+ BEGIN_BATCH(I915_DEST_SETUP_SIZE + 2, 0);
+ OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR0]);
+ OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR1]);
+ OUT_RELOC(state->draw_region->buffer,
+ DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
+ DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE,
+ state->draw_region->draw_offset);
+
+ if (state->depth_region) {
+ OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR0]);
+ OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR1]);
+ }
+
+ OUT_BATCH(state->Buffer[I915_DESTREG_DV1]);
+ ADVANCE_BATCH();
+}
+
+static void upload_buffers(struct i915_context *i915)
+{
+ struct intel_region *color_region = state->draw_region;
+ struct intel_region *depth_region = state->depth_region;
+ GLuint value;
+
+ if (color_region) {
+ BEGIN_BATCH(4, 0);
+ OUT_BATCH( _3DSTATE_BUF_INFO_CMD );
+ OUT_BATCH( BUF_3D_ID_COLOR_BACK |
+ BUF_3D_PITCH(color_region->pitch * color_region->cpp) |
+ BUF_3D_USE_FENCE);
+ OUT_RELOC(state->draw_region->buffer,
+ DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
+ DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE,
+ state->draw_region->draw_offset);
+ ADVANCE_BATCH();
+ }
+
+ if (depth_region) {
+ BEGIN_BATCH(4, 0);
+ OUT_BATCH( _3DSTATE_BUF_INFO_CMD );
+ OUT_BATCH( BUF_3D_ID_DEPTH |
+ BUF_3D_PITCH(depth_region->pitch * depth_region->cpp) |
+ BUF_3D_USE_FENCE );
+ OUT_RELOC(state->depth_region->buffer,
+ DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
+ DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE,
+ state->depth_region->draw_offset);
+ ADVANCE_BATCH();
+ }
+
+ /*
+ * Compute/set I915_DESTREG_DV1 value
+ */
+ BEGIN_BATCH(2, 0);
+ 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 |
+ DITHER_FULL_ALWAYS |
+ (color_region && color_region->cpp == 4
+ ? DV_PF_8888
+ : DV_PF_565) |
+ (depth_region && depth_region->cpp == 4
+ ? DEPTH_FRMT_24_FIXED_8_OTHER
+ : DEPTH_FRMT_16_FIXED) );
+
+ ADVANCE_BATCH();
+}
+
+const struct i915_tracked_state i915_upload_buffers = {
+ .dirty = {
+ .mesa = 0,
+ .i915 = I915_NEW_CBUF | I915_NEW_ZBUF,
+ .cache = 0
+ },
+ .update = upload_buffers
+};
+
+
+
+/***********************************************************************
+ * Polygon stipple
+ *
+ * The i915 supports a 4x4 stipple natively, GL wants 32x32.
+ * Fortunately stipple is usually a repeating pattern.
+ */
+static void upload_stipple( struct i915_context *i915 )
+{
+ struct i915_context *i915 = I915_CONTEXT(ctx);
+ const GLubyte *m = mask;
+ GLubyte p[4];
+ int i, j, k;
+
+ i915->state.Stipple[I915_STPREG_ST1] = 0;
+
+ if (ctx->Polygon.StippleFlag &&
+ i915->intel.reduced_primitive == GL_TRIANGLES)
+ {
+
+ GLuint newMask;
+
+ p[0] = mask[12] & 0xf;
+ p[0] |= p[0] << 4;
+ p[1] = mask[8] & 0xf;
+ p[1] |= p[1] << 4;
+ p[2] = mask[4] & 0xf;
+ p[2] |= p[2] << 4;
+ p[3] = mask[0] & 0xf;
+ p[3] |= p[3] << 4;
+
+ for (k = 0; k < 8; k++)
+ for (j = 3; j >= 0; j--)
+ for (i = 0; i < 4; i++, m++)
+ if (*m != p[j]) {
+ i915->intel.hw_stipple = 0;
+ return;
+ }
+
+ newMask = (((p[0] & 0xf) << 0) |
+ ((p[1] & 0xf) << 4) |
+ ((p[2] & 0xf) << 8) | ((p[3] & 0xf) << 12));
+
+
+ if (newMask == 0xffff || newMask == 0x0) {
+ /* this is needed to make conform pass */
+ i915->intel.hw_stipple = 0;
+ return;
+ }
+
+ i915->state.Stipple[I915_STPREG_ST0] = _3DSTATE_STIPPLE; if (active) {
+ I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE);
+ i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE;
+ }
+
+
+ i915->state.Stipple[I915_STPREG_ST1] &= ~0xffff;
+ i915->state.Stipple[I915_STPREG_ST1] |= newMask;
+ i915->intel.hw_stipple = 1;
+
+ if (active)
+ i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE;
+}
+
+
+const struct i915_tracked_state i915_polygon_stipple = {
+ .dirty = {
+ .mesa = _NEW_POLYGONSTIPPLE,
+ .i915 = 0,
+ .cache = 0
+ },
+ .update = upload_polygon_stipple
+};
+
+
+
+/***********************************************************************
+ * Misc invarient state packets
+ */
+
+static void upload_invarient_state( struct i915_context *i915 )
+{
+ static GLuint invarient_state[] = {
+
+ (_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),
+
+ /* Could use these to reduce the size of vertices when the incoming
+ * array is constant.
+ */
+ (_3DSTATE_DFLT_DIFFUSE_CMD),
+ (0),
+
+ (_3DSTATE_DFLT_SPEC_CMD),
+ (0),
+
+ (_3DSTATE_DFLT_Z_CMD),
+ (0),
+
+ /* We support texture crossbar via the fragment shader, rather than
+ * with this mechanism.
+ */
+ (_3DSTATE_COORD_SET_BINDINGS |
+ CSB_TCB(0, 0) |
+ CSB_TCB(1, 1) |
+ CSB_TCB(2, 2) |
+ CSB_TCB(3, 3) |
+ CSB_TCB(4, 4) |
+ CSB_TCB(5, 5) |
+ CSB_TCB(6, 6) |
+ CSB_TCB(7, 7)),
+
+ /* Setup OpenGL rasterization state:
+ */
+ (_3DSTATE_RASTER_RULES_CMD |
+ ENABLE_POINT_RASTER_RULE |
+ OGL_POINT_RASTER_RULE |
+ ENABLE_LINE_STRIP_PROVOKE_VRTX |
+ ENABLE_TRI_FAN_PROVOKE_VRTX |
+ LINE_STRIP_PROVOKE_VRTX(1) |
+ TRI_FAN_PROVOKE_VRTX(2) |
+ ENABLE_TEXKILL_3D_4D |
+ TEXKILL_4D),
+
+ /* Need to initialize this to zero.
+ */
+ (_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
+ I1_LOAD_S(3) |
+ (1)),
+ (0),
+
+ /* For private depth buffers but shared color buffers, eg
+ * front-buffer rendering with a private depthbuffer. We don't do
+ * this.
+ */
+ (_3DSTATE_DEPTH_SUBRECT_DISABLE),
+
+ /* Disable indirect state for now.
+ */
+ (_3DSTATE_LOAD_INDIRECT | 0),
+ (0),
+ };
+
+
+ BATCH_LOCALS;
+
+ BEGIN_BATCH(sizeof(invarient_state)/4, 0);
+
+ for (i = 0; i < sizeof(invarient_state)/4; i++)
+ OUT_BATCH( invarient_state[i] );
+
+ ADVANCE_BATCH();
+}
+
+const struct i915_tracked_state i915_invarient_state = {
+ .dirty = {
+ .mesa = 0,
+ .i915 = I915_NEW_CONTEXT,
+ .cache = 0
+ },
+ .update = upload_invarient_state
+};
+
+
+
+
+
+static void check_fallback()
+{
+ if (ctx->Color._LogicOpEnabled && i915->intel.intelScreen->cpp == 2) /* XXX FBO fix */
+ fallback = 1;
+
+ if (ctx->Stencil.Enabled) {
+ if (!ctx->DrawBuffer)
+ return GL_TRUE;
+
+ struct intel_renderbuffer *irbStencil
+ = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL);
+
+ if (!irbStencil || !irbStencil->region)
+ return GL_TRUE;
+ }
+
+
+}
+
+
+static void update_scissor()
+{
+ struct i915_context *i915 = I915_CONTEXT(ctx);
+
+ if (ctx->Scissor.Enabled && ctx->DrawBuffer) {
+ int x1, y1, x2, y2;
+
+ DBG("%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h);
+
+ if (ctx->DrawBuffer->Name == 0) {
+ x1 = x;
+ y1 = ctx->DrawBuffer->Height - (y + h);
+ x2 = x + w - 1;
+ y2 = y1 + h - 1;
+ DBG("%s %d..%d,%d..%d (inverted)\n", __FUNCTION__, x1, x2, y1, y2);
+ }
+ else {
+ /* FBO - not inverted
+ */
+ x1 = x;
+ y1 = y;
+ x2 = x + w - 1;
+ y2 = y + h - 1;
+ DBG("%s %d..%d,%d..%d (not inverted)\n", __FUNCTION__, x1, x2, y1, y2);
+ }
+
+ x1 = CLAMP(x1, 0, ctx->DrawBuffer->Width - 1);
+ y1 = CLAMP(y1, 0, ctx->DrawBuffer->Height - 1);
+ x2 = CLAMP(x2, 0, ctx->DrawBuffer->Width - 1);
+ y2 = CLAMP(y2, 0, ctx->DrawBuffer->Height - 1);
+
+ DBG("%s %d..%d,%d..%d (clamped)\n", __FUNCTION__, x1, x2, y1, y2);
+
+ I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS);
+ i915->state.Buffer[I915_DESTREG_SR0] = _3DSTATE_SCISSOR_RECT_0_CMD;
+ i915->state.Buffer[I915_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff);
+ i915->state.Buffer[I915_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff);
+
+
+ i915->state.Buffer[I915_DESTREG_SENABLE] =
+ (_3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT);
+ }
+ else
+ i915->state.Buffer[I915_DESTREG_SENABLE] =
+ (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT);
+
+}
+
+
+
+
diff --git a/src/mesa/drivers/dri/i915tex/i915_texstate.c b/src/mesa/drivers/dri/i915tex/i915_state_sampler.c
index e0ecdfde24..09d28a6bc1 100644
--- a/src/mesa/drivers/dri/i915tex/i915_texstate.c
+++ b/src/mesa/drivers/dri/i915tex/i915_state_sampler.c
@@ -115,51 +115,24 @@ translate_wrap_mode(GLenum wrap)
* something which is understandable and reliable.
*/
static GLboolean
-i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
+i915_update_sampler(struct intel_context *intel, GLuint unit)
{
GLcontext *ctx = &intel->ctx;
struct i915_context *i915 = i915_context(ctx);
- struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
+ struct gl_texture_unit *tUnit = &ctx->Texture.Unit[unit];
+ struct gl_texture_object *tObj = tUnit->_Current;
struct intel_texture_object *intelObj = intel_texture_object(tObj);
struct gl_texture_image *firstImage;
GLuint *state = i915->state.Tex[unit];
memset(state, 0, sizeof(state));
-
- /*We need to refcount these. */
-
- if (i915->state.tex_buffer[unit] != NULL) {
- driBOUnReference(i915->state.tex_buffer[unit]);
- i915->state.tex_buffer[unit] = NULL;
- }
-
- if (!intel_finalize_mipmap_tree(intel, unit))
- return GL_FALSE;
+
/* Get first image here, since intelObj->firstLevel will get set in
* the intel_finalize_mipmap_tree() call above.
*/
firstImage = tObj->Image[0][intelObj->firstLevel];
- i915->state.tex_buffer[unit] = driBOReference(intelObj->mt->region->buffer);
- i915->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, 0,
- intelObj->
- firstLevel);
-
- state[I915_TEXREG_MS3] =
- (((firstImage->Height - 1) << MS3_HEIGHT_SHIFT) |
- ((firstImage->Width - 1) << MS3_WIDTH_SHIFT) |
- translate_texture_format(firstImage->TexFormat->MesaFormat) |
- MS3_USE_FENCE_REGS);
-
- state[I915_TEXREG_MS4] =
- (((((intelObj->mt->pitch * intelObj->mt->cpp) / 4) -
- 1) << MS4_PITCH_SHIFT) | MS4_CUBE_FACE_ENA_MASK |
- ((((intelObj->lastLevel -
- intelObj->firstLevel) *
- 4)) << MS4_MAX_LOD_SHIFT) | ((firstImage->Depth -
- 1) << MS4_VOLUME_DEPTH_SHIFT));
-
{
GLuint minFilt, mipFilt, magFilt;
@@ -190,7 +163,8 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
mipFilt = MIPFILTER_LINEAR;
break;
default:
- return GL_FALSE;
+ minFilt = FILTER_NEAREST;
+ mipFilt = MIPFILTER_NONE;
}
if (tObj->MaxAnisotropy > 1.0) {
@@ -206,11 +180,18 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
magFilt = FILTER_LINEAR;
break;
default:
- return GL_FALSE;
+ magFilt = FILTER_NEAREST;
+ break;
}
}
- state[I915_TEXREG_SS2] = i915->lodbias_ss2[unit];
+ {
+ GLint b = (int) ((tObj->LodBias + tUnit->LodBias) * 16.0);
+ b = CLAMP(b, -256, 255);
+
+ state[I915_TEXREG_SS2] |= ((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK);
+ }
+
/* YUV conversion:
*/
@@ -256,8 +237,19 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
wt == GL_CLAMP ||
wr == GL_CLAMP ||
ws == GL_CLAMP_TO_BORDER ||
- wt == GL_CLAMP_TO_BORDER || wr == GL_CLAMP_TO_BORDER))
- return GL_FALSE;
+ wt == GL_CLAMP_TO_BORDER ||
+ wr == GL_CLAMP_TO_BORDER)) {
+
+/* return GL_FALSE; */
+ sampler->fallback = true;
+ }
+
+
+ /* Or some field in tObj? */
+ if (ctx->Texture.Unit[i]._ReallyEnabled == TEXTURE_RECT_BIT)
+ ss3 = SS3_NORMALIZED_COORDS;
+ else
+ ss3 = 0;
state[I915_TEXREG_SS3] = ss3; /* SS3_NORMALIZED_COORDS */
@@ -277,6 +269,7 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
tObj->_BorderChan[3]);
+
I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(unit), GL_TRUE);
/* memcmp was already disabled, but definitely won't work as the
* region might now change and that wouldn't be detected:
@@ -284,14 +277,9 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit));
-#if 0
DBG(TEXTURE, "state[I915_TEXREG_SS2] = 0x%x\n", state[I915_TEXREG_SS2]);
DBG(TEXTURE, "state[I915_TEXREG_SS3] = 0x%x\n", state[I915_TEXREG_SS3]);
DBG(TEXTURE, "state[I915_TEXREG_SS4] = 0x%x\n", state[I915_TEXREG_SS4]);
- DBG(TEXTURE, "state[I915_TEXREG_MS2] = 0x%x\n", state[I915_TEXREG_MS2]);
- DBG(TEXTURE, "state[I915_TEXREG_MS3] = 0x%x\n", state[I915_TEXREG_MS3]);
- DBG(TEXTURE, "state[I915_TEXREG_MS4] = 0x%x\n", state[I915_TEXREG_MS4]);
-#endif
return GL_TRUE;
}
@@ -299,40 +287,38 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
+
+
void
-i915UpdateTextureState(struct intel_context *intel)
+i915_tex_state_emit()
{
- GLboolean ok = GL_TRUE;
- GLuint i;
-
- for (i = 0; i < I915_TEX_UNITS && ok; i++) {
- switch (intel->ctx.Texture.Unit[i]._ReallyEnabled) {
- case TEXTURE_1D_BIT:
- case TEXTURE_2D_BIT:
- case TEXTURE_CUBE_BIT:
- case TEXTURE_3D_BIT:
- ok = i915_update_tex_unit(intel, i, SS3_NORMALIZED_COORDS);
- break;
- case TEXTURE_RECT_BIT:
- ok = i915_update_tex_unit(intel, i, 0);
- break;
- case 0:{
- struct i915_context *i915 = i915_context(&intel->ctx);
- if (i915->state.active & I915_UPLOAD_TEX(i))
- I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(i), GL_FALSE);
+ int nr = 0;
- if (i915->state.tex_buffer[i] != NULL) {
- driBOUnReference(i915->state.tex_buffer[i]);
- i915->state.tex_buffer[i] = NULL;
- }
+ for (i = 0; i < I915_TEX_UNITS; i++)
+ if (dirty & I915_UPLOAD_TEX(i))
+ nr++;
- break;
- }
- default:
- ok = GL_FALSE;
- break;
- }
- }
+ for (i = 0; i < I915_TEX_UNITS; i++)
+ update_sampler( i915, i );
- FALLBACK(intel, I915_FALLBACK_TEXTURE, !ok);
+
+ BEGIN_BATCH(2 + nr * 3, 0);
+ OUT_BATCH(_3DSTATE_SAMPLER_STATE | (3 * nr));
+ OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT);
+ for (i = 0; i < I915_TEX_UNITS; i++)
+ if (dirty & I915_UPLOAD_TEX(i)) {
+ OUT_BATCH(state->Tex[i][I915_TEXREG_SS2]);
+ OUT_BATCH(state->Tex[i][I915_TEXREG_SS3]);
+ OUT_BATCH(state->Tex[i][I915_TEXREG_SS4]);
+ }
+ ADVANCE_BATCH();
}
+
+const struct i915_tracked_state i915_upload_samplers = {
+ .dirty = {
+ .mesa = (_NEW_TEXTURE),
+ .intel = 0,
+ .indirect = 0
+ },
+ .update = upload_samplers
+};
diff --git a/src/mesa/drivers/dri/i915tex/i915_vtbl.c b/src/mesa/drivers/dri/i915tex/i915_vtbl.c
index 52db9a95e6..2703ca8d9f 100644
--- a/src/mesa/drivers/dri/i915tex/i915_vtbl.c
+++ b/src/mesa/drivers/dri/i915tex/i915_vtbl.c
@@ -55,226 +55,18 @@ i915_render_start(struct intel_context *intel)
static void
i915_reduced_primitive_state(struct intel_context *intel, GLenum rprim)
{
- struct i915_context *i915 = i915_context(&intel->ctx);
- GLuint st1 = i915->state.Stipple[I915_STPREG_ST1];
-
- st1 &= ~ST1_ENABLE;
-
- switch (rprim) {
- case GL_TRIANGLES:
- if (intel->ctx.Polygon.StippleFlag && intel->hw_stipple)
- st1 |= ST1_ENABLE;
- break;
- case GL_LINES:
- case GL_POINTS:
- default:
- break;
- }
-
- i915->intel.reduced_primitive = rprim;
-
- if (st1 != i915->state.Stipple[I915_STPREG_ST1]) {
- INTEL_FIREVERTICES(intel);
-
- I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE);
- i915->state.Stipple[I915_STPREG_ST1] = st1;
- }
}
-/* Pull apart the vertex format registers and figure out how large a
- * vertex is supposed to be.
- */
-static GLboolean
-i915_check_vertex_size(struct intel_context *intel, GLuint expected)
-{
- struct i915_context *i915 = i915_context(&intel->ctx);
- int lis2 = i915->current->Ctx[I915_CTXREG_LIS2];
- int lis4 = i915->current->Ctx[I915_CTXREG_LIS4];
- int i, sz = 0;
-
- switch (lis4 & S4_VFMT_XYZW_MASK) {
- case S4_VFMT_XY:
- sz = 2;
- break;
- case S4_VFMT_XYZ:
- sz = 3;
- break;
- case S4_VFMT_XYW:
- sz = 3;
- break;
- case S4_VFMT_XYZW:
- sz = 4;
- break;
- default:
- fprintf(stderr, "no xyzw specified\n");
- return 0;
- }
- if (lis4 & S4_VFMT_SPEC_FOG)
- sz++;
- if (lis4 & S4_VFMT_COLOR)
- sz++;
- if (lis4 & S4_VFMT_DEPTH_OFFSET)
- sz++;
- if (lis4 & S4_VFMT_POINT_WIDTH)
- sz++;
- if (lis4 & S4_VFMT_FOG_PARAM)
- sz++;
-
- for (i = 0; i < 8; i++) {
- switch (lis2 & S2_TEXCOORD_FMT0_MASK) {
- case TEXCOORDFMT_2D:
- sz += 2;
- break;
- case TEXCOORDFMT_3D:
- sz += 3;
- break;
- case TEXCOORDFMT_4D:
- sz += 4;
- break;
- case TEXCOORDFMT_1D:
- sz += 1;
- break;
- case TEXCOORDFMT_2D_16:
- sz += 1;
- break;
- case TEXCOORDFMT_4D_16:
- sz += 2;
- break;
- case TEXCOORDFMT_NOT_PRESENT:
- break;
- default:
- fprintf(stderr, "bad texcoord fmt %d\n", i);
- return GL_FALSE;
- }
- lis2 >>= S2_TEXCOORD_FMT1_SHIFT;
- }
-
- if (sz != expected)
- fprintf(stderr, "vertex size mismatch %d/%d\n", sz, expected);
-
- return sz == expected;
-}
static void
i915_emit_invarient_state(struct intel_context *intel)
{
- BATCH_LOCALS;
-
- BEGIN_BATCH(200, 0);
-
- 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);
-
- OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD);
- OUT_BATCH(0);
-
- OUT_BATCH(_3DSTATE_DFLT_Z_CMD);
- OUT_BATCH(0);
-
- /* Don't support texture crossbar yet */
- OUT_BATCH(_3DSTATE_COORD_SET_BINDINGS |
- CSB_TCB(0, 0) |
- CSB_TCB(1, 1) |
- CSB_TCB(2, 2) |
- CSB_TCB(3, 3) |
- CSB_TCB(4, 4) | 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 |
- ENABLE_LINE_STRIP_PROVOKE_VRTX |
- ENABLE_TRI_FAN_PROVOKE_VRTX |
- LINE_STRIP_PROVOKE_VRTX(1) |
- TRI_FAN_PROVOKE_VRTX(2) | ENABLE_TEXKILL_3D_4D | TEXKILL_4D);
-
- /* Need to initialize this to zero.
- */
- OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | (1));
- OUT_BATCH(0);
-
- /* XXX: Use this */
- 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 */
- OUT_BATCH(0);
-
-
- /* Don't support twosided stencil yet */
- OUT_BATCH(_3DSTATE_BACKFACE_STENCIL_OPS | BFO_ENABLE_STENCIL_TWO_SIDE | 0);
-
- ADVANCE_BATCH();
-}
-
-
-#define emit(intel, state, size ) \
- intel_batchbuffer_data(intel->batch, state, size, 0 )
-
-static GLuint
-get_dirty(struct i915_hw_state *state)
-{
- GLuint dirty;
-
- /* Workaround the multitex hang - if one texture unit state is
- * modified, emit all texture units.
- */
- dirty = state->active & ~state->emitted;
- if (dirty & I915_UPLOAD_TEX_ALL)
- state->emitted &= ~I915_UPLOAD_TEX_ALL;
- dirty = state->active & ~state->emitted;
- return dirty;
}
-static GLuint
-get_state_size(struct i915_hw_state *state)
-{
- GLuint dirty = get_dirty(state);
- GLuint i;
- GLuint sz = 0;
-
- if (dirty & I915_UPLOAD_CTX)
- sz += sizeof(state->Ctx);
-
- if (dirty & I915_UPLOAD_BUFFERS)
- sz += sizeof(state->Buffer);
-
- if (dirty & I915_UPLOAD_STIPPLE)
- sz += sizeof(state->Stipple);
-
- if (dirty & I915_UPLOAD_FOG)
- sz += sizeof(state->Fog);
-
- if (dirty & I915_UPLOAD_TEX_ALL) {
- int nr = 0;
- for (i = 0; i < I915_TEX_UNITS; i++)
- if (dirty & I915_UPLOAD_TEX(i))
- nr++;
-
- sz += (2 + nr * 3) * sizeof(GLuint) * 2;
- }
-
- if (dirty & I915_UPLOAD_CONSTANTS)
- sz += state->ConstantSize * sizeof(GLuint);
-
- if (dirty & I915_UPLOAD_PROGRAM)
- sz += state->ProgramSize * sizeof(GLuint);
-
- return sz;
-}
/* Push the state into the sarea and/or texture memory.
@@ -282,146 +74,6 @@ get_state_size(struct i915_hw_state *state)
static void
i915_emit_state(struct intel_context *intel)
{
- struct i915_context *i915 = i915_context(&intel->ctx);
- struct i915_hw_state *state = i915->current;
- int i;
- GLuint dirty;
- BATCH_LOCALS;
-
- /* We don't hold the lock at this point, so want to make sure that
- * there won't be a buffer wrap.
- *
- * It might be better to talk about explicit places where
- * scheduling is allowed, rather than assume that it is whenever a
- * batchbuffer fills up.
- */
- intel_batchbuffer_require_space(intel->batch, get_state_size(state), 0);
-
- /* Do this here as we may have flushed the batchbuffer above,
- * causing more state to be dirty!
- */
- dirty = get_dirty(state);
-
- if (INTEL_DEBUG & DEBUG_STATE)
- fprintf(stderr, "%s dirty: %x\n", __FUNCTION__, dirty);
-
- if (dirty & I915_UPLOAD_INVARIENT) {
- if (INTEL_DEBUG & DEBUG_STATE)
- fprintf(stderr, "I915_UPLOAD_INVARIENT:\n");
- i915_emit_invarient_state(intel);
- }
-
- if (dirty & I915_UPLOAD_CTX) {
- if (INTEL_DEBUG & DEBUG_STATE)
- fprintf(stderr, "I915_UPLOAD_CTX:\n");
-
- emit(intel, state->Ctx, sizeof(state->Ctx));
- }
-
- if (dirty & I915_UPLOAD_BUFFERS) {
- if (INTEL_DEBUG & DEBUG_STATE)
- fprintf(stderr, "I915_UPLOAD_BUFFERS:\n");
- BEGIN_BATCH(I915_DEST_SETUP_SIZE + 2, 0);
- OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR0]);
- OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR1]);
- OUT_RELOC(state->draw_region->buffer,
- DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
- DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE,
- state->draw_region->draw_offset);
-
- if (state->depth_region) {
- OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR0]);
- OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR1]);
- OUT_RELOC(state->depth_region->buffer,
- DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
- DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE,
- state->depth_region->draw_offset);
- }
-
- OUT_BATCH(state->Buffer[I915_DESTREG_DV0]);
- OUT_BATCH(state->Buffer[I915_DESTREG_DV1]);
- OUT_BATCH(state->Buffer[I915_DESTREG_SENABLE]);
- OUT_BATCH(state->Buffer[I915_DESTREG_SR0]);
- OUT_BATCH(state->Buffer[I915_DESTREG_SR1]);
- OUT_BATCH(state->Buffer[I915_DESTREG_SR2]);
- ADVANCE_BATCH();
- }
-
- if (dirty & I915_UPLOAD_STIPPLE) {
- if (INTEL_DEBUG & DEBUG_STATE)
- fprintf(stderr, "I915_UPLOAD_STIPPLE:\n");
- emit(intel, state->Stipple, sizeof(state->Stipple));
- }
-
- if (dirty & I915_UPLOAD_FOG) {
- if (INTEL_DEBUG & DEBUG_STATE)
- fprintf(stderr, "I915_UPLOAD_FOG:\n");
- emit(intel, state->Fog, sizeof(state->Fog));
- }
-
- /* Combine all the dirty texture state into a single command to
- * avoid lockups on I915 hardware.
- */
- if (dirty & I915_UPLOAD_TEX_ALL) {
- int nr = 0;
-
- for (i = 0; i < I915_TEX_UNITS; i++)
- if (dirty & I915_UPLOAD_TEX(i))
- nr++;
-
- BEGIN_BATCH(2 + nr * 3, 0);
- OUT_BATCH(_3DSTATE_MAP_STATE | (3 * nr));
- OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT);
- for (i = 0; i < I915_TEX_UNITS; i++)
- if (dirty & I915_UPLOAD_TEX(i)) {
-
- if (state->tex_buffer[i]) {
- OUT_RELOC(state->tex_buffer[i],
- DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
- DRM_BO_MASK_MEM | DRM_BO_FLAG_READ,
- state->tex_offset[i]);
- }
- else {
- assert(i == 0);
- assert(state == &i915->meta);
- OUT_BATCH(0);
- }
-
- OUT_BATCH(state->Tex[i][I915_TEXREG_MS3]);
- OUT_BATCH(state->Tex[i][I915_TEXREG_MS4]);
- }
- ADVANCE_BATCH();
-
- BEGIN_BATCH(2 + nr * 3, 0);
- OUT_BATCH(_3DSTATE_SAMPLER_STATE | (3 * nr));
- OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT);
- for (i = 0; i < I915_TEX_UNITS; i++)
- if (dirty & I915_UPLOAD_TEX(i)) {
- OUT_BATCH(state->Tex[i][I915_TEXREG_SS2]);
- OUT_BATCH(state->Tex[i][I915_TEXREG_SS3]);
- OUT_BATCH(state->Tex[i][I915_TEXREG_SS4]);
- }
- ADVANCE_BATCH();
- }
-
- if (dirty & I915_UPLOAD_CONSTANTS) {
- if (INTEL_DEBUG & DEBUG_STATE)
- fprintf(stderr, "I915_UPLOAD_CONSTANTS:\n");
- emit(intel, state->Constant, state->ConstantSize * sizeof(GLuint));
- }
-
- if (dirty & I915_UPLOAD_PROGRAM) {
- if (INTEL_DEBUG & DEBUG_STATE)
- fprintf(stderr, "I915_UPLOAD_PROGRAM:\n");
-
- assert((state->Program[0] & 0x1ff) + 2 == state->ProgramSize);
-
- emit(intel, state->Program, state->ProgramSize * sizeof(GLuint));
- if (INTEL_DEBUG & DEBUG_STATE)
- i915_disassemble_program(state->Program, state->ProgramSize);
- }
-
- state->emitted |= dirty;
}
static void
@@ -457,45 +109,8 @@ i915_state_draw_region(struct intel_context *intel,
intel_region_reference(&state->depth_region, depth_region);
}
- /*
- * Set stride/cpp values
- */
- if (color_region) {
- state->Buffer[I915_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD;
- state->Buffer[I915_DESTREG_CBUFADDR1] =
- (BUF_3D_ID_COLOR_BACK |
- BUF_3D_PITCH(color_region->pitch * color_region->cpp) |
- BUF_3D_USE_FENCE);
- }
-
- if (depth_region) {
- state->Buffer[I915_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD;
- state->Buffer[I915_DESTREG_DBUFADDR1] =
- (BUF_3D_ID_DEPTH |
- BUF_3D_PITCH(depth_region->pitch * depth_region->cpp) |
- BUF_3D_USE_FENCE);
- }
-
- /*
- * Compute/set I915_DESTREG_DV1 value
+ /* Everything else will get done later:
*/
- value = (DSTORG_HORT_BIAS(0x8) | /* .5 */
- DSTORG_VERT_BIAS(0x8) | /* .5 */
- LOD_PRECLAMP_OGL | TEX_DEFAULT_COLOR_OGL);
- if (color_region && color_region->cpp == 4) {
- value |= DV_PF_8888;
- }
- else {
- value |= (DITHER_FULL_ALWAYS | DV_PF_565);
- }
- if (depth_region && depth_region->cpp == 4) {
- value |= DEPTH_FRMT_24_FIXED_8_OTHER;
- }
- else {
- value |= DEPTH_FRMT_16_FIXED;
- }
- state->Buffer[I915_DESTREG_DV1] = value;
-
I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS);
}
@@ -537,7 +152,6 @@ i915_assert_not_dirty( struct intel_context *intel )
void
i915InitVtbl(struct i915_context *i915)
{
- i915->intel.vtbl.check_vertex_size = i915_check_vertex_size;
i915->intel.vtbl.destroy = i915_destroy_context;
i915->intel.vtbl.emit_state = i915_emit_state;
i915->intel.vtbl.lost_hardware = i915_lost_hardware;
diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h
index ab88e83853..20c95a88cb 100644
--- a/src/mesa/drivers/dri/i915tex/intel_context.h
+++ b/src/mesa/drivers/dri/i915tex/intel_context.h
@@ -131,14 +131,11 @@ struct intel_context
struct intel_region * draw_region,
struct intel_region * depth_region);
- GLuint(*flush_cmd) (void);
+ GLuint (*flush_cmd) (void);
void (*reduced_primitive_state) (struct intel_context * intel,
GLenum rprim);
- GLboolean(*check_vertex_size) (struct intel_context * intel,
- GLuint expected);
-
/* Metaops:
*/
diff --git a/src/mesa/drivers/dri/i915tex/intel_idx_render.c b/src/mesa/drivers/dri/i915tex/intel_idx_render.c
index b5b57c399f..fa16d670a3 100644
--- a/src/mesa/drivers/dri/i915tex/intel_idx_render.c
+++ b/src/mesa/drivers/dri/i915tex/intel_idx_render.c
@@ -46,9 +46,6 @@
#include "intel_reg.h"
#include "intel_idx_render.h"
-/* XXX: NAUGHTY:
- */
-#include "i915_reg.h"
#define FILE_DEBUG_FLAG DEBUG_IDX
@@ -62,7 +59,7 @@
* and the number of indices we can fit in a batchbuffer after
* making room for state.
*/
-#define HW_MAX_INDEXABLE_VERTS ((1<<16)-1)
+#define HW_MAX_INDEXABLE_VERTS 0xfffe
#define HW_MAX_INDICES ((BATCH_SZ - 1024) / 2)
@@ -73,20 +70,35 @@ struct intel_vb {
struct intel_buffer_object *vbo[MAX_VBO];
GLuint nr_vbo;
- struct intel_buffer_object *current_vbo;
GLuint current_vbo_size;
GLuint current_vbo_used;
void *current_vbo_ptr;
- GLuint hw_vbo_offset;
GLuint hw_vbo_delta;
GLuint vertex_size;
- GLuint dirty;
+ struct {
+ struct intel_buffer_object *current_vbo;
+ GLuint hw_vbo_offset;
+ } state;
};
+/* Have to fallback for:
+ * - points (needs different viewport)
+ * - twoside light
+ * - z offset
+ * - unfilled prims
+ * - lines && linestipple
+ * - tris && tristipple && !hwstipple
+ * - point attenuation (bug!)
+ * - aa tris && strict-conformance
+ * - aa points && strict-conformance
+ * - PLUS: any fallback-to-swrast condition (intel->Fallback)
+ *
+ * If binning, need to flush bins and fall
+ */
static GLboolean check_idx_render(GLcontext *ctx,
struct vertex_buffer *VB,
GLuint *max_nr_verts,
@@ -119,42 +131,6 @@ static GLboolean check_idx_render(GLcontext *ctx,
}
-static void
-emit_vb_state( struct intel_vb *vb )
-{
- struct intel_context *intel = vb->intel;
-
- DBG("%s\n", __FUNCTION__);
-
- /* Additionally, emit our vertex buffer state.
- *
- * XXX: need to push into the regular state mechanism, otherwise
- * will fail with multiple apps when they mix up the submit order
- * of their batchbuffers.
- *
- * XXX: need i830 version
- */
- BEGIN_BATCH(3, 0);
-
- OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
- I1_LOAD_S(0) |
- I1_LOAD_S(1) |
- 2);
-
- OUT_RELOC(vb->current_vbo->buffer,
- DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
- DRM_BO_MASK_MEM | DRM_BO_FLAG_READ,
- vb->hw_vbo_offset);
-
- OUT_BATCH((vb->vertex_size << 24) |
- (vb->vertex_size << 16));
-
- ADVANCE_BATCH();
-
- vb->dirty = 0;
-}
-
-
static void
release_current_vbo( struct intel_vb *vb )
{
@@ -167,11 +143,12 @@ release_current_vbo( struct intel_vb *vb )
GL_ARRAY_BUFFER_ARB,
&vb->current_vbo->Base );
- vb->current_vbo = NULL;
+ vb->state.current_vbo = NULL;
+ vb->intel->state.intel |= INTEL_NEW_VBO;
+
vb->current_vbo_ptr = NULL;
vb->current_vbo_size = 0;
vb->current_vbo_used = 0;
- vb->dirty = 0;
}
static void
@@ -212,11 +189,13 @@ get_next_vbo( struct intel_vb *vb, GLuint size )
if (size < VBO_SIZE)
size = VBO_SIZE;
- vb->current_vbo = vb->vbo[vb->nr_vbo++];
+ vb->state.current_vbo = vb->vbo[vb->nr_vbo++];
+ vb->state.hw_vbo_offset = 0;
+ vb->intel->state.intel |= INTEL_NEW_VBO;
+
vb->current_vbo_size = size;
vb->current_vbo_used = 0;
- vb->hw_vbo_offset = 0;
- vb->dirty = 1;
+
/* Clear out buffer contents and break any hardware dependency on
* the old memory:
@@ -243,8 +222,8 @@ static void *get_space( struct intel_vb *vb, GLuint nr, GLuint vertex_size )
if (vb->vertex_size != vertex_size) {
vb->vertex_size = vertex_size;
- vb->hw_vbo_offset = vb->current_vbo_used;
- vb->dirty = 1;
+ vb->state.hw_vbo_offset = vb->current_vbo_used;
+ vb->intel->state.intel |= INTEL_NEW_VBO;
}
if (!vb->current_vbo_ptr) {
@@ -343,13 +322,7 @@ static void emit_prims( GLcontext *ctx,
/* XXX: Can emit upto 64k indices, need to split larger prims
*/
- BEGIN_BATCH(2 + (nr+1)/2, INTEL_BATCH_CLIPRECTS);
-
- /* Most state has already been emitted by the RenderStart callback.
- */
- if (vb->dirty) {
- emit_vb_state( vb );
- }
+ EMIT_STATE_BEGIN_BATCH(2 + (nr+1)/2, INTEL_BATCH_CLIPRECTS);
OUT_BATCH(0);
OUT_BATCH( _3DPRIMITIVE |
@@ -368,10 +341,6 @@ static void emit_prims( GLcontext *ctx,
OUT_BATCH( (offset + indices[start+j]) );
ADVANCE_BATCH();
-
- /* This won't fail, but only because of the wierd emit above:
- */
- assert(!vb->dirty);
}