summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Whitwell <keith@tungstengraphics.com>2007-03-16 12:17:52 +0000
committerKeith Whitwell <keith@tungstengraphics.com>2007-03-16 12:17:52 +0000
commit83b7647450b860f1e282d3db22edf206373583bc (patch)
treef2af08650a9dca236a707f7553caf5393bce2d02
parent891050ea33c71aec14bd65fc42eef95d4b459013 (diff)
Reorganize state to match indirect state types.
Indirect state emit support added, but disabled. Trivial tri.c works.
-rw-r--r--src/mesa/drivers/dri/i915tex/Makefile10
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_cache.c396
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_cache.h140
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_context.c69
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_context.h38
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_fpc.h217
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_indirect.c (renamed from src/mesa/drivers/dri/i915tex/i915_state_indirect.c)38
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_state.c48
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_state.h54
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_state_constants.c (renamed from src/mesa/drivers/dri/i915tex/i915_state_fp.c)101
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_state_dynamic.c413
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_state_fallback.c53
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_state_immediate.c46
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_state_invarient.c143
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_state_map.c38
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_state_misc.c448
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_state_program.c96
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_state_sampler.c21
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_state_static.c393
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_state_vertex.c (renamed from src/mesa/drivers/dri/i915tex/i915_state_fp_inputs.c)8
-rw-r--r--src/mesa/drivers/dri/i915tex/i915_vtbl.c220
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_batchbuffer.c4
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_context.c20
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_idx_render.c430
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_idx_render.h37
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_program.c269
26 files changed, 2441 insertions, 1309 deletions
diff --git a/src/mesa/drivers/dri/i915tex/Makefile b/src/mesa/drivers/dri/i915tex/Makefile
index c8fee7dfb5..7c7ad84d51 100644
--- a/src/mesa/drivers/dri/i915tex/Makefile
+++ b/src/mesa/drivers/dri/i915tex/Makefile
@@ -7,6 +7,7 @@ LIBNAME = i915tex_dri.so
MINIGLX_SOURCES = server/intel_dri.c
DRIVER_SOURCES = \
+ i915_cache.c \
i915_context.c \
i915_fpc.c \
i915_fpc_debug.c \
@@ -14,14 +15,15 @@ DRIVER_SOURCES = \
i915_fpc_translate.c \
i915_program.c \
i915_state.c \
- i915_state_fp.c \
- i915_state_fp_inputs.c \
+ i915_state_constants.c \
+ i915_state_dynamic.c \
i915_state_fallback.c \
- i915_state_invarient.c \
i915_state_immediate.c \
i915_state_map.c \
- i915_state_misc.c \
+ i915_state_program.c \
i915_state_sampler.c \
+ i915_state_static.c \
+ i915_state_vertex.c \
i915_tex_layout.c \
i915_vtbl.c \
intel_render.c \
diff --git a/src/mesa/drivers/dri/i915tex/i915_cache.c b/src/mesa/drivers/dri/i915tex/i915_cache.c
new file mode 100644
index 0000000000..45644d77e4
--- /dev/null
+++ b/src/mesa/drivers/dri/i915tex/i915_cache.c
@@ -0,0 +1,396 @@
+/**************************************************************************
+ *
+ * Copyright 2007 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.
+ *
+ **************************************************************************/
+
+ /*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "i915_context.h"
+#include "i915_cache.h"
+#include "i915_reg.h"
+#include "intel_batchbuffer.h"
+
+/* Currently things are just being stuffed into the end of the
+ * batchbuffer. That's not great, but it works well for relocations.
+ *
+ * In future, keep non-relocation structs elsewhere, but want a way to
+ * be able to emit more (ie map a referenced buffer) without waiting
+ * on the fence - this should be possible as we currently do this with
+ * batchbuffers.
+ */
+
+struct i915_cache_item {
+ GLuint hash;
+ GLuint size;
+ const void *data;
+ GLuint offset; /* relative to the batchbuffer start */
+ struct i915_cache_item *next;
+};
+
+struct i915_cache {
+ GLuint id;
+ const char *name;
+ GLuint state_type;
+ struct i915_cache_item **items;
+ GLuint size, n_items;
+ GLuint force_load_flag;
+ GLuint last_addr;
+};
+
+struct i915_cache_context {
+ struct i915_context *i915;
+ struct i915_cache cache[I915_MAX_CACHE];
+};
+
+
+static void emit_load_indirect( struct intel_context *intel,
+ GLuint state_type,
+ GLuint force_load_flag,
+ GLuint offset,
+ GLuint size )
+{
+ BEGIN_BATCH(3,0);
+ OUT_BATCH( _3DSTATE_LOAD_INDIRECT | state_type | (1<<14) | 1);
+ OUT_RELOC( intel->batch->buffer,
+ DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE,
+ DRM_BO_MASK_MEM | DRM_BO_FLAG_EXE,
+ ( offset | force_load_flag | SIS0_BUFFER_VALID ) );
+ OUT_BATCH( (size/4)-1 );
+ ADVANCE_BATCH();
+}
+
+
+static GLuint emit_packet( struct intel_context *intel,
+ const struct i915_cache_packet *packet,
+ GLuint size )
+{
+ GLuint segment = SEGMENT_OTHER_INDIRECT;
+ GLuint offset = intel->batch->segment_finish_offset[segment];
+ GLuint i;
+
+ /* XXX:
+ */
+ assert(intel->batch->segment_finish_offset[segment] + size <
+ intel->batch->segment_max_offset[segment]);
+
+ intel->batch->segment_finish_offset[segment] += size;
+
+ memcpy(intel->batch->map + offset,
+ &packet->dword[0],
+ size );
+
+ for (i = 0; i < packet->nr_relocs; i++) {
+ intel_batchbuffer_set_reloc( intel->batch,
+ offset + packet->reloc[i].dword * sizeof(GLuint),
+ packet->reloc[i].buffer,
+ packet->reloc[i].flags,
+ packet->reloc[i].mask,
+ packet->dword[packet->reloc[i].dword].u );
+ }
+
+ return offset;
+}
+
+
+/* A cache for packets of variable sizes which are held in one of the
+ * indirect state bins.
+ *
+ * Note that dynamic indirect state is special and handled elsewhere.
+ */
+static GLuint hash_packet( const void *packet, GLuint size )
+{
+ GLuint hash = 0, i;
+
+ assert(size % 4 == 0);
+
+ /* I'm sure this can be improved on:
+ */
+ for (i = 0; i < size/4; i++)
+ hash += ((GLuint *)packet)[i];
+
+ return hash;
+}
+
+
+static void rehash( struct i915_cache *cache )
+{
+ struct i915_cache_item **items;
+ struct i915_cache_item *c, *next;
+ const GLuint size = cache->size * 2;
+ GLuint i;
+
+ items = (struct i915_cache_item**) _mesa_malloc(size * sizeof(*items));
+ _mesa_memset(items, 0, size * sizeof(*items));
+
+ for (i = 0; i < cache->size; i++) {
+ for (c = cache->items[i]; c; c = next) {
+ next = c->next;
+ c->next = items[c->hash & (size-1)];
+ items[c->hash & (size-1)] = c;
+ }
+ }
+
+ FREE(cache->items);
+ cache->items = items;
+ cache->size = size;
+}
+
+
+
+static GLuint search_cache( struct i915_cache *cache,
+ GLuint hash,
+ const void *data,
+ GLuint size)
+{
+ struct i915_cache_item *c;
+ GLuint mask = cache->size - 1;
+
+ for (c = cache->items[hash & mask]; c; c = c->next) {
+ if (c->hash == hash &&
+ c->size == size &&
+ memcmp(c->data, data, size) == 0)
+ {
+ return c->offset;
+ }
+ }
+
+ return 0;
+}
+
+
+static GLuint upload_cache( struct i915_cache *cache,
+ struct intel_context *intel,
+ GLuint hash,
+ const struct i915_cache_packet *packet,
+ GLuint size )
+{
+ struct i915_cache_item *item = CALLOC_STRUCT(i915_cache_item);
+ void *data = _mesa_malloc(size);
+
+ memcpy(data, packet->dword, size);
+
+ item->data = data;
+ item->hash = hash;
+ item->size = size;
+
+ if (++cache->n_items > cache->size)
+ rehash(cache);
+
+ hash &= cache->size - 1;
+ item->next = cache->items[hash];
+ cache->items[hash] = item;
+
+ /* Copy data to the buffer and emit relocations:
+ */
+ item->offset = emit_packet( intel, packet, size );
+
+ if (INTEL_DEBUG & DEBUG_STATE)
+ _mesa_printf("upload %s: %d bytes to batchbuffer offset %x\n",
+ cache->name,
+ size,
+ item->offset);
+
+ return item->offset;
+}
+
+
+/* Returns the size of the in-use packet:
+ */
+static GLuint packet_size( const struct i915_cache_packet *packet )
+{
+ return ((const char *)(packet->reloc + packet->nr_relocs) -
+ (const char *)packet);
+}
+
+
+void i915_cache_emit(struct i915_cache_context *cctx,
+ const struct i915_cache_packet *packet )
+{
+ struct intel_context *intel = &cctx->i915->intel;
+ GLuint size = packet_size( packet );
+#if 0
+ GLuint hash = hash_packet( packet, size );
+ struct i915_cache *cache = &cctx->cache[packet->cache_id];
+ GLuint addr;
+
+ addr = search_cache( cache, hash, packet->dword, size );
+ if (addr == 0)
+ addr = upload_cache( cache, intel, hash, packet, size );
+
+ /* Always have to tell the hardware about it, unless this is the
+ * same as last time!
+ */
+ if (addr != cache->last_addr) {
+ emit_load_indirect( intel, cache->state_type,
+ cache->force_load_flag,
+ addr, size );
+
+ cache->force_load_flag = 0;
+ cache->last_addr = addr;
+ }
+#else
+ GLuint i;
+
+ BEGIN_BATCH(packet->nr_dwords, 0);
+ for (i = 0; i < packet->nr_relocs; i++)
+ intel_batchbuffer_set_reloc( intel->batch,
+ ( intel->batch->segment_finish_offset[0] +
+ packet->reloc[i].dword * sizeof(GLuint) ),
+ packet->reloc[i].buffer,
+ packet->reloc[i].flags,
+ packet->reloc[i].mask,
+ packet->dword[packet->reloc[i].dword].u );
+
+ for (i = 0; i < packet->nr_dwords; i++)
+ OUT_BATCH(packet->dword[i].u);
+
+ ADVANCE_BATCH();
+#endif
+}
+
+
+
+/* When we lose hardware context, need to invalidate the surface cache
+ * as these structs must be explicitly re-uploaded. They are subject
+ * to fixup by the memory manager as they contain absolute agp
+ * offsets, so we need to ensure there is a fresh version of the
+ * struct available to receive the fixup.
+ */
+static void clear_cache( struct i915_cache *cache )
+{
+ struct i915_cache_item *c, *next;
+ GLuint i;
+
+ for (i = 0; i < cache->size; i++) {
+ for (c = cache->items[i]; c; c = next) {
+ next = c->next;
+ free((void *)c->data);
+ free(c);
+ }
+ cache->items[i] = NULL;
+ }
+
+ cache->n_items = 0;
+
+ /* Make sure hardware knows we've abandoned old data:
+ */
+ cache->force_load_flag = SIS0_FORCE_LOAD;
+ cache->last_addr = ~0;
+}
+
+
+
+static void init_cache( struct i915_cache_context *cctx,
+ const char *name,
+ GLuint id,
+ GLuint state_type )
+{
+ struct i915_cache *cache = &cctx->cache[id];
+
+ cache->id = id;
+ cache->name = name;
+ cache->state_type = state_type;
+ cache->size = 32;
+ cache->n_items = 0;
+ cache->items = ((struct i915_cache_item **)
+ _mesa_calloc(cache->size * sizeof(cache->items[0])));
+}
+
+struct i915_cache_context *i915_create_caches( struct i915_context *i915 )
+{
+ struct i915_cache_context *cctx = CALLOC_STRUCT(i915_cache_context);
+
+ cctx->i915 = i915;
+
+ init_cache( cctx,
+ "SAMPLER",
+ I915_CACHE_SAMPLER,
+ LI0_STATE_SAMPLER );
+
+ init_cache( cctx,
+ "PROGRAM",
+ I915_CACHE_PROGRAM,
+ LI0_STATE_PROGRAM );
+
+ init_cache( cctx,
+ "CONSTANTS",
+ I915_CACHE_CONSTANTS,
+ LI0_STATE_CONSTANTS );
+
+ init_cache( cctx,
+ "MAP",
+ I915_CACHE_MAP,
+ LI0_STATE_MAP );
+
+ /* These are all part of the LI0_STATIC_INDIRECT bucket. Not
+ * really sure how to handle these.
+ */
+ init_cache( cctx,
+ "BUFFERS",
+ I915_CACHE_BUFFERS,
+ LI0_STATE_STATIC_INDIRECT );
+
+ init_cache( cctx,
+ "STIPPLE",
+ I915_CACHE_STIPPLE,
+ LI0_STATE_STATIC_INDIRECT );
+
+ init_cache( cctx,
+ "SCISSOR",
+ I915_CACHE_SCISSOR,
+ LI0_STATE_STATIC_INDIRECT );
+
+ init_cache( cctx,
+ "INVARIENT",
+ I915_CACHE_INVARIENT,
+ LI0_STATE_STATIC_INDIRECT );
+
+ return cctx;
+}
+
+
+void i915_clear_caches( struct i915_cache_context *cctx )
+{
+ GLint i;
+
+ for (i = 0; i < I915_MAX_CACHE; i++)
+ clear_cache(&cctx->cache[i]);
+}
+
+
+void i915_destroy_caches( struct i915_cache_context *cctx )
+{
+ GLint i;
+
+ for (i = 0; i < I915_MAX_CACHE; i++) {
+ clear_cache(&cctx->cache[i]);
+ FREE(cctx->cache[i].items);
+ }
+
+ FREE(cctx);
+}
diff --git a/src/mesa/drivers/dri/i915tex/i915_cache.h b/src/mesa/drivers/dri/i915tex/i915_cache.h
new file mode 100644
index 0000000000..ca48b2daa1
--- /dev/null
+++ b/src/mesa/drivers/dri/i915tex/i915_cache.h
@@ -0,0 +1,140 @@
+/**************************************************************************
+ *
+ * Copyright 2007 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.
+ *
+ **************************************************************************/
+
+ /*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#ifndef I915_CACHE_H
+#define I915_CACHE_H
+
+struct i915_cache_context;
+struct i915_cache_packet;
+struct i915_context;
+
+enum {
+ I915_CACHE_SAMPLER,
+ I915_CACHE_PROGRAM,
+ I915_CACHE_CONSTANTS,
+ I915_CACHE_MAP,
+ I915_CACHE_BUFFERS,
+ I915_CACHE_STIPPLE,
+ I915_CACHE_SCISSOR,
+ I915_CACHE_INVARIENT,
+ I915_MAX_CACHE
+};
+
+struct i915_cache_context *i915_create_caches( struct i915_context *i915 );
+
+void i915_destroy_caches( struct i915_cache_context *cctx );
+void i915_clear_caches( struct i915_cache_context *cctx );
+
+void i915_cache_emit( struct i915_cache_context *cctx,
+ const struct i915_cache_packet *packet );
+
+
+/* A much of helpers for building packets containing relocation
+ * information.
+ *
+ * Initially allocate and fill in a maximally sized packet, as big as
+ * any that we ever submit to hardware.
+ *
+ * Once cached, we will store a compacted version of this packet, but
+ * this is a convient interface for clients to build & submit packets.
+ */
+#define PACKET_MAX_DWORDS (I915_MAX_CONSTANT * 4 + 4)
+#define PACKET_MAX_RELOCS (I915_TEX_UNITS)
+
+struct i915_cache_reloc {
+ struct _DriBufferObject *buffer;
+ GLuint flags;
+ GLuint mask;
+ GLuint dword;
+};
+
+union fi {
+ GLfloat f;
+ GLuint u;
+ GLint i;
+};
+
+struct i915_cache_packet {
+ GLuint nr_dwords;
+ GLuint nr_relocs;
+ GLuint max_dwords;
+ GLuint cache_id;
+
+ union fi dword[PACKET_MAX_DWORDS +
+ PACKET_MAX_RELOCS * sizeof(struct i915_cache_reloc) / sizeof(GLuint)];
+
+ struct i915_cache_reloc *reloc;
+} packet;
+
+
+static inline void packet_init( struct i915_cache_packet *packet,
+ GLuint cache_id,
+ GLuint nr_dwords,
+ GLuint nr_relocs )
+{
+ packet->nr_dwords = 0;
+ packet->nr_relocs = 0;
+ packet->reloc = (struct i915_cache_reloc *)&packet->dword[nr_dwords];
+ packet->max_dwords = nr_dwords;
+ packet->cache_id = cache_id;
+}
+
+static inline void packet_dword( struct i915_cache_packet *packet, GLuint d )
+{
+ assert(packet->nr_dwords < packet->max_dwords);
+ packet->dword[packet->nr_dwords++].u = d;
+}
+
+static inline void packet_float( struct i915_cache_packet *packet, GLfloat f )
+{
+ assert(packet->nr_dwords < packet->max_dwords);
+ packet->dword[packet->nr_dwords++].f = f;
+}
+
+static inline void packet_reloc( struct i915_cache_packet *packet,
+ struct _DriBufferObject *buf,
+ GLuint flags,
+ GLuint mask,
+ GLuint delta )
+{
+ packet->reloc[packet->nr_relocs].buffer = buf;
+ packet->reloc[packet->nr_relocs].flags = flags;
+ packet->reloc[packet->nr_relocs].mask = mask;
+ packet->reloc[packet->nr_relocs].dword = packet->nr_dwords;
+ packet->dword[packet->nr_dwords].u = delta;
+ packet->nr_relocs++;
+ packet->nr_dwords++;
+}
+
+
+
+#endif
diff --git a/src/mesa/drivers/dri/i915tex/i915_context.c b/src/mesa/drivers/dri/i915tex/i915_context.c
index 4ea8d1d1df..bf4e7b7f2f 100644
--- a/src/mesa/drivers/dri/i915tex/i915_context.c
+++ b/src/mesa/drivers/dri/i915tex/i915_context.c
@@ -40,6 +40,7 @@
#include "utils.h"
#include "i915_reg.h"
#include "i915_state.h"
+#include "i915_cache.h"
#include "intel_regions.h"
#include "intel_batchbuffer.h"
@@ -69,31 +70,9 @@ i915InitDriverFunctions(struct dd_function_table *functions)
i915InitFragProgFuncs(functions);
}
-
-
-GLboolean
-i915CreateContext(const __GLcontextModes * mesaVis,
- __DRIcontextPrivate * driContextPriv,
- void *sharedContextPrivate)
+static void i915_init_gl_constants( struct i915_context *i915 )
{
- struct dd_function_table functions;
- struct i915_context *i915 =
- (struct i915_context *) CALLOC_STRUCT(i915_context);
- struct intel_context *intel = &i915->intel;
- GLcontext *ctx = &intel->ctx;
-
- if (!i915)
- return GL_FALSE;
-
- i915InitVtbl(i915);
- i915InitDriverFunctions(&functions);
- i915_init_state(i915);
-
- if (!intelInitContext(intel, mesaVis, driContextPriv,
- sharedContextPrivate, &functions)) {
- FREE(i915);
- return GL_FALSE;
- }
+ GLcontext *ctx = &i915->intel.ctx;
ctx->Const.MaxTextureUnits = I915_TEX_UNITS;
ctx->Const.MaxTextureImageUnits = I915_TEX_UNITS;
@@ -121,9 +100,37 @@ i915CreateContext(const __GLcontextModes * mesaVis,
ctx->Const.FragmentProgram.MaxNativeTexInstructions = I915_MAX_TEX_INSN;
ctx->Const.FragmentProgram.MaxNativeInstructions = (I915_MAX_ALU_INSN +
I915_MAX_TEX_INSN);
- ctx->Const.FragmentProgram.MaxNativeTexIndirections =
- I915_MAX_TEX_INDIRECT;
+ ctx->Const.FragmentProgram.MaxNativeTexIndirections = I915_MAX_TEX_INDIRECT;
ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; /* I don't think we have one */
+}
+
+
+GLboolean
+i915CreateContext(const __GLcontextModes *mesaVis,
+ __DRIcontextPrivate *driContextPriv,
+ void *sharedContextPrivate)
+{
+ struct dd_function_table functions;
+ struct i915_context *i915 = CALLOC_STRUCT(i915_context);
+ struct intel_context *intel = &i915->intel;
+ GLcontext *ctx = &intel->ctx;
+
+ if (!i915)
+ goto bad;
+
+ i915InitVtbl(i915);
+ i915InitDriverFunctions(&functions);
+ i915_init_state(i915);
+
+ i915->cctx = i915_create_caches( i915 );
+ if (!i915->cctx)
+ goto bad;
+
+ if (!intelInitContext(intel, mesaVis, driContextPriv,
+ sharedContextPrivate, &functions))
+ goto bad;
+
+ i915_init_gl_constants( i915 );
ctx->_MaintainTexEnvProgram = 1;
ctx->_UseTexEnvProgram = 1;
@@ -135,11 +142,19 @@ i915CreateContext(const __GLcontextModes * mesaVis,
*/
_tnl_allow_vertex_fog( ctx, 0 );
_tnl_allow_pixel_fog( ctx, 1 );
-
_tnl_init_vertices(ctx, ctx->Const.MaxArrayLockSize + 12,
36 * sizeof(GLfloat));
intel->verts = TNL_CONTEXT(ctx)->clipspace.vertex_buf;
return GL_TRUE;
+
+ bad:
+ if (i915->cctx)
+ i915_destroy_caches( i915->cctx );
+
+ if (i915)
+ FREE(i915);
+
+ return GL_FALSE;
}
diff --git a/src/mesa/drivers/dri/i915tex/i915_context.h b/src/mesa/drivers/dri/i915tex/i915_context.h
index 2af65a1151..024d8f3c61 100644
--- a/src/mesa/drivers/dri/i915tex/i915_context.h
+++ b/src/mesa/drivers/dri/i915tex/i915_context.h
@@ -36,8 +36,9 @@
#define I915_PROGRAM_SIZE 192
-#define I915_NEW_INPUT_SIZES (INTEL_NEW_DRIVER0<<0)
-#define I915_NEW_VERTEX_FORMAT (INTEL_NEW_DRIVER0<<1)
+#define I915_NEW_INPUT_SIZES (INTEL_NEW_DRIVER0<<0)
+#define I915_NEW_VERTEX_FORMAT (INTEL_NEW_DRIVER0<<1)
+#define I915_NEW_DYNAMIC_INDIRECT (INTEL_NEW_DRIVER0<<2)
@@ -85,11 +86,24 @@ struct i915_fragment_program
+#define I915_DYNAMIC_MODES4 0
+#define I915_DYNAMIC_DEPTHSCALE_0 1
+#define I915_DYNAMIC_DEPTHSCALE_1 2
+#define I915_DYNAMIC_IAB 3
+#define I915_DYNAMIC_BC_0 4
+#define I915_DYNAMIC_BC_1 5
+#define I915_DYNAMIC_BFO_0 6
+#define I915_DYNAMIC_BFO_1 7
+#define I915_DYNAMIC_SIZE 8
+
+
+struct i915_cache_context;
struct i915_context
{
struct intel_context intel;
+ struct i915_cache_context *cctx;
struct i915_fragment_program *fragment_program;
@@ -104,22 +118,24 @@ struct i915_context
struct {
struct intel_tracked_state tracked_state;
-
- /* For short-circuiting
- */
- GLfloat last_buf[I915_MAX_CONSTANT][4];
- GLuint last_bufsz;
} constants;
struct {
- /* I915_NEW_INPUT_DIMENSIONS
+ /* I915_NEW_VERTEX_FORMAT
*/
- GLubyte input_sizes[FRAG_ATTRIB_MAX];
-
GLuint LIS2;
GLuint LIS4;
- } fragprog;
+ } vertex_format;
+ /* Used for short-circuiting packets. Won't work for packets
+ * containing relocations. This is zero'd out after lost_context
+ * events.
+ */
+ struct {
+ GLuint buf[I915_DYNAMIC_SIZE];
+ GLboolean done_reset;
+ } dyn_indirect;
+
GLuint program_id;
};
diff --git a/src/mesa/drivers/dri/i915tex/i915_fpc.h b/src/mesa/drivers/dri/i915tex/i915_fpc.h
new file mode 100644
index 0000000000..61ccdda6b1
--- /dev/null
+++ b/src/mesa/drivers/dri/i915tex/i915_fpc.h
@@ -0,0 +1,217 @@
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+
+#ifndef I915_PROGRAM_H
+#define I915_PROGRAM_H
+
+#include "i915_context.h"
+#include "i915_reg.h"
+
+/***********************************************************************
+ * Public interface for the compiler
+ */
+
+void i915_compile_fragment_program( struct i915_context *i915,
+ struct i915_fragment_program *fp );
+
+
+/***********************************************************************
+ * Private details of the compiler
+ */
+
+struct i915_fp_compile {
+ struct i915_fragment_program *fp;
+
+ GLuint declarations[I915_PROGRAM_SIZE];
+ GLuint program[I915_PROGRAM_SIZE];
+
+ GLuint constant_flags[I915_MAX_CONSTANT];
+
+
+ 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.
+ */
+
+ GLuint nr_tex_indirect;
+ GLuint nr_tex_insn;
+ GLuint nr_alu_insn;
+ GLuint nr_decl_insn;
+
+
+ GLfloat (*env_param)[4];
+};
+
+
+/* Having zero and one in here makes the definition of swizzle a lot
+ * easier.
+ */
+#define UREG_TYPE_SHIFT 29
+#define UREG_NR_SHIFT 24
+#define UREG_CHANNEL_X_NEGATE_SHIFT 23
+#define UREG_CHANNEL_X_SHIFT 20
+#define UREG_CHANNEL_Y_NEGATE_SHIFT 19
+#define UREG_CHANNEL_Y_SHIFT 16
+#define UREG_CHANNEL_Z_NEGATE_SHIFT 15
+#define UREG_CHANNEL_Z_SHIFT 12
+#define UREG_CHANNEL_W_NEGATE_SHIFT 11
+#define UREG_CHANNEL_W_SHIFT 8
+#define UREG_CHANNEL_ZERO_NEGATE_MBZ 5
+#define UREG_CHANNEL_ZERO_SHIFT 4
+#define UREG_CHANNEL_ONE_NEGATE_MBZ 1
+#define UREG_CHANNEL_ONE_SHIFT 0
+
+#define UREG_BAD 0xffffffff /* not a valid ureg */
+
+#define X SRC_X
+#define Y SRC_Y
+#define Z SRC_Z
+#define W SRC_W
+#define ZERO SRC_ZERO
+#define ONE SRC_ONE
+
+/* Construct a ureg:
+ */
+#define UREG( type, nr ) (((type)<< UREG_TYPE_SHIFT) | \
+ ((nr) << UREG_NR_SHIFT) | \
+ (X << UREG_CHANNEL_X_SHIFT) | \
+ (Y << UREG_CHANNEL_Y_SHIFT) | \
+ (Z << UREG_CHANNEL_Z_SHIFT) | \
+ (W << UREG_CHANNEL_W_SHIFT) | \
+ (ZERO << UREG_CHANNEL_ZERO_SHIFT) | \
+ (ONE << UREG_CHANNEL_ONE_SHIFT))
+
+#define GET_CHANNEL_SRC( reg, channel ) ((reg<<(channel*4)) & (0xf<<20))
+#define CHANNEL_SRC( src, channel ) (src>>(channel*4))
+
+#define GET_UREG_TYPE(reg) (((reg)>>UREG_TYPE_SHIFT)&REG_TYPE_MASK)
+#define GET_UREG_NR(reg) (((reg)>>UREG_NR_SHIFT)&REG_NR_MASK)
+
+
+
+#define UREG_XYZW_CHANNEL_MASK 0x00ffff00
+
+/* One neat thing about the UREG representation:
+ */
+static INLINE int
+swizzle(int reg, int x, int y, int z, int w)
+{
+ return ((reg & ~UREG_XYZW_CHANNEL_MASK) |
+ CHANNEL_SRC(GET_CHANNEL_SRC(reg, x), 0) |
+ CHANNEL_SRC(GET_CHANNEL_SRC(reg, y), 1) |
+ CHANNEL_SRC(GET_CHANNEL_SRC(reg, z), 2) |
+ CHANNEL_SRC(GET_CHANNEL_SRC(reg, w), 3));
+}
+
+/* Another neat thing about the UREG representation:
+ */
+static INLINE int
+negate(int reg, int x, int y, int z, int w)
+{
+ return reg ^ (((x & 1) << UREG_CHANNEL_X_NEGATE_SHIFT) |
+ ((y & 1) << UREG_CHANNEL_Y_NEGATE_SHIFT) |
+ ((z & 1) << UREG_CHANNEL_Z_NEGATE_SHIFT) |
+ ((w & 1) << UREG_CHANNEL_W_NEGATE_SHIFT));
+}
+
+
+extern GLuint i915_get_temp(struct i915_fp_compile *p);
+extern GLuint i915_get_utemp(struct i915_fp_compile *p);
+extern void i915_release_utemps(struct i915_fp_compile *p);
+
+
+extern GLuint i915_emit_texld(struct i915_fp_compile *p,
+ GLuint dest,
+ GLuint destmask,
+ GLuint sampler, GLuint coord, GLuint op);
+
+extern GLuint i915_emit_arith(struct i915_fp_compile *p,
+ GLuint op,
+ GLuint dest,
+ GLuint mask,
+ GLuint saturate,
+ GLuint src0, GLuint src1, GLuint src2);
+
+extern GLuint i915_emit_decl(struct i915_fp_compile *p,
+ GLuint type, GLuint nr, GLuint d0_flags);
+
+
+extern GLuint i915_emit_const1f(struct i915_fp_compile *p, GLfloat c0);
+
+extern GLuint i915_emit_const2f(struct i915_fp_compile *p,
+ GLfloat c0, GLfloat c1);
+
+extern GLuint i915_emit_const4fv(struct i915_fp_compile *p,
+ const GLfloat * c);
+
+extern GLuint i915_emit_const4f(struct i915_fp_compile *p,
+ GLfloat c0, GLfloat c1,
+ GLfloat c2, GLfloat c3);
+
+
+extern GLuint i915_emit_param4fv(struct i915_fp_compile *p,
+ const GLfloat * values);
+
+
+
+/*======================================================================
+ * i915_fpc_debug.c
+ */
+extern void i915_program_error(struct i915_fp_compile *p,
+ const char *msg);
+
+
+/*======================================================================
+ * i915_fpc_debug.c
+ */
+extern void i915_disassemble_program(const GLuint * program, GLuint sz);
+
+extern void i915_print_mesa_instructions( const struct prog_instruction *insn,
+ GLuint nr );
+
+/*======================================================================
+ * i915_fpc_translate.c
+ */
+void i915_fixup_depth_write(struct i915_fp_compile *p);
+void i915_translate_program(struct i915_fp_compile *p);
+
+
+
+#endif
diff --git a/src/mesa/drivers/dri/i915tex/i915_state_indirect.c b/src/mesa/drivers/dri/i915tex/i915_indirect.c
index 0445f8e6f7..9c3f6aaf2c 100644
--- a/src/mesa/drivers/dri/i915tex/i915_state_indirect.c
+++ b/src/mesa/drivers/dri/i915tex/i915_indirect.c
@@ -6,10 +6,10 @@
-static GLuint emit_indirect(struct intel_context *intel,
- GLuint flag,
- const GLuint *state,
- GLuint size )
+static GLuint i915_emit_indirect(struct intel_context *intel,
+ GLuint flag,
+ const GLuint *state,
+ GLuint size )
{
GLuint delta;
GLuint segment;
@@ -127,3 +127,33 @@ const struct i915_tracked_state i915_indirect_state = {
},
.update = upload_indirect_state
};
+
+
+#if 0
+ GLuint size = I915_DYNAMIC_SIZE * 4;
+ GLuint flag = i915->dyn_indirect.done_reset ? 0 : DIS0_BUFFER_RESET;
+
+ GLuint delta = ( (intel->batch->segment_finish_offset[segment] + size - 4) |
+ DIS0_BUFFER_VALID |
+ flag );
+
+ BEGIN_BATCH(2,0);
+ OUT_BATCH( _3DSTATE_LOAD_INDIRECT | LI0_STATE_DYNAMIC_INDIRECT | (1<<14) | 0);
+ OUT_RELOC( intel->batch->buffer,
+ DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE,
+ DRM_BO_MASK_MEM | DRM_BO_FLAG_EXE,
+ delta );
+ ADVANCE_BATCH();
+
+
+ {
+ GLuint segment = SEGMENT_DYNAMIC_INDIRECT;
+ GLuint offset = intel->batch->segment_finish_offset[segment];
+ intel->batch->segment_finish_offset[segment] += size;
+
+ if (state != NULL)
+ memcpy(intel->batch->map + offset, state, size);
+
+ return offset;
+ }
+#endif
diff --git a/src/mesa/drivers/dri/i915tex/i915_state.c b/src/mesa/drivers/dri/i915tex/i915_state.c
index e21237400f..b680d4fb49 100644
--- a/src/mesa/drivers/dri/i915tex/i915_state.c
+++ b/src/mesa/drivers/dri/i915tex/i915_state.c
@@ -46,20 +46,10 @@
const struct intel_tracked_state *atoms[] =
{
&i915_check_fallback,
- &i915_invarient_state,
-
&intel_update_viewport,
&intel_update_render_index,
- /*
- */
-/* &i915_fp_choose_prog, */
-
- /* Scan VB:
- */
-/* &i915_vb_output_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.
@@ -67,41 +57,41 @@ const struct intel_tracked_state *atoms[] =
* Also calculate vertex layout, immediate (S2,S4) state, vertex
* size.
*/
- &i915_fp_compile_and_upload,
+ &i915_upload_program,
/* Calculate vertex format, program t_vertex.c, etc:
*/
&i915_vertex_format,
-
/* Immediate state. Don't make any effort to combine packets yet.
*/
- &i915_upload_MODES4,
+ &i915_upload_S0S1,
&i915_upload_S2S4,
&i915_upload_S5,
&i915_upload_S6,
- &i915_upload_IAB,
+ &i915_upload_S7,
+
+ /* Dynamic indirect. Packets are combined in a final step.
+ */
+ &i915_upload_BFO,
&i915_upload_BLENDCOLOR,
+ &i915_upload_DEPTHSCALE,
+ &i915_upload_IAB,
+ &i915_upload_MODES4,
+ &i915_upload_dynamic_indirect,
- /* 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.
+ /* Static indirect state.
*/
+ &i915_upload_invarient,
&i915_upload_buffers,
&i915_upload_scissor,
+ &i915_upload_stipple,
- /* Note this packet has a dependency on the current primitive:
+ /* Other indirect state. Also includes program state, above.
*/
- &i915_upload_stipple,
-
&i915_upload_maps, /* must do before samplers */
&i915_upload_samplers,
-
- NULL, /* i915_fp_constants */
-
- &i915_upload_BFO,
- &i915_upload_S0S1
+ &i915_upload_constants /* will be patched out at runtime */
};
@@ -117,12 +107,12 @@ void i915_init_state( struct i915_context *i915 )
/* Patch in a pointer to the dynamic state atom:
*/
for (i = 0; i < intel->driver_state.nr_atoms; i++)
- if (intel->driver_state.atoms[i] == NULL)
+ if (intel->driver_state.atoms[i] == &i915_upload_constants)
intel->driver_state.atoms[i] = &i915->constants.tracked_state;
_mesa_memcpy(&i915->constants.tracked_state,
- &i915_fp_constants,
- sizeof(i915_fp_constants));
+ &i915_upload_constants,
+ sizeof(i915_upload_constants));
}
diff --git a/src/mesa/drivers/dri/i915tex/i915_state.h b/src/mesa/drivers/dri/i915tex/i915_state.h
index 4ba0d8b775..0f8464fdd7 100644
--- a/src/mesa/drivers/dri/i915tex/i915_state.h
+++ b/src/mesa/drivers/dri/i915tex/i915_state.h
@@ -34,29 +34,65 @@
#define I915_STATE_H
#include "i915_context.h"
+#include "i915_reg.h"
+
void i915_init_state( struct i915_context *i915 );
void i915_destroy_state( struct i915_context *i915 );
const struct intel_tracked_state i915_check_fallback;
-const struct intel_tracked_state i915_fp_constants;
-const struct intel_tracked_state i915_fp_compile_and_upload;
const struct intel_tracked_state i915_vertex_format;
-const struct intel_tracked_state i915_invarient_state;
-const struct intel_tracked_state i915_upload_BFO;
-const struct intel_tracked_state i915_upload_BLENDCOLOR;
-const struct intel_tracked_state i915_upload_IAB;
-const struct intel_tracked_state i915_upload_MODES4;
+
+/* Immediate state:
+ */
const struct intel_tracked_state i915_upload_S0S1;
const struct intel_tracked_state i915_upload_S2S4;
const struct intel_tracked_state i915_upload_S5;
const struct intel_tracked_state i915_upload_S6;
+const struct intel_tracked_state i915_upload_S7;
+
+/* Dynamic indirect:
+ */
+const struct intel_tracked_state i915_upload_BFO;
+const struct intel_tracked_state i915_upload_BLENDCOLOR;
+const struct intel_tracked_state i915_upload_DEPTHSCALE;
+const struct intel_tracked_state i915_upload_IAB;
+const struct intel_tracked_state i915_upload_MODES4;
+const struct intel_tracked_state i915_upload_dynamic_indirect;
+
+/* Static indirect:
+ */
+const struct intel_tracked_state i915_upload_invarient;
const struct intel_tracked_state i915_upload_buffers;
-const struct intel_tracked_state i915_upload_maps;
-const struct intel_tracked_state i915_upload_samplers;
const struct intel_tracked_state i915_upload_scissor;
const struct intel_tracked_state i915_upload_stipple;
+/* Other indirect:
+ */
+const struct intel_tracked_state i915_upload_constants;
+const struct intel_tracked_state i915_upload_program;
+const struct intel_tracked_state i915_upload_maps;
+const struct intel_tracked_state i915_upload_samplers;
+
+
+static INLINE GLuint
+i915_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;
+ }
+}
#endif
diff --git a/src/mesa/drivers/dri/i915tex/i915_state_fp.c b/src/mesa/drivers/dri/i915tex/i915_state_constants.c
index e8a768c2e3..630f2418b9 100644
--- a/src/mesa/drivers/dri/i915tex/i915_state_fp.c
+++ b/src/mesa/drivers/dri/i915tex/i915_state_constants.c
@@ -32,69 +32,11 @@
#include "intel_batchbuffer.h"
#include "i915_context.h"
-#include "i915_fpc.h"
+#include "i915_cache.h"
+#include "i915_reg.h"
-
-
-/*********************************************************************************
- * Program instructions (and decls)
- */
-
-
-static void i915_upload_fp( struct intel_context *intel )
-{
- struct i915_context *i915 = i915_context( &intel->ctx );
- struct i915_fragment_program *fp = i915->fragment_program;
- GLuint i;
-
- if (&fp->Base != intel->state.FragmentProgram->_Current) {
- i915->fragment_program = (struct i915_fragment_program *)
- intel->state.FragmentProgram->_Current;
-
- fp = i915->fragment_program;
- /* This is stupid
- */
- intel->state.dirty.intel |= INTEL_NEW_FRAGMENT_PROGRAM;
- }
-
- /* As the compiled program depends only on the original program
- * text (??? for now at least ???), there is no need for a compiled
- * program cache, just store the compiled version with the original
- * text.
- */
- if (!fp->translated) {
- i915_compile_fragment_program(i915, fp);
- }
-
- BEGIN_BATCH( fp->program_size, 0 );
-
- for (i = 0; i < fp->program_size; i++)
- OUT_BATCH( fp->program[i] );
-
- ADVANCE_BATCH();
-
-#if 0
- emit_indirect(intel, LI0_STATE_PROGRAM,
- state->Program, state->ProgramSize * sizeof(GLuint));
-#endif
-
-}
-
-
-/* See i915_wm.c:
- */
-const struct intel_tracked_state i915_fp_compile_and_upload = {
- .dirty = {
- .mesa = (0),
- .intel = (INTEL_NEW_FRAGMENT_PROGRAM), /* ?? Is this all ?? */
- .extra = 0
- },
- .update = i915_upload_fp
-};
-
-
/*********************************************************************************
* Program constants and state parameters
*/
@@ -105,40 +47,39 @@ upload_constants(struct intel_context *intel)
struct i915_fragment_program *p = i915->fragment_program;
GLint i;
- /* XXX: Pull from state, not ctx!!!
+ /* XXX: Pull from state, not ctx!!! Luckily no metaops programs
+ * have parameters, yet...
*/
- if (p->nr_params)
+ if (p->nr_params) {
+ assert(!intel->metaops.active);
_mesa_load_state_parameters(&intel->ctx, p->Base.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);
+ for (i = 0; i < p->nr_params; i++) {
+ GLint reg = p->param[i].reg;
+ COPY_4V(p->constant[reg], p->param[i].values);
+ }
}
- /* Always seemed to get a failure if I used memcmp() to
- * shortcircuit this state upload. Needs further investigation?
+ /* Another fairly pointless copy - need a better interface to the
+ * cache.
*/
if (p->nr_constants) {
GLuint nr = p->nr_constants;
+ struct i915_cache_packet packet;
- BEGIN_BATCH( nr * 4 + 2, 0 );
- OUT_BATCH( _3DSTATE_PIXEL_SHADER_CONSTANTS | (nr * 4) );
- OUT_BATCH( (1 << (nr - 1)) | ((1 << (nr - 1)) - 1) );
+ packet_init( &packet, I915_CACHE_CONSTANTS, nr * 4 + 2, 0 );
+ packet_dword( &packet, _3DSTATE_PIXEL_SHADER_CONSTANTS | (nr * 4) );
+ packet_dword( &packet, (1 << (nr - 1)) | ((1 << (nr - 1)) - 1) );
for (i = 0; i < nr; i++) {
- OUT_BATCH_F(p->constant[i][0]);
- OUT_BATCH_F(p->constant[i][1]);
- OUT_BATCH_F(p->constant[i][2]);
- OUT_BATCH_F(p->constant[i][3]);
+ packet_float(&packet, p->constant[i][0]);
+ packet_float(&packet, p->constant[i][1]);
+ packet_float(&packet, p->constant[i][2]);
+ packet_float(&packet, p->constant[i][3]);
}
- ADVANCE_BATCH();
+ i915_cache_emit( i915->cctx, &packet );
}
-
-#if 0
- emit_indirect(intel, LI0_STATE_CONSTANTS,
- state->Constant, state->ConstantSize * sizeof(GLuint));
-#endif
}
diff --git a/src/mesa/drivers/dri/i915tex/i915_state_dynamic.c b/src/mesa/drivers/dri/i915tex/i915_state_dynamic.c
new file mode 100644
index 0000000000..8239976ce5
--- /dev/null
+++ b/src/mesa/drivers/dri/i915tex/i915_state_dynamic.c
@@ -0,0 +1,413 @@
+/**************************************************************************
+ *
+ * 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 "intel_fbo.h"
+#include "intel_batchbuffer.h"
+#include "intel_regions.h"
+#include "intel_state_inlines.h"
+
+#include "i915_context.h"
+#include "i915_reg.h"
+#include "i915_state.h"
+
+#define FILE_DEBUG_FLAG DEBUG_STATE
+
+/* State that we have chosen to store in the DYNAMIC segment of the
+ * i915 indirect state mechanism.
+ *
+ * It is very nice to note that in normal rendering, none of these
+ * packets will end up being emitted.
+ *
+ * Can't cache these in the way we do the static state, as there is no
+ * start/size in the command packet, instead an 'end' value that gets
+ * incremented.
+ *
+ * Additionally, there seems to be a requirement to re-issue the full
+ * (active) state every time a 4kb boundary is crossed.
+ *
+ * Simplest implementation is probably just to emit the full active
+ * state every time. Next would be to diff against previous, but note
+ */
+
+static void set_dynamic_indirect( struct intel_context *intel,
+ GLuint offset,
+ const GLuint *src,
+ GLuint size )
+{
+#if 0
+ struct i915_context *i915 = i915_context( &intel->ctx );
+ GLuint *dest = i915->dyn_indirect.buf + offset;
+ GLuint i;
+
+ for (i = 0; i < size; i++) {
+ if (dest[i] != src[i]) {
+ dest[i] = src[i];
+ intel->state.dirty.intel |= I915_NEW_DYNAMIC_INDIRECT;
+ }
+ }
+#else
+ GLuint i;
+ BEGIN_BATCH(size, 0);
+ for (i = 0; i < size; i++)
+ OUT_BATCH(src[i]);
+ ADVANCE_BATCH();
+#endif
+}
+
+
+/***********************************************************************
+ * Modes4: stencil masks and logicop
+ */
+static void upload_MODES4( struct intel_context *intel )
+{
+ GLuint modes4 = 0;
+
+ /* _NEW_STENCIL */
+ if (intel->state.Stencil->Enabled) {
+ GLint testmask = intel->state.Stencil->ValueMask[0] & 0xff;
+ GLint writemask = intel->state.Stencil->WriteMask[0] & 0xff;
+
+ modes4 |= (_3DSTATE_MODES_4_CMD |
+ ENABLE_STENCIL_TEST_MASK |
+ STENCIL_TEST_MASK(testmask) |
+ ENABLE_STENCIL_WRITE_MASK |
+ STENCIL_WRITE_MASK(writemask));
+ }
+
+ /* _NEW_COLOR */
+ if (intel->state.Color->_LogicOpEnabled) {
+ modes4 |= (_3DSTATE_MODES_4_CMD |
+ ENABLE_LOGIC_OP_FUNC |
+ LOGIC_OP_FUNC(intel_translate_logic_op(intel->state.Color->LogicOp)));
+ }
+
+ /* Always, so that we know when state is in-active:
+ */
+ set_dynamic_indirect( intel,
+ I915_DYNAMIC_MODES4,
+ &modes4,
+ 1 );
+}
+
+const struct intel_tracked_state i915_upload_MODES4 = {
+ .dirty = {
+ .mesa = _NEW_COLOR | _NEW_STENCIL,
+ .intel = 0,
+ .extra = 0
+ },
+ .update = upload_MODES4
+};
+
+
+/***********************************************************************
+ */
+
+static void upload_BFO( struct intel_context *intel )
+{
+ GLuint bf[2];
+
+ bf[0] = 0;
+ bf[1] = 0;
+
+
+ /* _NEW_STENCIL
+ */
+ if (intel->state.Stencil->Enabled) {
+ if (intel->state.Stencil->TestTwoSide) {
+ GLint test = intel_translate_compare_func(intel->state.Stencil->Function[1]);
+ GLint fop = intel_translate_stencil_op(intel->state.Stencil->FailFunc[1]);
+ GLint dfop = intel_translate_stencil_op(intel->state.Stencil->ZFailFunc[1]);
+ GLint dpop = intel_translate_stencil_op(intel->state.Stencil->ZPassFunc[1]);
+ GLint ref = intel->state.Stencil->Ref[1] & 0xff;
+ GLint wmask = intel->state.Stencil->WriteMask[1] & 0xff;
+ GLint tmask = intel->state.Stencil->ValueMask[1] & 0xff;
+
+ bf[0] = (_3DSTATE_BACKFACE_STENCIL_OPS |
+ BFO_ENABLE_STENCIL_FUNCS |
+ BFO_ENABLE_STENCIL_TWO_SIDE |
+ BFO_ENABLE_STENCIL_REF |
+ BFO_STENCIL_TWO_SIDE |
+ (ref << BFO_STENCIL_REF_SHIFT) |
+ (test << BFO_STENCIL_TEST_SHIFT) |
+ (fop << BFO_STENCIL_FAIL_SHIFT) |
+ (dfop << BFO_STENCIL_PASS_Z_FAIL_SHIFT) |
+ (dpop << BFO_STENCIL_PASS_Z_PASS_SHIFT));
+
+ bf[1] = (_3DSTATE_BACKFACE_STENCIL_MASKS |
+ BFM_ENABLE_STENCIL_TEST_MASK |
+ BFM_ENABLE_STENCIL_WRITE_MASK |
+ (tmask << BFM_STENCIL_TEST_MASK_SHIFT) |
+ (wmask << BFM_STENCIL_WRITE_MASK_SHIFT));
+ }
+ else {
+ /* This actually disables two-side stencil: The bit set is a
+ * modify-enable bit to indicate we are changing the two-side
+ * setting. Then there is a symbolic zero to show that we are
+ * setting the flag to zero/off.
+ */
+ bf[0] = (_3DSTATE_BACKFACE_STENCIL_OPS |
+ BFO_ENABLE_STENCIL_TWO_SIDE |
+ 0);
+ bf[1] = 0;
+ }
+ }
+
+
+ set_dynamic_indirect( intel,
+ I915_DYNAMIC_BFO_0,
+ &bf[0],
+ 2 );
+}
+
+const struct intel_tracked_state i915_upload_BFO = {
+ .dirty = {
+ .mesa = _NEW_STENCIL,
+ .intel = 0,
+ .extra = 0
+ },
+ .update = upload_BFO
+};
+
+
+/***********************************************************************
+ */
+
+
+static void upload_BLENDCOLOR( struct intel_context *intel )
+{
+ GLuint bc[2];
+
+ /* _NEW_COLOR
+ */
+ if (intel->state.Color->BlendEnabled) {
+ const GLfloat *color = intel->state.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]);
+
+ bc[0] = (_3DSTATE_CONST_BLEND_COLOR_CMD);
+ bc[1] = (a << 24) | (r << 16) | (g << 8) | b;
+
+ }
+ else {
+ bc[0] = 0;
+ bc[1] = 0;
+ }
+
+ set_dynamic_indirect( intel,
+ I915_DYNAMIC_BC_0,
+ bc,
+ 2 );
+}
+
+const struct intel_tracked_state i915_upload_BLENDCOLOR = {
+ .dirty = {
+ .mesa = _NEW_COLOR,
+ .intel = 0,
+ .extra = 0
+ },
+ .update = upload_BLENDCOLOR
+};
+
+/***********************************************************************
+ */
+
+
+static void upload_IAB( struct intel_context *intel )
+{
+ GLuint iab = 0;
+
+ if (intel->state.Color->BlendEnabled) {
+ GLuint eqRGB = intel->state.Color->BlendEquationRGB;
+ GLuint eqA = intel->state.Color->BlendEquationA;
+ GLuint srcRGB = intel->state.Color->BlendSrcRGB;
+ GLuint dstRGB = intel->state.Color->BlendDstRGB;
+ GLuint srcA = intel->state.Color->BlendSrcA;
+ GLuint dstA = intel->state.Color->BlendDstA;
+
+ if (eqA == GL_MIN || eqA == GL_MAX) {
+ srcA = dstA = GL_ONE;
+ }
+
+ if (eqRGB == GL_MIN || eqRGB == GL_MAX) {
+ srcRGB = dstRGB = GL_ONE;
+ }
+
+ if (srcA != srcRGB ||
+ dstA != dstRGB ||
+ eqA != eqRGB) {
+
+ iab = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD |
+ IAB_MODIFY_ENABLE |
+ IAB_ENABLE |
+ IAB_MODIFY_FUNC |
+ IAB_MODIFY_SRC_FACTOR |
+ IAB_MODIFY_DST_FACTOR |
+ SRC_ABLND_FACT(intel_translate_blend_factor(srcA)) |
+ DST_ABLND_FACT(intel_translate_blend_factor(dstA)) |
+ (i915_translate_blend_equation(eqA) << IAB_FUNC_SHIFT));
+ }
+ else {
+ iab = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD |
+ IAB_MODIFY_ENABLE |
+ 0);
+ }
+ }
+
+
+ set_dynamic_indirect( intel,
+ I915_DYNAMIC_IAB,
+ &iab,
+ 1 );
+}
+
+const struct intel_tracked_state i915_upload_IAB = {
+ .dirty = {
+ .mesa = _NEW_COLOR,
+ .intel = 0,
+ .extra = 0
+ },
+ .update = upload_IAB
+};
+
+
+/***********************************************************************
+ */
+
+
+
+static void upload_DEPTHSCALE( struct intel_context *intel )
+{
+ union { GLfloat f; GLuint u; } ds[2];
+
+ ds[0].u = 0;
+ ds[1].u = 0;
+
+ if (intel->state.Polygon->OffsetFill) {
+
+ ds[0].u = (_3DSTATE_DEPTH_OFFSET_SCALE);
+ ds[1].f = 0; /* XXX */
+
+ }
+
+ set_dynamic_indirect( intel,
+ I915_DYNAMIC_DEPTHSCALE_0,
+ &ds[0].u,
+ 2 );
+}
+
+const struct intel_tracked_state i915_upload_DEPTHSCALE = {
+ .dirty = {
+ .mesa = _NEW_POLYGON,
+ .intel = 0,
+ .extra = 0
+ },
+ .update = upload_DEPTHSCALE
+};
+
+/***********************************************************************
+ * Do the group emit in a single packet.
+ */
+
+#define CHECK( idx, nr ) do { \
+ if (i915->dyn_indirect.buf[idx] != 0) { \
+ GLint i; \
+ for (i = 0; i < nr; i++) \
+ buf[count++] = i915->dyn_indirect.buf[idx+i]; \
+ } \
+} while (0)
+
+
+
+static void emit_indirect( struct intel_context *intel )
+{
+ struct i915_context *i915 = i915_context( &intel->ctx );
+ GLuint buf[I915_DYNAMIC_SIZE], count = 0;
+
+ return;
+
+ CHECK( I915_DYNAMIC_MODES4, 1 );
+ CHECK( I915_DYNAMIC_DEPTHSCALE_0, 2 );
+ CHECK( I915_DYNAMIC_IAB, 1 );
+ CHECK( I915_DYNAMIC_BC_0, 2 );
+ CHECK( I915_DYNAMIC_BFO_0, 2 );
+
+ /* XXX: need to check if we wrap 4kb and if so pad.
+ */
+ /* Or just emit the whole lot, zeros and all (fix later...):
+ */
+ /* Also - want to check that something has changed & we're not just
+ * re-emitting the same stuff.
+ */
+ if (count) {
+ GLuint size = I915_DYNAMIC_SIZE * 4;
+ GLuint flag = i915->dyn_indirect.done_reset ? 0 : DIS0_BUFFER_RESET;
+ GLuint segment = SEGMENT_DYNAMIC_INDIRECT;
+ GLuint offset = intel->batch->segment_finish_offset[segment];
+
+ i915->dyn_indirect.done_reset = 1;
+
+ BEGIN_BATCH(2,0);
+ OUT_BATCH( _3DSTATE_LOAD_INDIRECT | LI0_STATE_DYNAMIC_INDIRECT | (1<<14) | 0);
+ OUT_RELOC( intel->batch->buffer,
+ DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE,
+ DRM_BO_MASK_MEM | DRM_BO_FLAG_EXE,
+ ((offset + size - 4) | DIS0_BUFFER_VALID | flag) );
+ ADVANCE_BATCH();
+
+ /* XXX:
+ */
+ assert( offset + size < intel->batch->segment_max_offset[segment]);
+ intel->batch->segment_finish_offset[segment] += size;
+
+ /* Just emit the original buffer, zeros and all as this will
+ * avoid wrapping issues. This is usually not emitted at all,
+ * so not urgent to fix:
+ */
+ memcpy(intel->batch->map + offset, i915->dyn_indirect.buf, size );
+ }
+}
+
+const struct intel_tracked_state i915_upload_dynamic_indirect = {
+ .dirty = {
+ .mesa = 0,
+ .intel = I915_NEW_DYNAMIC_INDIRECT,
+ .extra = 0
+ },
+ .update = emit_indirect
+};
+
+
+
diff --git a/src/mesa/drivers/dri/i915tex/i915_state_fallback.c b/src/mesa/drivers/dri/i915tex/i915_state_fallback.c
index c327e19c44..a559037916 100644
--- a/src/mesa/drivers/dri/i915tex/i915_state_fallback.c
+++ b/src/mesa/drivers/dri/i915tex/i915_state_fallback.c
@@ -1,29 +1,30 @@
-/*
- 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.
-
- **********************************************************************/
+/**************************************************************************
+ *
+ * Copyright 2007 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.
+ *
+ **************************************************************************/
+
/*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
diff --git a/src/mesa/drivers/dri/i915tex/i915_state_immediate.c b/src/mesa/drivers/dri/i915tex/i915_state_immediate.c
index e08748ad96..495f8fe903 100644
--- a/src/mesa/drivers/dri/i915tex/i915_state_immediate.c
+++ b/src/mesa/drivers/dri/i915tex/i915_state_immediate.c
@@ -38,10 +38,15 @@
#include "i915_context.h"
#include "i915_state.h"
-#include "i915_state_inlines.h"
#include "i915_reg.h"
+/* All state expressable with the LOAD_STATE_IMMEDIATE_1 packet.
+ * Would like to opportunistically recombine all these fragments into
+ * a single packet containing only what has changed, but for now emit
+ * as multiple packets.
+ */
+
#define STATE_LOGICOP_ENABLED(state) \
((state)->Color->ColorLogicOpEnabled || \
((state)->Color->BlendEnabled && (state)->Color->BlendEquationRGB == GL_LOGIC_OP))
@@ -99,8 +104,8 @@ static void upload_S2S4(struct intel_context *intel)
GLuint LIS2, LIS4;
/* I915_NEW_VERTEX_FORMAT */
- LIS2 = i915->fragprog.LIS2;
- LIS4 = i915->fragprog.LIS4;
+ LIS2 = i915->vertex_format.LIS2;
+ LIS4 = i915->vertex_format.LIS4;
/* _NEW_POLYGON, _NEW_BUFFERS */
@@ -216,6 +221,12 @@ static void upload_S5( struct intel_context *intel )
LIS5 |= S5_COLOR_DITHER_ENABLE;
}
+ /* _NEW_POLYGON */
+ if (intel->state.Polygon->OffsetFill) {
+ LIS5 |= S5_GLOBAL_DEPTH_OFFSET_ENABLE;
+ }
+
+
{
const GLubyte *mask = intel->state.Color->ColorMask;
@@ -326,3 +337,32 @@ const struct intel_tracked_state i915_upload_S6 = {
.update = upload_S6
};
+
+/***********************************************************************
+ */
+static void upload_S7( struct intel_context *intel )
+{
+ GLfloat LIS7;
+
+ /* _NEW_POLYGON
+ */
+/* LIS7 = intel->state.Polygon->OffsetUnits * DEPTH_SCALE; */
+ LIS7 = 0;
+
+ BEGIN_BATCH(2, 0);
+ OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
+ I1_LOAD_S(7) |
+ 0);
+ OUT_BATCH_F(LIS7);
+ ADVANCE_BATCH();
+
+}
+
+const struct intel_tracked_state i915_upload_S7 = {
+ .dirty = {
+ .mesa = (_NEW_POLYGON),
+ .intel = 0,
+ .extra = 0
+ },
+ .update = upload_S7
+};
diff --git a/src/mesa/drivers/dri/i915tex/i915_state_invarient.c b/src/mesa/drivers/dri/i915tex/i915_state_invarient.c
deleted file mode 100644
index ecca70aad0..0000000000
--- a/src/mesa/drivers/dri/i915tex/i915_state_invarient.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/**************************************************************************
- *
- * 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 "program.h"
-
-#include "intel_batchbuffer.h"
-#include "i915_context.h"
-#include "i915_reg.h"
-
-
-
-
-/***********************************************************************
- * Misc invarient state packets
- */
-
-static void upload_invarient_state( struct intel_context *intel )
-{
- 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) |
- (0)),
- (0),
-
- (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT),
- (_3DSTATE_SCISSOR_RECT_0_CMD),
- (0),
- (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),
-
- (_3DSTATE_BACKFACE_STENCIL_OPS | BFO_ENABLE_STENCIL_TWO_SIDE | 0)
- };
-
- /* Disable indirect state for now.
- */
- BEGIN_BATCH(2, 0);
- OUT_BATCH(_3DSTATE_LOAD_INDIRECT | 0);
- OUT_BATCH(0);
- ADVANCE_BATCH();
-
-
- {
- GLuint i;
-
- 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 intel_tracked_state i915_invarient_state = {
- .dirty = {
- .mesa = 0,
- .intel = INTEL_NEW_CONTEXT, /* or less frequently? */
- .extra = 0
- },
- .update = upload_invarient_state
-};
-
-
-
diff --git a/src/mesa/drivers/dri/i915tex/i915_state_map.c b/src/mesa/drivers/dri/i915tex/i915_state_map.c
index ea01c54777..5f2f727374 100644
--- a/src/mesa/drivers/dri/i915tex/i915_state_map.c
+++ b/src/mesa/drivers/dri/i915tex/i915_state_map.c
@@ -36,6 +36,7 @@
#include "i915_context.h"
#include "i915_reg.h"
+#include "i915_cache.h"
static GLuint
@@ -141,33 +142,30 @@ upload_maps( struct intel_context *intel )
}
if (nr) {
- BEGIN_BATCH(2 + nr * 3, 0);
- OUT_BATCH(_3DSTATE_MAP_STATE | (3 * nr));
- OUT_BATCH(dirty);
+ struct i915_cache_packet packet;
+
+ packet_init( &packet, I915_CACHE_MAP, nr * 3 + 2, 0 );
+ packet_dword( &packet, _3DSTATE_MAP_STATE | (3 * nr));
+ packet_dword( &packet, dirty);
for (i = 0; i < I915_TEX_UNITS; i++) {
if (dirty & (1<<i)) {
- if (i915->state.tex_buffer[i]) {
- OUT_RELOC(i915->state.tex_buffer[i],
- DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
- DRM_BO_MASK_MEM | DRM_BO_FLAG_READ,
- i915->state.tex_offset[i]);
- }
- else {
- assert(i == 0);
- assert(intel->metaops.active); /* when does this happen? */
- OUT_BATCH(0);
- }
-
- OUT_BATCH(state[i][0]);
- OUT_BATCH(state[i][1]);
+ assert (i915->state.tex_buffer[i]);
+
+ packet_reloc( &packet,
+ i915->state.tex_buffer[i],
+ DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
+ DRM_BO_MASK_MEM | DRM_BO_FLAG_READ,
+ i915->state.tex_offset[i] );
+
+ packet_dword( &packet, state[i][0] );
+ packet_dword( &packet, state[i][1] );
}
}
- ADVANCE_BATCH();
- }
-/* return GL_TRUE; */
+ i915_cache_emit( i915->cctx, &packet );
+ }
}
diff --git a/src/mesa/drivers/dri/i915tex/i915_state_misc.c b/src/mesa/drivers/dri/i915tex/i915_state_misc.c
deleted file mode 100644
index 1c97d4d975..0000000000
--- a/src/mesa/drivers/dri/i915tex/i915_state_misc.c
+++ /dev/null
@@ -1,448 +0,0 @@
-/**************************************************************************
- *
- * 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 "intel_fbo.h"
-#include "intel_batchbuffer.h"
-#include "intel_regions.h"
-#include "intel_state_inlines.h"
-
-#include "i915_context.h"
-#include "i915_reg.h"
-#include "i915_state.h"
-#include "i915_state_inlines.h"
-
-#define FILE_DEBUG_FLAG DEBUG_STATE
-
-/***********************************************************************
- * Modes4: stencil masks and logicop
- */
-static void upload_MODES4( struct intel_context *intel )
-{
- GLuint modes4 = _3DSTATE_MODES_4_CMD;
-
- /* _NEW_STENCIL */
- if (1||intel->state.Stencil->Enabled) {
- GLint testmask = intel->state.Stencil->ValueMask[0] & 0xff;
- GLint writemask = intel->state.Stencil->WriteMask[0] & 0xff;
-
- modes4 |= (ENABLE_STENCIL_TEST_MASK |
- STENCIL_TEST_MASK(testmask) |
- ENABLE_STENCIL_WRITE_MASK |
- STENCIL_WRITE_MASK(writemask));
- }
-
- /* _NEW_COLOR */
- if (1 || intel->state.Color->_LogicOpEnabled)
- {
- modes4 |= (ENABLE_LOGIC_OP_FUNC |
- LOGIC_OP_FUNC(intel_translate_logic_op(intel->state.Color->LogicOp)));
- }
- 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.
- */
- modes4 |= (ENABLE_LOGIC_OP_FUNC |
- LOGICOP_COPY);
- }
-
- /* This needs to be sent in all states (subject eventually to
- * caching to avoid duplicate emits, and later to indirect state
- * management)
- */
- BEGIN_BATCH(1,0);
- OUT_BATCH(modes4);
- ADVANCE_BATCH();
-}
-
-const struct intel_tracked_state i915_upload_MODES4 = {
- .dirty = {
- .mesa = _NEW_STENCIL | _NEW_COLOR,
- .intel = 0,
- .extra = 0
- },
- .update = upload_MODES4
-};
-
-
-/***********************************************************************
- * BFO: Backface stencil
- */
-
-static void upload_BFO( struct intel_context *intel )
-{
- GLuint bfo;
-
- /* _NEW_STENCIL
- */
- if (intel->state.Stencil->Enabled) {
- GLint test = intel_translate_compare_func(intel->state.Stencil->Function[1]);
- GLint fop = intel_translate_stencil_op(intel->state.Stencil->FailFunc[1]);
- GLint dfop = intel_translate_stencil_op(intel->state.Stencil->ZFailFunc[1]);
- GLint dpop = intel_translate_stencil_op(intel->state.Stencil->ZPassFunc[1]);
- GLint ref = intel->state.Stencil->Ref[1] & 0xff;
-
- bfo = (_3DSTATE_BACKFACE_STENCIL_OPS |
- BFO_ENABLE_STENCIL_FUNCS |
- BFO_ENABLE_STENCIL_TWO_SIDE |
- BFO_ENABLE_STENCIL_REF |
- BFO_STENCIL_TWO_SIDE |
- (ref << BFO_STENCIL_REF_SHIFT) |
- (test << BFO_STENCIL_TEST_SHIFT) |
- (fop << BFO_STENCIL_FAIL_SHIFT) |
- (dfop << BFO_STENCIL_PASS_Z_FAIL_SHIFT) |
- (dpop << BFO_STENCIL_PASS_Z_PASS_SHIFT));
- }
- 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.
- */
- bfo = (_3DSTATE_BACKFACE_STENCIL_OPS |
- BFO_ENABLE_STENCIL_TWO_SIDE |
- 0);
- }
-
- BEGIN_BATCH(1,0);
- OUT_BATCH(bfo);
- ADVANCE_BATCH();
-}
-
-const struct intel_tracked_state i915_upload_BFO = {
- .dirty = {
- .mesa = _NEW_STENCIL,
- .intel = 0,
- .extra = 0
- },
- .update = upload_BFO
-};
-
-
-/***********************************************************************
- * BLENDCOLOR
- */
-static void upload_BLENDCOLOR( struct intel_context *intel )
-{
- /* _NEW_COLOR
- */
- if (1 || intel->state.Color->BlendEnabled) {
- const GLfloat *color = intel->state.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]);
-
- /* Only needs to be sent when blend is enabled
- */
- BEGIN_BATCH(2, 0);
- OUT_BATCH(_3DSTATE_CONST_BLEND_COLOR_CMD);
- OUT_BATCH( (a << 24) | (r << 16) | (g << 8) | b );
- ADVANCE_BATCH();
- }
-}
-
-const struct intel_tracked_state i915_upload_BLENDCOLOR = {
- .dirty = {
- .mesa = _NEW_COLOR,
- .intel = 0,
- .extra = 0
- },
- .update = upload_BLENDCOLOR
-};
-
-
-/***********************************************************************
- * IAB: Independent Alpha Blend
- */
-static void upload_IAB( struct intel_context *intel )
-{
- GLuint iab = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD |
- IAB_MODIFY_ENABLE |
- 0);
-
- if (1) {
- GLuint eqRGB = intel->state.Color->BlendEquationRGB;
- GLuint eqA = intel->state.Color->BlendEquationA;
- GLuint srcRGB = intel->state.Color->BlendSrcRGB;
- GLuint dstRGB = intel->state.Color->BlendDstRGB;
- GLuint srcA = intel->state.Color->BlendSrcA;
- GLuint dstA = intel->state.Color->BlendDstA;
-
- iab |= (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)) |
- (i915_translate_blend_equation(eqA) << IAB_FUNC_SHIFT));
-
- if (srcA != srcRGB ||
- dstA != dstRGB ||
- eqA != eqRGB) {
-
-#if 0
- /* later */
- if (eqA == GL_MIN || eqA == GL_MAX) {
- srcA = dstA = GL_ONE;
- }
-#endif
-
-
- if (intel->state.Color->BlendEnabled)
- iab |= IAB_ENABLE;
- }
- }
-
- BEGIN_BATCH(1, 0);
- OUT_BATCH( iab );
- ADVANCE_BATCH();
-}
-
-const struct intel_tracked_state i915_upload_IAB = {
- .dirty = {
- .mesa = _NEW_COLOR,
- .intel = 0,
- .extra = 0
- },
- .update = upload_IAB
-};
-
-
-/***********************************************************************
- * Depthbuffer - currently constant, but rotation would change that.
- */
-
-
-static void upload_buffers(struct intel_context *intel)
-{
- struct intel_region *color_region = intel->state.draw_region;
- struct intel_region *depth_region = intel->state.depth_region;
-
- 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(intel->state.draw_region->buffer,
- DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
- DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE,
- intel->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(intel->state.depth_region->buffer,
- DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
- DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE,
- intel->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 intel_tracked_state i915_upload_buffers = {
- .dirty = {
- .mesa = 0,
- .intel = INTEL_NEW_CBUF | INTEL_NEW_ZBUF | INTEL_NEW_FENCE,
- .extra = 0
- },
- .update = upload_buffers
-};
-
-
-
-/***********************************************************************
- * Polygon stipple
- *
- * The i915 supports a 4x4 stipple natively, GL wants 32x32.
- * Fortunately stipple is usually a repeating pattern.
- *
- * XXX: does stipple pattern need to be adjusted according to
- * the window position?
- *
- * XXX: possibly need workaround for conform paths test.
- */
-
-static void upload_stipple( struct intel_context *intel )
-{
- GLuint st0 = _3DSTATE_STIPPLE;
- GLuint st1 = 0;
-
- GLboolean hw_stipple_fallback = 0;
-
- /* _NEW_POLYGON, INTEL_NEW_REDUCED_PRIMITIVE
- */
- if (intel->state.Polygon->StippleFlag &&
- intel->reduced_primitive == GL_TRIANGLES) {
-
- /* _NEW_POLYGONSTIPPLE
- */
- const GLubyte *mask = (const GLubyte *)intel->state.PolygonStipple;
- GLubyte p[4];
- GLint i, j, k;
-
- 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;
-
- st1 |= ST1_ENABLE;
-
- for (k = 0; k < 8; k++) {
- for (j = 3; j >= 0; j--) {
- for (i = 0; i < 4; i++, mask++) {
- if (*mask != p[j]) {
- hw_stipple_fallback = 1;
- st1 &= ~ST1_ENABLE;
- }
- }
- }
- }
-
- st1 |= (((p[0] & 0xf) << 0) |
- ((p[1] & 0xf) << 4) |
- ((p[2] & 0xf) << 8) |
- ((p[3] & 0xf) << 12));
- }
-
- assert(!hw_stipple_fallback); /* TODO */
-
- BEGIN_BATCH(2, 0);
- OUT_BATCH(st0);
- OUT_BATCH(st1);
- ADVANCE_BATCH();
-}
-
-
-const struct intel_tracked_state i915_upload_stipple = {
- .dirty = {
- .mesa = _NEW_POLYGONSTIPPLE, _NEW_POLYGON,
- .intel = INTEL_NEW_REDUCED_PRIMITIVE,
- .extra = 0
- },
- .update = upload_stipple
-};
-
-
-
-/***********************************************************************
- * Scissor.
- */
-
-static void upload_scissor( struct intel_context *intel )
-{
- /* _NEW_SCISSOR, _NEW_BUFFERS
- */
- if (intel->state.Scissor->Enabled &&
- intel->state.DrawBuffer) {
-
- GLint x = intel->state.Scissor->X;
- GLint y = intel->state.Scissor->Y;
- GLint w = intel->state.Scissor->Width;
- GLint h = intel->state.Scissor->Height;
-
- GLint x1, y1, x2, y2;
-
- if (intel->state.DrawBuffer->Name == 0) {
- x1 = x;
- y1 = intel->state.DrawBuffer->Height - (y + h);
- x2 = x + w - 1;
- y2 = y1 + h - 1;
- }
- else {
- /* FBO - not inverted
- */
- x1 = x;
- y1 = y;
- x2 = x + w - 1;
- y2 = y + h - 1;
- }
-
- x1 = CLAMP(x1, 0, intel->state.DrawBuffer->Width - 1);
- y1 = CLAMP(y1, 0, intel->state.DrawBuffer->Height - 1);
- x2 = CLAMP(x2, 0, intel->state.DrawBuffer->Width - 1);
- y2 = CLAMP(y2, 0, intel->state.DrawBuffer->Height - 1);
-
- BEGIN_BATCH(4, 0);
- OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT);
- OUT_BATCH(_3DSTATE_SCISSOR_RECT_0_CMD);
- OUT_BATCH((y1 << 16) | (x1 & 0xffff));
- OUT_BATCH((y2 << 16) | (x2 & 0xffff));
- ADVANCE_BATCH();
- }
- else {
- BEGIN_BATCH(1, 0);
- OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT);
- ADVANCE_BATCH();
- }
-}
-
-const struct intel_tracked_state i915_upload_scissor = {
- .dirty = {
- .mesa = _NEW_SCISSOR | _NEW_BUFFERS,
- .intel = 0,
- .extra = 0
- },
- .update = upload_scissor
-};
-
diff --git a/src/mesa/drivers/dri/i915tex/i915_state_program.c b/src/mesa/drivers/dri/i915tex/i915_state_program.c
new file mode 100644
index 0000000000..17ac40c3c5
--- /dev/null
+++ b/src/mesa/drivers/dri/i915tex/i915_state_program.c
@@ -0,0 +1,96 @@
+/**************************************************************************
+ *
+ * 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 "program.h"
+
+#include "i915_context.h"
+#include "i915_fpc.h"
+#include "i915_cache.h"
+
+
+
+
+
+/*********************************************************************************
+ * Program instructions (and decls)
+ */
+
+
+static void upload_program( struct intel_context *intel )
+{
+ struct i915_context *i915 = i915_context( &intel->ctx );
+ struct i915_fragment_program *fp = i915->fragment_program;
+ GLuint i;
+
+ if (&fp->Base != intel->state.FragmentProgram->_Current) {
+ i915->fragment_program = (struct i915_fragment_program *)
+ intel->state.FragmentProgram->_Current;
+
+ fp = i915->fragment_program;
+ /* This is stupid
+ */
+ intel->state.dirty.intel |= INTEL_NEW_FRAGMENT_PROGRAM;
+ }
+
+ /* As the compiled program depends only on the original program
+ * text, just store the compiled version in the fragment program
+ * struct.
+ */
+ if (!fp->translated) {
+ i915_compile_fragment_program(i915, fp);
+ }
+
+ /* This is an unnnecessary copy - fix the interface...
+ */
+ {
+ struct i915_cache_packet packet;
+
+ packet_init( &packet, I915_CACHE_PROGRAM, fp->program_size, 0 );
+
+ for (i = 0; i < fp->program_size; i++)
+ packet_dword( &packet, fp->program[i] );
+
+ i915_cache_emit( i915->cctx, &packet );
+ }
+}
+
+
+/* See i915_wm.c:
+ */
+const struct intel_tracked_state i915_upload_program = {
+ .dirty = {
+ .mesa = (0),
+ .intel = (INTEL_NEW_FRAGMENT_PROGRAM), /* ?? Is this all ?? */
+ .extra = 0
+ },
+ .update = upload_program
+};
+
+
diff --git a/src/mesa/drivers/dri/i915tex/i915_state_sampler.c b/src/mesa/drivers/dri/i915tex/i915_state_sampler.c
index 5eba939e46..539fe77903 100644
--- a/src/mesa/drivers/dri/i915tex/i915_state_sampler.c
+++ b/src/mesa/drivers/dri/i915tex/i915_state_sampler.c
@@ -33,11 +33,11 @@
#include "intel_mipmap_tree.h"
#include "intel_tex.h"
-#include "intel_batchbuffer.h"
#include "intel_state_inlines.h"
#include "i915_context.h"
#include "i915_reg.h"
+#include "i915_cache.h"
@@ -221,6 +221,7 @@ static void update_sampler(struct intel_context *intel,
static void upload_samplers( struct intel_context *intel )
{
+ struct i915_context *i915 = i915_context( &intel->ctx );
GLint i, dirty = 0, nr = 0;
GLuint state[I915_TEX_UNITS][3];
@@ -233,17 +234,21 @@ static void upload_samplers( struct intel_context *intel )
}
if (nr) {
- BEGIN_BATCH(2 + nr * 3, 0);
- OUT_BATCH(_3DSTATE_SAMPLER_STATE | (3 * nr));
- OUT_BATCH(dirty);
+ struct i915_cache_packet packet;
+
+ packet_init( &packet, I915_CACHE_SAMPLER, 2 + nr * 3, 0 );
+ packet_dword( &packet, _3DSTATE_SAMPLER_STATE | (3 * nr) );
+ packet_dword( &packet, dirty );
+
for (i = 0; i < I915_TEX_UNITS; i++) {
if (intel->state.Texture->Unit[i]._ReallyEnabled) {
- OUT_BATCH(state[i][0]);
- OUT_BATCH(state[i][1]);
- OUT_BATCH(state[i][2]);
+ packet_dword( &packet, state[i][0] );
+ packet_dword( &packet, state[i][1] );
+ packet_dword( &packet, state[i][2] );
}
}
- ADVANCE_BATCH();
+
+ i915_cache_emit( i915->cctx, &packet );
}
}
diff --git a/src/mesa/drivers/dri/i915tex/i915_state_static.c b/src/mesa/drivers/dri/i915tex/i915_state_static.c
new file mode 100644
index 0000000000..ebbcfd7b8b
--- /dev/null
+++ b/src/mesa/drivers/dri/i915tex/i915_state_static.c
@@ -0,0 +1,393 @@
+/**************************************************************************
+ *
+ * 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 "intel_fbo.h"
+#include "intel_regions.h"
+#include "intel_state_inlines.h"
+
+#include "i915_context.h"
+#include "i915_reg.h"
+#include "i915_state.h"
+#include "i915_cache.h"
+
+#define FILE_DEBUG_FLAG DEBUG_STATE
+
+/* State that we have chosen to store in the STATIC segment of the
+ * i915 indirect state mechanism.
+ *
+ * There is a lot of flexibility for breaking state up between dynamic
+ * & static buckets of the indirect mechanism.
+ *
+ * At a hardware level they are treated slightly differently, dynamic
+ * state supports an incremental update model, whereas static is
+ * better suited to usage where the same set of packets are present
+ * every static state emit. This isn't enforced though, and in normal
+ * operations there is nothing preventing arbitary usage of either
+ * bucket.
+ */
+
+
+/***********************************************************************
+ * Depthbuffer - currently constant, but rotation would change that.
+ */
+
+
+static void upload_buffers(struct intel_context *intel)
+{
+ struct i915_context *i915 = i915_context( &intel->ctx );
+ struct intel_region *color_region = intel->state.draw_region;
+ struct intel_region *depth_region = intel->state.depth_region;
+
+ GLuint dwords = ((color_region ? 3 : 0) +
+ (depth_region ? 3 : 0) +
+ 2);
+
+ GLuint relocs = ((color_region ? 1 : 0) +
+ (depth_region ? 1 : 0));
+
+ struct i915_cache_packet packet;
+
+ packet_init( &packet, I915_CACHE_BUFFERS, dwords, relocs );
+
+ if (color_region) {
+ packet_dword( &packet, _3DSTATE_BUF_INFO_CMD );
+ packet_dword( &packet, BUF_3D_ID_COLOR_BACK |
+ BUF_3D_PITCH(color_region->pitch * color_region->cpp) |
+ BUF_3D_USE_FENCE);
+
+ packet_reloc( &packet, color_region->buffer,
+ DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
+ DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE,
+ color_region->draw_offset);
+ }
+
+ if (depth_region) {
+ packet_dword( &packet, _3DSTATE_BUF_INFO_CMD );
+ packet_dword( &packet, BUF_3D_ID_DEPTH |
+ BUF_3D_PITCH(depth_region->pitch * depth_region->cpp) |
+ BUF_3D_USE_FENCE );
+ packet_reloc( &packet, depth_region->buffer,
+ DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
+ DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE,
+ depth_region->draw_offset);
+ }
+
+
+ packet_dword( &packet,_3DSTATE_DST_BUF_VARS_CMD);
+ packet_dword( &packet, 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) );
+
+ i915_cache_emit( i915->cctx, &packet );
+}
+
+const struct intel_tracked_state i915_upload_buffers = {
+ .dirty = {
+ .mesa = 0,
+ .intel = INTEL_NEW_CBUF | INTEL_NEW_ZBUF | INTEL_NEW_FENCE,
+ .extra = 0
+ },
+ .update = upload_buffers
+};
+
+
+
+/***********************************************************************
+ * Polygon stipple
+ *
+ * The i915 supports a 4x4 stipple natively, GL wants 32x32.
+ * Fortunately stipple is usually a repeating pattern.
+ *
+ * XXX: does stipple pattern need to be adjusted according to
+ * the window position?
+ *
+ * XXX: possibly need workaround for conform paths test.
+ */
+
+static void upload_stipple( struct intel_context *intel )
+{
+ struct i915_context *i915 = i915_context( &intel->ctx );
+ GLuint st0 = _3DSTATE_STIPPLE;
+ GLuint st1 = 0;
+
+ GLboolean hw_stipple_fallback = 0;
+
+ /* _NEW_POLYGON, INTEL_NEW_REDUCED_PRIMITIVE
+ */
+ if (intel->state.Polygon->StippleFlag &&
+ intel->reduced_primitive == GL_TRIANGLES) {
+
+ /* _NEW_POLYGONSTIPPLE
+ */
+ const GLubyte *mask = (const GLubyte *)intel->state.PolygonStipple;
+ GLubyte p[4];
+ GLint i, j, k;
+
+ 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;
+
+ st1 |= ST1_ENABLE;
+
+ for (k = 0; k < 8; k++) {
+ for (j = 3; j >= 0; j--) {
+ for (i = 0; i < 4; i++, mask++) {
+ if (*mask != p[j]) {
+ hw_stipple_fallback = 1;
+ st1 &= ~ST1_ENABLE;
+ }
+ }
+ }
+ }
+
+ st1 |= (((p[0] & 0xf) << 0) |
+ ((p[1] & 0xf) << 4) |
+ ((p[2] & 0xf) << 8) |
+ ((p[3] & 0xf) << 12));
+ }
+
+ assert(!hw_stipple_fallback); /* TODO */
+
+ {
+ struct i915_cache_packet packet;
+
+ packet_init( &packet, I915_CACHE_STIPPLE, 2, 0 );
+ packet_dword( &packet,st0);
+ packet_dword( &packet,st1);
+ i915_cache_emit( i915->cctx, &packet );
+ }
+}
+
+
+const struct intel_tracked_state i915_upload_stipple = {
+ .dirty = {
+ .mesa = _NEW_POLYGONSTIPPLE, _NEW_POLYGON,
+ .intel = INTEL_NEW_REDUCED_PRIMITIVE,
+ .extra = 0
+ },
+ .update = upload_stipple
+};
+
+
+
+/***********************************************************************
+ * Scissor.
+ */
+
+static void upload_scissor( struct intel_context *intel )
+{
+ struct i915_context *i915 = i915_context( &intel->ctx );
+ struct i915_cache_packet packet;
+
+ /* _NEW_SCISSOR, _NEW_BUFFERS
+ */
+ if (intel->state.Scissor->Enabled &&
+ intel->state.DrawBuffer) {
+
+ GLint x = intel->state.Scissor->X;
+ GLint y = intel->state.Scissor->Y;
+ GLint w = intel->state.Scissor->Width;
+ GLint h = intel->state.Scissor->Height;
+
+ GLint x1, y1, x2, y2;
+
+ if (intel->state.DrawBuffer->Name == 0) {
+ x1 = x;
+ y1 = intel->state.DrawBuffer->Height - (y + h);
+ x2 = x + w - 1;
+ y2 = y1 + h - 1;
+ }
+ else {
+ /* FBO - not inverted
+ */
+ x1 = x;
+ y1 = y;
+ x2 = x + w - 1;
+ y2 = y + h - 1;
+ }
+
+ x1 = CLAMP(x1, 0, intel->state.DrawBuffer->Width - 1);
+ y1 = CLAMP(y1, 0, intel->state.DrawBuffer->Height - 1);
+ x2 = CLAMP(x2, 0, intel->state.DrawBuffer->Width - 1);
+ y2 = CLAMP(y2, 0, intel->state.DrawBuffer->Height - 1);
+
+ packet_init( &packet, I915_CACHE_SCISSOR, 4, 0 );
+ packet_dword( &packet,_3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT);
+ packet_dword( &packet,_3DSTATE_SCISSOR_RECT_0_CMD);
+ packet_dword( &packet,(y1 << 16) | (x1 & 0xffff));
+ packet_dword( &packet,(y2 << 16) | (x2 & 0xffff));
+ i915_cache_emit( i915->cctx, &packet );
+ }
+ else {
+ packet_init( &packet, I915_CACHE_SCISSOR, 1, 0 );
+ packet_dword( &packet,_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT);
+ i915_cache_emit( i915->cctx, &packet );
+ }
+}
+
+const struct intel_tracked_state i915_upload_scissor = {
+ .dirty = {
+ .mesa = _NEW_SCISSOR | _NEW_BUFFERS,
+ .intel = 0,
+ .extra = 0
+ },
+ .update = upload_scissor
+};
+
+
+
+
+
+
+/***********************************************************************
+ * Misc invarient state packets
+ */
+
+static void upload_invarient( struct intel_context *intel )
+{
+ struct i915_context *i915 = i915_context( &intel->ctx );
+ GLuint i;
+
+ 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) |
+ (0)),
+ (0),
+
+ (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT),
+ (_3DSTATE_SCISSOR_RECT_0_CMD),
+ (0),
+ (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),
+
+ (_3DSTATE_BACKFACE_STENCIL_OPS | BFO_ENABLE_STENCIL_TWO_SIDE | 0)
+ };
+
+ /* Disable indirect state for now.
+ */
+#if 0
+ BEGIN_BATCH(2, 0);
+ OUT_BATCH(_3DSTATE_LOAD_INDIRECT | 0);
+ OUT_BATCH(0);
+ ADVANCE_BATCH();
+#endif
+
+ /* Will be nice if this can be preserved over several frames. I
+ * guess logical contexts would do much the same thing.
+ */
+ {
+ struct i915_cache_packet packet;
+
+ packet_init( &packet, I915_CACHE_INVARIENT, sizeof(invarient_state)/4, 0);
+ for (i = 0; i < sizeof(invarient_state)/4; i++)
+ packet_dword( &packet, invarient_state[i] );
+
+ i915_cache_emit( i915->cctx, &packet );
+ }
+}
+
+const struct intel_tracked_state i915_upload_invarient = {
+ .dirty = {
+ .mesa = 0,
+ .intel = INTEL_NEW_CONTEXT, /* or less frequently? */
+ .extra = 0
+ },
+ .update = upload_invarient
+};
+
+
+
diff --git a/src/mesa/drivers/dri/i915tex/i915_state_fp_inputs.c b/src/mesa/drivers/dri/i915tex/i915_state_vertex.c
index 8bbdc0f29a..0cd0e69237 100644
--- a/src/mesa/drivers/dri/i915tex/i915_state_fp_inputs.c
+++ b/src/mesa/drivers/dri/i915tex/i915_state_vertex.c
@@ -173,8 +173,8 @@ static void i915_calculate_vertex_format( struct intel_context *intel )
}
}
- if (s2 != i915->fragprog.LIS2 ||
- s4 != i915->fragprog.LIS4) {
+ if (s2 != i915->vertex_format.LIS2 ||
+ s4 != i915->vertex_format.LIS4) {
GLuint vs = _tnl_install_attrs(&intel->ctx,
intel->vertex_attrs,
@@ -186,8 +186,8 @@ static void i915_calculate_vertex_format( struct intel_context *intel )
_mesa_printf("inputs %x vertex size %d\n",
inputsRead,
intel->vertex_size);
- i915->fragprog.LIS2 = s2;
- i915->fragprog.LIS4 = s4;
+ i915->vertex_format.LIS2 = s2;
+ i915->vertex_format.LIS4 = s4;
intel->state.dirty.intel |= I915_NEW_VERTEX_FORMAT;
}
}
diff --git a/src/mesa/drivers/dri/i915tex/i915_vtbl.c b/src/mesa/drivers/dri/i915tex/i915_vtbl.c
index 14b9c50ace..0e0f926a31 100644
--- a/src/mesa/drivers/dri/i915tex/i915_vtbl.c
+++ b/src/mesa/drivers/dri/i915tex/i915_vtbl.c
@@ -42,228 +42,35 @@
#include "i915_reg.h"
#include "i915_context.h"
+#include "i915_cache.h"
-#if 0
-
-
-
-#define OUT(x) do { \
- if (0) _mesa_printf("OUT(0x%08x)\n", x); \
- *p++ = (x); \
-} while(0)
-
-/* Push the state into the sarea and/or texture memory.
- */
-static void
-i915_emit_state(struct intel_context *intel)
+static void i915_destroy_context(struct intel_context *intel)
{
- struct i915_context *i915 = i915_context(&intel->ctx);
- struct i915_hw_state *state = i915->current;
- 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, 0,
- 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);
-
- /* This should not change during a scene for HWZ, correct?
- *
- * If it does change, we probably have to flush everything and
- * restart.
- */
- if (dirty & (I915_UPLOAD_INVARIENT | I915_UPLOAD_BUFFERS)) {
- if (INTEL_DEBUG & DEBUG_STATE)
- fprintf(stderr, "I915_UPLOAD_INVARIENT:\n");
-
- i915_emit_invarient_state(intel);
-
- if (INTEL_DEBUG & DEBUG_STATE)
- fprintf(stderr, "I915_UPLOAD_BUFFERS:\n");
-
- /* Does this go in dynamic indirect state, or static indirect
- * state???
- */
- BEGIN_BATCH(3, 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);
- ADVANCE_BATCH();
-
- if (state->depth_region) {
- BEGIN_BATCH(3, 0);
- 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);
- ADVANCE_BATCH();
- }
-
- BEGIN_BATCH(2, 0);
- OUT_BATCH(state->Buffer[I915_DESTREG_DV0]);
- OUT_BATCH(state->Buffer[I915_DESTREG_DV1]);
- ADVANCE_BATCH();
-
-#if 0
- /* Where does scissor go?
- */
- 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]);
-#endif
- }
-
- if (dirty & I915_UPLOAD_CTX) {
- if (INTEL_DEBUG & DEBUG_STATE)
- fprintf(stderr, "I915_UPLOAD_CTX:\n");
-
- /* Immediate state: always goes in the batchbuffer.
- */
- BEGIN_BATCH(5, 0);
- OUT_BATCH(state->Ctx[I915_CTXREG_LI]);
- OUT_BATCH(state->Ctx[I915_CTXREG_LIS2]);
- OUT_BATCH(state->Ctx[I915_CTXREG_LIS4]);
- OUT_BATCH(state->Ctx[I915_CTXREG_LIS5]);
- OUT_BATCH(state->Ctx[I915_CTXREG_LIS6]);
- ADVANCE_BATCH();
-
- emit_indirect(intel,
- LI0_STATE_DYNAMIC_INDIRECT,
- state->Ctx + I915_CTXREG_STATE4,
- 4 * sizeof(GLuint) );
- }
-
-
- /* Combine all the dirty texture state into a single command to
- * avoid lockups on I915 hardware.
- */
- if (dirty & I915_UPLOAD_TEX_ALL) {
- GLuint offset;
- GLuint *p;
- int i, nr = 0;
-
- for (i = 0; i < I915_TEX_UNITS; i++)
- if (dirty & I915_UPLOAD_TEX(i))
- nr++;
-
- /* A bit of a nasty kludge so that we can setup the relocation
- * information for the buffer address in the indirect state
- * packet:
- */
- offset = emit_indirect(intel,
- LI0_STATE_MAP,
- NULL,
- (2 + nr * 3) * sizeof(GLuint) );
-
- p = (GLuint *)(intel->batch->map + offset);
-
- OUT(_3DSTATE_MAP_STATE | (3 * nr));
- OUT((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT);
+ struct i915_context *i915 = i915_context( &intel->ctx );
- for (i = 0; i < I915_TEX_UNITS; i++)
- if (dirty & I915_UPLOAD_TEX(i)) {
- if (state->tex_buffer[i]) {
- intel_batchbuffer_set_reloc( intel->batch,
- ((GLubyte *)p) - intel->batch->map,
- 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]);
- OUT(0); /* placeholder */
- }
- else {
- assert(i == 0);
- assert(state == &i915->meta);
- OUT(0);
- }
+ if (i915->cctx)
+ i915_destroy_caches( i915->cctx );
- OUT(state->Tex[i][I915_TEXREG_MS3]);
- OUT(state->Tex[i][I915_TEXREG_MS4]);
- }
-
-
-
- if (INTEL_DEBUG & DEBUG_STATE)
- fprintf(stderr, "UPLOAD SAMPLERS:\n");
-
- offset = emit_indirect(intel,
- LI0_STATE_SAMPLER,
- NULL,
- (2 + nr * 3) * sizeof(GLuint) );
-
-
- p = (GLuint *)(intel->batch->map + offset);
-
-
- OUT(_3DSTATE_SAMPLER_STATE | (3 * nr));
- OUT((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(state->Tex[i][I915_TEXREG_SS2]);
- OUT(state->Tex[i][I915_TEXREG_SS3]);
- OUT(state->Tex[i][I915_TEXREG_SS4]);
- }
- }
- }
-
- if (dirty & I915_UPLOAD_PROGRAM) {
- if (INTEL_DEBUG & DEBUG_STATE)
- fprintf(stderr, "I915_UPLOAD_PROGRAM:\n");
-
- assert((state->Program[0] & 0x1ff) + 2 == state->ProgramSize);
-
- if (INTEL_DEBUG & DEBUG_STATE)
- i915_disassemble_program(state->Program, state->ProgramSize);
- }
-
-
- if (dirty & I915_UPLOAD_CONSTANTS) {
- if (INTEL_DEBUG & DEBUG_STATE)
- fprintf(stderr, "I915_UPLOAD_CONSTANTS:\n");
-
- }
-
-
- state->emitted |= dirty;
+ FREE( i915 );
}
-#endif
-static void
-i915_destroy_context(struct intel_context *intel)
+static GLuint i915_flush_cmd(void)
{
- _tnl_free_vertices(&intel->ctx);
+ return MI_FLUSH | FLUSH_MAP_CACHE;
}
+static void i915_lost_hardware( struct intel_context *intel )
+{
+ struct i915_context *i915 = i915_context( &intel->ctx );
+ i915_clear_caches( i915->cctx );
-static GLuint
-i915_flush_cmd(void)
-{
- return MI_FLUSH | FLUSH_MAP_CACHE;
+ memset(&i915->dyn_indirect, 0, sizeof(i915->dyn_indirect));
}
@@ -272,4 +79,5 @@ i915InitVtbl(struct i915_context *i915)
{
i915->intel.vtbl.destroy = i915_destroy_context;
i915->intel.vtbl.flush_cmd = i915_flush_cmd;
+ i915->intel.vtbl.lost_hardware = i915_lost_hardware;
}
diff --git a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c
index d63d9ba086..7537251f9a 100644
--- a/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/i915tex/intel_batchbuffer.c
@@ -242,8 +242,8 @@ do_flush_locked(struct intel_batchbuffer *batch,
r->offset, driBOOffset(r->buf), r->delta);
}
- if (INTEL_DEBUG & DEBUG_BATCH)
- intel_dump_batchbuffer(batch, ptr);
+/* if (INTEL_DEBUG & DEBUG_BATCH) */
+ intel_dump_batchbuffer(batch, (GLubyte *)ptr);
driBOUnmap(batch->buffer);
batch->map = NULL;
diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c
index ad4b9b0053..871eae86bb 100644
--- a/src/mesa/drivers/dri/i915tex/intel_context.c
+++ b/src/mesa/drivers/dri/i915tex/intel_context.c
@@ -264,6 +264,7 @@ void intel_lost_hardware( struct intel_context *intel )
{
intel->state.dirty.intel |= ~0;
intel->state.dirty.mesa |= ~0;
+ intel->vtbl.lost_hardware( intel );
}
@@ -520,21 +521,14 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv)
assert(intel); /* should never be null */
if (intel) {
- GLboolean release_texture_heaps;
-
INTEL_FIREVERTICES(intel);
intel_idx_destroy(intel);
- intel->vtbl.destroy(intel);
-
- release_texture_heaps = (intel->ctx.Shared->RefCount == 1);
_swsetup_DestroyContext(&intel->ctx);
_tnl_DestroyContext(&intel->ctx);
_vbo_DestroyContext(&intel->ctx);
-
_swrast_DestroyContext(&intel->ctx);
- intel->Fallback = 0; /* don't call _swrast_Flush later */
intel_batchbuffer_free(intel->batch);
@@ -543,23 +537,17 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv)
driFenceUnReference(intel->last_swap_fence);
intel->last_swap_fence = NULL;
}
+
if (intel->first_swap_fence) {
driFenceFinish(intel->first_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE);
driFenceUnReference(intel->first_swap_fence);
intel->first_swap_fence = NULL;
}
-
- if (release_texture_heaps) {
- /* This share group is about to go away, free our private
- * texture object data.
- */
- if (INTEL_DEBUG & DEBUG_TEXTURE)
- fprintf(stderr, "do something to free texture heaps\n");
- }
-
/* free the Mesa context */
_mesa_free_context_data(&intel->ctx);
+
+ intel->vtbl.destroy(intel);
}
}
diff --git a/src/mesa/drivers/dri/i915tex/intel_idx_render.c b/src/mesa/drivers/dri/i915tex/intel_idx_render.c
new file mode 100644
index 0000000000..3a6b6c061c
--- /dev/null
+++ b/src/mesa/drivers/dri/i915tex/intel_idx_render.c
@@ -0,0 +1,430 @@
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+/*
+ * Render vertex buffers by emitting vertices directly to dma buffers.
+ */
+#include "glheader.h"
+#include "context.h"
+#include "macros.h"
+#include "imports.h"
+#include "mtypes.h"
+#include "enums.h"
+
+#include "tnl/t_context.h"
+#include "tnl/t_vertex.h"
+
+#include "intel_screen.h"
+#include "intel_context.h"
+#include "intel_tris.h"
+#include "intel_batchbuffer.h"
+#include "intel_buffer_objects.h"
+#include "intel_reg.h"
+#include "intel_state.h"
+#include "intel_idx_render.h"
+
+
+#define FILE_DEBUG_FLAG DEBUG_IDX
+
+
+
+#define MAX_VBO 32 /* XXX: make dynamic */
+#define VBO_SIZE (128*1024)
+
+
+/* Basically limited to what is addressable by the 16-bit indices,
+ * and the number of indices we can fit in a batchbuffer after
+ * making room for state.
+ */
+#define HW_MAX_INDEXABLE_VERTS 0xfffe
+#define HW_MAX_INDICES ((BATCH_SZ - 1024) / 2)
+
+
+
+struct intel_vb {
+ struct intel_context *intel;
+
+ 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;
+};
+
+
+/* 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,
+ GLuint *max_nr_indices )
+
+{
+ struct intel_context *intel = intel_context(ctx);
+ GLuint i;
+
+ if (intel->Fallback != 0 ||
+ intel->RenderIndex != 0)
+ return GL_FALSE;
+
+ /* These are constant, but for some hardware they might vary
+ * depending on the state, eg. according to vertex size.
+ */
+ *max_nr_verts = HW_MAX_INDEXABLE_VERTS;
+ *max_nr_indices = HW_MAX_INDICES;
+
+ /* Fix points with different dstorg bias state?? or use different
+ * viewport transform in this case only (requires flush at level
+ * above).
+ */
+ for (i = 0; i < VB->PrimitiveCount; i++) {
+ if (VB->Primitive[i].mode == GL_POINTS)
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+static void
+emit_vb_state( struct intel_vb *vb )
+{
+ struct intel_context *intel = vb->intel;
+
+ DBG("%s\n", __FUNCTION__);
+
+ intel->state.vbo = vb->current_vbo->buffer;
+ intel->state.vbo_offset = vb->hw_vbo_offset;
+ intel->state.dirty.intel |= INTEL_NEW_VBO;
+
+ vb->dirty = 0;
+}
+
+static void
+release_current_vbo( struct intel_vb *vb )
+{
+ GLcontext *ctx = &vb->intel->ctx;
+
+ DBG("%s\n", __FUNCTION__);
+
+ if (vb->current_vbo_ptr)
+ ctx->Driver.UnmapBuffer( ctx,
+ GL_ARRAY_BUFFER_ARB,
+ &vb->current_vbo->Base );
+
+ vb->current_vbo = NULL;
+ vb->current_vbo_ptr = NULL;
+ vb->current_vbo_size = 0;
+ vb->current_vbo_used = 0;
+ vb->dirty = 0;
+}
+
+static void
+reset_vbo( struct intel_vb *vb )
+{
+ DBG("%s\n", __FUNCTION__);
+
+ if (vb->current_vbo)
+ release_current_vbo( vb );
+
+ vb->nr_vbo = 0;
+}
+
+
+
+
+static void
+get_next_vbo( struct intel_vb *vb, GLuint size )
+{
+ GLcontext *ctx = &vb->intel->ctx;
+
+ DBG("%s\n", __FUNCTION__);
+
+ /* XXX: just allocate more vbos here:
+ */
+ if (vb->nr_vbo == MAX_VBO) {
+ DBG("XXX: out of vbo's, flushing\n");
+ INTEL_FIREVERTICES(vb->intel);
+ intel_batchbuffer_flush(vb->intel->batch);
+ reset_vbo(vb);
+ }
+
+ /* Unmap current vbo:
+ */
+ if (vb->current_vbo)
+ release_current_vbo( vb );
+
+ if (size < VBO_SIZE)
+ size = VBO_SIZE;
+
+ vb->current_vbo = vb->vbo[vb->nr_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:
+ */
+ ctx->Driver.BufferData( ctx,
+ GL_ARRAY_BUFFER_ARB,
+ vb->current_vbo_size,
+ NULL,
+ GL_DYNAMIC_DRAW_ARB,
+ &vb->current_vbo->Base );
+
+}
+
+static void *get_space( struct intel_vb *vb, GLuint nr, GLuint vertex_size )
+{
+ GLcontext *ctx = &vb->intel->ctx;
+ void *ptr;
+ GLuint space = nr * vertex_size * 4;
+
+ DBG("%s %d*%d, vbo %d\n", __FUNCTION__, nr, vertex_size, vb->nr_vbo);
+
+ if (vb->current_vbo_used + space > vb->current_vbo_size || !vb->current_vbo_ptr)
+ get_next_vbo( vb, space );
+
+ if (vb->vertex_size != vertex_size) {
+ vb->vertex_size = vertex_size;
+ vb->hw_vbo_offset = vb->current_vbo_used;
+ vb->dirty = 1;
+ }
+
+ if (!vb->current_vbo_ptr) {
+ DBG("%s map vbo %d\n", __FUNCTION__, vb->nr_vbo);
+
+ /* Map the vbo now, will be unmapped in release_current_vbo, above.
+ */
+ vb->current_vbo_ptr = ctx->Driver.MapBuffer( ctx,
+ GL_ARRAY_BUFFER_ARB,
+ GL_WRITE_ONLY,
+ &vb->current_vbo->Base );
+ }
+
+
+ /* Hmm, could just re-emit the vertex buffer packet & avoid this:
+ */
+ vb->hw_vbo_delta = (vb->current_vbo_used - vb->hw_vbo_offset) / (vb->vertex_size * 4);
+
+ ptr = vb->current_vbo_ptr + vb->current_vbo_used;
+ vb->current_vbo_used += space;
+
+ return ptr;
+}
+
+
+static void
+build_and_emit_vertices(GLcontext * ctx, GLuint nr)
+{
+ struct intel_context *intel = intel_context(ctx);
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ void *ptr = get_space(intel->vb, nr, intel->vertex_size );
+
+ DBG("%s %d\n", __FUNCTION__, nr);
+
+ assert(tnl->clipspace.vertex_size == intel->vertex_size * 4);
+
+ tnl->clipspace.new_inputs |= VERT_BIT_POS;
+ _tnl_emit_vertices_to_buffer( ctx, 0, nr, ptr );
+}
+
+/* Emits vertices previously built by a call to BuildVertices.
+ *
+ * XXX: have t_vertex.c use our buffer to build into and avoid the
+ * copy (assuming our buffer is cached...)
+ */
+static void emit_built_vertices( GLcontext *ctx, GLuint nr )
+{
+ struct intel_context *intel = intel_context(ctx);
+ void *ptr = get_space(intel->vb, nr, intel->vertex_size );
+
+ DBG("%s %d\n", __FUNCTION__, nr);
+
+ memcpy(ptr, _tnl_get_vertex(ctx, 0),
+ nr * intel->vertex_size * sizeof(GLuint));
+}
+
+/* Emit primitives and indices referencing the previously emitted
+ * vertex buffer.
+ */
+static void emit_prims( GLcontext *ctx,
+ const struct _mesa_prim *prim,
+ GLuint nr_prims,
+ const GLuint *indices,
+ GLuint nr_indices )
+{
+ struct intel_context *intel = intel_context(ctx);
+ struct intel_vb *vb = intel->vb;
+ GLuint i, j;
+
+ assert(indices);
+
+ DBG("%s - start\n", __FUNCTION__);
+
+
+ for (i = 0; i < nr_prims; i++) {
+ GLuint nr, hw_prim;
+ GLuint start = prim[i].start;
+ GLuint offset = vb->hw_vbo_delta;
+
+ switch (prim[i].mode) {
+ case GL_TRIANGLES:
+ hw_prim = PRIM3D_TRILIST;
+ nr = prim[i].count - prim[i].count % 3;
+ break;
+ case GL_LINES:
+ hw_prim = PRIM3D_LINELIST;
+ nr = prim[i].count - prim[i].count % 2;
+ break;
+ default:
+ assert(0);
+ continue;
+ }
+
+ if (nr == 0)
+ continue;
+
+ /* XXX: Need to ensure that both the state and the primitive
+ * command below end up in the same batchbuffer, otherwise there
+ * is a risk that another context might interpose a batchbuffer
+ * containing different statesetting commands. Using logical
+ * contexts would fix this, as would the BRW scheme of only
+ * emitting batch commands while holding the lock.
+ */
+ if (vb->dirty)
+ emit_vb_state( vb );
+
+ intel_emit_state(intel);
+
+ /* XXX: Can emit upto 64k indices, need to split larger prims
+ */
+ BEGIN_BATCH(2 + (nr+1)/2, INTEL_BATCH_CLIPRECTS);
+
+ OUT_BATCH(0);
+ OUT_BATCH( _3DPRIMITIVE |
+ hw_prim |
+ PRIM_INDIRECT |
+ PRIM_INDIRECT_ELTS |
+ nr );
+
+ /* Pack indices into 16bits
+ */
+ for (j = 0; j < nr-1; j += 2) {
+ OUT_BATCH( (offset + indices[start+j]) | ((offset + indices[start+j+1])<<16) );
+ }
+
+ if (j < nr)
+ OUT_BATCH( (offset + indices[start+j]) );
+
+ ADVANCE_BATCH();
+ }
+
+
+ DBG("%s - done\n", __FUNCTION__);
+}
+
+
+/* Callback from (eventually) intel_batchbuffer_flush()
+ */
+void intel_idx_lost_hardware( struct intel_context *intel )
+{
+ GLcontext *ctx = &intel->ctx;
+ struct intel_vb *vb = intel->vb;
+
+ DBG("%s\n", __FUNCTION__);
+
+ if (vb->current_vbo_ptr) {
+ ctx->Driver.UnmapBuffer( ctx,
+ GL_ARRAY_BUFFER_ARB,
+ &vb->current_vbo->Base );
+ vb->current_vbo_ptr = NULL;
+ }
+}
+
+void intel_idx_init( struct intel_context *intel )
+{
+ GLcontext *ctx = &intel->ctx;
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ GLuint i;
+
+ tnl->Driver.Render.CheckIdxRender = check_idx_render;
+ tnl->Driver.Render.BuildAndEmitVertices = build_and_emit_vertices;
+ tnl->Driver.Render.EmitBuiltVertices = emit_built_vertices;
+ tnl->Driver.Render.EmitPrims = emit_prims;
+
+
+ /* Create the vb context:
+ */
+ intel->vb = CALLOC_STRUCT( intel_vb );
+ intel->vb->intel = intel;
+
+ for (i = 0; i < MAX_VBO; i++) {
+ intel->vb->vbo[i] = (struct intel_buffer_object *)
+ ctx->Driver.NewBufferObject(ctx, 1, GL_ARRAY_BUFFER_ARB);
+ }
+}
+
+void intel_idx_destroy( struct intel_context *intel )
+{
+ GLcontext *ctx = &intel->ctx;
+ struct intel_vb *vb = intel->vb;
+ GLuint i;
+
+ if (vb) {
+ reset_vbo( vb );
+
+ /* Destroy the vbo:
+ */
+ for (i = 0; i < MAX_VBO; i++)
+ if (vb->vbo[i])
+ ctx->Driver.DeleteBuffer( ctx, &vb->vbo[i]->Base );
+
+ FREE( intel->vb );
+ }
+}
diff --git a/src/mesa/drivers/dri/i915tex/intel_idx_render.h b/src/mesa/drivers/dri/i915tex/intel_idx_render.h
new file mode 100644
index 0000000000..6639bf5507
--- /dev/null
+++ b/src/mesa/drivers/dri/i915tex/intel_idx_render.h
@@ -0,0 +1,37 @@
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+#ifndef INTEL_IDX_H
+#define INTEL_IDX_H
+
+#include "intel_context.h"
+
+void intel_idx_init( struct intel_context *intel );
+void intel_idx_destroy( struct intel_context *intel );
+void intel_idx_lost_hardware( struct intel_context *intel );
+
+#endif
diff --git a/src/mesa/drivers/dri/i915tex/intel_program.c b/src/mesa/drivers/dri/i915tex/intel_program.c
deleted file mode 100644
index e54b600667..0000000000
--- a/src/mesa/drivers/dri/i915tex/intel_program.c
+++ /dev/null
@@ -1,269 +0,0 @@
-/**************************************************************************
- *
- * 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_fp.h"
-
-#include "program_instruction.h"
-#include "program.h"
-#include "programopt.h"
-
-
-static void brwBindProgram( GLcontext *ctx,
- GLenum target,
- struct gl_program *prog )
-{
- struct brw_context *brw = brw_context(ctx);
-
- 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;
- }
-}
-
-static struct gl_program *brwNewProgram( GLcontext *ctx,
- GLenum target,
- GLuint id )
-{
- struct brw_context *brw = brw_context(ctx);
-
- switch (target) {
- case GL_VERTEX_PROGRAM_ARB: {
- struct brw_vertex_program *prog = CALLOC_STRUCT(brw_vertex_program);
- if (prog) {
- prog->id = brw->program_id++;
-
- return _mesa_init_vertex_program( ctx, &prog->program,
- target, id );
- }
- else
- return NULL;
- }
-
- case GL_FRAGMENT_PROGRAM_ARB: {
- struct brw_fragment_program *prog = CALLOC_STRUCT(brw_fragment_program);
- if (prog) {
- prog->id = brw->program_id++;
-
- return _mesa_init_fragment_program( ctx, &prog->program,
- target, id );
- }
- else
- return NULL;
- }
-
- default:
- return _mesa_new_program(ctx, target, id);
- }
-}
-
-static void brwDeleteProgram( GLcontext *ctx,
- struct gl_program *prog )
-{
-
- _mesa_delete_program( ctx, prog );
-}
-
-
-static GLboolean brwIsProgramNative( GLcontext *ctx,
- GLenum target,
- struct gl_program *prog )
-{
- return GL_TRUE;
-}
-
-static void brwProgramStringNotify( GLcontext *ctx,
- GLenum target,
- struct gl_program *prog )
-{
- 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);
- }
-}
-
-void brwInitFragProgFuncs( struct dd_function_table *functions )
-{
- assert(functions->ProgramStringNotify == _tnl_program_string);
-
- functions->BindProgram = brwBindProgram;
- functions->NewProgram = brwNewProgram;
- functions->DeleteProgram = brwDeleteProgram;
- functions->IsProgramNative = brwIsProgramNative;
- functions->ProgramStringNotify = brwProgramStringNotify;
-}
-
-
-
-
-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
-i915InitFragProgFuncs(struct dd_function_table *functions)
-{
- functions->BindProgram = i915BindProgram;
- functions->NewProgram = i915NewProgram;
- functions->DeleteProgram = i915DeleteProgram;
- functions->IsProgramNative = i915IsProgramNative;
- functions->ProgramStringNotify = i915ProgramStringNotify;
-}