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