diff --git a/src/mesa/drivers/dri/i915/bufmgr_fake.c b/src/mesa/drivers/dri/i915/bufmgr_fake.c index 7e498a8afd5..8de70d10670 100644 --- a/src/mesa/drivers/dri/i915/bufmgr_fake.c +++ b/src/mesa/drivers/dri/i915/bufmgr_fake.c @@ -86,8 +86,11 @@ static struct block *alloc_agp( struct bufmgr *bm, if (!block) return NULL; + _mesa_printf("alloc_agp 0x%x\n", size); + block->mem = mmAllocMem(bm->pool.heap, size, align, 0); if (!block->mem) { + _mesa_printf("\t- failed\n"); free(block); return NULL; } @@ -96,6 +99,7 @@ static struct block *alloc_agp( struct bufmgr *bm, block->memType = BM_MEM_AGP; block->virtual = bm->pool.virtual + block->mem->ofs; + _mesa_printf("\t- offset 0x%x\n", block->mem->ofs); return block; } @@ -106,6 +110,8 @@ static struct block *alloc_local( unsigned size ) if (!block) return NULL; + _mesa_printf("alloc_local 0x%x\n", size); + block->memType = BM_MEM_LOCAL; block->virtual = malloc(size); if (!block->virtual) { @@ -136,12 +142,15 @@ static int bmAllocMem( struct bufmgr *bm, struct buffer *buf, unsigned flags ) /* unused */ { - if (buf->block == 0) + if (buf->block == NULL) buf->block = alloc_block(bm, buf->size, 4, BM_MEM_AGP); - if (buf->block == 0) + if (buf->block == NULL) buf->block = alloc_block(bm, buf->size, 4, BM_MEM_LOCAL); + if (buf->block) + buf->block->buf = buf; + return buf->block != NULL; } @@ -212,6 +221,9 @@ static int move_buffers( struct bufmgr *bm, if (flags & BM_NO_UPLOAD) goto cleanup; + _mesa_printf("try to move buffer size 0x%x to pool %d\n", + buffers[i]->size, newMemType); + newMem[i] = alloc_block(bm, buffers[i]->size, buffers[i]->alignment, @@ -219,6 +231,8 @@ static int move_buffers( struct bufmgr *bm, if (!newMem[i]) goto cleanup; + + newMem[i]->buf = buffers[i]; } } @@ -346,6 +360,9 @@ void bmInitPool( struct bufmgr *bm, { if (pool > 0 || low_offset >= high_offset) return; + + _mesa_printf("bmInitPool %d %x..%x\n", + pool, low_offset, high_offset); bm->pool.size = high_offset - low_offset; bm->pool.heap = mmInit( low_offset, bm->pool.size ); @@ -362,7 +379,7 @@ void bmGenBuffers(struct bufmgr *bm, unsigned n, unsigned *buffers) unsigned i; for (i = 0; i < n; i++) { - buffers[i] = bm->buf_nr++; + buffers[i] = ++bm->buf_nr; _mesa_HashInsert(bm->hash, buffers[i], calloc(sizeof(struct buffer), 1)); } } @@ -393,6 +410,8 @@ void bmBufferData(struct bufmgr *bm, { struct buffer *buf = (struct buffer *)_mesa_HashLookup( bm->hash, buffer ); + _mesa_printf("bmBufferData %d sz 0x%x data: %p\n", buffer, size, data); + if (buf->block) { if ((buf->block->memType == BM_MEM_AGP && !bmTestFence(bm, buf->block->fence)) || (buf->size && buf->size != size) || @@ -420,6 +439,8 @@ void bmBufferSubData(struct bufmgr *bm, { struct buffer *buf = (struct buffer *)_mesa_HashLookup( bm->hash, buffer ); + _mesa_printf("bmBufferSubdata %d offset 0x%x sz 0x%x\n", buffer, offset, size); + if (buf->block == 0) bmAllocMem(bm, buf, 0); @@ -438,6 +459,8 @@ void *bmMapBuffer( struct bufmgr *bm, { struct buffer *buf = (struct buffer *)_mesa_HashLookup( bm->hash, buffer ); + _mesa_printf("bmMapBuffer %d\n", buffer); + if (buf->mapped) return NULL; @@ -457,6 +480,8 @@ void *bmMapBuffer( struct bufmgr *bm, void bmUnmapBuffer( struct bufmgr *bm, unsigned buffer ) { struct buffer *buf = (struct buffer *)_mesa_HashLookup( bm->hash, buffer ); + + _mesa_printf("bmUnmapBuffer %d\n", buffer); buf->mapped = 0; } @@ -485,6 +510,7 @@ void bm_fake_SetFixedBufferParams( struct bufmgr *bm struct bm_buffer_list *bmNewBufferList( void ) { struct bm_buffer_list *list = calloc(sizeof(*list), 1); + _mesa_printf("bmNewBufferList\n"); return list; } @@ -497,6 +523,8 @@ void bmAddBuffer( struct bufmgr *bm, { assert(list->nr < BM_LIST_MAX); + _mesa_printf("bmAddBuffer %d\n", buffer); + list->buffer[list->nr] = _mesa_HashLookup(bm->hash, buffer); list->offset_return[list->nr] = offset_return; list->nr++; @@ -528,11 +556,14 @@ int bmValidateBufferList( struct bufmgr *bm, unsigned i; unsigned total = 0; + _mesa_printf("%s\n", __FUNCTION__); + if (list->nr > BM_LIST_MAX) return 0; for (i = 0; i < list->nr; i++) { assert(!list->buffer[i]->mapped); + assert(list->buffer[i]->block); total += list->buffer[i]->size; } @@ -568,9 +599,14 @@ void bmFenceBufferList( struct bufmgr *bm, struct bm_buffer_list *list ) { unsigned i; + _mesa_printf("%s (%d bufs)\n", __FUNCTION__, list->nr); + assert(list->need_fence); list->need_fence = 0; + if (!list->nr) + return; + bm->last_fence = bmSetFence( bm ); /* Move all buffers to head of resident list and set their fences @@ -635,7 +671,7 @@ void bmFlushReadCaches( struct bufmgr *bm ) * have to emit another fence and wait for the hw queue to drain to be * sure the caches had flushed. * - * Strategy: + * A possible strategy: * - every once in a while, when there is no last_draw_flush_fence outstanding, * emit a draw-cache flush just prior to the fence. * - note the fence (last_draw_flush_fence) diff --git a/src/mesa/drivers/dri/i915/i830_metaops.c b/src/mesa/drivers/dri/i915/i830_metaops.c index 53997f83366..50511bfa7fd 100644 --- a/src/mesa/drivers/dri/i915/i830_metaops.c +++ b/src/mesa/drivers/dri/i915/i830_metaops.c @@ -295,6 +295,7 @@ static void draw_quad(i830ContextPtr i830, GLfloat s0, GLfloat s1, GLfloat t0, GLfloat t1 ) { +#if 0 GLuint vertex_size = 8; GLuint *vb = intelEmitInlinePrimitiveLocked( &i830->intel, PRIM3D_TRIFAN, @@ -350,6 +351,7 @@ static void draw_quad(i830ContextPtr i830, /* fprintf(stderr, "%s: DV1: %x\n", */ /* __FUNCTION__, i830->meta.Buffer[I830_DESTREG_DV1]); */ +#endif } void diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c index 817a7bb5f1c..3928fe1d60a 100644 --- a/src/mesa/drivers/dri/i915/i915_context.c +++ b/src/mesa/drivers/dri/i915/i915_context.c @@ -107,6 +107,8 @@ GLboolean i915CreateContext( const __GLcontextModes *mesaVis, if (!i915) return GL_FALSE; + _mesa_printf( "\ntexmem branch\n\n"); + i915InitVtbl( i915 ); i915InitDriverFunctions( &functions ); @@ -129,9 +131,6 @@ GLboolean i915CreateContext( const __GLcontextModes *mesaVis, intel->intelScreen->tex.size, /* high offset */ intel->intelScreen->tex.map); /* virtual base */ - /* AGP allocation won't work: - */ - intel->intelScreen->allow_batchbuffer = GL_FALSE; ctx->Const.MaxTextureLevels = 11; ctx->Const.Max3DTextureLevels = 8; diff --git a/src/mesa/drivers/dri/i915/i915_metaops.c b/src/mesa/drivers/dri/i915/i915_metaops.c index 066c6b5ecdf..b24dfe8a02a 100644 --- a/src/mesa/drivers/dri/i915/i915_metaops.c +++ b/src/mesa/drivers/dri/i915/i915_metaops.c @@ -387,6 +387,7 @@ static void draw_quad(i915ContextPtr i915, GLfloat s0, GLfloat s1, GLfloat t0, GLfloat t1 ) { +#if 0 GLuint vertex_size = 8; GLuint *vb = intelEmitInlinePrimitiveLocked( &i915->intel, PRIM3D_TRIFAN, @@ -440,6 +441,7 @@ static void draw_quad(i915ContextPtr i915, tmp.v.u0 = s0; for (i = 0 ; i < vertex_size ; i++) vb[i] = tmp.ui[i]; +#endif } void diff --git a/src/mesa/drivers/dri/i915/i915_tex_layout.c b/src/mesa/drivers/dri/i915/i915_tex_layout.c index d79a64ea677..3c95af1f788 100644 --- a/src/mesa/drivers/dri/i915/i915_tex_layout.c +++ b/src/mesa/drivers/dri/i915/i915_tex_layout.c @@ -55,7 +55,6 @@ static GLuint minify( GLuint d ) GLboolean i915_miptree_layout( struct intel_mipmap_tree *mt ) { GLint i; - GLint numLevels = mt->last_level - mt->first_level + 1; switch (mt->target) { case GL_TEXTURE_CUBE_MAP: { @@ -71,12 +70,12 @@ GLboolean i915_miptree_layout( struct intel_mipmap_tree *mt ) GLuint y = initial_offsets[face][1] * dim; GLuint d = dim; - for (i = 0; i < numLevels; i++) { + for (i = mt->first_level; i <= mt->last_level; i++) { mt->offset[face][i].x = x; mt->offset[face][i].y = y; mt->offset[face][i].width = d; mt->offset[face][i].height = d; - mt->offset[face][i].depth = 0; + mt->offset[face][i].depth = 1; d >>= 1; assert(d > 0); @@ -91,7 +90,6 @@ GLboolean i915_miptree_layout( struct intel_mipmap_tree *mt ) GLuint width = mt->width0; GLuint height = mt->height0; GLuint depth = mt->depth0; - GLuint tmp_numLevels = MAX2(numLevels, 9); /* Calculate the size of a single slice. Hardware demands a * minimum of 8 mipmaps, some of which might ultimately not be @@ -100,7 +98,9 @@ GLboolean i915_miptree_layout( struct intel_mipmap_tree *mt ) mt->pitch = (mt->width0 * mt->cpp + 3) & ~3; mt->total_height = 0; - for ( i = 0 ; i < tmp_numLevels ; i++ ) { + /* XXX: fixme! hardware expects/requires 9 levels at minimum. + */ + for ( i = mt->first_level ; i <= mt->last_level ; i++ ) { mt->offset[0][i].x = 0; mt->offset[0][i].y = mt->total_height; mt->offset[0][i].width = width; @@ -131,12 +131,12 @@ GLboolean i915_miptree_layout( struct intel_mipmap_tree *mt ) mt->pitch = (mt->width0 * mt->cpp + 3) & ~3; mt->total_height = 0; - for ( i = 0 ; i < numLevels ; i++ ) { + for ( i = mt->first_level ; i <= mt->last_level ; i++ ) { mt->offset[0][i].x = 0; mt->offset[0][i].y = mt->total_height; mt->offset[0][i].height = height; mt->offset[0][i].width = width; - mt->offset[0][i].depth = 0; + mt->offset[0][i].depth = 1; if (mt->compressed) @@ -157,7 +157,6 @@ GLboolean i915_miptree_layout( struct intel_mipmap_tree *mt ) GLboolean i945_miptree_layout( struct intel_mipmap_tree *mt ) { - GLint numLevels = mt->last_level - mt->first_level + 1; GLint i; switch (mt->target) { @@ -191,12 +190,12 @@ GLboolean i945_miptree_layout( struct intel_mipmap_tree *mt ) x = face * 8; } - for (i = 0; i < numLevels; i++) { + for ( i = mt->first_level ; i <= mt->last_level ; i++ ) { mt->offset[face][i].x = x; mt->offset[face][i].y = y; mt->offset[face][i].width = d; mt->offset[face][i].height = d; - mt->offset[face][i].depth = 0; + mt->offset[face][i].depth = 1; d >>= 1; assert(d > 0); @@ -251,7 +250,7 @@ GLboolean i945_miptree_layout( struct intel_mipmap_tree *mt ) depth_pack_pitch = mt->pitch; - for ( i = 0 ; i < numLevels ; i++ ) { + for ( i = mt->first_level ; i <= mt->last_level ; i++ ) { mt->offset[0][i].x = 0; mt->offset[0][i].y = mt->total_height; @@ -291,12 +290,12 @@ GLboolean i945_miptree_layout( struct intel_mipmap_tree *mt ) mt->pitch = (mt->width0 * mt->cpp + 3) & ~3; mt->total_height = 0; - for ( i = 0 ; i < numLevels ; i++ ) { + for ( i = mt->first_level ; i <= mt->last_level ; i++ ) { mt->offset[0][i].x = x; mt->offset[0][i].y = y; mt->offset[0][i].height = height; mt->offset[0][i].width = width; - mt->offset[0][i].depth = 0; + mt->offset[0][i].depth = 1; /* LPT change: step right after second mipmap. diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c index 410890f6da3..289eeb92e10 100644 --- a/src/mesa/drivers/dri/i915/i915_texstate.c +++ b/src/mesa/drivers/dri/i915/i915_texstate.c @@ -118,23 +118,11 @@ static GLboolean i915_update_tex_unit( GLcontext *ctx, struct intel_texture_object *intelObj = intel_texture_object(tObj); struct i915_context *i915 = i915_context(ctx); GLuint state[I915_TEX_SETUP_SIZE]; - struct gl_texture_image *firstImage; - GLuint firstImageOffset; + struct gl_texture_image *firstImage = tObj->Image[0][intelObj->firstLevel]; memset(state, 0, sizeof(state)); - /* Will return the offset for the image at intelObj->firstLevel - * (firstLevel and lastLevel are calculated in - * validate_mipmap_tree). We will program the hardware as if this - * is level 0. - */ - firstImageOffset = intel_validate_mipmap_tree( intel_context(ctx), intelObj ); - firstImage = tObj->Image[0][intelObj->firstLevel]; - - if (!firstImageOffset) - return GL_FALSE; - - state[I915_TEXREG_MS2] = firstImageOffset; + state[I915_TEXREG_MS2] = 0; /* will fixup later */ state[I915_TEXREG_MS3] = (((firstImage->Height - 1) << MS3_HEIGHT_SHIFT) | ((firstImage->Width - 1) << MS3_WIDTH_SHIFT) | @@ -264,17 +252,27 @@ static GLboolean i915_update_tex_unit( GLcontext *ctx, tObj->_BorderChan[3]); + I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(unit), GL_TRUE); - if (memcmp(state, i915->state.Tex[unit], sizeof(state)) != 0) { + if (1 || memcmp(state, i915->state.Tex[unit], sizeof(state)) != 0) { I915_STATECHANGE( i915, I915_UPLOAD_TEX(unit) ); memcpy(i915->state.Tex[unit], state, sizeof(state)); } - + + _mesa_printf("state[I915_TEXREG_SS2] = 0x%x\n", state[I915_TEXREG_SS2]); + _mesa_printf("state[I915_TEXREG_SS3] = 0x%x\n", state[I915_TEXREG_SS3]); + _mesa_printf("state[I915_TEXREG_SS4] = 0x%x\n", state[I915_TEXREG_SS4]); + + _mesa_printf("state[I915_TEXREG_MS2] = 0x%x\n", state[I915_TEXREG_MS2]); + _mesa_printf("state[I915_TEXREG_MS3] = 0x%x\n", state[I915_TEXREG_MS3]); + _mesa_printf("state[I915_TEXREG_MS4] = 0x%x\n", state[I915_TEXREG_MS4]); + return GL_TRUE; } + void i915UpdateTextureState( intelContextPtr intel ) { GLcontext *ctx = &intel->ctx; diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c index aaf75ffa840..7765076b118 100644 --- a/src/mesa/drivers/dri/i915/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915/i915_vtbl.c @@ -37,6 +37,7 @@ #include "tnl/t_vertex.h" #include "intel_batchbuffer.h" +#include "intel_tex.h" #include "i915_reg.h" #include "i915_context.h" @@ -271,7 +272,10 @@ static void i915_emit_state( intelContextPtr intel ) OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT); for (i = 0 ; i < I915_TEX_UNITS ; i++) if (dirty & I915_UPLOAD_TEX(i)) { - OUT_BATCH(state->Tex[i][I915_TEXREG_MS2]); + /* Emit zero texture offset, will fixup before firing */ + intel_add_texoffset_fixup(intel, i, (GLuint *)batch_ptr); + _mesa_printf("MS2: %x\n", *(GLuint *)batch_ptr); + batch_ptr += 4; OUT_BATCH(state->Tex[i][I915_TEXREG_MS3]); OUT_BATCH(state->Tex[i][I915_TEXREG_MS4]); } diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.c b/src/mesa/drivers/dri/i915/intel_batchbuffer.c index 84ec70e2b9e..8961ea0c9d1 100644 --- a/src/mesa/drivers/dri/i915/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915/intel_batchbuffer.c @@ -40,280 +40,6 @@ -/* ================================================================ - * Performance monitoring functions - */ - -static void intel_fill_box( intelContextPtr intel, - GLshort x, GLshort y, - GLshort w, GLshort h, - GLubyte r, GLubyte g, GLubyte b ) -{ - intelEmitFillBlitLocked( intel, - intel->intelScreen->cpp, - intel->intelScreen->back.pitch, - intel->intelScreen->front.offset, - x, y, w, h, - INTEL_PACKCOLOR(intel->intelScreen->fbFormat, - r,g,b,0xff)); -} - -static void intel_draw_performance_boxes( intelContextPtr intel ) -{ - /* Purple box for page flipping - */ - if ( intel->perf_boxes & I830_BOX_FLIP ) - intel_fill_box( intel, 4, 4, 8, 8, 255, 0, 255 ); - - /* Red box if we have to wait for idle at any point - */ - if ( intel->perf_boxes & I830_BOX_WAIT ) - intel_fill_box( intel, 16, 4, 8, 8, 255, 0, 0 ); - - /* Blue box: lost context? - */ - if ( intel->perf_boxes & I830_BOX_LOST_CONTEXT ) - intel_fill_box( intel, 28, 4, 8, 8, 0, 0, 255 ); - - /* Yellow box for texture swaps - */ - if ( intel->perf_boxes & I830_BOX_TEXTURE_LOAD ) - intel_fill_box( intel, 40, 4, 8, 8, 255, 255, 0 ); - - /* Green box if hardware never idles (as far as we can tell) - */ - if ( !(intel->perf_boxes & I830_BOX_RING_EMPTY) ) - intel_fill_box( intel, 64, 4, 8, 8, 0, 255, 0 ); - - - /* Draw bars indicating number of buffers allocated - * (not a great measure, easily confused) - */ -#if 0 - if (intel->dma_used) { - int bar = intel->dma_used / 10240; - if (bar > 100) bar = 100; - if (bar < 1) bar = 1; - intel_fill_box( intel, 4, 16, bar, 4, 196, 128, 128 ); - intel->dma_used = 0; - } -#endif - - intel->perf_boxes = 0; -} - - - - - - -static int bad_prim_vertex_nr( int primitive, int nr ) -{ - switch (primitive & PRIM3D_MASK) { - case PRIM3D_POINTLIST: - return nr < 1; - case PRIM3D_LINELIST: - return (nr & 1) || nr == 0; - case PRIM3D_LINESTRIP: - return nr < 2; - case PRIM3D_TRILIST: - case PRIM3D_RECTLIST: - return nr % 3 || nr == 0; - case PRIM3D_POLY: - case PRIM3D_TRIFAN: - case PRIM3D_TRISTRIP: - case PRIM3D_TRISTRIP_RVRSE: - return nr < 3; - default: - return 1; - } -} - -static void intel_flush_inline_primitive( GLcontext *ctx ) -{ - intelContextPtr intel = INTEL_CONTEXT( ctx ); - GLuint used = intel->batch.ptr - intel->prim.start_ptr; - GLuint vertcount; - - assert(intel->prim.primitive != ~0); - - if (1) { - /* Check vertex size against the vertex we're specifying to - * hardware. If it's wrong, ditch the primitive. - */ - if (!intel->vtbl.check_vertex_size( intel, intel->vertex_size )) - goto do_discard; - - vertcount = (used - 4)/ (intel->vertex_size * 4); - - if (!vertcount) - goto do_discard; - - if (vertcount * intel->vertex_size * 4 != used - 4) { - fprintf(stderr, "vertex size confusion %d %d\n", used, - intel->vertex_size * vertcount * 4); - goto do_discard; - } - - if (bad_prim_vertex_nr( intel->prim.primitive, vertcount )) { - fprintf(stderr, "bad_prim_vertex_nr %x %d\n", intel->prim.primitive, - vertcount); - goto do_discard; - } - } - - if (used < 8) - goto do_discard; - - *(int *)intel->prim.start_ptr = (_3DPRIMITIVE | - intel->prim.primitive | - (used/4-2)); - - goto finished; - - do_discard: - intel->batch.ptr -= used; - intel->batch.space += used; - assert(intel->batch.space >= 0); - - finished: - intel->prim.primitive = ~0; - intel->prim.start_ptr = 0; - intel->prim.flush = 0; -} - - -/* Emit a primitive referencing vertices in a vertex buffer. - */ -void intelStartInlinePrimitive( intelContextPtr intel, GLuint prim ) -{ - BATCH_LOCALS; - - if (0) - fprintf(stderr, "%s %x\n", __FUNCTION__, prim); - - - /* Finish any in-progress primitive: - */ - INTEL_FIREVERTICES( intel ); - - /* Emit outstanding state: - */ - intel->vtbl.emit_state( intel ); - - /* Make sure there is some space in this buffer: - */ - if (intel->vertex_size * 10 * sizeof(GLuint) >= intel->batch.space) - intelFlushBatch(intel, GL_TRUE); - - -#if 1 - if (((int)intel->batch.ptr) & 0x4) { - BEGIN_BATCH(1); - OUT_BATCH(0); - ADVANCE_BATCH(); - } -#endif - - /* Emit a slot which will be filled with the inline primitive - * command later. - */ - BEGIN_BATCH(2); - OUT_BATCH( 0 ); - - intel->prim.start_ptr = batch_ptr; - intel->prim.primitive = prim; - intel->prim.flush = intel_flush_inline_primitive; - - OUT_BATCH( 0 ); - ADVANCE_BATCH(); -} - - -void intelRestartInlinePrimitive( intelContextPtr intel ) -{ - GLuint prim = intel->prim.primitive; - - intel_flush_inline_primitive( &intel->ctx ); - if (1) intelFlushBatch(intel, GL_TRUE); /* GL_TRUE - is critical */ - intelStartInlinePrimitive( intel, prim ); -} - - - -void intelWrapInlinePrimitive( intelContextPtr intel ) -{ - GLuint prim = intel->prim.primitive; - - if (0) - fprintf(stderr, "%s\n", __FUNCTION__); - intel_flush_inline_primitive( &intel->ctx ); - intelFlushBatch(intel, GL_TRUE); - intelStartInlinePrimitive( intel, prim ); -} - - -/* Emit a primitive with space for inline vertices. - */ -GLuint *intelEmitInlinePrimitiveLocked(intelContextPtr intel, - int primitive, - int dwords, - int vertex_size ) -{ - GLuint *tmp = 0; - BATCH_LOCALS; - - if (0) - fprintf(stderr, "%s 0x%x %d\n", __FUNCTION__, primitive, dwords); - - /* Emit outstanding state: - */ - intel->vtbl.emit_state( intel ); - - - if (1) { - int used = dwords * 4; - int vertcount; - - /* Check vertex size against the vertex we're specifying to - * hardware. If it's wrong, ditch the primitive. - */ - if (!intel->vtbl.check_vertex_size( intel, vertex_size )) - goto do_discard; - - vertcount = dwords / vertex_size; - - if (dwords % vertex_size) { - fprintf(stderr, "did not request a whole number of vertices\n"); - goto do_discard; - } - - if (bad_prim_vertex_nr( primitive, vertcount )) { - fprintf(stderr, "bad_prim_vertex_nr %x %d\n", primitive, vertcount); - goto do_discard; - } - - if (used < 8) - goto do_discard; - } - - /* Emit 3D_PRIMITIVE commands: - */ - BEGIN_BATCH(1 + dwords); - OUT_BATCH( _3DPRIMITIVE | - primitive | - (dwords-1) ); - - tmp = (GLuint *)batch_ptr; - batch_ptr += dwords * 4; - - ADVANCE_BATCH(); - - do_discard: - return tmp; -} - - /* * Copy the back buffer to the front buffer. @@ -360,9 +86,6 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv ) break; } - if (0) - intel_draw_performance_boxes( intel ); - for (i = 0 ; i < nbox; i++, pbox++) { if (pbox->x1 > pbox->x2 || @@ -646,7 +369,9 @@ void intelInitBatchBuffer( GLcontext *ctx ) { intelContextPtr intel = INTEL_CONTEXT(ctx); - if (!intel->intelScreen->allow_batchbuffer || getenv("INTEL_NO_BATCH")) { + /* AGP allocation won't work: + */ + if (1 || !intel->intelScreen->allow_batchbuffer || getenv("INTEL_NO_BATCH")) { intel->alloc.size = 8 * 1024; intel->alloc.ptr = malloc( intel->alloc.size ); intel->alloc.offset = 0; diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.h b/src/mesa/drivers/dri/i915/intel_batchbuffer.h index bd879af159c..b62c77f5bf7 100644 --- a/src/mesa/drivers/dri/i915/intel_batchbuffer.h +++ b/src/mesa/drivers/dri/i915/intel_batchbuffer.h @@ -34,10 +34,7 @@ #define BATCH_LOCALS GLubyte *batch_ptr; -/* #define VERBOSE 0 */ -#ifndef VERBOSE -extern int VERBOSE; -#endif +#define VERBOSE 1 #define BEGIN_BATCH(n) \ @@ -70,7 +67,6 @@ extern void intelDestroyBatchBuffer( GLcontext *ctx ); extern void intelStartInlinePrimitive( intelContextPtr intel, GLuint prim ); extern void intelWrapInlinePrimitive( intelContextPtr intel ); -extern void intelRestartInlinePrimitive( intelContextPtr intel ); extern GLuint *intelEmitInlinePrimitiveLocked(intelContextPtr intel, int primitive, int dwords, int vertex_size); @@ -99,25 +95,7 @@ extern void intelEmitFillBlitLocked( intelContextPtr intel, -static __inline GLuint *intelExtendInlinePrimitive( intelContextPtr intel, - GLuint dwords ) -{ - GLuint sz = dwords * sizeof(GLuint); - GLuint *ptr; - - if (intel->batch.space < sz) { - intelWrapInlinePrimitive( intel ); -/* assert(intel->batch.space >= sz); */ - } - -/* assert(intel->prim.primitive != ~0); */ - ptr = (GLuint *)intel->batch.ptr; - intel->batch.ptr += sz; - intel->batch.space -= sz; - - return ptr; -} - - +GLuint *intelExtendInlinePrimitive( intelContextPtr intel, + GLuint dwords ); #endif diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c index dad68a19ec0..699824f012c 100644 --- a/src/mesa/drivers/dri/i915/intel_context.c +++ b/src/mesa/drivers/dri/i915/intel_context.c @@ -214,7 +214,7 @@ static const struct tnl_pipeline_stage *intel_pipeline[] = { &_tnl_point_attenuation_stage, &_tnl_arb_vertex_program_stage, &_tnl_vertex_program_stage, -#if 1 +#if 0 &_intel_render_stage, /* ADD: unclipped rastersetup-to-dma */ #endif &_tnl_render_stage, diff --git a/src/mesa/drivers/dri/i915/intel_context.h b/src/mesa/drivers/dri/i915/intel_context.h index 588fc4730a5..638ada4d22e 100644 --- a/src/mesa/drivers/dri/i915/intel_context.h +++ b/src/mesa/drivers/dri/i915/intel_context.h @@ -81,6 +81,10 @@ struct intel_texture_object GLuint firstLevel; GLuint lastLevel; + /* Offset for firstLevel image: + */ + GLuint textureOffset; + /* On validation any active images held in main memory or in other * regions will be copied to this region and the old storage freed. */ @@ -97,10 +101,22 @@ struct intel_texture_image { GLuint level; GLuint face; + /* If intelImage->mt != NULL, image data is stored here. + * Else if intelImage->base.Data != NULL, image is stored there. + * Else there is no image data. + */ struct intel_mipmap_tree *mt; }; +struct intel_reloc { + GLuint *value; + GLuint delta; + GLuint *dest; +}; + +#define INTEL_MAX_FIXUP 64 + struct intel_context { GLcontext ctx; /* the parent class */ @@ -182,8 +198,11 @@ struct intel_context /* AGP memory buffer manager: */ struct bufmgr *bm; + struct bm_buffer_list *buffer_list; + + struct intel_reloc fixup[INTEL_MAX_FIXUP]; + GLuint nr_fixups; - struct intel_texture_object *CurrentTexObj[MAX_TEXTURE_UNITS]; /* State for intelvb.c and inteltris.c. */ diff --git a/src/mesa/drivers/dri/i915/intel_ioctl.c b/src/mesa/drivers/dri/i915/intel_ioctl.c index ebe2f760be6..a0300e3d22c 100644 --- a/src/mesa/drivers/dri/i915/intel_ioctl.c +++ b/src/mesa/drivers/dri/i915/intel_ioctl.c @@ -196,7 +196,7 @@ void intelFlushBatchLocked( intelContextPtr intel, } } - if (0) + if (1) intel_dump_batchbuffer( batch.start, (int *)(intel->batch.ptr - batch.used), batch.used ); diff --git a/src/mesa/drivers/dri/i915/intel_mipmap_tree.c b/src/mesa/drivers/dri/i915/intel_mipmap_tree.c index 72bc25fa529..4b067fd023d 100644 --- a/src/mesa/drivers/dri/i915/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i915/intel_mipmap_tree.c @@ -29,6 +29,7 @@ #include "intel_mipmap_tree.h" #include "intel_regions.h" #include "bufmgr.h" +#include "enums.h" static GLenum target_to_target( GLenum target ) { @@ -59,6 +60,12 @@ struct intel_mipmap_tree *intel_miptree_create( struct intel_context *intel, GLboolean ok; struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1); + _mesa_printf("%s target %s format %s level %d..%d\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(target), + _mesa_lookup_enum_by_nr(internal_format), + first_level, + last_level); + mt->target = target_to_target(target); mt->internal_format = internal_format; mt->first_level = first_level; @@ -125,6 +132,11 @@ GLboolean intel_miptree_match_image( struct intel_mipmap_tree *mt, GLuint face, GLuint level ) { + _mesa_printf("%s %d %d/%d %d/%d\n", __FUNCTION__, + image->Border, + image->InternalFormat, mt->internal_format, + image->IsCompressed, mt->compressed); + /* Images with borders are never pulled into mipmap trees. */ if (image->Border) @@ -134,6 +146,11 @@ GLboolean intel_miptree_match_image( struct intel_mipmap_tree *mt, image->IsCompressed != mt->compressed) return GL_FALSE; + _mesa_printf("%s: %d/%d %d/%d %d/%d\n", __FUNCTION__, + image->Width, mt->offset[face][level].width, + image->Height, mt->offset[face][level].height, + image->Depth, mt->offset[face][level].depth); + /* Test image dimensions against the base level image adjusted for * minification. This will also catch images not present in the * tree, changed targets, etc. @@ -143,34 +160,47 @@ GLboolean intel_miptree_match_image( struct intel_mipmap_tree *mt, image->Depth != mt->offset[face][level].depth) return GL_FALSE; + + _mesa_printf("%s: success\n", __FUNCTION__); return GL_TRUE; } +GLuint intel_miptree_image_offset(struct intel_mipmap_tree *mt, + GLuint face, + GLuint level) +{ + return (mt->offset[face][level].x + + mt->offset[face][level].y * mt->pitch) * mt->cpp; +} + + + + GLubyte *intel_miptree_image_map(struct intel_context *intel, struct intel_mipmap_tree *mt, GLuint face, GLuint level, GLuint *stride) { - GLubyte *img = intel_region_map(intel, mt->region); + _mesa_printf("%s\n", __FUNCTION__); if (stride) *stride = mt->pitch * mt->cpp; - return img + (mt->offset[face][level].x + - mt->offset[face][level].y * mt->pitch) * mt->cpp; + return (intel_region_map(intel, mt->region) + + intel_miptree_image_offset(mt, face, level)); } void intel_miptree_image_unmap(struct intel_context *intel, struct intel_mipmap_tree *mt) { + _mesa_printf("%s\n", __FUNCTION__); intel_region_unmap(intel, mt->region); } - /* Upload data for a particular image. * * TODO: 3D textures @@ -181,6 +211,7 @@ void intel_miptree_image_data(struct intel_context *intel, GLuint level, void *src, GLuint src_pitch ) { + _mesa_printf("%s\n", __FUNCTION__); intel_region_data(intel, dst->region, dst->offset[face][level].x, @@ -199,6 +230,7 @@ void intel_miptree_image_copy( struct intel_context *intel, GLuint face, GLuint level, struct intel_mipmap_tree *src ) { + _mesa_printf("%s\n", __FUNCTION__); assert(src->offset[face][level].width == dst->offset[face][level].width); diff --git a/src/mesa/drivers/dri/i915/intel_mipmap_tree.h b/src/mesa/drivers/dri/i915/intel_mipmap_tree.h index 2064f65bad1..e9b2279cff8 100644 --- a/src/mesa/drivers/dri/i915/intel_mipmap_tree.h +++ b/src/mesa/drivers/dri/i915/intel_mipmap_tree.h @@ -131,6 +131,16 @@ GLubyte *intel_miptree_image_map( struct intel_context *intel, void intel_miptree_image_unmap( struct intel_context *intel, struct intel_mipmap_tree *mt ); + +/* Return the linear offset of an image relative to the start of the + * tree: + */ +GLuint intel_miptree_image_offset( struct intel_mipmap_tree *mt, + GLuint face, + GLuint level ); + + + /* Upload an image into a tree */ void intel_miptree_image_data(struct intel_context *intel, diff --git a/src/mesa/drivers/dri/i915/intel_regions.c b/src/mesa/drivers/dri/i915/intel_regions.c index a90795d82f0..2709c068d0f 100644 --- a/src/mesa/drivers/dri/i915/intel_regions.c +++ b/src/mesa/drivers/dri/i915/intel_regions.c @@ -48,6 +48,7 @@ */ GLubyte *intel_region_map(struct intel_context *intel, struct intel_region *region) { + _mesa_printf("%s\n", __FUNCTION__); if (!region->map_refcount++) { region->map = bmMapBuffer(intel->bm, region->buffer, 0); } @@ -58,6 +59,7 @@ GLubyte *intel_region_map(struct intel_context *intel, struct intel_region *regi void intel_region_unmap(struct intel_context *intel, struct intel_region *region) { + _mesa_printf("%s\n", __FUNCTION__); if (!--region->map_refcount) { bmUnmapBuffer(intel->bm, region->buffer); } @@ -70,6 +72,8 @@ struct intel_region *intel_region_alloc( struct intel_context *intel, { struct intel_region *region = calloc(sizeof(*region), 1); + _mesa_printf("%s\n", __FUNCTION__); + region->cpp = cpp; region->pitch = pitch; region->height = height; /* needed? */ @@ -201,6 +205,8 @@ void intel_region_data(struct intel_context *intel, GLuint srcx, GLuint srcy, GLuint width, GLuint height) { + _mesa_printf("%s\n", __FUNCTION__); + LOCK_HARDWARE(intel); _mesa_copy_rect(intel_region_map(intel, dst), @@ -232,6 +238,8 @@ void intel_region_copy( struct intel_context *intel, unsigned src_offset; struct bm_buffer_list *list = bmNewBufferList(); + _mesa_printf("%s\n", __FUNCTION__); + assert(src->cpp == dst->cpp); LOCK_HARDWARE(intel); @@ -282,6 +290,8 @@ void intel_region_fill( struct intel_context *intel, unsigned dst_offset; struct bm_buffer_list *list = bmNewBufferList(); + _mesa_printf("%s\n", __FUNCTION__); + LOCK_HARDWARE(intel); bmAddBuffer(intel->bm, list, dst->buffer, BM_WRITE, NULL, &dst_offset); diff --git a/src/mesa/drivers/dri/i915/intel_render.c b/src/mesa/drivers/dri/i915/intel_render.c index d9438ba0fd8..1d7811eb696 100644 --- a/src/mesa/drivers/dri/i915/intel_render.c +++ b/src/mesa/drivers/dri/i915/intel_render.c @@ -199,6 +199,10 @@ static GLboolean intel_run_render( GLcontext *ctx, struct vertex_buffer *VB = &tnl->vb; GLuint i; + /* disabled + */ + return GL_TRUE; + /* Don't handle clipping or indexed vertices. */ if (intel->RenderIndex != 0 || diff --git a/src/mesa/drivers/dri/i915/intel_tex.h b/src/mesa/drivers/dri/i915/intel_tex.h index 9ce775270f2..c3f3cdd0531 100644 --- a/src/mesa/drivers/dri/i915/intel_tex.h +++ b/src/mesa/drivers/dri/i915/intel_tex.h @@ -82,7 +82,14 @@ void intelTexSubImage1D(GLcontext *ctx, GLuint intel_validate_mipmap_tree( struct intel_context *intel, struct intel_texture_object *intelObj ); +void intel_add_texoffset_fixup( struct intel_context *intel, + GLuint unit, + GLuint *ptr ); +void intel_apply_fixups( struct intel_context *intel ); +GLboolean intel_prevalidate_buffers( struct intel_context *intel ); +GLboolean intel_validate_buffers( struct intel_context *intel ); +void intel_fence_buffers( struct intel_context *intel ); #endif diff --git a/src/mesa/drivers/dri/i915/intel_tex_image.c b/src/mesa/drivers/dri/i915/intel_tex_image.c index 0cb553c554f..d307e507b54 100644 --- a/src/mesa/drivers/dri/i915/intel_tex_image.c +++ b/src/mesa/drivers/dri/i915/intel_tex_image.c @@ -65,6 +65,8 @@ static void guess_and_alloc_mipmap_tree( struct intel_context *intel, GLuint l2width, l2height, l2depth; GLuint i; + _mesa_printf("%s\n", __FUNCTION__); + if (intelImage->base.Border) return; @@ -121,6 +123,8 @@ static void guess_and_alloc_mipmap_tree( struct intel_context *intel, depth, intelImage->base.TexFormat->TexelBytes, intelImage->base.IsCompressed ); + + _mesa_printf("%s - success\n", __FUNCTION__); } @@ -161,6 +165,11 @@ static void intelTexImage(GLcontext *ctx, GLint texelBytes, sizeInBytes; GLuint dstRowStride; + _mesa_printf("%s target %s level %d %dx%d border %d\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(target), + level, + width, height, border); + intelImage->face = target_to_face( target ); intelImage->level = level; @@ -219,15 +228,23 @@ static void intelTexImage(GLcontext *ctx, LOCK_HARDWARE(intel); if (intelObj->mt && + intelObj->mt != intelImage->mt && intel_miptree_match_image(intelObj->mt, &intelImage->base, intelImage->face, intelImage->level)) { + if (intelImage->mt) + intel_miptree_release(intel, intelImage->mt); + + intelImage->mt = intel_miptree_reference(intelObj->mt); + } + + if (intelImage->mt) { texImage->Data = intel_miptree_image_map(intel, - intelObj->mt, + intelImage->mt, intelImage->face, intelImage->level, &dstRowStride); - } + } else { /* Allocate regular memory and store the image there temporarily. */ if (texImage->IsCompressed) { diff --git a/src/mesa/drivers/dri/i915/intel_tex_subimage.c b/src/mesa/drivers/dri/i915/intel_tex_subimage.c index 5c5e4a2b313..4c7910ffa8f 100644 --- a/src/mesa/drivers/dri/i915/intel_tex_subimage.c +++ b/src/mesa/drivers/dri/i915/intel_tex_subimage.c @@ -3,6 +3,7 @@ #include "mtypes.h" #include "texobj.h" #include "texstore.h" +#include "enums.h" #include "intel_context.h" #include "intel_tex.h" @@ -24,6 +25,12 @@ static void intelTexSubimage (GLcontext *ctx, GLuint dstImageStride = 0; GLuint dstRowStride; + _mesa_printf("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(target), + level, + xoffset, yoffset, + width, height); + pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, format, type, pixels, packing, "glTexSubImage2D"); if (!pixels) diff --git a/src/mesa/drivers/dri/i915/intel_tex_validate.c b/src/mesa/drivers/dri/i915/intel_tex_validate.c index e99f91cc776..14f6c44b396 100644 --- a/src/mesa/drivers/dri/i915/intel_tex_validate.c +++ b/src/mesa/drivers/dri/i915/intel_tex_validate.c @@ -4,7 +4,7 @@ #include "intel_context.h" #include "intel_mipmap_tree.h" #include "intel_tex.h" - +#include "bufmgr.h" /** * Compute which mipmap levels that really need to be sent to the hardware. @@ -96,9 +96,11 @@ static void copy_image_data_to_tree( struct intel_context *intel, /* */ -GLuint intel_validate_mipmap_tree( struct intel_context *intel, - struct intel_texture_object *intelObj ) +static GLuint intel_finalize_mipmap_tree( struct intel_context *intel, GLuint unit ) { + struct gl_texture_object *tObj = intel->ctx.Texture.Unit[unit]._Current; + struct intel_texture_object *intelObj = intel_texture_object(tObj); + GLuint face, i; GLuint nr_faces = 0; struct intel_texture_image *firstImage; @@ -139,6 +141,12 @@ GLuint intel_validate_mipmap_tree( struct intel_context *intel, /* Check tree can hold all active levels. Check tree matches * target, imageFormat, etc. + * + * XXX: For some layouts (eg i945?), the test might have to be + * first_level == firstLevel, as the tree isn't valid except at the + * original start level. Hope to get around this by + * programming minLod, maxLod, baseLevel into the hardware and + * leaving the tree alone. */ if (intelObj->mt && ((intelObj->mt->first_level > intelObj->firstLevel) || @@ -152,7 +160,6 @@ GLuint intel_validate_mipmap_tree( struct intel_context *intel, /* May need to create a new tree: */ if (!intelObj->mt) { - assert(!firstImage->mt); intelObj->mt = intel_miptree_create(intel, intelObj->base.Target, firstImage->base.InternalFormat, @@ -165,13 +172,9 @@ GLuint intel_validate_mipmap_tree( struct intel_context *intel, firstImage->base.IsCompressed); } - assert(intelObj->mt); - - assert(firstImage->mt == intelObj->mt || - firstImage->mt == NULL); - + /* Pull in any images not in the object's tree: + */ nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; - for (face = 0; face < nr_faces; face++) { for (i = intelObj->firstLevel; i < intelObj->lastLevel; i++) { struct intel_texture_image *intelImage = @@ -190,9 +193,105 @@ GLuint intel_validate_mipmap_tree( struct intel_context *intel, return GL_TRUE; } +void intel_add_texoffset_fixup( struct intel_context *intel, + GLuint unit, + GLuint *ptr ) +{ + struct gl_texture_object *tObj = intel->ctx.Texture.Unit[unit]._Current; + struct intel_texture_object *intelObj = intel_texture_object(tObj); + +#if 0 + struct intel_reloc *f = &intel->fixup[intel->nr_fixups++]; + assert(intel->nr_fixups <= INTEL_MAX_FIXUP); + f->dest = ptr; + f->value = &intelObj->textureOffset; + f->delta = (intel->intelScreen->tex.offset + + intel_miptree_image_offset(intelObj->mt, 0, intelObj->firstLevel)); +#else + *ptr = (intelObj->textureOffset + + intel->intelScreen->tex.offset + + intel_miptree_image_offset(intelObj->mt, 0, intelObj->firstLevel)); + *ptr = 9999; +#endif +} + +/* Fix up the command buffer: + */ +void intel_apply_fixups( struct intel_context *intel ) +{ + GLuint i; + + for (i = 0; i < intel->nr_fixups; i++) { + struct intel_reloc *f = &intel->fixup[i]; + *f->dest = *f->value + f->delta; + } + + intel->nr_fixups = 0; +} +/* One upshot of the new manager is that it should be possible to tell + * ahead of time whether a certain set of buffers will cause a + * fallback. + * + * Unless we do this we either have to a) hold the DRI lock + * while emitting all vertices and fire after each vertex buffer, or + * b) build a fallback path that operates on i915 command streams + * rather than the state in the GLcontext. + */ +GLboolean intel_prevalidate_buffers( struct intel_context *intel ) +{ + return GL_TRUE; /* never fallback */ +} +GLboolean intel_validate_buffers( struct intel_context *intel ) +{ + GLcontext *ctx = &intel->ctx; + GLboolean ok = GL_TRUE; + GLuint i; + + _mesa_printf("%s\n", __FUNCTION__); + + assert(intel->locked); + assert (!intel->buffer_list); + + intel->buffer_list = bmNewBufferList(); + + /* Add the color and depth buffers: + */ + + /* Add each enabled texture: + */ + for (i = 0 ; i < ctx->Const.MaxTextureUnits && ok ; i++) { + if (ctx->Texture.Unit[i]._ReallyEnabled) { + struct gl_texture_object *tObj = intel->ctx.Texture.Unit[i]._Current; + struct intel_texture_object *intelObj = intel_texture_object(tObj); + + ok = intel_finalize_mipmap_tree( intel, i ); + if (ok) { + bmAddBuffer(intel->bm, + intel->buffer_list, + intelObj->mt->region->buffer, + BM_READ, + NULL, + &intelObj->textureOffset); + } + } + } + + ok = bmValidateBufferList(intel->bm, intel->buffer_list, 0); + assert(ok); + return ok; +} + +void intel_fence_buffers( struct intel_context *intel ) +{ + assert(intel->locked); + assert(intel->buffer_list); + bmFenceBufferList(intel->bm, intel->buffer_list); + bmFreeBufferList(intel->buffer_list); + intel->buffer_list = NULL; +} diff --git a/src/mesa/drivers/dri/i915/intel_tris.c b/src/mesa/drivers/dri/i915/intel_tris.c index cef6db7a195..f99f0a393e9 100644 --- a/src/mesa/drivers/dri/i915/intel_tris.c +++ b/src/mesa/drivers/dri/i915/intel_tris.c @@ -42,10 +42,131 @@ #include "intel_batchbuffer.h" #include "intel_reg.h" #include "intel_span.h" +#include "intel_tex.h" static void intelRenderPrimitive( GLcontext *ctx, GLenum prim ); static void intelRasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim ); +/* The simplest but least-good technique for integrating new buffer + * management: + * + * LOCK_HARDWARE + * validate_buffers + * emit_state to batch + * emit_vertices to batch + * flush batch + * fence_buffers + * UNLOCK_HARDWARE + * + * Will look later at ways to get the emit_state and emit_vertices out + * of the locked region - vertex buffers, second batch buffer for + * primitives, relocation fixups for texture addresses. + */ +static void intel_flush_inline_primitive( GLcontext *ctx ) +{ + intelContextPtr intel = INTEL_CONTEXT( ctx ); + GLuint used = intel->batch.ptr - intel->prim.start_ptr; + + assert(intel->prim.primitive != ~0); + + if (used < 8) + goto do_discard; + + *(int *)intel->prim.start_ptr = (_3DPRIMITIVE | + intel->prim.primitive | + (used/4-2)); + + goto finished; + + do_discard: + intel->batch.ptr -= used; + intel->batch.space += used; + assert(intel->batch.space >= 0); + + finished: + intel->prim.primitive = ~0; + intel->prim.start_ptr = 0; + intel->prim.flush = 0; + + intelFlushBatch(intel, GL_TRUE); + intel_fence_buffers(intel); + UNLOCK_HARDWARE(intel); + + +} + + +/* Emit a primitive referencing vertices in a vertex buffer. + */ +void intelStartInlinePrimitive( intelContextPtr intel, GLuint prim ) +{ + BATCH_LOCALS; + + fprintf(stderr, "%s %x\n", __FUNCTION__, prim); + + + /* Finish any in-progress primitive: + */ + INTEL_FIREVERTICES( intel ); + + LOCK_HARDWARE(intel); + intel_validate_buffers( intel ); + intel->vtbl.emit_state( intel ); + + /* Make sure there is some space in this buffer: + */ + if (intel->vertex_size * 10 * sizeof(GLuint) >= intel->batch.space) + intelFlushBatch(intel, GL_TRUE); + + if (((int)intel->batch.ptr) & 0x4) { + BEGIN_BATCH(1); + OUT_BATCH(0); + ADVANCE_BATCH(); + } + + /* Emit a slot which will be filled with the inline primitive + * command later. + */ + BEGIN_BATCH(2); + OUT_BATCH( 0 ); + + intel->prim.start_ptr = batch_ptr; + intel->prim.primitive = prim; + intel->prim.flush = intel_flush_inline_primitive; + + OUT_BATCH( 0 ); + ADVANCE_BATCH(); +} + + +void intelWrapInlinePrimitive( intelContextPtr intel ) +{ + GLuint prim = intel->prim.primitive; + + intel_flush_inline_primitive( &intel->ctx ); + intelFlushBatch(intel, GL_TRUE); + intelStartInlinePrimitive( intel, prim ); +} + +GLuint *intelExtendInlinePrimitive( intelContextPtr intel, + GLuint dwords ) +{ + GLuint sz = dwords * sizeof(GLuint); + GLuint *ptr; + + if (intel->batch.space < sz) { + intelWrapInlinePrimitive( intel ); + } + + ptr = (GLuint *)intel->batch.ptr; + intel->batch.ptr += sz; + intel->batch.space -= sz; + + return ptr; +} + + + /*********************************************************************** * Emit primitives as inline vertices * ***********************************************************************/ @@ -520,22 +641,6 @@ intel_fallback_line( intelContextPtr intel, } -static void -intel_fallback_point( intelContextPtr intel, - intelVertex *v0 ) -{ - GLcontext *ctx = &intel->ctx; - SWvertex v[1]; - - if (0) - fprintf(stderr, "\n%s\n", __FUNCTION__); - - _swsetup_Translate( ctx, v0, &v[0] ); - intelSpanRenderStart( ctx ); - _swrast_Point( ctx, &v[0] ); - intelSpanRenderFinish( ctx ); -} - /**********************************************************************/ @@ -630,12 +735,8 @@ static void intelFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, -#define POINT_FALLBACK (0) -#define LINE_FALLBACK (DD_LINE_STIPPLE) -#define TRI_FALLBACK (0) -#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK|\ - DD_TRI_STIPPLE|DD_POINT_ATTEN) -#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED) +#define ANY_FALLBACK_FLAGS (DD_LINE_STIPPLE | DD_TRI_STIPPLE | DD_POINT_ATTEN) +#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE | DD_TRI_OFFSET | DD_TRI_UNFILLED) void intelChooseRenderState(GLcontext *ctx) { @@ -672,19 +773,14 @@ void intelChooseRenderState(GLcontext *ctx) intel->draw_tri = intel_draw_triangle; } +#if 0 /* Hook in fallbacks for specific primitives. */ if (flags & ANY_FALLBACK_FLAGS) { - if (flags & POINT_FALLBACK) - intel->draw_point = intel_fallback_point; - - if (flags & LINE_FALLBACK) + if (flags & DD_LINE_STIPPLE) intel->draw_line = intel_fallback_line; - if (flags & TRI_FALLBACK) - intel->draw_tri = intel_fallback_tri; - if ((flags & DD_TRI_STIPPLE) && !intel->hw_stipple) intel->draw_tri = intel_fallback_tri; @@ -693,6 +789,8 @@ void intelChooseRenderState(GLcontext *ctx) index |= INTEL_FALLBACK_BIT; } +#endif + } if (intel->RenderIndex != index) { @@ -765,8 +863,13 @@ static void intelRenderStart( GLcontext *ctx ) static void intelRenderFinish( GLcontext *ctx ) { - if (INTEL_CONTEXT(ctx)->RenderIndex & INTEL_FALLBACK_BIT) + struct intel_context *intel = intel_context(ctx); + + if (intel->RenderIndex & INTEL_FALLBACK_BIT) _swrast_flush( ctx ); + + if (intel->prim.flush) + intel->prim.flush(ctx); }