diff options
author | Keith Whitwell <keith@tungstengraphics.com> | 2006-02-22 15:16:01 +0000 |
---|---|---|
committer | Keith Whitwell <keith@tungstengraphics.com> | 2006-02-22 15:16:01 +0000 |
commit | 9c02649d1821361225672d70090a0449d3c845b4 (patch) | |
tree | 124cb0c8b37b6f53df42ae7f2e49596e870f85cd /src | |
parent | 2c34704e41890b090b096de86adfa68e91746666 (diff) |
Introduce fixup/relocation lists for dma buffers.
Diffstat (limited to 'src')
50 files changed, 2587 insertions, 2761 deletions
diff --git a/src/mesa/drivers/dri/i915/Makefile b/src/mesa/drivers/dri/i915/Makefile index c46d9c2b630..d1dd2d6a513 100644 --- a/src/mesa/drivers/dri/i915/Makefile +++ b/src/mesa/drivers/dri/i915/Makefile @@ -7,6 +7,7 @@ LIBNAME = i915_dri.so DRIVER_SOURCES = \ bufmgr_fake.c \ intel_regions.c \ + intel_batchbuffer.c \ intel_mipmap_tree.c \ i915_tex_layout.c \ intel_tex_image.c \ @@ -15,6 +16,11 @@ DRIVER_SOURCES = \ intel_tex_validate.c \ intel_tex_format.c \ intel_tex.c \ + intel_pixel.c \ + intel_pixel_copy.c \ + intel_pixel_read.c \ + intel_pixel_draw.c \ + intel_buffers.c \ intel_blit.c \ i915_tex.c \ i915_texstate.c \ @@ -26,10 +32,8 @@ DRIVER_SOURCES = \ i915_state.c \ i915_texprog.c \ i915_vtbl.c \ - intel_batchbuffer.c \ intel_context.c \ intel_ioctl.c \ - intel_pixel.c \ intel_screen.c \ intel_span.c \ intel_state.c \ diff --git a/src/mesa/drivers/dri/i915/bufmgr.h b/src/mesa/drivers/dri/i915/bufmgr.h index 64affa09697..bf740274255 100644 --- a/src/mesa/drivers/dri/i915/bufmgr.h +++ b/src/mesa/drivers/dri/i915/bufmgr.h @@ -10,9 +10,23 @@ /* The buffer manager context. Opaque. */ struct bufmgr; -struct bm_buffer_list; -struct bufmgr *bm_fake_intel_Attach( struct intel_context *intel ); +#define BM_LIST_MAX 32 + +/* List of buffers to validate. Probably better managed by the client: + */ +struct bm_buffer_list { + struct { + unsigned buffer; + unsigned *offset_return; + unsigned *memtype_return; + } elem[BM_LIST_MAX]; + + unsigned nr; +}; + + +struct bufmgr *bm_fake_intel_Attach( struct intel_context *intel ); /* struct bufmgr *bmCreate( ... ); */ /* struct bufmgr *bmAttach( ... ); */ @@ -58,7 +72,8 @@ int bmInitPool( struct bufmgr *, #define BM_NO_EVICT 0x40 #define BM_NO_MOVE 0x80 /* not yet used */ #define BM_NO_ALLOC 0x100 /* legacy "fixed" buffers only */ - +#define BM_CLIENT 0x200 /* for map - pointer will be accessed + * without dri lock */ #define BM_MEM_MASK (BM_MEM_LOCAL|BM_MEM_AGP|BM_MEM_VRAM) diff --git a/src/mesa/drivers/dri/i915/bufmgr_fake.c b/src/mesa/drivers/dri/i915/bufmgr_fake.c index 5baebc02cb6..9e6fb36fd47 100644 --- a/src/mesa/drivers/dri/i915/bufmgr_fake.c +++ b/src/mesa/drivers/dri/i915/bufmgr_fake.c @@ -21,9 +21,6 @@ struct _mesa_HashTable; static int delayed_free( struct bufmgr *bm ); -/* Maximum number of buffers to pass to bmValidateBufferList: - */ -#define BM_LIST_MAX 32 #define BM_POOL_MAX 8 @@ -72,17 +69,6 @@ struct bufmgr { }; -/* List of buffers to validate: - */ -struct bm_buffer_list { - struct { - unsigned buffer; - unsigned *offset_return; - unsigned *memtype_return; - } elem[BM_LIST_MAX]; - - unsigned nr; -}; @@ -145,20 +131,22 @@ static struct block *alloc_block( struct bufmgr *bm, { GLuint i; - for (i = 0; i < bm->nr_pools; i++) { - struct block *block; - - if (bm->pool[i].flags & BM_NO_ALLOC) - continue; - - if ((bm->pool[i].flags & flags & BM_MEM_MASK) == 0) - continue; - - block = alloc_from_pool(bm, i, size, align); - if (block) - return block; + if (!(flags & BM_CLIENT)) { + for (i = 0; i < bm->nr_pools; i++) { + struct block *block; + + if (bm->pool[i].flags & BM_NO_ALLOC) + continue; + + if ((bm->pool[i].flags & flags & BM_MEM_MASK) == 0) + continue; + + block = alloc_from_pool(bm, i, size, align); + if (block) + return block; + } } - + if (flags & BM_MEM_LOCAL) return alloc_local(size); @@ -166,14 +154,15 @@ static struct block *alloc_block( struct bufmgr *bm, } static int bmAllocMem( struct bufmgr *bm, - struct buffer *buf ) + struct buffer *buf, + GLuint flags ) { delayed_free(bm); buf->block = alloc_block(bm, buf->size, buf->alignment, - buf->flags); + buf->flags | flags); if (buf->block) buf->block->buf = buf; @@ -191,30 +180,43 @@ static int bmAllocMem( struct bufmgr *bm, */ static void free_block( struct bufmgr *bm, struct block *block ) { + DBG("free block %p\n", block); + if (!block) return; - remove_from_list(block); + DBG("free block (mem: %d, sz %d) from buf %d\n", + block->mem_type, + block->buf->size, + block->buf->id); switch (block->mem_type) { case BM_MEM_AGP: case BM_MEM_VRAM: + remove_from_list(block); + + DBG(" - offset %x\n", block->mem->ofs); + if (bmTestFence(bm, block->fence)) { + DBG(" - free immediately\n"); mmFreeMem(block->mem); free(block); } else { + DBG(" - place on delayed_free list\n"); block->buf = NULL; insert_at_tail(&block->pool->freed, block); } break; case BM_MEM_LOCAL: + DBG(" - free local memory\n"); ALIGN_FREE(block->virtual); free(block); break; default: + DBG(" - unknown memory type\n"); free(block); break; } @@ -259,8 +261,8 @@ static int move_buffers( struct bufmgr *bm, */ for (i = 0; i < nr; i++) { if (!buffers[i]->block) { -/* if (flags & BM_NO_ALLOC) */ -/* goto cleanup; */ + if (flags & BM_NO_ALLOC) + goto cleanup; newMem[i] = alloc_block(bm, buffers[i]->size, @@ -276,8 +278,8 @@ static int move_buffers( struct bufmgr *bm, goto cleanup; /* Known issue: this assert will get hit on texture swapping. - * There's not much to do about that at this stage - it's - * tbd. + * There's not much to do about that at this stage - it's a + * todo item. */ assert(!buffers[i]->mapped); @@ -304,7 +306,7 @@ static int move_buffers( struct bufmgr *bm, * mechanisms in final version. Memcpy (or sse_memcpy) is * probably pretty good for local->agp uploads. */ - _mesa_printf("* %d\n", buffers[i]->size); + DBG("memcpy %d bytes\n", buffers[i]->size); memcpy(newMem[i]->virtual, buffers[i]->block->virtual, buffers[i]->size); @@ -535,25 +537,9 @@ unsigned bmBufferStatic(struct bufmgr *bm, } -#if 0 -/* How wise/useful is this? - */ -void bmBufferSetParams( struct bufmgr *bm, - unsigned buffer, - unsigned flags, - unsigned alignment ) -{ - struct buffer *buf = (struct buffer *)_mesa_HashLookup( bm->hash, buffer ); - assert(!buf->block); - buf->flags = flags; - buf->alignment = alignment; -} -#endif - - -/* If buffer size changes, create new buffer in local memory. - * Otherwise update in place. +/* If buffer size changes, free and reallocate. Otherwise update in + * place. */ void bmBufferData(struct bufmgr *bm, unsigned buffer, @@ -579,7 +565,7 @@ void bmBufferData(struct bufmgr *bm, buf->size = size; if (data != NULL) { - bmAllocMem(bm, buf); + bmAllocMem(bm, buf, buf->flags | flags); memcpy(buf->block->virtual, data, size); } } @@ -597,7 +583,7 @@ void bmBufferSubData(struct bufmgr *bm, DBG("bmBufferSubdata %d offset 0x%x sz 0x%x\n", buffer, offset, size); if (buf->block == 0) - bmAllocMem(bm, buf); + bmAllocMem(bm, buf, buf->flags); if (buf->block->mem_type != BM_MEM_LOCAL) bmFinishFence(bm, buf->block->fence); @@ -611,7 +597,7 @@ void bmBufferSubData(struct bufmgr *bm, */ void *bmMapBuffer( struct bufmgr *bm, unsigned buffer, - unsigned access ) + unsigned flags ) { struct buffer *buf = (struct buffer *)_mesa_HashLookup( bm->hash, buffer ); @@ -620,14 +606,14 @@ void *bmMapBuffer( struct bufmgr *bm, if (buf->mapped) return NULL; - buf->mapped = 1; - if (buf->block == 0) - bmAllocMem(bm, buf); + bmAllocMem(bm, buf, flags); if (buf->block == 0) return NULL; + buf->mapped = 1; + /* Finish any outstanding operations to/from this memory: */ if (buf->block->mem_type != BM_MEM_LOCAL) @@ -731,6 +717,7 @@ int bmValidateBufferList( struct bufmgr *bm, if (!delayed_free(bm) && !evict_lru(bm, flags)) return 0; + _mesa_printf("couldn't allocate sufficient texture memory\n"); exit(1); } @@ -739,6 +726,8 @@ int bmValidateBufferList( struct bufmgr *bm, DBG("%d: buf %d ofs 0x%x\n", i, bufs[i]->id, bufs[i]->block->mem->ofs); + assert(!bufs[i]->mapped); + if (list->elem[i].offset_return) list->elem[i].offset_return[0] = bufs[i]->block->mem->ofs; @@ -791,7 +780,6 @@ unsigned bmFenceBufferList( struct bufmgr *bm, struct bm_buffer_list *list ) */ unsigned bmSetFence( struct bufmgr *bm ) { - assert(bm->intel->batch.space == bm->intel->batch.size); assert(bm->intel->locked); return intelEmitIrqLocked( bm->intel ); diff --git a/src/mesa/drivers/dri/i915/i830_context.c b/src/mesa/drivers/dri/i915/i830_context.c index 3979f531a8b..56d03864ad4 100644 --- a/src/mesa/drivers/dri/i915/i830_context.c +++ b/src/mesa/drivers/dri/i915/i830_context.c @@ -59,7 +59,7 @@ GLboolean i830CreateContext( const __GLcontextModes *mesaVis, { struct dd_function_table functions; i830ContextPtr i830 = (i830ContextPtr) CALLOC_STRUCT(i830_context); - intelContextPtr intel = &i830->intel; + struct intel_context *intel = &i830->intel; GLcontext *ctx = &intel->ctx; if (!i830) return GL_FALSE; diff --git a/src/mesa/drivers/dri/i915/i830_context.h b/src/mesa/drivers/dri/i915/i830_context.h index 62e20d0a02e..6ab6ccb68ae 100644 --- a/src/mesa/drivers/dri/i915/i830_context.h +++ b/src/mesa/drivers/dri/i915/i830_context.h @@ -48,10 +48,8 @@ */ #define I830_DESTREG_CBUFADDR0 0 #define I830_DESTREG_CBUFADDR1 1 -#define I830_DESTREG_CBUFADDR2 2 #define I830_DESTREG_DBUFADDR0 3 #define I830_DESTREG_DBUFADDR1 4 -#define I830_DESTREG_DBUFADDR2 5 #define I830_DESTREG_DV0 6 #define I830_DESTREG_DV1 7 #define I830_DESTREG_SENABLE 8 @@ -160,7 +158,7 @@ i830CreateContext( const __GLcontextModes *mesaVis, /* i830_tex.c, i830_texstate.c */ extern void -i830UpdateTextureState( intelContextPtr intel ); +i830UpdateTextureState( struct intel_context *intel ); extern void i830InitTextureFuncs( struct dd_function_table *functions ); @@ -206,7 +204,7 @@ i830TryTextureDrawPixels( GLcontext *ctx, const GLvoid *pixels ); extern void -i830ClearWithTris( intelContextPtr intel, GLbitfield mask, +i830ClearWithTris( struct intel_context *intel, GLbitfield mask, GLboolean all, GLint cx, GLint cy, GLint cw, GLint ch); diff --git a/src/mesa/drivers/dri/i915/i830_metaops.c b/src/mesa/drivers/dri/i915/i830_metaops.c index 8984b6c6ecd..635a73041a4 100644 --- a/src/mesa/drivers/dri/i915/i830_metaops.c +++ b/src/mesa/drivers/dri/i915/i830_metaops.c @@ -58,7 +58,7 @@ do { \ * current GL state and used for other purposes than simply rendering * incoming triangles. */ -static void set_initial_state( i830ContextPtr i830 ) +static void set_initial_state( struct intel_context *intel ) { memcpy(&i830->meta, &i830->initial, sizeof(i830->meta) ); i830->meta.active = ACTIVE; @@ -66,7 +66,7 @@ static void set_initial_state( i830ContextPtr i830 ) } -static void set_no_depth_stencil_write( i830ContextPtr i830 ) +static void set_no_depth_stencil_write( struct intel_context *intel ) { /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE ) */ @@ -88,7 +88,7 @@ static void set_no_depth_stencil_write( i830ContextPtr i830 ) /* Set stencil unit to replace always with the reference value. */ -static void set_stencil_replace( i830ContextPtr i830, +static void set_stencil_replace( struct intel_context *intel, GLuint s_mask, GLuint s_clear) { @@ -140,7 +140,7 @@ static void set_stencil_replace( i830ContextPtr i830, } -static void set_color_mask( i830ContextPtr i830, GLboolean state ) +static void set_color_mask( struct intel_context *intel, GLboolean state ) { const GLuint mask = ((1 << WRITEMASK_RED_SHIFT) | (1 << WRITEMASK_GREEN_SHIFT) | @@ -161,7 +161,7 @@ static void set_color_mask( i830ContextPtr i830, GLboolean state ) /* Installs a one-stage passthrough texture blend pipeline. Is there * more that can be done to turn off texturing? */ -static void set_no_texture( i830ContextPtr i830 ) +static void set_no_texture( struct intel_context *intel ) { static const struct gl_tex_env_combine_state comb = { GL_NONE, GL_NONE, @@ -181,7 +181,7 @@ static void set_no_texture( i830ContextPtr i830 ) /* Set up a single element blend stage for 'replace' texturing with no * funny ops. */ -static void enable_texture_blend_replace( i830ContextPtr i830, +static void enable_texture_blend_replace( struct intel_context *intel, GLenum format ) { static const struct gl_tex_env_combine_state comb = { @@ -207,7 +207,7 @@ static void enable_texture_blend_replace( i830ContextPtr i830, /* Set up an arbitary piece of memory as a rectangular texture * (including the front or back buffer). */ -static void set_tex_rect_source( i830ContextPtr i830, +static void set_tex_rect_source( struct intel_context *intel, GLuint offset, GLuint width, GLuint height, @@ -249,17 +249,17 @@ static void set_tex_rect_source( i830ContextPtr i830, /* Select between front and back draw buffers. */ -static void set_draw_offset( i830ContextPtr i830, +static void set_draw_offset( struct intel_context *intel, GLuint offset ) { - i830->meta.Buffer[I830_DESTREG_CBUFADDR2] = offset; +/* i830->meta.Buffer[I830_DESTREG_CBUFADDR2] = offset; */ i830->meta.emitted &= ~I830_UPLOAD_BUFFERS; } /* Setup an arbitary draw format, useful for targeting * texture or agp memory. */ -static void set_draw_format( i830ContextPtr i830, +static void set_draw_format( struct intel_context *intel, GLuint format, GLuint depth_format) { @@ -271,7 +271,7 @@ static void set_draw_format( i830ContextPtr i830, } -static void set_vertex_format( i830ContextPtr i830 ) +static void set_vertex_format( struct intel_context *intel ) { i830->meta.Ctx[I830_CTXREG_VF] = (_3DSTATE_VFT0_CMD | VFT0_TEX_COUNT(1) | @@ -287,448 +287,6 @@ static void set_vertex_format( i830ContextPtr i830 ) } -static void draw_quad(i830ContextPtr i830, - GLfloat x0, GLfloat x1, - GLfloat y0, GLfloat y1, - GLubyte red, GLubyte green, - GLubyte blue, GLubyte alpha, - GLfloat s0, GLfloat s1, - GLfloat t0, GLfloat t1 ) -{ -#if 0 - GLuint vertex_size = 8; - GLuint *vb = intelEmitInlinePrimitiveLocked( &i830->intel, - PRIM3D_TRIFAN, - 4*vertex_size, - vertex_size ); - intelVertex tmp; - int i; - - -/* fprintf(stderr, "%s: %f,%f-%f,%f 0x%x%x%x%x %f,%f-%f,%f\n", */ -/* __FUNCTION__, */ -/* x0,y0,x1,y1,red,green,blue,alpha,s0,t0,s1,t1); */ - - - /* initial vertex, left bottom */ - tmp.v.x = x0; - tmp.v.y = y0; - tmp.v.z = 1.0; - tmp.v.w = 1.0; - tmp.v.color.red = red; - tmp.v.color.green = green; - tmp.v.color.blue = blue; - tmp.v.color.alpha = alpha; - tmp.v.specular.red = 0; - tmp.v.specular.green = 0; - tmp.v.specular.blue = 0; - tmp.v.specular.alpha = 0; - tmp.v.u0 = s0; - tmp.v.v0 = t0; - for (i = 0 ; i < 8 ; i++) - vb[i] = tmp.ui[i]; - - /* right bottom */ - vb += 8; - tmp.v.x = x1; - tmp.v.u0 = s1; - for (i = 0 ; i < 8 ; i++) - vb[i] = tmp.ui[i]; - - /* right top */ - vb += 8; - tmp.v.y = y1; - tmp.v.v0 = t1; - for (i = 0 ; i < 8 ; i++) - vb[i] = tmp.ui[i]; - - /* left top */ - vb += 8; - tmp.v.x = x0; - tmp.v.u0 = s0; - for (i = 0 ; i < 8 ; i++) - vb[i] = tmp.ui[i]; - -/* fprintf(stderr, "%s: DV1: %x\n", */ -/* __FUNCTION__, i830->meta.Buffer[I830_DESTREG_DV1]); */ -#endif -} - -void -i830ClearWithTris(intelContextPtr intel, GLbitfield mask, - GLboolean all, - GLint cx, GLint cy, GLint cw, GLint ch) -{ - i830ContextPtr i830 = I830_CONTEXT( intel ); - __DRIdrawablePrivate *dPriv = intel->driDrawable; - intelScreenPrivate *screen = intel->intelScreen; - int x0, y0, x1, y1; - - - SET_STATE( i830, meta ); - set_initial_state( i830 ); - set_no_texture( i830 ); - set_vertex_format( i830 ); - - LOCK_HARDWARE(intel); - - if(!all) { - x0 = cx; - y0 = cy; - x1 = x0 + cw; - y1 = y0 + ch; - } else { - x0 = 0; - y0 = 0; - x1 = x0 + dPriv->w; - y1 = y0 + dPriv->h; - } - - /* Don't do any clipping to screen - these are window coordinates. - * The active cliprects will be applied as for any other geometry. - */ - - if(mask & BUFFER_BIT_FRONT_LEFT) { - set_no_depth_stencil_write( i830 ); - set_color_mask( i830, GL_TRUE ); - set_draw_offset( i830, screen->front.offset ); - draw_quad(i830, x0, x1, y0, y1, - intel->clear_red, intel->clear_green, - intel->clear_blue, intel->clear_alpha, - 0, 0, 0, 0); - } - - if(mask & BUFFER_BIT_BACK_LEFT) { - set_no_depth_stencil_write( i830 ); - set_color_mask( i830, GL_TRUE ); - set_draw_offset( i830, screen->back.offset ); - - draw_quad(i830, x0, x1, y0, y1, - intel->clear_red, intel->clear_green, - intel->clear_blue, intel->clear_alpha, - 0, 0, 0, 0); - } - - if(mask & BUFFER_BIT_STENCIL) { - set_stencil_replace( i830, - intel->ctx.Stencil.WriteMask[0], - intel->ctx.Stencil.Clear); - - set_color_mask( i830, GL_FALSE ); - set_draw_offset( i830, screen->front.offset ); - draw_quad( i830, x0, x1, y0, y1, 0, 0, 0, 0, 0, 0, 0, 0 ); - } - UNLOCK_HARDWARE(intel); - - SET_STATE( i830, state ); -} - - - - -GLboolean -i830TryTextureReadPixels( GLcontext *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *pack, - GLvoid *pixels ) -{ - i830ContextPtr i830 = I830_CONTEXT(ctx); - intelContextPtr intel = INTEL_CONTEXT(ctx); - intelScreenPrivate *screen = i830->intel.intelScreen; - GLint pitch = pack->RowLength ? pack->RowLength : width; - __DRIdrawablePrivate *dPriv = i830->intel.driDrawable; - int textureFormat; - GLenum glTextureFormat; - int src_offset = i830->meta.Buffer[I830_DESTREG_CBUFADDR2]; - int destOffset = 0; - int destFormat, depthFormat, destPitch; - drm_clip_rect_t tmp; - - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s\n", __FUNCTION__); - - - if ( ctx->_ImageTransferState || - pack->SwapBytes || - pack->LsbFirst || - !pack->Invert) { - fprintf(stderr, "%s: check_color failed\n", __FUNCTION__); - return GL_FALSE; - } - - switch (screen->fbFormat) { - case DV_PF_565: - textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565; - glTextureFormat = GL_RGB; - break; - case DV_PF_555: - textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB1555; - glTextureFormat = GL_RGBA; - break; - case DV_PF_8888: - textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888; - glTextureFormat = GL_RGBA; - break; - default: - fprintf(stderr, "%s: textureFormat failed %x\n", __FUNCTION__, - screen->fbFormat); - return GL_FALSE; - } - - - switch (type) { - case GL_UNSIGNED_SHORT_5_6_5: - if (format != GL_RGB) return GL_FALSE; - destFormat = COLR_BUF_RGB565; - depthFormat = DEPTH_FRMT_16_FIXED; - destPitch = pitch * 2; - break; - case GL_UNSIGNED_INT_8_8_8_8_REV: - if (format != GL_BGRA) return GL_FALSE; - destFormat = COLR_BUF_ARGB8888; - depthFormat = DEPTH_FRMT_24_FIXED_8_OTHER; - destPitch = pitch * 4; - break; - default: - fprintf(stderr, "%s: destFormat failed %s\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(type)); - return GL_FALSE; - } - - destFormat |= (0x02<<24); - -/* fprintf(stderr, "type: %s destFormat: %x\n", */ -/* _mesa_lookup_enum_by_nr(type), */ -/* destFormat); */ - - intelFlush( ctx ); - - SET_STATE( i830, meta ); - set_initial_state( i830 ); - set_no_depth_stencil_write( i830 ); - - LOCK_HARDWARE( intel ); - { - intelWaitForIdle( intel ); /* required by GL */ - - if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) { - UNLOCK_HARDWARE( intel ); - SET_STATE(i830, state); - fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__); - return GL_TRUE; - } - -#if 0 - /* FIXME -- Just emit the correct state - */ - if (i830SetParam(i830->driFd, I830_SETPARAM_CBUFFER_PITCH, - destPitch) != 0) { - UNLOCK_HARDWARE( intel ); - SET_STATE(i830, state); - fprintf(stderr, "%s: setparam failed\n", __FUNCTION__); - return GL_FALSE; - } -#endif - - - y = dPriv->h - y - height; - x += dPriv->x; - y += dPriv->y; - - - /* Set the frontbuffer up as a large rectangular texture. - */ - set_tex_rect_source( i830, - src_offset, - screen->width, - screen->height, - screen->front.pitch, - textureFormat ); - - - enable_texture_blend_replace( i830, glTextureFormat ); - - - /* Set the 3d engine to draw into the agp memory - */ - - set_draw_offset( i830, destOffset ); - set_draw_format( i830, destFormat, depthFormat ); - - - /* Draw a single quad, no cliprects: - */ - i830->intel.numClipRects = 1; - i830->intel.pClipRects = &tmp; - i830->intel.pClipRects[0].x1 = 0; - i830->intel.pClipRects[0].y1 = 0; - i830->intel.pClipRects[0].x2 = width; - i830->intel.pClipRects[0].y2 = height; - - draw_quad( i830, - 0, width, 0, height, - 0, 255, 0, 0, - x, x+width, y, y+height ); - - intelWindowMoved( intel ); - } - UNLOCK_HARDWARE( intel ); - intelFinish( ctx ); /* required by GL */ - SET_STATE( i830, state ); - return GL_TRUE; -} - - -GLboolean -i830TryTextureDrawPixels( GLcontext *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels ) -{ - intelContextPtr intel = INTEL_CONTEXT(ctx); - i830ContextPtr i830 = I830_CONTEXT(ctx); - GLint pitch = unpack->RowLength ? unpack->RowLength : width; - __DRIdrawablePrivate *dPriv = intel->driDrawable; - int textureFormat; - GLenum glTextureFormat; - int dst_offset = i830->meta.Buffer[I830_DESTREG_CBUFADDR2]; - int src_offset = 0; - - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s\n", __FUNCTION__); - - /* Todo -- upload images that aren't in agp space, then texture - * from them. - */ - - if ( !intelIsAgpMemory( intel, pixels, pitch*height ) ) { - fprintf(stderr, "%s: intelIsAgpMemory failed\n", __FUNCTION__); - return GL_FALSE; - } - - /* Todo -- don't want to clobber all the drawing state like we do - * for readpixels -- most of this state can be handled just fine. - */ - if ( ctx->_ImageTransferState || - unpack->SwapBytes || - unpack->LsbFirst || - ctx->Color.AlphaEnabled || - ctx->Depth.Test || - ctx->Fog.Enabled || - ctx->Scissor.Enabled || - ctx->Stencil.Enabled || - !ctx->Color.ColorMask[0] || - !ctx->Color.ColorMask[1] || - !ctx->Color.ColorMask[2] || - !ctx->Color.ColorMask[3] || - ctx->Color.ColorLogicOpEnabled || - ctx->Texture._EnabledUnits) { - fprintf(stderr, "%s: other tests failed\n", __FUNCTION__); - return GL_FALSE; - } - - /* Todo -- remove these restrictions: - */ - if (ctx->Pixel.ZoomX != 1.0F || - ctx->Pixel.ZoomY != -1.0F) - return GL_FALSE; - - - - switch (type) { - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - if (format != GL_BGRA) return GL_FALSE; - textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB1555; - glTextureFormat = GL_RGBA; - break; - case GL_UNSIGNED_SHORT_5_6_5: - if (format != GL_RGB) return GL_FALSE; - textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565; - glTextureFormat = GL_RGB; - break; - case GL_UNSIGNED_SHORT_8_8_MESA: - if (format != GL_YCBCR_MESA) return GL_FALSE; - textureFormat = (MAPSURF_422 | MT_422_YCRCB_SWAPY -/* | TM0S1_COLORSPACE_CONVERSION */ - ); - glTextureFormat = GL_YCBCR_MESA; - break; - case GL_UNSIGNED_SHORT_8_8_REV_MESA: - if (format != GL_YCBCR_MESA) return GL_FALSE; - textureFormat = (MAPSURF_422 | MT_422_YCRCB_NORMAL -/* | TM0S1_COLORSPACE_CONVERSION */ - ); - glTextureFormat = GL_YCBCR_MESA; - break; - case GL_UNSIGNED_INT_8_8_8_8_REV: - if (format != GL_BGRA) return GL_FALSE; - textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888; - glTextureFormat = GL_RGBA; - break; - default: - fprintf(stderr, "%s: destFormat failed\n", __FUNCTION__); - return GL_FALSE; - } - - intelFlush( ctx ); - - SET_STATE( i830, meta ); - - LOCK_HARDWARE( intel ); - { - intelWaitForIdle( intel ); /* required by GL */ - - y -= height; /* cope with pixel zoom */ - - if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) { - UNLOCK_HARDWARE( intel ); - SET_STATE(i830, state); - fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__); - return GL_TRUE; - } - - - y = dPriv->h - y - height; - - set_initial_state( i830 ); - - /* Set the pixel image up as a rectangular texture. - */ - set_tex_rect_source( i830, - src_offset, - width, - height, - pitch, /* XXXX!!!! -- /2 sometimes */ - textureFormat ); - - - enable_texture_blend_replace( i830, glTextureFormat ); - - - /* Draw to the current draw buffer: - */ - set_draw_offset( i830, dst_offset ); - - /* Draw a quad, use regular cliprects - */ -/* fprintf(stderr, "x: %d y: %d width %d height %d\n", x, y, width, height); */ - - draw_quad( i830, - x, x+width, y, y+height, - 0, 255, 0, 0, - 0, width, 0, height ); - - intelWindowMoved( intel ); - } - UNLOCK_HARDWARE( intel ); - intelFinish( ctx ); /* required by GL */ - - SET_STATE(i830, state); - - return GL_TRUE; -} diff --git a/src/mesa/drivers/dri/i915/i830_reg.h b/src/mesa/drivers/dri/i915/i830_reg.h index c45b88ca520..ff08683d7e3 100644 --- a/src/mesa/drivers/dri/i915/i830_reg.h +++ b/src/mesa/drivers/dri/i915/i830_reg.h @@ -407,10 +407,10 @@ #define LOGICOP_SET 0xf #define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00)) #define ENABLE_STENCIL_TEST_MASK (1<<17) -#define STENCIL_TEST_MASK(x) ((x)<<8) +#define STENCIL_TEST_MASK(x) (((x)&0xff)<<8) #define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff)) #define ENABLE_STENCIL_WRITE_MASK (1<<16) -#define STENCIL_WRITE_MASK(x) (x) +#define STENCIL_WRITE_MASK(x) ((x)&0xff) /* _3DSTATE_MODES_5, p196 */ #define _3DSTATE_MODES_5_CMD (CMD_3D|(0x0c<<24)) diff --git a/src/mesa/drivers/dri/i915/i830_state.c b/src/mesa/drivers/dri/i915/i830_state.c index 605f400c06d..f810bd1bd7a 100644 --- a/src/mesa/drivers/dri/i915/i830_state.c +++ b/src/mesa/drivers/dri/i915/i830_state.c @@ -1012,13 +1012,12 @@ static void i830_init_packets( i830ContextPtr i830 ) (BUF_3D_ID_DEPTH | BUF_3D_PITCH(screen->depth.pitch * screen->cpp) | BUF_3D_USE_FENCE); - i830->state.Buffer[I830_DESTREG_DBUFADDR2] = screen->depth.offset; +/* i830->state.Buffer[I830_DESTREG_DBUFADDR2] = screen->depth.offset; */ i830->state.Buffer[I830_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD; switch (screen->fbFormat) { - case DV_PF_555: case DV_PF_565: i830->state.Buffer[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ DSTORG_VERT_BIAS(0x8) | /* .5 */ diff --git a/src/mesa/drivers/dri/i915/i830_texblend.c b/src/mesa/drivers/dri/i915/i830_texblend.c index 49e0347643c..19560868963 100644 --- a/src/mesa/drivers/dri/i915/i830_texblend.c +++ b/src/mesa/drivers/dri/i915/i830_texblend.c @@ -101,7 +101,7 @@ static GLuint emit_factor( GLuint blendUnit, GLuint *state, GLuint count, } -static __inline__ GLuint GetTexelOp(GLint unit) +static inline GLuint GetTexelOp(GLint unit) { switch(unit) { case 0: return TEXBLENDARG_TEXEL0; diff --git a/src/mesa/drivers/dri/i915/i830_texstate.c b/src/mesa/drivers/dri/i915/i830_texstate.c index 85da0ee281f..d248eba2964 100644 --- a/src/mesa/drivers/dri/i915/i830_texstate.c +++ b/src/mesa/drivers/dri/i915/i830_texstate.c @@ -428,7 +428,7 @@ static GLboolean i830UpdateTexUnit( GLcontext *ctx, GLuint unit ) struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; if (texUnit->_ReallyEnabled && - INTEL_CONTEXT(ctx)->intelScreen->tex.size < 2048 * 1024) + intel_context(ctx)->intelScreen->tex.size < 2048 * 1024) return GL_FALSE; switch(texUnit->_ReallyEnabled) { @@ -450,7 +450,7 @@ static GLboolean i830UpdateTexUnit( GLcontext *ctx, GLuint unit ) } -void i830UpdateTextureState( intelContextPtr intel ) +void i830UpdateTextureState( struct intel_context *intel ) { i830ContextPtr i830 = I830_CONTEXT(intel); GLcontext *ctx = &intel->ctx; diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c index 6e73f83728c..47b53033cbb 100644 --- a/src/mesa/drivers/dri/i915/i830_vtbl.c +++ b/src/mesa/drivers/dri/i915/i830_vtbl.c @@ -34,7 +34,7 @@ #include "tnl/t_context.h" #include "tnl/t_vertex.h" -static GLboolean i830_check_vertex_size( intelContextPtr intel, +static GLboolean i830_check_vertex_size( struct intel_context *intel, GLuint expected ); #define SZ_TO_HW(sz) ((sz-2)&0x3) @@ -59,7 +59,7 @@ do { \ #define VRTX_TEX_SET_FMT(n, x) ((x)<<((n)*2)) #define TEXBIND_SET(n, x) ((x)<<((n)*4)) -static void i830_render_start( intelContextPtr intel ) +static void i830_render_start( struct intel_context *intel ) { GLcontext *ctx = &intel->ctx; i830ContextPtr i830 = I830_CONTEXT(intel); @@ -186,7 +186,7 @@ static void i830_render_start( intelContextPtr intel ) } } -static void i830_reduced_primitive_state( intelContextPtr intel, +static void i830_reduced_primitive_state( struct intel_context *intel, GLenum rprim ) { i830ContextPtr i830 = I830_CONTEXT(intel); @@ -217,7 +217,7 @@ static void i830_reduced_primitive_state( intelContextPtr intel, /* Pull apart the vertex format registers and figure out how large a * vertex is supposed to be. */ -static GLboolean i830_check_vertex_size( intelContextPtr intel, +static GLboolean i830_check_vertex_size( struct intel_context *intel, GLuint expected ) { i830ContextPtr i830 = I830_CONTEXT(intel); @@ -257,11 +257,11 @@ static GLboolean i830_check_vertex_size( intelContextPtr intel, return sz == expected; } -static void i830_emit_invarient_state( intelContextPtr intel ) +static void i830_emit_invarient_state( struct intel_context *intel ) { BATCH_LOCALS; - BEGIN_BATCH( 200 ); + BEGIN_BATCH(200, 0); OUT_BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(0)); OUT_BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(1)); @@ -355,7 +355,7 @@ static void i830_emit_invarient_state( intelContextPtr intel ) #define emit( intel, state, size ) \ do { \ int k; \ - BEGIN_BATCH( size / sizeof(GLuint)); \ + BEGIN_BATCH(size / sizeof(GLuint), 0); \ for (k = 0 ; k < size / sizeof(GLuint) ; k++) \ OUT_BATCH(state[k]); \ ADVANCE_BATCH(); \ @@ -364,7 +364,7 @@ do { \ /* Push the state into the sarea and/or texture memory. */ -static void i830_emit_state( intelContextPtr intel ) +static void i830_emit_state( struct intel_context *intel ) { i830ContextPtr i830 = I830_CONTEXT(intel); struct i830_hw_state *state = i830->current; @@ -405,32 +405,32 @@ static void i830_emit_state( intelContextPtr intel ) state->emitted |= dirty; } -static void i830_destroy_context( intelContextPtr intel ) +static void i830_destroy_context( struct intel_context *intel ) { _tnl_free_vertices(&intel->ctx); } -static void i830_set_draw_offset( intelContextPtr intel, int offset ) +static void i830_set_draw_offset( struct intel_context *intel, int offset ) { i830ContextPtr i830 = I830_CONTEXT(intel); I830_STATECHANGE( i830, I830_UPLOAD_BUFFERS ); - i830->state.Buffer[I830_DESTREG_CBUFADDR2] = offset; +/* i830->state.Buffer[I830_DESTREG_CBUFADDR2] = offset; */ } /* This isn't really handled at the moment. */ -static void i830_lost_hardware( intelContextPtr intel ) +static void i830_lost_hardware( struct intel_context *intel ) { I830_CONTEXT(intel)->state.emitted = 0; } -static void i830_emit_flush( intelContextPtr intel ) +static void i830_emit_flush( struct intel_context *intel ) { BATCH_LOCALS; - BEGIN_BATCH(2); + BEGIN_BATCH(2, 0); OUT_BATCH( MI_FLUSH | FLUSH_MAP_CACHE ); OUT_BATCH( 0 ); ADVANCE_BATCH(); diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c index f1b11bf95b1..0fe88794df6 100644 --- a/src/mesa/drivers/dri/i915/i915_context.c +++ b/src/mesa/drivers/dri/i915/i915_context.c @@ -69,7 +69,7 @@ static void i915InvalidateState( GLcontext *ctx, GLuint new_state ) _ac_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); _tnl_invalidate_vertex_state( ctx, new_state ); - INTEL_CONTEXT(ctx)->NewGLState |= new_state; + intel_context(ctx)->NewGLState |= new_state; /* Todo: gather state values under which tracked parameters become * invalidated, add callbacks for things like @@ -103,9 +103,8 @@ GLboolean i915CreateContext( const __GLcontextModes *mesaVis, void *sharedContextPrivate) { struct dd_function_table functions; - i915ContextPtr i915 = (i915ContextPtr) CALLOC_STRUCT(i915_context); - intelContextPtr intel = &i915->intel; - intelScreenPrivate *intelScreen; + 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; @@ -113,6 +112,7 @@ GLboolean i915CreateContext( const __GLcontextModes *mesaVis, _mesa_printf( "\ntexmem branch (i915, drop2)\n\n"); i915InitVtbl( i915 ); + i915InitMetaFuncs( i915 ); i915InitDriverFunctions( &functions ); @@ -126,49 +126,6 @@ GLboolean i915CreateContext( const __GLcontextModes *mesaVis, ctx->Const.MaxTextureImageUnits = I915_TEX_UNITS; ctx->Const.MaxTextureCoordUnits = I915_TEX_UNITS; - intel->bm = bm_fake_intel_Attach( intel ); - - bmInitPool(intel->bm, - intel->intelScreen->tex.offset, /* low offset */ - intel->intelScreen->tex.map, /* low virtual */ - intel->intelScreen->tex.size, - BM_MEM_AGP); - - intelScreen = intel->intelScreen; - - /* These are still static, but create regions for them. - */ - intel->front_region = - intel_region_create_static(intel, - BM_MEM_AGP, - intelScreen->front.offset, - intelScreen->front.map, - intelScreen->cpp, - intelScreen->front.pitch, - intelScreen->height); - - - intel->back_region = - intel_region_create_static(intel, - BM_MEM_AGP, - intelScreen->back.offset, - intelScreen->back.map, - intelScreen->cpp, - intelScreen->back.pitch, - intelScreen->height); - - /* Still assuming front.cpp == depth.cpp - */ - intel->depth_region = - intel_region_create_static(intel, - BM_MEM_AGP, - intelScreen->depth.offset, - intelScreen->depth.map, - intelScreen->cpp, - intelScreen->depth.pitch, - intelScreen->height); - - intelInitBatchBuffer(intel); /* Advertise the full hardware capabilities. The new memory * manager should cope much better with overload situations: diff --git a/src/mesa/drivers/dri/i915/i915_context.h b/src/mesa/drivers/dri/i915/i915_context.h index 0db119cd413..a50b6275fbf 100644 --- a/src/mesa/drivers/dri/i915/i915_context.h +++ b/src/mesa/drivers/dri/i915/i915_context.h @@ -53,10 +53,8 @@ */ #define I915_DESTREG_CBUFADDR0 0 #define I915_DESTREG_CBUFADDR1 1 -#define I915_DESTREG_CBUFADDR2 2 #define I915_DESTREG_DBUFADDR0 3 #define I915_DESTREG_DBUFADDR1 4 -#define I915_DESTREG_DBUFADDR2 5 #define I915_DESTREG_DV0 6 #define I915_DESTREG_DV1 7 #define I915_DESTREG_SENABLE 8 @@ -87,7 +85,6 @@ #define I915_STPREG_ST1 1 #define I915_STP_SETUP_SIZE 2 -#define I915_TEXREG_MS2 0 #define I915_TEXREG_MS3 1 #define I915_TEXREG_MS4 2 #define I915_TEXREG_SS2 3 @@ -198,6 +195,15 @@ struct i915_hw_state { GLuint ConstantSize; GLuint Program[I915_PROGRAM_SIZE]; GLuint ProgramSize; + + /* Region pointers for relocation: + */ + struct intel_region *draw_region; + struct intel_region *depth_region; + struct intel_region *tex_region[I915_TEX_UNITS]; + GLuint tex_offset[I915_TEX_UNITS]; + + GLuint active; /* I915_UPLOAD_* */ GLuint emitted; /* I915_UPLOAD_* */ }; @@ -222,20 +228,14 @@ struct i915_context }; -typedef struct i915_context *i915ContextPtr; - - #define I915_STATECHANGE(i915, flag) \ do { \ - if (0) fprintf(stderr, "I915_STATECHANGE %x in %s\n", flag, __FUNCTION__); \ INTEL_FIREVERTICES( &(i915)->intel ); \ (i915)->state.emitted &= ~(flag); \ } while (0) #define I915_ACTIVESTATE(i915, flag, mode) \ do { \ - if (0) fprintf(stderr, "I915_ACTIVESTATE %x %d in %s\n", \ - flag, mode, __FUNCTION__); \ INTEL_FIREVERTICES( &(i915)->intel ); \ if (mode) \ (i915)->state.active |= (flag); \ @@ -247,7 +247,7 @@ do { \ /*====================================================================== * i915_vtbl.c */ -extern void i915InitVtbl( i915ContextPtr i915 ); +extern void i915InitVtbl( struct i915_context *i915 ); @@ -284,7 +284,7 @@ extern GLboolean i915CreateContext( const __GLcontextModes *mesaVis, /*====================================================================== * i915_texprog.c */ -extern void i915ValidateTextureProgram( i915ContextPtr i915 ); +extern void i915ValidateTextureProgram( struct i915_context *i915 ); /*====================================================================== @@ -298,42 +298,26 @@ extern void i915_print_ureg( const char *msg, GLuint ureg ); * i915_state.c */ extern void i915InitStateFunctions( struct dd_function_table *functions ); -extern void i915InitState( i915ContextPtr i915 ); +extern void i915InitState( struct i915_context *i915 ); extern void i915_update_fog( GLcontext *ctx ); /*====================================================================== * i915_tex.c */ -extern void i915UpdateTextureState( intelContextPtr intel ); +extern void i915UpdateTextureState( struct intel_context *intel ); extern void i915InitTextureFuncs( struct dd_function_table *functions ); /*====================================================================== * i915_metaops.c */ -extern GLboolean -i915TryTextureReadPixels( GLcontext *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *pack, - GLvoid *pixels ); - -extern GLboolean -i915TryTextureDrawPixels( GLcontext *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels ); - -extern void -i915ClearWithTris( intelContextPtr intel, GLbitfield mask, - GLboolean all, GLint cx, GLint cy, GLint cw, GLint ch); +void i915InitMetaFuncs( struct i915_context *i915 ); /*====================================================================== * i915_fragprog.c */ -extern void i915ValidateFragmentProgram( i915ContextPtr i915 ); +extern void i915ValidateFragmentProgram( struct i915_context *i915 ); extern void i915InitFragProgFuncs( struct dd_function_table *functions ); /*====================================================================== diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c index 5cd6ea4de51..c35f72ba75c 100644 --- a/src/mesa/drivers/dri/i915/i915_fragprog.c +++ b/src/mesa/drivers/dri/i915/i915_fragprog.c @@ -806,7 +806,7 @@ static void check_wpos( struct i915_fragment_program *p ) static void translate_program( struct i915_fragment_program *p ) { - i915ContextPtr i915 = I915_CONTEXT(p->ctx); + struct i915_context *i915 = I915_CONTEXT(p->ctx); i915_init_program( i915, p ); check_wpos( p ); @@ -840,7 +840,7 @@ static void i915BindProgram( GLcontext *ctx, struct program *prog ) { if (target == GL_FRAGMENT_PROGRAM_ARB) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); struct i915_fragment_program *p = (struct i915_fragment_program *)prog; if (i915->current_program == p) @@ -896,7 +896,7 @@ static void i915DeleteProgram( GLcontext *ctx, struct program *prog ) { if (prog->Target == GL_FRAGMENT_PROGRAM_ARB) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); struct i915_fragment_program *p = (struct i915_fragment_program *)prog; if (i915->current_program == p) @@ -940,10 +940,10 @@ static void i915ProgramStringNotify( GLcontext *ctx, } -void i915ValidateFragmentProgram( i915ContextPtr i915 ) +void i915ValidateFragmentProgram( struct i915_context *i915 ) { GLcontext *ctx = &i915->intel.ctx; - intelContextPtr intel = INTEL_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; diff --git a/src/mesa/drivers/dri/i915/i915_metaops.c b/src/mesa/drivers/dri/i915/i915_metaops.c index b24dfe8a02a..59bd64f4425 100644 --- a/src/mesa/drivers/dri/i915/i915_metaops.c +++ b/src/mesa/drivers/dri/i915/i915_metaops.c @@ -34,39 +34,32 @@ #include "intel_screen.h" #include "intel_batchbuffer.h" #include "intel_ioctl.h" +#include "intel_regions.h" #include "i915_context.h" #include "i915_reg.h" /* A large amount of state doesn't need to be uploaded. */ -#define ACTIVE (I915_UPLOAD_PROGRAM | \ +#define ACTIVE (I915_UPLOAD_INVARIENT | \ + I915_UPLOAD_PROGRAM | \ I915_UPLOAD_STIPPLE | \ I915_UPLOAD_CTX | \ I915_UPLOAD_BUFFERS | \ I915_UPLOAD_TEX(0)) -#define SET_STATE( i915, STATE ) \ +#define SET_STATE( i915, STATE ) \ do { \ i915->current->emitted &= ~ACTIVE; \ - i915->current = &i915->STATE; \ + i915->current = &i915->STATE; \ i915->current->emitted &= ~ACTIVE; \ } while (0) -/* Operations where the 3D engine is decoupled temporarily from the - * current GL state and used for other purposes than simply rendering - * incoming triangles. - */ -static void set_initial_state( i915ContextPtr i915 ) -{ - memcpy(&i915->meta, &i915->initial, sizeof(i915->meta) ); - i915->meta.active = ACTIVE; - i915->meta.emitted = 0; -} - -static void set_no_depth_stencil_write( i915ContextPtr i915 ) +static void meta_no_depth_stencil_write( struct intel_context *intel ) { + struct i915_context *i915 = i915_context(&intel->ctx); + /* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE ) */ i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_TEST_ENABLE | @@ -82,10 +75,11 @@ static void set_no_depth_stencil_write( i915ContextPtr i915 ) /* Set stencil unit to replace always with the reference value. */ -static void set_stencil_replace( i915ContextPtr i915, +static void meta_stencil_replace( struct intel_context *intel, GLuint s_mask, GLuint s_clear) { + struct i915_context *i915 = i915_context(&intel->ctx); GLuint op = STENCILOP_REPLACE; GLuint func = COMPAREFUNC_ALWAYS; @@ -100,7 +94,6 @@ static void set_stencil_replace( i915ContextPtr i915, i915->meta.Ctx[I915_CTXREG_LIS6] &= ~(S6_DEPTH_TEST_ENABLE | S6_DEPTH_WRITE_ENABLE); - /* ctx->Driver.StencilMask( ctx, s_mask ) */ i915->meta.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; @@ -108,7 +101,6 @@ static void set_stencil_replace( i915ContextPtr i915, i915->meta.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | STENCIL_WRITE_MASK(s_mask)); - /* ctx->Driver.StencilOp( ctx, GL_REPLACE, GL_REPLACE, GL_REPLACE ) */ i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK | @@ -137,8 +129,9 @@ static void set_stencil_replace( i915ContextPtr i915, } -static void set_color_mask( i915ContextPtr i915, GLboolean state ) +static void meta_color_mask( struct intel_context *intel, GLboolean state ) { + struct i915_context *i915 = i915_context(&intel->ctx); const GLuint mask = (S5_WRITEDISABLE_RED | S5_WRITEDISABLE_GREEN | S5_WRITEDISABLE_BLUE | @@ -210,8 +203,10 @@ static void set_color_mask( i915ContextPtr i915, GLboolean state ) -static void set_no_texture( i915ContextPtr i915 ) +static void meta_no_texture( struct intel_context *intel ) { + struct i915_context *i915 = i915_context(&intel->ctx); + static const GLuint prog[] = { _3DSTATE_PIXEL_SHADER_PROGRAM, @@ -240,9 +235,10 @@ static void set_no_texture( i915ContextPtr i915 ) i915->meta.emitted &= ~I915_UPLOAD_PROGRAM; } -#if 0 -static void enable_texture_blend_replace( i915ContextPtr i915 ) +static void meta_texture_blend_replace( struct intel_context *intel ) { + struct i915_context *i915 = i915_context(&intel->ctx); + static const GLuint prog[] = { _3DSTATE_PIXEL_SHADER_PROGRAM, @@ -285,78 +281,86 @@ static void enable_texture_blend_replace( i915ContextPtr i915 ) /* Set up an arbitary piece of memory as a rectangular texture * (including the front or back buffer). */ -static void set_tex_rect_source( i915ContextPtr i915, - GLuint offset, - GLuint width, - GLuint height, - GLuint pitch, +static void meta_tex_rect_source( struct intel_context *intel, + struct intel_region *region, GLuint textureFormat ) { + struct i915_context *i915 = i915_context(&intel->ctx); GLuint unit = 0; GLint numLevels = 1; GLuint *state = i915->meta.Tex[0]; - pitch *= i915->intel.intelScreen->cpp; + GLuint pitch = region->pitch * region->cpp; /* fprintf(stderr, "%s: offset: %x w: %d h: %d pitch %d format %x\n", */ /* __FUNCTION__, offset, width, height, pitch, textureFormat ); */ - state[I915_TEXREG_MS2] = offset; - state[I915_TEXREG_MS3] = (((height - 1) << MS3_HEIGHT_SHIFT) | - ((width - 1) << MS3_WIDTH_SHIFT) | - textureFormat | - MS3_USE_FENCE_REGS); + intel_region_release(intel, &i915->meta.tex_region[0]); + intel_region_reference(&i915->meta.tex_region[0], region); + i915->meta.tex_offset[0] = 0; + + state[I915_TEXREG_MS3] = (((region->height - 1) << MS3_HEIGHT_SHIFT) | + ((region->pitch - 1) << MS3_WIDTH_SHIFT) | + textureFormat | + MS3_USE_FENCE_REGS); state[I915_TEXREG_MS4] = ((((pitch / 4) - 1) << MS4_PITCH_SHIFT) | - MS4_CUBE_FACE_ENA_MASK | - ((((numLevels-1) * 4)) << MS4_MAX_LOD_SHIFT)); + MS4_CUBE_FACE_ENA_MASK | + ((((numLevels-1) * 4)) << MS4_MAX_LOD_SHIFT)); state[I915_TEXREG_SS2] = ((FILTER_NEAREST << SS2_MIN_FILTER_SHIFT) | - (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT) | - (FILTER_NEAREST << SS2_MAG_FILTER_SHIFT)); + (MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT) | + (FILTER_NEAREST << SS2_MAG_FILTER_SHIFT)); + state[I915_TEXREG_SS3] = ((TEXCOORDMODE_WRAP << SS3_TCX_ADDR_MODE_SHIFT) | - (TEXCOORDMODE_WRAP << SS3_TCY_ADDR_MODE_SHIFT) | - (TEXCOORDMODE_WRAP << SS3_TCZ_ADDR_MODE_SHIFT) | - (unit<<SS3_TEXTUREMAP_INDEX_SHIFT)); + (TEXCOORDMODE_WRAP << SS3_TCY_ADDR_MODE_SHIFT) | + (TEXCOORDMODE_WRAP << SS3_TCZ_ADDR_MODE_SHIFT) | + (unit<<SS3_TEXTUREMAP_INDEX_SHIFT)); state[I915_TEXREG_SS4] = 0; i915->meta.emitted &= ~I915_UPLOAD_TEX(0); } -#endif /* Select between front and back draw buffers. */ -static void set_draw_offset( i915ContextPtr i915, - GLuint offset ) +static void meta_draw_region( struct intel_context *intel, + struct intel_region *draw_region, + struct intel_region *depth_region ) { - i915->meta.Buffer[I915_DESTREG_CBUFADDR2] = offset; + struct i915_context *i915 = i915_context(&intel->ctx); + + intel_region_release(intel, &i915->meta.draw_region); + intel_region_release(intel, &i915->meta.depth_region); + intel_region_reference(&i915->meta.draw_region, draw_region); + intel_region_reference(&i915->meta.depth_region, depth_region); + i915->meta.emitted &= ~I915_UPLOAD_BUFFERS; } -#if 0 /* Setup an arbitary draw format, useful for targeting texture or agp * memory. */ -static void set_draw_format( i915ContextPtr i915, +static void set_draw_format( struct intel_context *intel, GLuint format, GLuint depth_format) { + struct i915_context *i915 = i915_context(&intel->ctx); + i915->meta.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ - DSTORG_VERT_BIAS(0x8) | /* .5 */ - format | - LOD_PRECLAMP_OGL | - TEX_DEFAULT_COLOR_OGL | - depth_format); + DSTORG_VERT_BIAS(0x8) | /* .5 */ + format | + LOD_PRECLAMP_OGL | + TEX_DEFAULT_COLOR_OGL | + depth_format); i915->meta.emitted &= ~I915_UPLOAD_BUFFERS; -/* fprintf(stderr, "%s: DV1: %x\n", */ -/* __FUNCTION__, i915->meta.Buffer[I915_DESTREG_DV1]); */ } -#endif -static void set_vertex_format( i915ContextPtr i915 ) +static void set_vertex_format( struct intel_context *intel ) { + struct i915_context *i915 = i915_context(&intel->ctx); + i915->meta.Ctx[I915_CTXREG_LIS2] = (S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) | S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) | @@ -371,148 +375,50 @@ static void set_vertex_format( i915ContextPtr i915 ) i915->meta.Ctx[I915_CTXREG_LIS4] |= (S4_VFMT_COLOR | - S4_VFMT_SPEC_FOG | - S4_VFMT_XYZW); + S4_VFMT_XYZ); i915->meta.emitted &= ~I915_UPLOAD_CTX; - } -static void draw_quad(i915ContextPtr i915, - GLfloat x0, GLfloat x1, - GLfloat y0, GLfloat y1, - GLubyte red, GLubyte green, - GLubyte blue, GLubyte alpha, - GLfloat s0, GLfloat s1, - GLfloat t0, GLfloat t1 ) -{ -#if 0 - GLuint vertex_size = 8; - GLuint *vb = intelEmitInlinePrimitiveLocked( &i915->intel, - PRIM3D_TRIFAN, - 4 * vertex_size, - vertex_size ); - intelVertex tmp; - int i; - - if (0) - fprintf(stderr, "%s: %f,%f-%f,%f 0x%x%x%x%x %f,%f-%f,%f\n", - __FUNCTION__, - x0,y0,x1,y1,red,green,blue,alpha,s0,t0,s1,t1); - - - /* initial vertex, left bottom */ - tmp.v.x = x0; - tmp.v.y = y0; - tmp.v.z = 1.0; - tmp.v.w = 1.0; - tmp.v.color.red = red; - tmp.v.color.green = green; - tmp.v.color.blue = blue; - tmp.v.color.alpha = alpha; - tmp.v.specular.red = 0; - tmp.v.specular.green = 0; - tmp.v.specular.blue = 0; - tmp.v.specular.alpha = 0; - tmp.v.u0 = s0; - tmp.v.v0 = t0; - - for (i = 0 ; i < vertex_size ; i++) - vb[i] = tmp.ui[i]; - - /* right bottom */ - vb += vertex_size; - tmp.v.x = x1; - tmp.v.u0 = s1; - for (i = 0 ; i < vertex_size ; i++) - vb[i] = tmp.ui[i]; - - /* right top */ - vb += vertex_size; - tmp.v.y = y1; - tmp.v.v0 = t1; - for (i = 0 ; i < vertex_size ; i++) - vb[i] = tmp.ui[i]; - - /* left top */ - vb += vertex_size; - tmp.v.x = x0; - tmp.v.u0 = s0; - for (i = 0 ; i < vertex_size ; i++) - vb[i] = tmp.ui[i]; -#endif -} -void -i915ClearWithTris(intelContextPtr intel, GLbitfield mask, - GLboolean all, - GLint cx, GLint cy, GLint cw, GLint ch) +/* Operations where the 3D engine is decoupled temporarily from the + * current GL state and used for other purposes than simply rendering + * incoming triangles. + */ +static void install_meta_state( struct intel_context *intel ) { - i915ContextPtr i915 = i915_context( &intel->ctx ); - __DRIdrawablePrivate *dPriv = intel->driDrawable; - intelScreenPrivate *screen = intel->intelScreen; - int x0, y0, x1, y1; - - SET_STATE( i915, meta ); - set_initial_state( i915 ); - set_no_texture( i915 ); - set_vertex_format( i915 ); - - LOCK_HARDWARE(intel); - - if(!all) { - x0 = cx; - y0 = cy; - x1 = x0 + cw; - y1 = y0 + ch; - } else { - x0 = 0; - y0 = 0; - x1 = x0 + dPriv->w; - y1 = y0 + dPriv->h; - } - - /* Don't do any clipping to screen - these are window coordinates. - * The active cliprects will be applied as for any other geometry. - */ - - if (mask & BUFFER_BIT_FRONT_LEFT) { - set_no_depth_stencil_write( i915 ); - set_color_mask( i915, GL_TRUE ); - set_draw_offset( i915, screen->front.offset ); - - draw_quad(i915, x0, x1, y0, y1, - intel->clear_red, intel->clear_green, - intel->clear_blue, intel->clear_alpha, - 0, 0, 0, 0); - } - - if (mask & BUFFER_BIT_BACK_LEFT) { - set_no_depth_stencil_write( i915 ); - set_color_mask( i915, GL_TRUE ); - set_draw_offset( i915, screen->back.offset ); + struct i915_context *i915 = i915_context(&intel->ctx); + memcpy(&i915->meta, &i915->initial, sizeof(i915->meta) ); + i915->meta.active = ACTIVE; + i915->meta.emitted = 0; - draw_quad(i915, x0, x1, y0, y1, - intel->clear_red, intel->clear_green, - intel->clear_blue, intel->clear_alpha, - 0, 0, 0, 0); - } + SET_STATE(i915, meta); + set_vertex_format(intel); + meta_no_texture(intel); +} - if (mask & BUFFER_BIT_STENCIL) { - set_stencil_replace( i915, - intel->ctx.Stencil.WriteMask[0], - intel->ctx.Stencil.Clear); - - set_color_mask( i915, GL_FALSE ); - set_draw_offset( i915, screen->front.offset ); /* could be either? */ +static void leave_meta_state( struct intel_context *intel ) +{ + struct i915_context *i915 = i915_context(&intel->ctx); + intel_region_release(intel, &i915->meta.draw_region); + intel_region_release(intel, &i915->meta.depth_region); + intel_region_release(intel, &i915->meta.tex_region[0]); + SET_STATE(i915, state); +} - draw_quad( i915, x0, x1, y0, y1, 0, 0, 0, 0, 0, 0, 0, 0 ); - } - UNLOCK_HARDWARE(intel); - SET_STATE( i915, state ); +void i915InitMetaFuncs( struct i915_context *i915 ) +{ + i915->intel.vtbl.install_meta_state = install_meta_state; + i915->intel.vtbl.leave_meta_state = leave_meta_state; + i915->intel.vtbl.meta_no_depth_stencil_write = meta_no_depth_stencil_write; + i915->intel.vtbl.meta_stencil_replace = meta_stencil_replace; + i915->intel.vtbl.meta_color_mask = meta_color_mask; + i915->intel.vtbl.meta_no_texture = meta_no_texture; + i915->intel.vtbl.meta_texture_blend_replace = meta_texture_blend_replace; + i915->intel.vtbl.meta_tex_rect_source = meta_tex_rect_source; + i915->intel.vtbl.meta_draw_region = meta_draw_region; + i915->intel.vtbl.meta_draw_format = set_draw_format; } - - diff --git a/src/mesa/drivers/dri/i915/i915_program.c b/src/mesa/drivers/dri/i915/i915_program.c index 45276fb6908..84f25a431a6 100644 --- a/src/mesa/drivers/dri/i915/i915_program.c +++ b/src/mesa/drivers/dri/i915/i915_program.c @@ -358,7 +358,7 @@ void i915_program_error( struct i915_fragment_program *p, const char *msg ) p->error = 1; } -void i915_init_program( i915ContextPtr i915, struct i915_fragment_program *p ) +void i915_init_program( struct i915_context *i915, struct i915_fragment_program *p ) { GLcontext *ctx = &i915->intel.ctx; TNLcontext *tnl = TNL_CONTEXT( ctx ); @@ -431,7 +431,7 @@ void i915_fini_program( struct i915_fragment_program *p ) p->declarations[0] |= program_size + decl_size - 2; } -void i915_upload_program( i915ContextPtr i915, struct i915_fragment_program *p ) +void i915_upload_program( struct i915_context *i915, struct i915_fragment_program *p ) { GLuint program_size = p->csr - p->program; GLuint decl_size = p->decl - p->declarations; diff --git a/src/mesa/drivers/dri/i915/i915_program.h b/src/mesa/drivers/dri/i915/i915_program.h index 8891a177855..8b9849e3401 100644 --- a/src/mesa/drivers/dri/i915/i915_program.h +++ b/src/mesa/drivers/dri/i915/i915_program.h @@ -84,7 +84,7 @@ /* One neat thing about the UREG representation: */ -static __inline int swizzle( int reg, int x, int y, int z, int w ) +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 ) | @@ -95,7 +95,7 @@ static __inline int swizzle( int reg, int x, int y, int z, int w ) /* Another neat thing about the UREG representation: */ -static __inline int negate( int reg, int x, int y, int z, int w ) +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)| @@ -149,10 +149,10 @@ extern GLuint i915_emit_param4fv( struct i915_fragment_program *p, extern void i915_program_error( struct i915_fragment_program *p, const char *msg ); -extern void i915_init_program( i915ContextPtr i915, +extern void i915_init_program( struct i915_context *i915, struct i915_fragment_program *p ); -extern void i915_upload_program( i915ContextPtr i915, +extern void i915_upload_program( struct i915_context *i915, struct i915_fragment_program *p ); extern void i915_fini_program( struct i915_fragment_program *p ); diff --git a/src/mesa/drivers/dri/i915/i915_reg.h b/src/mesa/drivers/dri/i915/i915_reg.h index 3241b36b660..3bc8a23c1b9 100644 --- a/src/mesa/drivers/dri/i915/i915_reg.h +++ b/src/mesa/drivers/dri/i915/i915_reg.h @@ -435,10 +435,10 @@ #define LOGICOP_MASK (0xf<<18) #define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00)) #define ENABLE_STENCIL_TEST_MASK (1<<17) -#define STENCIL_TEST_MASK(x) ((x)<<8) +#define STENCIL_TEST_MASK(x) (((x)&0xff)<<8) #define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff)) #define ENABLE_STENCIL_WRITE_MASK (1<<16) -#define STENCIL_WRITE_MASK(x) (x) +#define STENCIL_WRITE_MASK(x) ((x)&0xff) /* _3DSTATE_MODES_5, p220 */ #define _3DSTATE_MODES_5_CMD (CMD_3D|(0x0c<<24)) diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c index 8c67bea2ec9..2586219b82b 100644 --- a/src/mesa/drivers/dri/i915/i915_state.c +++ b/src/mesa/drivers/dri/i915/i915_state.c @@ -48,7 +48,7 @@ static void i915StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, GLint ref, GLuint mask) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); int test = intel_translate_compare_func( func ); mask = mask & 0xff; @@ -73,7 +73,7 @@ i915StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, GLint ref, static void i915StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); if (INTEL_DEBUG&DEBUG_DRI) fprintf(stderr, "%s : mask 0x%x\n", __FUNCTION__, mask); @@ -91,7 +91,7 @@ static void i915StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, GLenum zfail, GLenum zpass) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); int fop = intel_translate_stencil_op(fail); int dfop = intel_translate_stencil_op(zfail); int dpop = intel_translate_stencil_op(zpass); @@ -116,7 +116,7 @@ i915StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, GLenum zfail, static void i915AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); int test = intel_translate_compare_func( func ); GLubyte refByte; @@ -137,7 +137,7 @@ static void i915AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) */ static void i915EvalLogicOpBlendState(GLcontext *ctx) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); I915_STATECHANGE(i915, I915_UPLOAD_CTX); @@ -157,7 +157,7 @@ static void i915EvalLogicOpBlendState(GLcontext *ctx) static void i915BlendColor(GLcontext *ctx, const GLfloat color[4]) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); GLubyte r, g, b, a; if (INTEL_DEBUG&DEBUG_DRI) @@ -194,7 +194,7 @@ static GLuint translate_blend_equation( GLenum mode ) static void i915UpdateBlendState( GLcontext *ctx ) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); GLuint iab = (i915->state.Ctx[I915_CTXREG_IAB] & ~(IAB_SRC_FACTOR_MASK | IAB_DST_FACTOR_MASK | @@ -261,7 +261,7 @@ static void i915BlendEquationSeparate(GLcontext *ctx, GLenum eqRGB, static void i915DepthFunc(GLcontext *ctx, GLenum func) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); int test = intel_translate_compare_func( func ); if (INTEL_DEBUG&DEBUG_DRI) @@ -274,7 +274,7 @@ static void i915DepthFunc(GLcontext *ctx, GLenum func) static void i915DepthMask(GLcontext *ctx, GLboolean flag) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); if (INTEL_DEBUG&DEBUG_DRI) fprintf(stderr, "%s flag (%d)\n", __FUNCTION__, flag); @@ -295,7 +295,7 @@ static void i915DepthMask(GLcontext *ctx, GLboolean flag) */ static void i915PolygonStipple( GLcontext *ctx, const GLubyte *mask ) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); const GLubyte *m = mask; GLubyte p[4]; int i,j,k; @@ -348,7 +348,7 @@ static void i915PolygonStipple( GLcontext *ctx, const GLubyte *mask ) static void i915Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); intelScreenPrivate *screen = i915->intel.intelScreen; int x1, y1, x2, y2; @@ -382,7 +382,7 @@ static void i915Scissor(GLcontext *ctx, GLint x, GLint y, static void i915LogicOp(GLcontext *ctx, GLenum opcode) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); int tmp = intel_translate_logic_op(opcode); if (INTEL_DEBUG&DEBUG_DRI) @@ -397,7 +397,7 @@ static void i915LogicOp(GLcontext *ctx, GLenum opcode) static void i915CullFaceFrontFace(GLcontext *ctx, GLenum unused) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); GLuint mode; if (INTEL_DEBUG&DEBUG_DRI) @@ -425,7 +425,7 @@ static void i915CullFaceFrontFace(GLcontext *ctx, GLenum unused) static void i915LineWidth( GLcontext *ctx, GLfloat widthf ) { - i915ContextPtr i915 = I915_CONTEXT( ctx ); + struct i915_context *i915 = I915_CONTEXT( ctx ); int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_LINE_WIDTH_MASK; int width; @@ -444,7 +444,7 @@ static void i915LineWidth( GLcontext *ctx, GLfloat widthf ) static void i915PointSize(GLcontext *ctx, GLfloat size) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_POINT_WIDTH_MASK; GLint point_size = (int)size; @@ -469,7 +469,7 @@ static void i915ColorMask(GLcontext *ctx, GLboolean r, GLboolean g, GLboolean b, GLboolean a) { - i915ContextPtr i915 = I915_CONTEXT( ctx ); + struct i915_context *i915 = I915_CONTEXT( ctx ); GLuint tmp = i915->state.Ctx[I915_CTXREG_LIS5] & ~S5_WRITEDISABLE_MASK; if (INTEL_DEBUG&DEBUG_DRI) @@ -490,7 +490,7 @@ static void update_specular( GLcontext *ctx ) { /* A hack to trigger the rebuild of the fragment program. */ - INTEL_CONTEXT(ctx)->NewGLState |= _NEW_TEXTURE; + intel_context(ctx)->NewGLState |= _NEW_TEXTURE; I915_CONTEXT(ctx)->tex_program.translated = 0; } @@ -507,7 +507,7 @@ static void i915LightModelfv(GLcontext *ctx, GLenum pname, static void i915ShadeModel(GLcontext *ctx, GLenum mode) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); I915_STATECHANGE(i915, I915_UPLOAD_CTX); if (mode == GL_SMOOTH) { @@ -526,7 +526,7 @@ static void i915ShadeModel(GLcontext *ctx, GLenum mode) */ void i915_update_fog( GLcontext *ctx ) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); GLenum mode; GLboolean enabled; GLboolean try_pixel_fog; @@ -619,7 +619,7 @@ void i915_update_fog( GLcontext *ctx ) static void i915Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); switch (pname) { case GL_FOG_COORDINATE_SOURCE_EXT: @@ -671,7 +671,7 @@ static void i915Hint(GLcontext *ctx, GLenum target, GLenum state) static void i915Enable(GLcontext *ctx, GLenum cap, GLboolean state) { - i915ContextPtr i915 = I915_CONTEXT(ctx); + struct i915_context *i915 = I915_CONTEXT(ctx); switch(cap) { case GL_TEXTURE_2D: @@ -785,7 +785,7 @@ static void i915Enable(GLcontext *ctx, GLenum cap, GLboolean state) } -static void i915_init_packets( i915ContextPtr i915 ) +static void i915_init_packets( struct i915_context *i915 ) { intelScreenPrivate *screen = i915->intel.intelScreen; @@ -823,7 +823,6 @@ static void i915_init_packets( i915ContextPtr i915 ) ENABLE_STENCIL_WRITE_MASK | STENCIL_WRITE_MASK(0xff)); - i915->state.Ctx[I915_CTXREG_IAB] = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | IAB_MODIFY_ENABLE | IAB_MODIFY_FUNC | @@ -862,19 +861,15 @@ static void i915_init_packets( i915ContextPtr i915 ) BUF_3D_PITCH(screen->front.pitch * screen->cpp) | BUF_3D_USE_FENCE); - i915->state.Buffer[I915_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD; i915->state.Buffer[I915_DESTREG_DBUFADDR1] = (BUF_3D_ID_DEPTH | BUF_3D_PITCH(screen->depth.pitch * screen->cpp) | BUF_3D_USE_FENCE); - i915->state.Buffer[I915_DESTREG_DBUFADDR2] = screen->depth.offset; - i915->state.Buffer[I915_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD; switch (screen->fbFormat) { - case DV_PF_555: case DV_PF_565: i915->state.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ DSTORG_VERT_BIAS(0x8) | /* .5 */ @@ -938,7 +933,7 @@ void i915InitStateFunctions( struct dd_function_table *functions ) } -void i915InitState( i915ContextPtr i915 ) +void i915InitState( struct i915_context *i915 ) { GLcontext *ctx = &i915->intel.ctx; diff --git a/src/mesa/drivers/dri/i915/i915_tex.c b/src/mesa/drivers/dri/i915/i915_tex.c index 92bc94b8eef..7f47cf90445 100644 --- a/src/mesa/drivers/dri/i915/i915_tex.c +++ b/src/mesa/drivers/dri/i915/i915_tex.c @@ -48,7 +48,7 @@ static void i915TexEnv( GLcontext *ctx, GLenum target, GLenum pname, const GLfloat *param ) { - i915ContextPtr i915 = I915_CONTEXT( ctx ); + struct i915_context *i915 = I915_CONTEXT( ctx ); switch (pname) { case GL_TEXTURE_ENV_COLOR: /* Should be a tracked param */ diff --git a/src/mesa/drivers/dri/i915/i915_texprog.c b/src/mesa/drivers/dri/i915/i915_texprog.c index 74ece96f8b7..e1ec7a6e8a1 100644 --- a/src/mesa/drivers/dri/i915/i915_texprog.c +++ b/src/mesa/drivers/dri/i915/i915_texprog.c @@ -536,7 +536,7 @@ static void emit_program_fini( struct i915_fragment_program *p ) } -static void i915EmitTextureProgram( i915ContextPtr i915 ) +static void i915EmitTextureProgram( struct i915_context *i915 ) { GLcontext *ctx = &i915->intel.ctx; struct i915_fragment_program *p = &i915->tex_program; @@ -570,9 +570,9 @@ static void i915EmitTextureProgram( i915ContextPtr i915 ) } -void i915ValidateTextureProgram( i915ContextPtr i915 ) +void i915ValidateTextureProgram( struct i915_context *i915 ) { - intelContextPtr intel = &i915->intel; + struct intel_context *intel = &i915->intel; GLcontext *ctx = &intel->ctx; TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c index f1db5f646cd..f498bcdea82 100644 --- a/src/mesa/drivers/dri/i915/i915_texstate.c +++ b/src/mesa/drivers/dri/i915/i915_texstate.c @@ -110,19 +110,31 @@ static GLuint translate_wrap_mode( GLenum wrap ) * efficient, but this has gotten complex enough that we need * something which is understandable and reliable. */ -static GLboolean i915_update_tex_unit( GLcontext *ctx, +static GLboolean i915_update_tex_unit( struct intel_context *intel, GLuint unit, GLuint ss3 ) { + GLcontext *ctx = &intel->ctx; + struct i915_context *i915 = i915_context(ctx); struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current; 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 = tObj->Image[0][intelObj->firstLevel]; + GLuint *state = i915->state.Tex[unit]; memset(state, 0, sizeof(state)); - state[I915_TEXREG_MS2] = 0; /* will fixup later */ + intel_region_release(intel, &i915->state.tex_region[unit]); + + if (!intel_finalize_mipmap_tree(intel, unit)) + return GL_FALSE; + + intel_region_reference(&i915->state.tex_region[unit], + intelObj->mt->region); + + i915->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, 0, + intelObj->firstLevel); + + state[I915_TEXREG_MS3] = (((firstImage->Height - 1) << MS3_HEIGHT_SHIFT) | ((firstImage->Width - 1) << MS3_WIDTH_SHIFT) | @@ -253,11 +265,11 @@ static GLboolean i915_update_tex_unit( GLcontext *ctx, I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(unit), GL_TRUE); + /* memcmp was already disabled, but definitely won't work as the + * region might now change and that wouldn't be detected: + */ + I915_STATECHANGE( i915, I915_UPLOAD_TEX(unit) ); - 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)); - } #if 0 DBG(TEXTURE, "state[I915_TEXREG_SS2] = 0x%x\n", state[I915_TEXREG_SS2]); @@ -274,25 +286,24 @@ static GLboolean i915_update_tex_unit( GLcontext *ctx, -void i915UpdateTextureState( intelContextPtr intel ) +void i915UpdateTextureState( struct intel_context *intel ) { - GLcontext *ctx = &intel->ctx; GLboolean ok = GL_TRUE; GLuint i; for (i = 0 ; i < I915_TEX_UNITS && ok ; i++) { - switch (ctx->Texture.Unit[i]._ReallyEnabled) { + switch (intel->ctx.Texture.Unit[i]._ReallyEnabled) { case TEXTURE_1D_BIT: case TEXTURE_2D_BIT: case TEXTURE_CUBE_BIT: - ok = i915_update_tex_unit( ctx, i, SS3_NORMALIZED_COORDS ); + ok = i915_update_tex_unit( intel, i, SS3_NORMALIZED_COORDS ); break; case TEXTURE_RECT_BIT: case TEXTURE_3D_BIT: - ok = i915_update_tex_unit( ctx, i, 0 ); + ok = i915_update_tex_unit( intel, i, 0 ); break; case 0: { - struct i915_context *i915 = i915_context(ctx); + struct i915_context *i915 = i915_context(&intel->ctx); if (i915->state.active & I915_UPLOAD_TEX(i)) I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(i), GL_FALSE); break; diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c index 4f4792c0eed..eb6af9056c3 100644 --- a/src/mesa/drivers/dri/i915/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915/i915_vtbl.c @@ -38,14 +38,15 @@ #include "intel_batchbuffer.h" #include "intel_tex.h" +#include "intel_regions.h" #include "i915_reg.h" #include "i915_context.h" -static void i915_render_start( intelContextPtr intel ) +static void i915_render_start( struct intel_context *intel ) { GLcontext *ctx = &intel->ctx; - i915ContextPtr i915 = i915_context(&intel->ctx); + struct i915_context *i915 = i915_context(&intel->ctx); if (ctx->FragmentProgram._Active) i915ValidateFragmentProgram( i915 ); @@ -54,42 +55,42 @@ static void i915_render_start( intelContextPtr intel ) } -static void i915_reduced_primitive_state( intelContextPtr intel, +static void i915_reduced_primitive_state( struct intel_context *intel, GLenum rprim ) { - i915ContextPtr i915 = i915_context(&intel->ctx); - GLuint st1 = i915->state.Stipple[I915_STPREG_ST1]; - - st1 &= ~ST1_ENABLE; - - switch (rprim) { - case GL_TRIANGLES: - if (intel->ctx.Polygon.StippleFlag && - intel->hw_stipple) - st1 |= ST1_ENABLE; - break; - case GL_LINES: - case GL_POINTS: - default: - break; - } - - i915->intel.reduced_primitive = rprim; - - if (st1 != i915->state.Stipple[I915_STPREG_ST1]) { - I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); - i915->state.Stipple[I915_STPREG_ST1] = st1; - } + struct i915_context *i915 = i915_context(&intel->ctx); + GLuint st1 = i915->state.Stipple[I915_STPREG_ST1]; + + st1 &= ~ST1_ENABLE; + + switch (rprim) { + case GL_TRIANGLES: + if (intel->ctx.Polygon.StippleFlag && + intel->hw_stipple) + st1 |= ST1_ENABLE; + break; + case GL_LINES: + case GL_POINTS: + default: + break; + } + + i915->intel.reduced_primitive = rprim; + + if (st1 != i915->state.Stipple[I915_STPREG_ST1]) { + I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); + i915->state.Stipple[I915_STPREG_ST1] = st1; + } } /* Pull apart the vertex format registers and figure out how large a * vertex is supposed to be. */ -static GLboolean i915_check_vertex_size( intelContextPtr intel, +static GLboolean i915_check_vertex_size( struct intel_context *intel, GLuint expected ) { - i915ContextPtr i915 = i915_context(&intel->ctx); + struct i915_context *i915 = i915_context(&intel->ctx); int lis2 = i915->current->Ctx[I915_CTXREG_LIS2]; int lis4 = i915->current->Ctx[I915_CTXREG_LIS4]; int i, sz = 0; @@ -133,11 +134,11 @@ static GLboolean i915_check_vertex_size( intelContextPtr intel, } -static void i915_emit_invarient_state( intelContextPtr intel ) +static void i915_emit_invarient_state( struct intel_context *intel ) { BATCH_LOCALS; - BEGIN_BATCH( 200 ); + BEGIN_BATCH( 200, 0 ); OUT_BATCH(_3DSTATE_AA_CMD | AA_LINE_ECAAR_WIDTH_ENABLE | @@ -205,21 +206,15 @@ static void i915_emit_invarient_state( intelContextPtr intel ) } -#define emit( intel, state, size ) \ -do { \ - int k; \ - BEGIN_BATCH( (size) / sizeof(GLuint)); \ - for (k = 0 ; k < (size) / sizeof(GLuint) ; k++) \ - OUT_BATCH((state)[k]); \ - ADVANCE_BATCH(); \ -} while (0); +#define emit(intel, state, size ) \ + intel_batchbuffer_data(intel->batch, state, size, 0 ) /* Push the state into the sarea and/or texture memory. */ -static void i915_emit_state( intelContextPtr intel ) +static void i915_emit_state( struct intel_context *intel ) { - i915ContextPtr i915 = i915_context(&intel->ctx); + struct i915_context *i915 = i915_context(&intel->ctx); struct i915_hw_state *state = i915->current; int i; GLuint dirty; @@ -234,32 +229,48 @@ static void i915_emit_state( intelContextPtr intel ) dirty = state->active & ~state->emitted; - if (VERBOSE) + if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "%s dirty: %x\n", __FUNCTION__, dirty); if (dirty & I915_UPLOAD_INVARIENT) { - if (VERBOSE) fprintf(stderr, "I915_UPLOAD_INVARIENT:\n"); + if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_INVARIENT:\n"); i915_emit_invarient_state( intel ); } if (dirty & I915_UPLOAD_CTX) { - if (VERBOSE) fprintf(stderr, "I915_UPLOAD_CTX:\n"); - emit( i915, state->Ctx, sizeof(state->Ctx) ); + if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_CTX:\n"); + emit(intel, state->Ctx, sizeof(state->Ctx) ); } if (dirty & I915_UPLOAD_BUFFERS) { - if (VERBOSE) fprintf(stderr, "I915_UPLOAD_BUFFERS:\n"); - emit( i915, state->Buffer, sizeof(state->Buffer) ); + if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_BUFFERS:\n"); + + BEGIN_BATCH(I915_DEST_SETUP_SIZE, 0); + OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR0]); + OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR1]); + OUT_RELOC(state->draw_region->buffer, BM_MEM_AGP|BM_WRITE, 0); + + OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR0]); + OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR1]); + OUT_RELOC(state->depth_region->buffer, BM_MEM_AGP|BM_WRITE, 0); + + OUT_BATCH(state->Buffer[I915_DESTREG_DV0]); + OUT_BATCH(state->Buffer[I915_DESTREG_DV1]); + OUT_BATCH(state->Buffer[I915_DESTREG_SENABLE]); + OUT_BATCH(state->Buffer[I915_DESTREG_SR0]); + OUT_BATCH(state->Buffer[I915_DESTREG_SR1]); + OUT_BATCH(state->Buffer[I915_DESTREG_SR2]); + ADVANCE_BATCH(); } if (dirty & I915_UPLOAD_STIPPLE) { - if (VERBOSE) fprintf(stderr, "I915_UPLOAD_STIPPLE:\n"); - emit( i915, state->Stipple, sizeof(state->Stipple) ); + if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_STIPPLE:\n"); + emit(intel, state->Stipple, sizeof(state->Stipple) ); } if (dirty & I915_UPLOAD_FOG) { - if (VERBOSE) fprintf(stderr, "I915_UPLOAD_FOG:\n"); - emit( i915, state->Fog, sizeof(state->Fog) ); + if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_FOG:\n"); + emit(intel, state->Fog, sizeof(state->Fog) ); } /* Combine all the dirty texture state into a single command to @@ -272,20 +283,29 @@ static void i915_emit_state( intelContextPtr intel ) if (dirty & I915_UPLOAD_TEX(i)) nr++; - BEGIN_BATCH(2+nr*3); + BEGIN_BATCH(2+nr*3, 0); OUT_BATCH(_3DSTATE_MAP_STATE | (3*nr)); OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT); for (i = 0 ; i < I915_TEX_UNITS ; i++) if (dirty & I915_UPLOAD_TEX(i)) { - /* Emit zero texture offset, will fixup before firing */ - intel_add_texoffset_fixup(intel, i, (GLuint *)batch_ptr); - batch_ptr += 4; + + if (state->tex_region[i]) { + OUT_RELOC(state->tex_region[i]->buffer, + BM_MEM_AGP|BM_READ, + state->tex_offset[i]); + } + else { + assert(i == 0); + assert(state == &i915->meta); + OUT_BATCH(0); + } + OUT_BATCH(state->Tex[i][I915_TEXREG_MS3]); OUT_BATCH(state->Tex[i][I915_TEXREG_MS4]); } ADVANCE_BATCH(); - BEGIN_BATCH(2+nr*3); + BEGIN_BATCH(2+nr*3, 0); OUT_BATCH(_3DSTATE_SAMPLER_STATE | (3*nr)); OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT); for (i = 0 ; i < I915_TEX_UNITS ; i++) @@ -298,63 +318,69 @@ static void i915_emit_state( intelContextPtr intel ) } if (dirty & I915_UPLOAD_CONSTANTS) { - if (VERBOSE) fprintf(stderr, "I915_UPLOAD_CONSTANTS:\n"); - emit( i915, state->Constant, state->ConstantSize * sizeof(GLuint) ); + if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_CONSTANTS:\n"); + emit(intel, state->Constant, state->ConstantSize * sizeof(GLuint) ); } if (dirty & I915_UPLOAD_PROGRAM) { - if (VERBOSE) fprintf(stderr, "I915_UPLOAD_PROGRAM:\n"); + if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_PROGRAM:\n"); assert((state->Program[0] & 0x1ff)+2 == state->ProgramSize); - emit( i915, state->Program, state->ProgramSize * sizeof(GLuint) ); - if (VERBOSE) + emit(intel, state->Program, state->ProgramSize * sizeof(GLuint) ); + if (INTEL_DEBUG & DEBUG_STATE) i915_disassemble_program( state->Program, state->ProgramSize ); } state->emitted |= dirty; } -static void i915_destroy_context( intelContextPtr intel ) +static void i915_destroy_context( struct intel_context *intel ) { _tnl_free_vertices(&intel->ctx); } -static void i915_set_draw_offset( intelContextPtr intel, int offset ) +static void i915_set_draw_region( struct intel_context *intel, + struct intel_region *draw_region, + struct intel_region *depth_region) { - i915ContextPtr i915 = i915_context(&intel->ctx); + struct i915_context *i915 = i915_context(&intel->ctx); + + intel_region_release(intel, &i915->state.draw_region); + intel_region_release(intel, &i915->state.depth_region); + intel_region_reference(&i915->state.draw_region, draw_region); + intel_region_reference(&i915->state.depth_region, depth_region); + I915_STATECHANGE( i915, I915_UPLOAD_BUFFERS ); - i915->state.Buffer[I915_DESTREG_CBUFADDR2] = offset; } -static void i915_lost_hardware( intelContextPtr intel ) +static void i915_lost_hardware( struct intel_context *intel ) { - i915ContextPtr i915 = i915_context(&intel->ctx); + struct i915_context *i915 = i915_context(&intel->ctx); i915->state.emitted = 0; } -static void i915_emit_flush( intelContextPtr intel ) +static void i915_emit_flush( struct intel_context *intel ) { BATCH_LOCALS; - BEGIN_BATCH(2); + BEGIN_BATCH(2, 0); OUT_BATCH( MI_FLUSH | FLUSH_MAP_CACHE | FLUSH_RENDER_CACHE ); OUT_BATCH( 0 ); ADVANCE_BATCH(); } -void i915InitVtbl( i915ContextPtr i915 ) +void i915InitVtbl( struct i915_context *i915 ) { i915->intel.vtbl.check_vertex_size = i915_check_vertex_size; - i915->intel.vtbl.clear_with_tris = i915ClearWithTris; i915->intel.vtbl.destroy = i915_destroy_context; i915->intel.vtbl.emit_invarient_state = i915_emit_invarient_state; i915->intel.vtbl.emit_state = i915_emit_state; i915->intel.vtbl.lost_hardware = i915_lost_hardware; i915->intel.vtbl.reduced_primitive_state = i915_reduced_primitive_state; i915->intel.vtbl.render_start = i915_render_start; - i915->intel.vtbl.set_draw_offset = i915_set_draw_offset; + i915->intel.vtbl.set_draw_region = i915_set_draw_region; i915->intel.vtbl.update_texture_state = i915UpdateTextureState; i915->intel.vtbl.emit_flush = i915_emit_flush; } diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.c b/src/mesa/drivers/dri/i915/intel_batchbuffer.c index 91fbaed4da5..fd04b054abe 100644 --- a/src/mesa/drivers/dri/i915/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/i915/intel_batchbuffer.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -25,79 +25,263 @@ * **************************************************************************/ +#include "intel_batchbuffer.h" +#include "intel_ioctl.h" +#include "bufmgr.h" -#include <stdio.h> -#include <errno.h> +/* Relocations in kernel space: + * - pass dma buffer seperately + * - memory manager knows how to patch + * - pass list of dependent buffers + * - pass relocation list + * + * Either: + * - get back an offset for buffer to fire + * - memory manager knows how to fire buffer + * + * Really want the buffer to be AGP and pinned. + * + */ -#include "mtypes.h" -#include "context.h" -#include "enums.h" +/* Cliprect fence: The highest fence protecting a dma buffer + * containing explicit cliprect information. Like the old drawable + * lock but irq-driven. X server must wait for this fence to expire + * before changing cliprects [and then doing sw rendering?]. For + * other dma buffers, the scheduler will grab current cliprect info + * and mix into buffer. X server must hold the lock while changing + * cliprects??? Make per-drawable. Need cliprects in shared memory + * -- beats storing them with every cmd buffer in the queue. + * + * ==> X server must wait for this fence to expire before touching the + * framebuffer with new cliprects. + * + * ==> Cliprect-dependent buffers associated with a + * cliprect-timestamp. All of the buffers associated with a timestamp + * must go to hardware before any buffer with a newer timestamp. + * + * ==> Dma should be queued per-drawable for correct X/GL + * synchronization. Or can fences be used for this? + * + * Applies to: Blit operations, metaops, X server operations -- X + * server automatically waits on its own dma to complete before + * modifying cliprects ??? + */ -#include "intel_reg.h" -#include "intel_batchbuffer.h" -#include "intel_context.h" +static void intel_dump_batchbuffer( unsigned offset, + int *ptr, + int count ) +{ + int i; + fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", count/4); + for (i = 0; i < count/4; i += 4) + fprintf(stderr, "0x%x:\t0x%08x 0x%08x 0x%08x 0x%08x\n", + offset + i*4, ptr[i], ptr[i+1], ptr[i+2], ptr[i+3]); + fprintf(stderr, "END BATCH\n\n\n"); +} -#include "bufmgr.h" +static void intel_batchbuffer_reset( struct intel_batchbuffer *batch ) +{ + bmBufferData(batch->bm, + batch->buffer, + BATCH_SZ, + NULL, + 0); + + if (!batch->list) + batch->list = bmNewBufferList(); + + batch->list->nr = 0; + batch->nr_relocs = 0; + batch->flags = 0; + bmAddBuffer( batch->list, + batch->buffer, + 0, + NULL, + &batch->offset[batch->list->nr]); -void intelDestroyBatchBuffer( struct intel_context *intel ) + batch->map = bmMapBuffer(batch->bm, batch->buffer, + BM_MEM_AGP|BM_MEM_LOCAL|BM_CLIENT|BM_WRITE); + batch->ptr = batch->map; +} + +/*====================================================================== + * Public functions + */ +struct intel_batchbuffer *intel_batchbuffer_alloc( struct intel_context *intel ) { + struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1); + + batch->intel = intel; + batch->bm = intel->bm; + + bmGenBuffers(intel->bm, 1, &batch->buffer); + intel_batchbuffer_reset( batch ); + return batch; +} + +void intel_batchbuffer_free( struct intel_batchbuffer *batch ) +{ + if (batch->map) + bmUnmapBuffer(batch->bm, batch->buffer); + + free(batch); +} + +/* TODO: Push this whole function into bufmgr. + */ +static void do_flush_locked( struct intel_batchbuffer *batch, + GLuint used, + GLboolean ignore_cliprects) +{ + GLuint *ptr; + GLuint i; + + bmValidateBufferList( batch->bm, + batch->list, + BM_MEM_AGP ); + + /* Apply the relocations. This nasty map indicates to me that the + * whole task should be done internally by the memory manager, and + * that dma buffers probably need to be pinned within agp space. + */ + ptr = (GLuint *)bmMapBuffer(batch->bm, batch->buffer, + BM_NO_MOVE|BM_NO_UPLOAD| + BM_NO_EVICT|BM_MEM_AGP| + BM_WRITE); + + for (i = 0; i < batch->nr_relocs; i++) { + struct buffer_reloc *r = &batch->reloc[i]; + + DBG("apply fixup at offset 0x%x, elem %d (buf %d, offset 0x%x), delta 0x%x\n", + r->offset, r->elem, batch->list->elem[r->elem].buffer, + batch->offset[r->elem], r->delta); + + ptr[r->offset/4] = batch->offset[r->elem] + r->delta; + } + + if (0) + intel_dump_batchbuffer( 0, ptr, used ); + + + + bmUnmapBuffer(batch->bm, batch->buffer); + + + /* Fire the batch buffer, which was uploaded above: + */ + intel_batch_ioctl(batch->intel, + batch->offset[0], + used, + ignore_cliprects); + + batch->last_fence = bmFenceBufferList(batch->bm, batch->list); } -void intelInstallBatchBuffer( struct intel_context *intel ) + +GLuint intel_batchbuffer_flush( struct intel_batchbuffer *batch ) { - assert(!intel->batch.ptr); + struct intel_context *intel = batch->intel; + GLuint used = batch->ptr - batch->map; - intel->alloc.current++; - intel->alloc.current %= INTEL_ALLOC_NR; + if (used == 0) + return batch->last_fence; - DBG("%s: %d\n", __FUNCTION__, intel->alloc.current); + /* Add the MI_BATCH_BUFFER_END: + */ + if (intel_batchbuffer_space(batch) & 4) { + ((int *)batch->ptr)[0] = MI_BATCH_BUFFER_END; + used += 4; + } + else { + ((int *)batch->ptr)[0] = 0; + ((int *)batch->ptr)[1] = MI_BATCH_BUFFER_END; + used += 8; + } - intel->batch.size = INTEL_ALLOC_SIZE; - intel->batch.space = intel->batch.size; - intel->batch.start_offset = 0; + bmUnmapBuffer(batch->bm, batch->buffer); + batch->ptr = NULL; + batch->map = NULL; - intel->batch.ptr = bmMapBuffer( intel->bm, - intel->alloc.buffer[intel->alloc.current], - BM_WRITE | BM_MEM_AGP ); + /* TODO: Just pass the relocation list and dma buffer up to the + * kernel. + */ + if (!intel->locked) + { + assert(!(batch->flags & INTEL_BATCH_NO_CLIPRECTS)); + LOCK_HARDWARE(intel); + do_flush_locked(batch, used, GL_FALSE); + UNLOCK_HARDWARE(intel); + } + else { + assert(!(batch->flags & INTEL_BATCH_CLIPRECTS)); - assert(!intel->buffer_list); - intel->buffer_list = bmNewBufferList(); - - /* Add the batchbuffer + do_flush_locked(batch, used, GL_TRUE); + } + + /* Reset the buffer: */ - bmAddBuffer(intel->buffer_list, - intel->alloc.buffer[intel->alloc.current], - BM_READ, - NULL, - &intel->batch.start_offset); + intel_batchbuffer_reset( batch ); + return batch->last_fence; +} + +void intel_batchbuffer_finish( struct intel_batchbuffer *batch ) +{ + bmFinishFence(batch->bm, + intel_batchbuffer_flush(batch)); } + -void intelInitBatchBuffer( struct intel_context *intel ) +/* This is the only way buffers get added to the validate list. + */ +GLboolean intel_batchbuffer_emit_reloc( struct intel_batchbuffer *batch, + GLuint buffer, + GLuint flags, + GLuint delta ) { - GLint i; - - _mesa_printf("%s: %d\n", __FUNCTION__, intel->alloc.current); - bmGenBuffers(intel->bm, - INTEL_ALLOC_NR, - intel->alloc.buffer); - - for (i = 0; i < INTEL_ALLOC_NR; i++) - bmBufferData(intel->bm, - intel->alloc.buffer[i], - INTEL_ALLOC_SIZE, - NULL, - BM_MEM_AGP); - + GLuint i; + + assert(batch->nr_relocs <= MAX_RELOCS); + + for (i = 0; i < batch->list->nr; i++) + if (buffer == batch->list->elem[i].buffer) + break; + if (i == batch->list->nr) { + if (i == BM_LIST_MAX) + return GL_FALSE; + + bmAddBuffer(batch->list, + buffer, + flags, + NULL, + &batch->offset[i]); + } + + { + struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++]; + r->offset = batch->ptr - batch->map; + r->delta = delta; + r->elem = i; + } + + batch->ptr += 4; + return GL_TRUE; } -void intelValidateBuffers( struct intel_context *intel ) + +void intel_batchbuffer_data(struct intel_batchbuffer *batch, + const void *data, + GLuint bytes, + GLuint flags) { - if (!bmValidateBufferList(intel->bm, intel->buffer_list, BM_MEM_AGP)) - assert(0); + assert((bytes & 3) == 0); + intel_batchbuffer_require_space(batch, bytes, flags); + __memcpy(batch->ptr, data, bytes); + batch->ptr += bytes; } + diff --git a/src/mesa/drivers/dri/i915/intel_batchbuffer.h b/src/mesa/drivers/dri/i915/intel_batchbuffer.h index 00ca9920cb1..e451a0e7284 100644 --- a/src/mesa/drivers/dri/i915/intel_batchbuffer.h +++ b/src/mesa/drivers/dri/i915/intel_batchbuffer.h @@ -1,74 +1,111 @@ -/************************************************************************** - * - * 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_BATCHBUFFER_H #define INTEL_BATCHBUFFER_H -#include "intel_context.h" -#include "intel_ioctl.h" +#include "mtypes.h" +#include "bufmgr.h" + +struct intel_context; + +#define BATCH_SZ 4096 +#define MAX_RELOCS 100 + +#define INTEL_BATCH_NO_CLIPRECTS 0x1 +#define INTEL_BATCH_CLIPRECTS 0x2 + +struct buffer_reloc { + GLuint offset; + GLuint elem; /* elem in buffer list, not buffer id */ + GLuint delta; /* not needed? */ +}; + +struct intel_batchbuffer { + struct bufmgr *bm; + struct intel_context *intel; + + GLuint buffer; + GLuint last_fence; + GLuint flags; + + /* In progress: + */ + GLuint offset[BM_LIST_MAX]; + struct bm_buffer_list *list; + GLubyte *map; + GLubyte *ptr; + + struct buffer_reloc reloc[MAX_RELOCS]; + GLuint nr_relocs; +}; + +struct intel_batchbuffer *intel_batchbuffer_alloc( struct intel_context *intel ); + +void intel_batchbuffer_free( struct intel_batchbuffer *batch ); + + +void intel_batchbuffer_finish( struct intel_batchbuffer *batch ); +GLuint intel_batchbuffer_flush( struct intel_batchbuffer *batch ); -#define BATCH_LOCALS GLubyte *batch_ptr; -#define VERBOSE 0 +/* Unlike bmBufferData, this currently requires the buffer be mapped. + * Consider it a convenience function wrapping multple + * intel_buffer_dword() calls. + */ +void intel_batchbuffer_data(struct intel_batchbuffer *batch, + const void *data, + GLuint bytes, + GLuint flags); +void intel_batchbuffer_release_space(struct intel_batchbuffer *batch, + GLuint bytes); -#define BEGIN_BATCH(n) \ -do { \ - if (VERBOSE) fprintf(stderr, \ - "BEGIN_BATCH(%d) in %s, %d dwords free\n", \ - (n), __FUNCTION__, intel->batch.space/4); \ - assert(intel->locked); \ - if (intel->batch.space < (n)*4) \ - intelFlushBatch(intel, GL_TRUE); \ - batch_ptr = intel->batch.ptr; \ -} while (0) +GLboolean intel_batchbuffer_emit_reloc( struct intel_batchbuffer *batch, + GLuint buffer, + GLuint flags, + GLuint offset ); -#define OUT_BATCH(n) \ -do { \ - *(GLuint *)batch_ptr = (n); \ - if (VERBOSE) fprintf(stderr, " -- %08x at %s/%d\n", (n), __FILE__, __LINE__); \ - batch_ptr += 4; \ -} while (0) +/* Inline functions - might actually be better off with these + * non-inlined. Certainly better off switching all command packets to + * be passed as structs rather than dwords, but that's a little bit of + * work... + */ +static inline GLuint +intel_batchbuffer_space( struct intel_batchbuffer *batch ) +{ + return (BATCH_SZ - 8) - (batch->ptr - batch->map); +} -#define ADVANCE_BATCH() \ -do { \ - if (VERBOSE) fprintf(stderr, "ADVANCE_BATCH()\n"); \ - intel->batch.space -= (batch_ptr - intel->batch.ptr); \ - intel->batch.ptr = batch_ptr; \ - assert(intel->batch.space >= 0); \ -} while(0) -extern void intelInitBatchBuffer( struct intel_context *intel ); -extern void intelDestroyBatchBuffer( struct intel_context *intel ); +static inline void +intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, + GLuint dword) +{ + assert(batch->map); + assert(intel_batchbuffer_space(batch) >= 4); + *(GLuint *)(batch->ptr) = dword; + batch->ptr += 4; +} -void intelInstallBatchBuffer( struct intel_context *intel ); +static inline void +intel_batchbuffer_require_space(struct intel_batchbuffer *batch, + GLuint sz, + GLuint flags) +{ + assert(sz < BATCH_SZ - 8); + if (intel_batchbuffer_space(batch) < sz || + (batch->flags != 0 && flags != 0 && batch->flags != flags)) + intel_batchbuffer_flush(batch); + + batch->flags |= flags; +} +/* Here are the crusty old macros, to be removed: + */ +#define BATCH_LOCALS +#define BEGIN_BATCH(n, flags) intel_batchbuffer_require_space(intel->batch, n*4, flags) +#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d) +#define OUT_RELOC(buf,flags,delta) intel_batchbuffer_emit_reloc(intel->batch, buf, flags, delta) +#define ADVANCE_BATCH() do { } while(0) -void intelValidateBuffers( struct intel_context *intel ); #endif diff --git a/src/mesa/drivers/dri/i915/intel_blit.c b/src/mesa/drivers/dri/i915/intel_blit.c index 47786a48f9b..147713dc349 100644 --- a/src/mesa/drivers/dri/i915/intel_blit.c +++ b/src/mesa/drivers/dri/i915/intel_blit.c @@ -37,6 +37,7 @@ #include "intel_batchbuffer.h" #include "intel_context.h" #include "intel_blit.h" +#include "intel_regions.h" #include "bufmgr.h" @@ -48,7 +49,7 @@ */ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv ) { - intelContextPtr intel; + struct intel_context *intel; if (0) fprintf(stderr, "%s\n", __FUNCTION__); @@ -57,13 +58,13 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv ) assert(dPriv->driContextPriv); assert(dPriv->driContextPriv->driverPrivate); - intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate; - + intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate; intelFlush( &intel->ctx ); - LOCK_HARDWARE( intel ); - intelInstallBatchBuffer(intel); - intelValidateBuffers( intel ); + /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets + * should work regardless. + */ + LOCK_HARDWARE( intel ); { intelScreenPrivate *intelScreen = intel->intelScreen; __DRIdrawablePrivate *dPriv = intel->driDrawable; @@ -71,24 +72,18 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv ) drm_clip_rect_t *pbox = dPriv->pClipRects; int pitch = intelScreen->front.pitch; int cpp = intelScreen->cpp; + int BR13, CMD; int i; - GLuint CMD, BR13; - BATCH_LOCALS; - switch(cpp) { - case 2: + + if (cpp == 2) { BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24); CMD = XY_SRC_COPY_BLT_CMD; - break; - case 4: + } + else { BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24) | (1<<25); CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB); - break; - default: - BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24); - CMD = XY_SRC_COPY_BLT_CMD; - break; } for (i = 0 ; i < nbox; i++, pbox++) @@ -99,44 +94,44 @@ void intelCopyBuffer( const __DRIdrawablePrivate *dPriv ) pbox->y2 > intelScreen->height) continue; - BEGIN_BATCH( 8); + BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); OUT_BATCH( CMD ); OUT_BATCH( BR13 ); OUT_BATCH( (pbox->y1 << 16) | pbox->x1 ); OUT_BATCH( (pbox->y2 << 16) | pbox->x2 ); if (intel->sarea->pf_current_page == 0) - OUT_BATCH( intelScreen->front.offset ); + OUT_RELOC( intel->front_region->buffer, BM_MEM_AGP|BM_WRITE, 0 ); else - OUT_BATCH( intelScreen->back.offset ); + OUT_RELOC( intel->back_region->buffer, BM_MEM_AGP|BM_WRITE, 0 ); OUT_BATCH( (pbox->y1 << 16) | pbox->x1 ); OUT_BATCH( BR13 & 0xffff ); if (intel->sarea->pf_current_page == 0) - OUT_BATCH( intelScreen->back.offset ); + OUT_RELOC( intel->back_region->buffer, BM_MEM_AGP|BM_READ, 0 ); else - OUT_BATCH( intelScreen->front.offset ); + OUT_RELOC( intel->front_region->buffer, BM_MEM_AGP|BM_READ, 0 ); ADVANCE_BATCH(); } } - intelFlushBatchLocked( intel, GL_TRUE, GL_TRUE, GL_TRUE ); - assert(intel->buffer_list == NULL); + intel_batchbuffer_flush( intel->batch ); UNLOCK_HARDWARE( intel ); } -void intelEmitFillBlitLocked( intelContextPtr intel, - GLuint cpp, - GLshort dst_pitch, - GLuint dst_offset, - GLshort x, GLshort y, - GLshort w, GLshort h, - GLuint color ) +void intelEmitFillBlit( struct intel_context *intel, + GLuint cpp, + GLshort dst_pitch, + GLuint dst_buffer, + GLuint dst_offset, + GLshort x, GLshort y, + GLshort w, GLshort h, + GLuint color ) { GLuint BR13, CMD; BATCH_LOCALS; @@ -159,12 +154,12 @@ void intelEmitFillBlitLocked( intelContextPtr intel, return; } - BEGIN_BATCH( 6); + BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS); OUT_BATCH( CMD ); OUT_BATCH( BR13 ); OUT_BATCH( (y << 16) | x ); OUT_BATCH( ((y+h) << 16) | (x+w) ); - OUT_BATCH( dst_offset ); + OUT_RELOC( dst_buffer, BM_MEM_AGP|BM_WRITE, dst_offset ); OUT_BATCH( color ); ADVANCE_BATCH(); } @@ -172,15 +167,17 @@ void intelEmitFillBlitLocked( intelContextPtr intel, /* Copy BitBlt */ -void intelEmitCopyBlitLocked( intelContextPtr intel, - GLuint cpp, - GLshort src_pitch, - GLuint src_offset, - GLshort dst_pitch, - GLuint dst_offset, - GLshort src_x, GLshort src_y, - GLshort dst_x, GLshort dst_y, - GLshort w, GLshort h ) +void intelEmitCopyBlit( struct intel_context *intel, + GLuint cpp, + GLshort src_pitch, + GLuint src_buffer, + GLuint src_offset, + GLshort dst_pitch, + GLuint dst_buffer, + GLuint dst_offset, + GLshort src_x, GLshort src_y, + GLshort dst_x, GLshort dst_y, + GLshort w, GLshort h ) { GLuint CMD, BR13; int dst_y2 = dst_y + h; @@ -188,11 +185,11 @@ void intelEmitCopyBlitLocked( intelContextPtr intel, BATCH_LOCALS; - if (0) - _mesa_printf("%s src:0x%x/%d %d,%d dst:0x%x/%d %d,%d sz:%dx%d\n", + if (1) + _mesa_printf("%s src:buf(%d)/%d %d,%d dst:buf(%d)/%d %d,%d sz:%dx%d\n", __FUNCTION__, - src_offset, src_pitch, src_x, src_y, - dst_offset, dst_pitch, dst_x, dst_y, + src_buffer, src_pitch, src_x, src_y, + dst_buffer, dst_pitch, dst_x, dst_y, w,h); src_pitch *= cpp; @@ -223,30 +220,27 @@ void intelEmitCopyBlitLocked( intelContextPtr intel, * we adjust the offsets manually (below), it seems to work fine. */ if (0) { - BEGIN_BATCH(8); + BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); OUT_BATCH( CMD ); OUT_BATCH( BR13 ); OUT_BATCH( (dst_y << 16) | dst_x ); OUT_BATCH( (dst_y2 << 16) | dst_x2 ); - OUT_BATCH( dst_offset ); + OUT_RELOC( dst_buffer, BM_MEM_AGP|BM_WRITE, dst_offset ); OUT_BATCH( (src_y << 16) | src_x ); OUT_BATCH( ((GLint)src_pitch&0xffff) ); - OUT_BATCH( src_offset ); + OUT_RELOC( src_buffer, BM_MEM_AGP|BM_READ, src_offset ); ADVANCE_BATCH(); } else { - src_offset += src_y * src_pitch; - dst_offset += dst_y * dst_pitch; - - BEGIN_BATCH(8); + BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS); OUT_BATCH( CMD ); OUT_BATCH( BR13 ); OUT_BATCH( (0 << 16) | dst_x ); OUT_BATCH( (h << 16) | dst_x2 ); - OUT_BATCH( dst_offset ); + OUT_RELOC( dst_buffer, BM_MEM_AGP|BM_WRITE, dst_offset + dst_y * dst_pitch ); OUT_BATCH( (0 << 16) | src_x ); OUT_BATCH( ((GLint)src_pitch&0xffff) ); - OUT_BATCH( src_offset ); + OUT_RELOC( src_buffer, BM_MEM_AGP|BM_READ, src_offset + src_y * src_pitch ); ADVANCE_BATCH(); } } @@ -256,7 +250,7 @@ void intelEmitCopyBlitLocked( intelContextPtr intel, void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, GLint cx1, GLint cy1, GLint cw, GLint ch) { - intelContextPtr intel = INTEL_CONTEXT( ctx ); + struct intel_context *intel = intel_context( ctx ); intelScreenPrivate *intelScreen = intel->intelScreen; GLuint clear_depth, clear_color; GLint cx, cy; @@ -300,8 +294,6 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, intelFlush( &intel->ctx ); LOCK_HARDWARE( intel ); - intelInstallBatchBuffer(intel); - intelValidateBuffers( intel ); { /* flip top to bottom */ cy = intel->driDrawable->h-cy1-ch; @@ -351,40 +343,40 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all, continue; if ( flags & BUFFER_BIT_FRONT_LEFT ) { - BEGIN_BATCH( 6); + BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS); OUT_BATCH( CMD ); OUT_BATCH( BR13 ); OUT_BATCH( (b.y1 << 16) | b.x1 ); OUT_BATCH( (b.y2 << 16) | b.x2 ); - OUT_BATCH( intelScreen->front.offset ); + OUT_RELOC( intel->front_region->buffer, BM_MEM_AGP|BM_WRITE, 0 ); OUT_BATCH( clear_color ); ADVANCE_BATCH(); } if ( flags & BUFFER_BIT_BACK_LEFT ) { - BEGIN_BATCH( 6); + BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS); OUT_BATCH( CMD ); OUT_BATCH( BR13 ); OUT_BATCH( (b.y1 << 16) | b.x1 ); OUT_BATCH( (b.y2 << 16) | b.x2 ); - OUT_BATCH( intelScreen->back.offset ); + OUT_RELOC( intel->back_region->buffer, BM_MEM_AGP|BM_WRITE, 0 ); OUT_BATCH( clear_color ); ADVANCE_BATCH(); } if ( flags & (BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH) ) { - BEGIN_BATCH( 6); + BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS); OUT_BATCH( D_CMD ); OUT_BATCH( BR13 ); OUT_BATCH( (b.y1 << 16) | b.x1 ); OUT_BATCH( (b.y2 << 16) | b.x2 ); - OUT_BATCH( intelScreen->depth.offset ); + OUT_RELOC( intel->depth_region->buffer, BM_MEM_AGP|BM_WRITE, 0 ); OUT_BATCH( clear_depth ); ADVANCE_BATCH(); } } } - intelFlushBatchLocked( intel, GL_TRUE, GL_FALSE, GL_TRUE ); + intel_batchbuffer_flush( intel->batch ); UNLOCK_HARDWARE( intel ); } diff --git a/src/mesa/drivers/dri/i915/intel_blit.h b/src/mesa/drivers/dri/i915/intel_blit.h index dd75844730d..0bbdb0a7ed8 100644 --- a/src/mesa/drivers/dri/i915/intel_blit.h +++ b/src/mesa/drivers/dri/i915/intel_blit.h @@ -35,23 +35,26 @@ extern void intelCopyBuffer( const __DRIdrawablePrivate *dpriv ); extern void intelClearWithBlit(GLcontext *ctx, GLbitfield mask, GLboolean all, GLint cx1, GLint cy1, GLint cw, GLint ch); -extern void intelEmitCopyBlitLocked( intelContextPtr intel, - GLuint cpp, - GLshort src_pitch, - GLuint src_offset, - GLshort dst_pitch, - GLuint dst_offset, - GLshort srcx, GLshort srcy, - GLshort dstx, GLshort dsty, - GLshort w, GLshort h ); +extern void intelEmitCopyBlit( struct intel_context *intel, + GLuint cpp, + GLshort src_pitch, + GLuint src_buffer, + GLuint src_offset, + GLshort dst_pitch, + GLuint dst_buffer, + GLuint dst_offset, + GLshort srcx, GLshort srcy, + GLshort dstx, GLshort dsty, + GLshort w, GLshort h ); -extern void intelEmitFillBlitLocked( intelContextPtr intel, - GLuint cpp, - GLshort dst_pitch, - GLuint dst_offset, - GLshort x, GLshort y, - GLshort w, GLshort h, - GLuint color ); +extern void intelEmitFillBlit( struct intel_context *intel, + GLuint cpp, + GLshort dst_pitch, + GLuint dst_buffer, + GLuint dst_offset, + GLshort x, GLshort y, + GLshort w, GLshort h, + GLuint color ); #endif diff --git a/src/mesa/drivers/dri/i915/intel_buffers.c b/src/mesa/drivers/dri/i915/intel_buffers.c new file mode 100644 index 00000000000..fd937d0b0ba --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_buffers.c @@ -0,0 +1,505 @@ +/************************************************************************** + * + * 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 "intel_screen.h" +#include "intel_context.h" +#include "intel_blit.h" +#include "intel_tris.h" +#include "intel_regions.h" +#include "intel_batchbuffer.h" +#include "context.h" +#include "framebuffer.h" +#include "swrast/swrast.h" + +GLboolean intel_intersect_cliprects( drm_clip_rect_t *dst, + const drm_clip_rect_t *a, + const drm_clip_rect_t *b ) +{ + GLint bx = b->x1; + GLint by = b->y1; + GLint bw = b->x2 - bx; + GLint bh = b->y2 - by; + + if (bx < a->x1) bw -= a->x1 - bx, bx = a->x1; + if (by < a->y1) bh -= a->y1 - by, by = a->y1; + if (bx + bw > a->x2) bw = a->x2 - bx; + if (by + bh > a->y2) bh = a->y2 - by; + if (bw <= 0) return GL_FALSE; + if (bh <= 0) return GL_FALSE; + + dst->x1 = bx; + dst->y1 = by; + dst->x2 = bx + bw; + dst->y2 = by + bh; + + return GL_TRUE; +} + +struct intel_region *intel_drawbuf_region( struct intel_context *intel ) +{ + switch (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0]) { + case BUFFER_BIT_FRONT_LEFT: + return intel->front_region; + case BUFFER_BIT_BACK_LEFT: + return intel->back_region; + default: + /* Not necessary to fallback - could handle either NONE or + * FRONT_AND_BACK cases below. + */ + return NULL; + } +} + +struct intel_region *intel_readbuf_region( struct intel_context *intel ) +{ + GLcontext *ctx = &intel->ctx; + + /* This will have to change to support EXT_fbo's, but is correct + * for now: + */ + switch (ctx->ReadBuffer->_ColorReadBufferIndex) { + case BUFFER_FRONT_LEFT: + return intel->front_region; + case BUFFER_BACK_LEFT: + return intel->back_region; + default: + assert(0); + return NULL; + } +} + + + +static void intelBufferSize(GLframebuffer *buffer, + GLuint *width, + GLuint *height) +{ + GET_CURRENT_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); + /* Need to lock to make sure the driDrawable is uptodate. This + * information is used to resize Mesa's software buffers, so it has + * to be correct. + */ + LOCK_HARDWARE(intel); + if (intel->driDrawable) { + *width = intel->driDrawable->w; + *height = intel->driDrawable->h; + } + else { + *width = 0; + *height = 0; + } + UNLOCK_HARDWARE(intel); +} + + +static void intelSetFrontClipRects( struct intel_context *intel ) +{ + __DRIdrawablePrivate *dPriv = intel->driDrawable; + + if (!dPriv) return; + + intel->numClipRects = dPriv->numClipRects; + intel->pClipRects = dPriv->pClipRects; + intel->drawX = dPriv->x; + intel->drawY = dPriv->y; +} + + +static void intelSetBackClipRects( struct intel_context *intel ) +{ + __DRIdrawablePrivate *dPriv = intel->driDrawable; + + if (!dPriv) return; + + if (intel->sarea->pf_enabled == 0 && dPriv->numBackClipRects == 0) { + intel->numClipRects = dPriv->numClipRects; + intel->pClipRects = dPriv->pClipRects; + intel->drawX = dPriv->x; + intel->drawY = dPriv->y; + } else { + intel->numClipRects = dPriv->numBackClipRects; + intel->pClipRects = dPriv->pBackClipRects; + intel->drawX = dPriv->backX; + intel->drawY = dPriv->backY; + + if (dPriv->numBackClipRects == 1 && + dPriv->x == dPriv->backX && + dPriv->y == dPriv->backY) { + + /* Repeat the calculation of the back cliprect dimensions here + * as early versions of dri.a in the Xserver are incorrect. Try + * very hard not to restrict future versions of dri.a which + * might eg. allocate truly private back buffers. + */ + int x1, y1; + int x2, y2; + + x1 = dPriv->x; + y1 = dPriv->y; + x2 = dPriv->x + dPriv->w; + y2 = dPriv->y + dPriv->h; + + if (x1 < 0) x1 = 0; + if (y1 < 0) y1 = 0; + if (x2 > intel->intelScreen->width) x2 = intel->intelScreen->width; + if (y2 > intel->intelScreen->height) y2 = intel->intelScreen->height; + + if (x1 == dPriv->pBackClipRects[0].x1 && + y1 == dPriv->pBackClipRects[0].y1) { + + dPriv->pBackClipRects[0].x2 = x2; + dPriv->pBackClipRects[0].y2 = y2; + } + } + } +} + + +void intelWindowMoved( struct intel_context *intel ) +{ + if (!intel->ctx.DrawBuffer) { + intelSetFrontClipRects( intel ); + } + else { + switch (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0]) { + case BUFFER_BIT_FRONT_LEFT: + intelSetFrontClipRects( intel ); + break; + case BUFFER_BIT_BACK_LEFT: + intelSetBackClipRects( intel ); + break; + default: + /* glDrawBuffer(GL_NONE or GL_FRONT_AND_BACK): software fallback */ + intelSetFrontClipRects( intel ); + } + } + + /* Set state we know depends on drawable parameters: + */ + { + GLcontext *ctx = &intel->ctx; + + ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height ); + + ctx->Driver.DepthRange( ctx, + ctx->Viewport.Near, + ctx->Viewport.Far ); + } +} + +static void emit_clip_rect_quads(struct intel_context *intel, + const drm_clip_rect_t *clear) +{ + GLuint i; + + for (i = 0; i < intel->numClipRects; i++) { + drm_clip_rect_t rect; + + if (intel_intersect_cliprects(&rect, + clear, + &intel->pClipRects[i])) + { + intel_meta_draw_quad(intel, + rect.x1, rect.x2, + rect.y1, rect.y2, + 0, + intel->ClearColor, + 0, 0, 0, 0, + INTEL_BATCH_NO_CLIPRECTS); + } + } +} + + +/* A true meta version of this would be very simple and additionally + * machine independent. Maybe we'll get there one day. + */ +static void intelClearWithTris(struct intel_context *intel, + GLbitfield mask, + GLboolean all, + GLint cx, GLint cy, + GLint cw, GLint ch) +{ + __DRIdrawablePrivate *dPriv = intel->driDrawable; + drm_clip_rect_t clear; + + LOCK_HARDWARE(intel); + intel->vtbl.install_meta_state(intel); + + if(!all) { + clear.x1 = cx; + clear.y1 = cy; + clear.x2 = cx + cw; + clear.y2 = cy + ch; + } else { + clear.x1 = 0; + clear.y1 = 0; + clear.x2 = dPriv->w; + clear.y2 = dPriv->h; + } + + /* Back and stencil cliprects are the same. Try and do both + * buffers at once: + */ + if (mask & (BUFFER_BIT_BACK_LEFT|BUFFER_BIT_STENCIL)) { + intel->vtbl.meta_draw_region(intel, + intel->back_region, + intel->depth_region ); + + if (mask & BUFFER_BIT_BACK_LEFT) + intel->vtbl.meta_color_mask(intel, GL_TRUE ); + else + intel->vtbl.meta_color_mask(intel, GL_FALSE ); + + if (mask & BUFFER_BIT_STENCIL) + intel->vtbl.meta_stencil_replace( intel, + intel->ctx.Stencil.WriteMask[0], + intel->ctx.Stencil.Clear); + else + intel->vtbl.meta_no_depth_stencil_write(intel); + + /* Do cliprects explicitly: + */ + emit_clip_rect_quads(intel, &clear); + } + + /* Front may have different cliprects: + */ + if (mask & BUFFER_BIT_FRONT_LEFT) { + intel->vtbl.meta_no_depth_stencil_write(intel); + intel->vtbl.meta_color_mask(intel, GL_TRUE ); + intel->vtbl.meta_draw_region(intel, + intel->front_region, + intel->depth_region); + + emit_clip_rect_quads(intel, &clear); + } + + intel->vtbl.leave_meta_state( intel ); + intel_batchbuffer_flush( intel->batch ); + UNLOCK_HARDWARE(intel); +} + + + + + +static void intelClear(GLcontext *ctx, + GLbitfield mask, + GLboolean all, + GLint cx, GLint cy, + GLint cw, GLint ch) +{ + struct intel_context *intel = intel_context( ctx ); + const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); + GLbitfield tri_mask = 0; + GLbitfield blit_mask = 0; + GLbitfield swrast_mask = 0; + + if (0) + fprintf(stderr, "%s\n", __FUNCTION__); + + + if (mask & BUFFER_BIT_FRONT_LEFT) { + if (colorMask == ~0) { + blit_mask |= BUFFER_BIT_FRONT_LEFT; + } + else { + tri_mask |= BUFFER_BIT_FRONT_LEFT; + } + } + + if (mask & BUFFER_BIT_BACK_LEFT) { + if (colorMask == ~0) { + blit_mask |= BUFFER_BIT_BACK_LEFT; + } + else { + tri_mask |= BUFFER_BIT_BACK_LEFT; + } + } + + if (mask & BUFFER_BIT_DEPTH) { + blit_mask |= BUFFER_BIT_DEPTH; + } + + if (mask & BUFFER_BIT_STENCIL) { + if (!intel->hw_stencil) { + swrast_mask |= BUFFER_BIT_STENCIL; + } + else if (ctx->Stencil.WriteMask[0] != 0xff) { + tri_mask |= BUFFER_BIT_STENCIL; + } + else { + blit_mask |= BUFFER_BIT_STENCIL; + } + } + + swrast_mask |= (mask & BUFFER_BIT_ACCUM); + + intelFlush( ctx ); + + if (blit_mask) + intelClearWithBlit( ctx, blit_mask, all, cx, cy, cw, ch ); + + if (tri_mask) + intelClearWithTris( intel, tri_mask, all, cx, cy, cw, ch); + + if (swrast_mask) + _swrast_Clear( ctx, swrast_mask, all, cx, cy, cw, ch ); +} + + + + + + + +/* Flip the front & back buffers + */ +static void intelPageFlip( const __DRIdrawablePrivate *dPriv ) +{ +#if 0 + struct intel_context *intel; + int tmp, ret; + + if (INTEL_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s\n", __FUNCTION__); + + assert(dPriv); + assert(dPriv->driContextPriv); + assert(dPriv->driContextPriv->driverPrivate); + + intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate; + + intelFlush( &intel->ctx ); + LOCK_HARDWARE( intel ); + + if (dPriv->pClipRects) { + *(drm_clip_rect_t *)intel->sarea->boxes = dPriv->pClipRects[0]; + intel->sarea->nbox = 1; + } + + ret = drmCommandNone(intel->driFd, DRM_I830_FLIP); + if (ret) { + fprintf(stderr, "%s: %d\n", __FUNCTION__, ret); + UNLOCK_HARDWARE( intel ); + exit(1); + } + + tmp = intel->sarea->last_enqueue; + intelRefillBatchLocked( intel ); + UNLOCK_HARDWARE( intel ); + + + intelSetDrawBuffer( &intel->ctx, intel->ctx.Color.DriverDrawBuffer ); +#endif +} + + +void intelSwapBuffers( __DRIdrawablePrivate *dPriv ) +{ + if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { + struct intel_context *intel; + GLcontext *ctx; + intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate; + ctx = &intel->ctx; + if (ctx->Visual.doubleBufferMode) { + _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */ + if ( 0 /*intel->doPageFlip*/ ) { /* doPageFlip is never set !!! */ + intelPageFlip( dPriv ); + } else { + intelCopyBuffer( dPriv ); + } + } + } else { + /* XXX this shouldn't be an error but we can't handle it for now */ + fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__); + } +} + +static void intelDrawBuffer(GLcontext *ctx, GLenum mode ) +{ + struct intel_context *intel = intel_context(ctx); + int front = 0; + + if (!ctx->DrawBuffer) + return; + + switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0] ) { + case BUFFER_BIT_FRONT_LEFT: + front = 1; + FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE ); + break; + case BUFFER_BIT_BACK_LEFT: + front = 0; + FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE ); + break; + default: + FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE ); + return; + } + + if ( intel->sarea->pf_current_page == 1 ) + front ^= 1; + + intelSetFrontClipRects( intel ); + + + if (front) { + if (intel->draw_region != intel->front_region) { + intel_region_release(intel, &intel->draw_region); + intel_region_reference(&intel->draw_region, intel->front_region); + } + } else { + if (intel->draw_region != intel->back_region) { + intel_region_release(intel, &intel->draw_region); + intel_region_reference(&intel->draw_region, intel->back_region); + } + } + + intel->vtbl.set_draw_region( intel, + intel->draw_region, + intel->depth_region); +} + +static void intelReadBuffer( GLcontext *ctx, GLenum mode ) +{ + /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */ +} + + + +void intelInitBufferFuncs( struct dd_function_table *functions ) +{ + functions->Clear = intelClear; + functions->GetBufferSize = intelBufferSize; + functions->ResizeBuffers = _mesa_resize_framebuffer; + functions->DrawBuffer = intelDrawBuffer; + functions->ReadBuffer = intelReadBuffer; +} diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c index 53b28a8a6be..50510dac2b5 100644 --- a/src/mesa/drivers/dri/i915/intel_context.c +++ b/src/mesa/drivers/dri/i915/intel_context.c @@ -55,6 +55,8 @@ #include "intel_ioctl.h" #include "intel_batchbuffer.h" #include "intel_blit.h" +#include "intel_pixel.h" +#include "intel_regions.h" #include "bufmgr.h" @@ -80,9 +82,6 @@ int INTEL_DEBUG = (0); #define need_GL_NV_vertex_program #include "extension_helper.h" -#ifndef VERBOSE -int VERBOSE = 0; -#endif #if DEBUG_LOCKING char *prevLockFile; @@ -95,7 +94,7 @@ int prevLockLine; #define DRIVER_DATE "20060212" -const GLubyte *intelGetString( GLcontext *ctx, GLenum name ) +static const GLubyte *intelGetString( GLcontext *ctx, GLenum name ) { const char * chipset; static char buffer[128]; @@ -106,7 +105,7 @@ const GLubyte *intelGetString( GLcontext *ctx, GLenum name ) break; case GL_RENDERER: - switch (INTEL_CONTEXT(ctx)->intelScreen->deviceID) { + switch (intel_context(ctx)->intelScreen->deviceID) { case PCI_CHIP_845_G: chipset = "Intel(R) 845G"; break; case PCI_CHIP_I830_M: @@ -133,27 +132,6 @@ const GLubyte *intelGetString( GLcontext *ctx, GLenum name ) } } -static void intelBufferSize(GLframebuffer *buffer, - GLuint *width, GLuint *height) -{ - GET_CURRENT_CONTEXT(ctx); - intelContextPtr intel = INTEL_CONTEXT(ctx); - /* Need to lock to make sure the driDrawable is uptodate. This - * information is used to resize Mesa's software buffers, so it has - * to be correct. - */ - LOCK_HARDWARE(intel); - if (intel->driDrawable) { - *width = intel->driDrawable->w; - *height = intel->driDrawable->h; - } - else { - *width = 0; - *height = 0; - } - UNLOCK_HARDWARE(intel); -} - /** * Extension strings exported by the intel driver. @@ -252,7 +230,32 @@ static void intelInvalidateState( GLcontext *ctx, GLuint new_state ) _ac_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); _tnl_invalidate_vertex_state( ctx, new_state ); - INTEL_CONTEXT(ctx)->NewGLState |= new_state; + intel_context(ctx)->NewGLState |= new_state; +} + + +void intelFlush( GLcontext *ctx ) +{ + struct intel_context *intel = intel_context( ctx ); + + if (intel->Fallback) + _swrast_flush( ctx ); + + INTEL_FIREVERTICES( intel ); + + if (intel->batch->map != intel->batch->ptr) + intel_batchbuffer_flush( intel->batch ); + + /* XXX: Need to do an MI_FLUSH here. Actually, the bufmgr_fake.c + * code will have done one already. + */ +} + +void intelFinish( GLcontext *ctx ) +{ + struct intel_context *intel = intel_context( ctx ); + intelFlush( ctx ); + bmFinishFence( intel->bm, intel->last_fence ); } @@ -261,10 +264,7 @@ void intelInitDriverFunctions( struct dd_function_table *functions ) _mesa_init_driver_functions( functions ); functions->Flush = intelFlush; - functions->Clear = intelClear; functions->Finish = intelFinish; - functions->GetBufferSize = intelBufferSize; - functions->ResizeBuffers = _mesa_resize_framebuffer; functions->GetString = intelGetString; functions->UpdateState = intelInvalidateState; functions->CopyColorTable = _swrast_CopyColorTable; @@ -275,11 +275,12 @@ void intelInitDriverFunctions( struct dd_function_table *functions ) intelInitTextureFuncs( functions ); intelInitPixelFuncs( functions ); intelInitStateFuncs( functions ); + intelInitBufferFuncs( functions ); } -GLboolean intelInitContext( intelContextPtr intel, +GLboolean intelInitContext( struct intel_context *intel, const __GLcontextModes *mesaVis, __DRIcontextPrivate *driContextPriv, void *sharedContextPrivate, @@ -379,6 +380,51 @@ GLboolean intelInitContext( intelContextPtr intel, /* GL_TRUE, */ GL_FALSE); + + /* Buffer manager: + */ + intel->bm = bm_fake_intel_Attach( intel ); + + bmInitPool(intel->bm, + intel->intelScreen->tex.offset, /* low offset */ + intel->intelScreen->tex.map, /* low virtual */ + intel->intelScreen->tex.size, + BM_MEM_AGP); + + /* These are still static, but create regions for them. + */ + intel->front_region = + intel_region_create_static(intel, + BM_MEM_AGP, + intelScreen->front.offset, + intelScreen->front.map, + intelScreen->cpp, + intelScreen->front.pitch, + intelScreen->height); + + + intel->back_region = + intel_region_create_static(intel, + BM_MEM_AGP, + intelScreen->back.offset, + intelScreen->back.map, + intelScreen->cpp, + intelScreen->back.pitch, + intelScreen->height); + + /* Still assuming front.cpp == depth.cpp + */ + intel->depth_region = + intel_region_create_static(intel, + BM_MEM_AGP, + intelScreen->depth.offset, + intelScreen->depth.map, + intelScreen->cpp, + intelScreen->depth.pitch, + intelScreen->height); + + intel->batch = intel_batchbuffer_alloc( intel ); + if (intel->ctx.Mesa_DXTn) { _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); _mesa_enable_extension( ctx, "GL_S3_s3tc" ); @@ -393,24 +439,16 @@ GLboolean intelInitContext( intelContextPtr intel, /* DRI_TEXMGR_DO_TEXTURE_RECT ); */ - intel->prim.flush = NULL; intel->prim.primitive = ~0; #if DO_DEBUG INTEL_DEBUG = driParseDebugString( getenv( "INTEL_DEBUG" ), debug_control ); - INTEL_DEBUG |= driParseDebugString( getenv( "INTEL_DEBUG" ), - debug_control ); #endif -#ifndef VERBOSE - if (getenv("INTEL_VERBOSE")) - VERBOSE=1; -#endif - if (getenv("INTEL_NO_RAST") || - getenv("INTEL_NO_RAST")) { + if (getenv("INTEL_NO_RAST")) { fprintf(stderr, "disabling 3D rasterization\n"); FALLBACK(intel, INTEL_FALLBACK_USER, 1); } @@ -420,7 +458,7 @@ GLboolean intelInitContext( intelContextPtr intel, void intelDestroyContext(__DRIcontextPrivate *driContextPriv) { - intelContextPtr intel = (intelContextPtr) driContextPriv->driverPrivate; + struct intel_context *intel = (struct intel_context *) driContextPriv->driverPrivate; assert(intel); /* should never be null */ if (intel) { @@ -437,7 +475,7 @@ void intelDestroyContext(__DRIcontextPrivate *driContextPriv) _swrast_DestroyContext (&intel->ctx); intel->Fallback = 0; /* don't call _swrast_Flush later */ - intelDestroyBatchBuffer(intel); + intel_batchbuffer_free(intel->batch); if ( release_texture_heaps ) { @@ -452,102 +490,6 @@ void intelDestroyContext(__DRIcontextPrivate *driContextPriv) } } -void intelSetFrontClipRects( intelContextPtr intel ) -{ - __DRIdrawablePrivate *dPriv = intel->driDrawable; - - if (!dPriv) return; - - intel->numClipRects = dPriv->numClipRects; - intel->pClipRects = dPriv->pClipRects; - intel->drawX = dPriv->x; - intel->drawY = dPriv->y; -} - - -void intelSetBackClipRects( intelContextPtr intel ) -{ - __DRIdrawablePrivate *dPriv = intel->driDrawable; - - if (!dPriv) return; - - if (intel->sarea->pf_enabled == 0 && dPriv->numBackClipRects == 0) { - intel->numClipRects = dPriv->numClipRects; - intel->pClipRects = dPriv->pClipRects; - intel->drawX = dPriv->x; - intel->drawY = dPriv->y; - } else { - intel->numClipRects = dPriv->numBackClipRects; - intel->pClipRects = dPriv->pBackClipRects; - intel->drawX = dPriv->backX; - intel->drawY = dPriv->backY; - - if (dPriv->numBackClipRects == 1 && - dPriv->x == dPriv->backX && - dPriv->y == dPriv->backY) { - - /* Repeat the calculation of the back cliprect dimensions here - * as early versions of dri.a in the Xserver are incorrect. Try - * very hard not to restrict future versions of dri.a which - * might eg. allocate truly private back buffers. - */ - int x1, y1; - int x2, y2; - - x1 = dPriv->x; - y1 = dPriv->y; - x2 = dPriv->x + dPriv->w; - y2 = dPriv->y + dPriv->h; - - if (x1 < 0) x1 = 0; - if (y1 < 0) y1 = 0; - if (x2 > intel->intelScreen->width) x2 = intel->intelScreen->width; - if (y2 > intel->intelScreen->height) y2 = intel->intelScreen->height; - - if (x1 == dPriv->pBackClipRects[0].x1 && - y1 == dPriv->pBackClipRects[0].y1) { - - dPriv->pBackClipRects[0].x2 = x2; - dPriv->pBackClipRects[0].y2 = y2; - } - } - } -} - - -void intelWindowMoved( intelContextPtr intel ) -{ - if (!intel->ctx.DrawBuffer) { - intelSetFrontClipRects( intel ); - } - else { - switch (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0]) { - case BUFFER_BIT_FRONT_LEFT: - intelSetFrontClipRects( intel ); - break; - case BUFFER_BIT_BACK_LEFT: - intelSetBackClipRects( intel ); - break; - default: - /* glDrawBuffer(GL_NONE or GL_FRONT_AND_BACK): software fallback */ - intelSetFrontClipRects( intel ); - } - } - - /* Set state we know depends on drawable parameters: - */ - { - GLcontext *ctx = &intel->ctx; - - ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y, - ctx->Scissor.Width, ctx->Scissor.Height ); - - ctx->Driver.DepthRange( ctx, - ctx->Viewport.Near, - ctx->Viewport.Far ); - } -} - GLboolean intelUnbindContext(__DRIcontextPrivate *driContextPriv) { return GL_TRUE; @@ -559,7 +501,7 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv, { if (driContextPriv) { - intelContextPtr intel = (intelContextPtr) driContextPriv->driverPrivate; + struct intel_context *intel = (struct intel_context *) driContextPriv->driverPrivate; if ( intel->driDrawable != driDrawPriv ) { /* Shouldn't the readbuffer be stored also? */ @@ -579,7 +521,7 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv, return GL_TRUE; } -void intelGetLock( intelContextPtr intel, GLuint flags ) +void intelGetLock( struct intel_context *intel, GLuint flags ) { __DRIdrawablePrivate *dPriv = intel->driDrawable; __DRIscreenPrivate *sPriv = intel->driScreen; @@ -611,117 +553,4 @@ void intelGetLock( intelContextPtr intel, GLuint flags ) } } -void intelSwapBuffers( __DRIdrawablePrivate *dPriv ) -{ - if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { - intelContextPtr intel; - GLcontext *ctx; - intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate; - ctx = &intel->ctx; - if (ctx->Visual.doubleBufferMode) { - _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */ - if ( 0 /*intel->doPageFlip*/ ) { /* doPageFlip is never set !!! */ - intelPageFlip( dPriv ); - } else { - intelCopyBuffer( dPriv ); - } - } - } else { - /* XXX this shouldn't be an error but we can't handle it for now */ - fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__); - } -} - - -void intelInitState( GLcontext *ctx ) -{ - /* Mesa should do this for us: - */ - ctx->Driver.AlphaFunc( ctx, - ctx->Color.AlphaFunc, - ctx->Color.AlphaRef); - - ctx->Driver.BlendColor( ctx, - ctx->Color.BlendColor ); - - ctx->Driver.BlendEquationSeparate( ctx, - ctx->Color.BlendEquationRGB, - ctx->Color.BlendEquationA); - - ctx->Driver.BlendFuncSeparate( ctx, - ctx->Color.BlendSrcRGB, - ctx->Color.BlendDstRGB, - ctx->Color.BlendSrcA, - ctx->Color.BlendDstA); - - ctx->Driver.ColorMask( ctx, - ctx->Color.ColorMask[RCOMP], - ctx->Color.ColorMask[GCOMP], - ctx->Color.ColorMask[BCOMP], - ctx->Color.ColorMask[ACOMP]); - - ctx->Driver.CullFace( ctx, ctx->Polygon.CullFaceMode ); - ctx->Driver.DepthFunc( ctx, ctx->Depth.Func ); - ctx->Driver.DepthMask( ctx, ctx->Depth.Mask ); - - ctx->Driver.Enable( ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled ); - ctx->Driver.Enable( ctx, GL_BLEND, ctx->Color.BlendEnabled ); - ctx->Driver.Enable( ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled ); - ctx->Driver.Enable( ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled ); - ctx->Driver.Enable( ctx, GL_CULL_FACE, ctx->Polygon.CullFlag ); - ctx->Driver.Enable( ctx, GL_DEPTH_TEST, ctx->Depth.Test ); - ctx->Driver.Enable( ctx, GL_DITHER, ctx->Color.DitherFlag ); - ctx->Driver.Enable( ctx, GL_FOG, ctx->Fog.Enabled ); - ctx->Driver.Enable( ctx, GL_LIGHTING, ctx->Light.Enabled ); - ctx->Driver.Enable( ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag ); - ctx->Driver.Enable( ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag ); - ctx->Driver.Enable( ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled ); - ctx->Driver.Enable( ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled ); - ctx->Driver.Enable( ctx, GL_TEXTURE_1D, GL_FALSE ); - ctx->Driver.Enable( ctx, GL_TEXTURE_2D, GL_FALSE ); - ctx->Driver.Enable( ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE ); - ctx->Driver.Enable( ctx, GL_TEXTURE_3D, GL_FALSE ); - ctx->Driver.Enable( ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE ); - - ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color ); - ctx->Driver.Fogfv( ctx, GL_FOG_MODE, 0 ); - ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density ); - ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start ); - ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End ); - - ctx->Driver.FrontFace( ctx, ctx->Polygon.FrontFace ); - - { - GLfloat f = (GLfloat)ctx->Light.Model.ColorControl; - ctx->Driver.LightModelfv( ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f ); - } - ctx->Driver.LineWidth( ctx, ctx->Line.Width ); - ctx->Driver.LogicOpcode( ctx, ctx->Color.LogicOp ); - ctx->Driver.PointSize( ctx, ctx->Point.Size ); - ctx->Driver.PolygonStipple( ctx, (const GLubyte *)ctx->PolygonStipple ); - ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y, - ctx->Scissor.Width, ctx->Scissor.Height ); - ctx->Driver.ShadeModel( ctx, ctx->Light.ShadeModel ); - ctx->Driver.StencilFuncSeparate( ctx, GL_FRONT, - ctx->Stencil.Function[0], - ctx->Stencil.Ref[0], - ctx->Stencil.ValueMask[0] ); - ctx->Driver.StencilFuncSeparate( ctx, GL_BACK, - ctx->Stencil.Function[1], - ctx->Stencil.Ref[1], - ctx->Stencil.ValueMask[1] ); - ctx->Driver.StencilMaskSeparate( ctx, GL_FRONT, ctx->Stencil.WriteMask[0] ); - ctx->Driver.StencilMaskSeparate( ctx, GL_BACK, ctx->Stencil.WriteMask[1] ); - ctx->Driver.StencilOpSeparate( ctx, GL_FRONT, - ctx->Stencil.FailFunc[0], - ctx->Stencil.ZFailFunc[0], - ctx->Stencil.ZPassFunc[0]); - ctx->Driver.StencilOpSeparate( ctx, GL_BACK, - ctx->Stencil.FailFunc[1], - ctx->Stencil.ZFailFunc[1], - ctx->Stencil.ZPassFunc[1]); - - - ctx->Driver.DrawBuffer( ctx, ctx->Color.DrawBuffer[0] ); -} diff --git a/src/mesa/drivers/dri/i915/intel_context.h b/src/mesa/drivers/dri/i915/intel_context.h index 1234a8241dc..8e6ec161802 100644 --- a/src/mesa/drivers/dri/i915/intel_context.h +++ b/src/mesa/drivers/dri/i915/intel_context.h @@ -48,28 +48,22 @@ #define DV_PF_8888 (3<<8) struct intel_region; +struct intel_context; -typedef struct intel_context *intelContextPtr; - -typedef void (*intel_tri_func)(intelContextPtr, intelVertex *, intelVertex *, +typedef void (*intel_tri_func)(struct intel_context *, intelVertex *, intelVertex *, intelVertex *); -typedef void (*intel_line_func)(intelContextPtr, intelVertex *, intelVertex *); -typedef void (*intel_point_func)(intelContextPtr, intelVertex *); +typedef void (*intel_line_func)(struct intel_context *, intelVertex *, intelVertex *); +typedef void (*intel_point_func)(struct intel_context *, intelVertex *); #define INTEL_FALLBACK_DRAW_BUFFER 0x1 #define INTEL_FALLBACK_READ_BUFFER 0x2 #define INTEL_FALLBACK_USER 0x4 -#define INTEL_FALLBACK_NO_BATCHBUFFER 0x8 -#define INTEL_FALLBACK_NO_TEXMEM 0x10 -#define INTEL_FALLBACK_RENDERMODE 0x20 +#define INTEL_FALLBACK_RENDERMODE 0x8 -extern void intelFallback( intelContextPtr intel, GLuint bit, GLboolean mode ); +extern void intelFallback( struct intel_context *intel, GLuint bit, GLboolean mode ); #define FALLBACK( intel, bit, mode ) intelFallback( intel, bit, mode ) -#define INTEL_TEX_MAXLEVELS 10 - - struct intel_texture_object { @@ -93,7 +87,8 @@ struct intel_texture_object -struct intel_texture_image { +struct intel_texture_image +{ struct gl_texture_image base; /* These aren't stored in gl_texture_image @@ -109,12 +104,6 @@ struct intel_texture_image { }; -struct intel_reloc { - GLuint *value; - GLuint delta; - GLuint *dest; -}; - #define INTEL_MAX_FIXUP 64 struct intel_context @@ -122,24 +111,59 @@ struct intel_context GLcontext ctx; /* the parent class */ struct { - void (*destroy)( intelContextPtr intel ); - void (*emit_state)( intelContextPtr intel ); - void (*emit_invarient_state)( intelContextPtr intel ); - void (*lost_hardware)( intelContextPtr intel ); - void (*update_texture_state)( intelContextPtr intel ); + void (*destroy)( struct intel_context *intel ); + void (*emit_state)( struct intel_context *intel ); + void (*emit_invarient_state)( struct intel_context *intel ); + void (*lost_hardware)( struct intel_context *intel ); + void (*update_texture_state)( struct intel_context *intel ); - void (*render_start)( intelContextPtr intel ); - void (*set_draw_offset)( intelContextPtr intel, int offset ); - void (*emit_flush)( intelContextPtr intel ); + void (*render_start)( struct intel_context *intel ); + void (*set_draw_region)( struct intel_context *intel, + struct intel_region *draw_region, + struct intel_region *depth_region ); + void (*emit_flush)( struct intel_context *intel ); - void (*reduced_primitive_state)( intelContextPtr intel, GLenum rprim ); + void (*reduced_primitive_state)( struct intel_context *intel, GLenum rprim ); - GLboolean (*check_vertex_size)( intelContextPtr intel, GLuint expected ); + GLboolean (*check_vertex_size)( struct intel_context *intel, GLuint expected ); - void (*clear_with_tris)( intelContextPtr intel, GLbitfield mask, + void (*clear_with_tris)( struct intel_context *intel, GLbitfield mask, GLboolean all, GLint cx, GLint cy, GLint cw, GLint ch); + + /* Metaops: + */ + void (*install_meta_state)( struct intel_context *intel ); + void (*leave_meta_state)( struct intel_context *intel ); + + void (*meta_draw_region)( struct intel_context *intel, + struct intel_region *draw_region, + struct intel_region *depth_region ); + + void (*meta_color_mask)( struct intel_context *intel, + GLboolean ); + + void (*meta_stencil_replace)( struct intel_context *intel, + GLuint mask, + GLuint clear ); + + void (*meta_no_depth_stencil_write)( struct intel_context *intel ); + + void (*meta_no_texture)( struct intel_context *intel ); + void (*meta_texture_blend_replace)( struct intel_context *intel ); + + void (*meta_tex_rect_source)( struct intel_context *intel, + struct intel_region *region, + GLuint textureFormat ); + + void (*meta_draw_format)( struct intel_context *intel, + GLuint format, + GLuint depth_format ); + + + + } vtbl; GLint refcount; @@ -148,42 +172,24 @@ struct intel_context GLuint last_fence; - struct { - GLuint start_offset; - GLint size; - GLint space; - GLubyte *ptr; - } batch; - -#define INTEL_ALLOC_NR 64 -#define INTEL_ALLOC_SIZE 4096 - - struct { - GLuint buffer[INTEL_ALLOC_NR]; - GLuint current; - } alloc; + struct intel_batchbuffer *batch; struct { GLuint id; GLuint primitive; GLubyte *start_ptr; - void (*flush)( GLcontext * ); + void (*flush)( struct intel_context * ); } prim; GLboolean locked; - GLubyte clear_red; - GLubyte clear_green; - GLubyte clear_blue; - GLubyte clear_alpha; GLuint ClearColor; GLuint ClearDepth; + /* Offsets of fields within the current vertex: + */ GLuint coloroffset; GLuint specoffset; - - /* Support for duplicating XYZW as WPOS parameter (crutch for I915). - */ GLuint wpos_offset; GLuint wpos_size; @@ -201,10 +207,6 @@ 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; /* State for intelvb.c and inteltris.c. @@ -231,7 +233,6 @@ struct intel_context /* These refer to the current draw (front vs. back) buffer: */ - GLuint drawOffset; /* agp offset of drawbuffer */ int drawX; /* origin of drawable in draw buffer */ int drawY; GLuint numClipRects; /* cliprects for that buffer */ @@ -347,8 +348,7 @@ do { \ #define INTEL_FIREVERTICES(intel) \ do { \ - if ((intel)->prim.flush) \ - (intel)->prim.flush(&(intel)->ctx); \ + assert(!(intel)->prim.flush); \ } while (0) /* ================================================================ @@ -382,7 +382,7 @@ do { \ * than COPY_DWORDS would: */ #if defined(i386) || defined(__i386__) -static __inline__ void * __memcpy(void * to, const void * from, size_t n) +static inline void * __memcpy(void * to, const void * from, size_t n) { int d0, d1, d2; __asm__ __volatile__( @@ -443,21 +443,19 @@ extern int INTEL_DEBUG; * intel_context.c: */ -extern void intelInitDriverFunctions( struct dd_function_table *functions ); - -extern GLboolean intelInitContext( intelContextPtr intel, +extern GLboolean intelInitContext( struct intel_context *intel, const __GLcontextModes *mesaVis, __DRIcontextPrivate *driContextPriv, void *sharedContextPrivate, struct dd_function_table *functions ); -extern void intelGetLock(intelContextPtr intel, GLuint flags); -extern void intelSetBackClipRects(intelContextPtr intel); -extern void intelSetFrontClipRects(intelContextPtr intel); -extern void intelWindowMoved( intelContextPtr intel ); +extern void intelGetLock(struct intel_context *intel, GLuint flags); extern void intelInitState( GLcontext *ctx ); -extern const GLubyte *intelGetString( GLcontext *ctx, GLenum name ); +extern void intelFinish( GLcontext *ctx ); +extern void intelFlush( GLcontext *ctx ); + +extern void intelInitDriverFunctions( struct dd_function_table *functions ); /* ================================================================ @@ -517,6 +515,8 @@ extern void intelInitStateFuncs( struct dd_function_table *functions ); #define BLENDFACT_INV_CONST_ALPHA 0x0f #define BLENDFACT_MASK 0x0f +#define MI_BATCH_BUFFER_END (0xA<<23) + extern int intel_translate_compare_func( GLenum func ); extern int intel_translate_stencil_op( GLenum op ); @@ -525,28 +525,19 @@ extern int intel_translate_logic_op( GLenum opcode ); /* ================================================================ - * intel_ioctl.c: + * intel_buffers.c: */ -extern void intel_dump_batchbuffer( long offset, - int *ptr, - int count ); - - -/* ================================================================ - * intel_pixel.c: - */ -extern void intelInitPixelFuncs( struct dd_function_table *functions ); - -GLboolean intel_check_color_per_fragment_ops( const GLcontext *ctx ); - -GLboolean intel_clip_to_framebuffer( GLcontext *ctx, - const GLframebuffer *buffer, - GLint *x, GLint *y, - GLsizei *width, GLsizei *height ); +void intelInitBufferFuncs( struct dd_function_table *functions ); struct intel_region *intel_readbuf_region( struct intel_context *intel ); struct intel_region *intel_drawbuf_region( struct intel_context *intel ); +extern void intelWindowMoved( struct intel_context *intel ); + +extern GLboolean intel_intersect_cliprects( drm_clip_rect_t *dest, + const drm_clip_rect_t *a, + const drm_clip_rect_t *b ); + /*====================================================================== @@ -568,8 +559,6 @@ static inline struct intel_texture_image *intel_texture_image( struct gl_texture return (struct intel_texture_image *)img; } -#define INTEL_CONTEXT(ctx) intel_context(ctx) - #endif diff --git a/src/mesa/drivers/dri/i915/intel_ioctl.c b/src/mesa/drivers/dri/i915/intel_ioctl.c index 4080782b5a4..4569c57d9a4 100644 --- a/src/mesa/drivers/dri/i915/intel_ioctl.c +++ b/src/mesa/drivers/dri/i915/intel_ioctl.c @@ -44,7 +44,7 @@ #include "bufmgr.h" -int intelEmitIrqLocked( intelContextPtr intel ) +int intelEmitIrqLocked( struct intel_context *intel ) { drmI830IrqEmit ie; int ret, seq = 0; @@ -54,14 +54,12 @@ int intelEmitIrqLocked( intelContextPtr intel ) ie.irq_seq = &seq; -#if 1 ret = drmCommandWriteRead( intel->driFd, DRM_I830_IRQ_EMIT, &ie, sizeof(ie) ); if ( ret ) { fprintf( stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret ); exit(1); } -#endif if (0) fprintf(stderr, "%s --> %d\n", __FUNCTION__, seq ); @@ -69,7 +67,7 @@ int intelEmitIrqLocked( intelContextPtr intel ) return seq; } -void intelWaitIrq( intelContextPtr intel, int seq ) +void intelWaitIrq( struct intel_context *intel, int seq ) { drmI830IrqWait iw; int ret; @@ -79,7 +77,6 @@ void intelWaitIrq( intelContextPtr intel, int seq ) iw.irq_seq = seq; -#if 1 do { ret = drmCommandWrite( intel->driFd, DRM_I830_IRQ_WAIT, &iw, sizeof(iw) ); } while (ret == -EAGAIN || ret == -EINTR); @@ -88,294 +85,61 @@ void intelWaitIrq( intelContextPtr intel, int seq ) fprintf( stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret ); exit(1); } -#endif -} - - - -void intel_dump_batchbuffer( long offset, - int *ptr, - int count ) -{ - int i; - fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", count); - for (i = 0; i < count/4; i += 4) - fprintf(stderr, "\t0x%08x 0x%08x 0x%08x 0x%08x\n", -/* (unsigned int)offset + i*4, */ - ptr[i], ptr[i+1], ptr[i+2], ptr[i+3]); - fprintf(stderr, "END BATCH\n\n\n"); } -#define MI_BATCH_BUFFER_END (0xA<<23) - - -void intelFlushBatchLocked( intelContextPtr intel, - GLboolean ignore_cliprects, - GLboolean refill, - GLboolean allow_unlock) +void intel_batch_ioctl( struct intel_context *intel, + GLuint start_offset, + GLuint used, + GLboolean ignore_cliprects) { drmI830BatchBuffer batch; assert(intel->locked); - assert(intel->buffer_list); - assert(intel->batch.ptr); - + assert(used); if (0) - fprintf(stderr, "%s used %d of %d offset %x..%x refill %d\n", + fprintf(stderr, "%s used %d offset %x..%x ignore_cliprects %d\n", __FUNCTION__, - (intel->batch.size - intel->batch.space), - intel->batch.size, - intel->batch.start_offset, - intel->batch.start_offset + - (intel->batch.size - intel->batch.space), - refill); + used, + start_offset, + start_offset + used, + ignore_cliprects); /* Throw away non-effective packets. Won't work once we have * hardware contexts which would preserve statechanges beyond a * single buffer. */ if (intel->numClipRects == 0 && !ignore_cliprects) { - /* Note that any state thought to have been emitted actually - * hasn't: - */ - intel->batch.ptr -= (intel->batch.size - intel->batch.space); - intel->batch.space = intel->batch.size; intel->vtbl.lost_hardware( intel ); + return; } - if (intel->batch.space != intel->batch.size) { - batch.start = intel->batch.start_offset; - batch.used = intel->batch.size - intel->batch.space; - batch.cliprects = intel->pClipRects; - batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; - batch.DR1 = 0; - batch.DR4 = ((((GLuint)intel->drawX) & 0xffff) | - (((GLuint)intel->drawY) << 16)); + batch.start = start_offset; + batch.used = used; + batch.cliprects = intel->pClipRects; + batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects; + batch.DR1 = 0; + batch.DR4 = ((((GLuint)intel->drawX) & 0xffff) | + (((GLuint)intel->drawY) << 16)); - if ((batch.used & 0x4) == 0) { - ((int *)intel->batch.ptr)[0] = 0; - ((int *)intel->batch.ptr)[1] = MI_BATCH_BUFFER_END; - batch.used += 0x8; - intel->batch.ptr += 0x8; - } - else { - ((int *)intel->batch.ptr)[0] = MI_BATCH_BUFFER_END; - batch.used += 0x4; - intel->batch.ptr += 0x4; - } - - if (0) - intel_dump_batchbuffer( batch.start, - (int *)(intel->batch.ptr - batch.used), - batch.used ); - - if (0) - fprintf(stderr, "%s: 0x%x..0x%x DR4: %x cliprects: %d\n", - __FUNCTION__, - batch.start, - batch.start + batch.used * 4, - batch.DR4, batch.num_cliprects); - + if (0) + fprintf(stderr, "%s: 0x%x..0x%x DR4: %x cliprects: %d\n", + __FUNCTION__, + batch.start, + batch.start + batch.used * 4, + batch.DR4, batch.num_cliprects); #if 1 - if (drmCommandWrite (intel->driFd, DRM_I830_BATCHBUFFER, &batch, - sizeof(batch))) { - fprintf(stderr, "DRM_I830_BATCHBUFFER: %d\n", -errno); - UNLOCK_HARDWARE(intel); - exit(1); - } -#endif - - /* FIXME: use hardware contexts to avoid 'losing' hardware after - * each buffer flush. - */ - intel->vtbl.lost_hardware( intel ); - } - - bmUnmapBuffer( intel->bm, - intel->alloc.buffer[intel->alloc.current] ); - intel->batch.ptr = NULL; - intel->batch.size = 0; - intel->batch.space = 0; - - intel->last_fence = bmFenceBufferList(intel->bm, intel->buffer_list); - bmFreeBufferList(intel->buffer_list); - - - intel->buffer_list = NULL; -} - -void intelFlushBatch( intelContextPtr intel, GLboolean refill ) -{ - if (intel->locked) { - intelFlushBatchLocked( intel, GL_FALSE, refill, GL_FALSE ); - } - else { - assert(intel->batch.size == intel->batch.space); - } -} - - - - - -static void wait_for_idle_locked( struct intel_context *intel ) -{ - intelInstallBatchBuffer(intel); - - bmAddBuffer(intel->buffer_list, intel->draw_region->buffer, - BM_WRITE, NULL, NULL); - - intelValidateBuffers(intel); - - intel->vtbl.emit_flush( intel ); - intelFlushBatch( intel, GL_TRUE ); - - bmFinishFence( intel->bm, intel->last_fence ); -} - -void intelWaitForIdle( intelContextPtr intel ) -{ - if (intel->locked) { - wait_for_idle_locked( intel ); - } - else { - LOCK_HARDWARE(intel); - wait_for_idle_locked( intel ); + if (drmCommandWrite (intel->driFd, DRM_I830_BATCHBUFFER, &batch, + sizeof(batch))) { + fprintf(stderr, "DRM_I830_BATCHBUFFER: %d\n", -errno); UNLOCK_HARDWARE(intel); - } -} - - - -void intelFlush( GLcontext *ctx ) -{ - intelContextPtr intel = INTEL_CONTEXT( ctx ); - - if (intel->Fallback) - _swrast_flush( ctx ); - - INTEL_FIREVERTICES( intel ); - - if (intel->batch.size != intel->batch.space) - intelFlushBatch( intel, GL_FALSE ); -} - -void intelFinish( GLcontext *ctx ) -{ - intelContextPtr intel = INTEL_CONTEXT( ctx ); - intelFlush( ctx ); - intelWaitForIdle( intel ); -} - - -void intelClear(GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint cx, GLint cy, GLint cw, GLint ch) -{ - intelContextPtr intel = INTEL_CONTEXT( ctx ); - const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); - GLbitfield tri_mask = 0; - GLbitfield blit_mask = 0; - GLbitfield swrast_mask = 0; - - if (0) - fprintf(stderr, "%s\n", __FUNCTION__); - - /* Take care of cliprects, which are handled differently for - * clears, etc. - */ - intelFlush( &intel->ctx ); - - if (mask & BUFFER_BIT_FRONT_LEFT) { - if (colorMask == ~0) { - blit_mask |= BUFFER_BIT_FRONT_LEFT; - } - else { - tri_mask |= BUFFER_BIT_FRONT_LEFT; - } - } - - if (mask & BUFFER_BIT_BACK_LEFT) { - if (colorMask == ~0) { - blit_mask |= BUFFER_BIT_BACK_LEFT; - } - else { - tri_mask |= BUFFER_BIT_BACK_LEFT; - } - } - - if (mask & BUFFER_BIT_DEPTH) { - blit_mask |= BUFFER_BIT_DEPTH; - } - - if (mask & BUFFER_BIT_STENCIL) { - if (!intel->hw_stencil) { - swrast_mask |= BUFFER_BIT_STENCIL; - } - else if (ctx->Stencil.WriteMask[0] != 0xff) { - tri_mask |= BUFFER_BIT_STENCIL; - } - else { - blit_mask |= BUFFER_BIT_STENCIL; - } - } - - swrast_mask |= (mask & BUFFER_BIT_ACCUM); - - if (blit_mask) - intelClearWithBlit( ctx, blit_mask, all, cx, cy, cw, ch ); - - if (tri_mask) - intel->vtbl.clear_with_tris( intel, tri_mask, all, cx, cy, cw, ch); - - if (swrast_mask) - _swrast_Clear( ctx, swrast_mask, all, cx, cy, cw, ch ); -} - - - - - - - -/* Flip the front & back buffes - */ -void intelPageFlip( const __DRIdrawablePrivate *dPriv ) -{ -#if 0 - intelContextPtr intel; - int tmp, ret; - - if (INTEL_DEBUG & DEBUG_IOCTL) - fprintf(stderr, "%s\n", __FUNCTION__); - - assert(dPriv); - assert(dPriv->driContextPriv); - assert(dPriv->driContextPriv->driverPrivate); - - intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate; - - intelFlush( &intel->ctx ); - LOCK_HARDWARE( intel ); - - if (dPriv->pClipRects) { - *(drm_clip_rect_t *)intel->sarea->boxes = dPriv->pClipRects[0]; - intel->sarea->nbox = 1; - } - - ret = drmCommandNone(intel->driFd, DRM_I830_FLIP); - if (ret) { - fprintf(stderr, "%s: %d\n", __FUNCTION__, ret); - UNLOCK_HARDWARE( intel ); exit(1); } - - tmp = intel->sarea->last_enqueue; - intelRefillBatchLocked( intel ); - UNLOCK_HARDWARE( intel ); - - - intelSetDrawBuffer( &intel->ctx, intel->ctx.Color.DriverDrawBuffer ); #endif + + /* FIXME: use hardware contexts to avoid 'losing' hardware after + * each buffer flush. + */ + intel->vtbl.lost_hardware( intel ); } diff --git a/src/mesa/drivers/dri/i915/intel_ioctl.h b/src/mesa/drivers/dri/i915/intel_ioctl.h index 89d2be06323..955681774b5 100644 --- a/src/mesa/drivers/dri/i915/intel_ioctl.h +++ b/src/mesa/drivers/dri/i915/intel_ioctl.h @@ -30,25 +30,13 @@ #include "intel_context.h" -extern void intelWaitAgeLocked( intelContextPtr intel, int age, GLboolean unlock ); +void intelWaitIrq( struct intel_context *intel, int seq ); +int intelEmitIrqLocked( struct intel_context *intel ); -extern void intelClear(GLcontext *ctx, GLbitfield mask, GLboolean all, - GLint cx, GLint cy, GLint cw, GLint ch); - -extern void intelPageFlip( const __DRIdrawablePrivate *dpriv ); -extern void intelWaitForIdle( intelContextPtr intel ); -extern void intelFlushBatch( intelContextPtr intel, GLboolean refill ); -extern void intelFlushBatchLocked( intelContextPtr intel, - GLboolean ignore_cliprects, - GLboolean refill, - GLboolean allow_unlock); -extern void intelRefillBatchLocked( intelContextPtr intel, GLboolean allow_unlock ); -extern void intelFinish( GLcontext *ctx ); -extern void intelFlush( GLcontext *ctx ); - - -void intelWaitIrq( intelContextPtr intel, int seq ); -int intelEmitIrqLocked( intelContextPtr intel ); +void intel_batch_ioctl( struct intel_context *intel, + GLuint start_offset, + GLuint used, + GLboolean ignore_cliprects); #endif diff --git a/src/mesa/drivers/dri/i915/intel_pixel.c b/src/mesa/drivers/dri/i915/intel_pixel.c index b2484975ccf..e38c6be576b 100644 --- a/src/mesa/drivers/dri/i915/intel_pixel.c +++ b/src/mesa/drivers/dri/i915/intel_pixel.c @@ -1,78 +1,40 @@ -/************************************************************************** - * - * 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 "enums.h" -#include "mtypes.h" -#include "macros.h" #include "swrast/swrast.h" - -#include "intel_screen.h" #include "intel_context.h" -#include "intel_ioctl.h" -#include "intel_batchbuffer.h" -#include "intel_blit.h" -#include "intel_regions.h" -#include "bufmgr.h" +#include "intel_pixel.h" -static GLboolean -check_color( GLcontext *ctx, GLenum type, GLenum format, - const struct gl_pixelstore_attrib *packing, - const void *pixels, GLint sz, GLint pitch ) -{ - intelContextPtr intel = INTEL_CONTEXT(ctx); - GLuint cpp = intel->intelScreen->cpp; - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s\n", __FUNCTION__); - if ( (pitch & 63) || - ctx->_ImageTransferState || - packing->SwapBytes || - packing->LsbFirst) { - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: failed 1\n", __FUNCTION__); - return GL_FALSE; - } +#if 0 +struct intel_client_region *intel_pack_region( struct intel_context *intel, + const struct gl_pixelstore_attrib *pack, + GLenum format, + GLenum type, + GLvoid *pixels ) +{ +} - if ( type == GL_UNSIGNED_INT_8_8_8_8_REV && - cpp == 4 && - format == GL_BGRA ) { - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: passed 2\n", __FUNCTION__); - return GL_TRUE; - } - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: failed\n", __FUNCTION__); +struct intel_client_region *intel_unpack_region( struct intel_context *intel, + const struct gl_pixelstore_attrib *pack, + GLenum format, + GLenum type, + GLvoid *pixels ) +{ + GLint pitch = unpack->RowLength ? unpack->RowLength : width; + /* XXX: Need to adjust pixels pointer for unpack->skip pixels/rows + * offsets. + */ - return GL_FALSE; } +void release_client_region( struct intel_context *intel, + struct intel_region *region ) +{ +} +#endif + + + GLboolean intel_check_color_per_fragment_ops( const GLcontext *ctx ) { return !(ctx->Color.AlphaEnabled || @@ -88,6 +50,33 @@ GLboolean intel_check_color_per_fragment_ops( const GLcontext *ctx ) ctx->Texture._EnabledUnits); } +#if 0 +/* The intel_region struct doesn't really do enough to capture the + * format of the pixels in the region. For now this code assumes that + * the region is a display surface and hence is either ARGB8888 or + * RGB565. + */ +GLboolean intel_check_blit_format( struct intel_region *region, + struct intel_client_region *client_region ) +{ + if (region->cpp == 4 + client_region->cpp == 4 && + client_region->type == GL_UNSIGNED_INT_8_8_8_8_REV && + client_region->format == GL_BGRA ) { + return GL_TRUE; + } + + if (region->cpp == 2 && + client_region->cpp == 2 && + client_region->type == GL_UNSIGNED_INT_5_6_5_REV && + client_region->format == GL_BGR ) { + return GL_TRUE; + } + + fprintf(stderr, "%s: request doesn't match pixel format\n", __FUNCTION__); + return GL_FALSE; +} +#endif GLboolean intel_clip_to_framebuffer( GLcontext *ctx, @@ -124,496 +113,6 @@ GLboolean intel_clip_to_framebuffer( GLcontext *ctx, return GL_TRUE; } -static GLboolean -intelTryReadPixels( GLcontext *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *pack, - GLvoid *pixels ) -{ - intelContextPtr intel = INTEL_CONTEXT(ctx); - GLint size = 0; - GLint pitch = pack->RowLength ? pack->RowLength : width; - - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s\n", __FUNCTION__); - - /* Only accelerate reading to agp buffers. - */ - if ( 1 ) { - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: dest not agp\n", __FUNCTION__); - return GL_FALSE; - } - - /* Need GL_PACK_INVERT_MESA to cope with upsidedown results from - * blitter: - */ - if (!pack->Invert) { - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: MESA_PACK_INVERT not set\n", __FUNCTION__); - return GL_FALSE; - } - - if (!check_color(ctx, type, format, pack, pixels, size, pitch)) - return GL_FALSE; - - switch ( intel->intelScreen->cpp ) { - case 4: - break; - default: - return GL_FALSE; - } - - - /* Although the blits go on the command buffer, need to do this and - * fire with lock held to guarentee cliprects and drawOffset are - * correct. - * - * This is an unusual situation however, as the code which flushes - * a full command buffer expects to be called unlocked. As a - * workaround, immediately flush the buffer on aquiring the lock. - */ - intelFlush( &intel->ctx ); - LOCK_HARDWARE( intel ); - { - __DRIdrawablePrivate *dPriv = intel->driDrawable; - int nbox = dPriv->numClipRects; - int src_offset = intel->drawOffset; - int src_pitch = intel->intelScreen->front.pitch; - int dst_offset = 0; - drm_clip_rect_t *box = dPriv->pClipRects; - int i; - - if (!intel_clip_to_framebuffer(ctx, ctx->ReadBuffer, &x, &y, &width, &height)) { - UNLOCK_HARDWARE( intel ); - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s totally clipped -- nothing to do\n", - __FUNCTION__); - return GL_TRUE; - } - - - y = dPriv->h - y - height; - x += dPriv->x; - y += dPriv->y; - - - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "readpixel blit src_pitch %d dst_pitch %d\n", - src_pitch, pitch); - - for (i = 0 ; i < nbox ; i++) - { - GLint bx = box[i].x1; - GLint by = box[i].y1; - GLint bw = box[i].x2 - bx; - GLint bh = box[i].y2 - by; - - if (bx < x) bw -= x - bx, bx = x; - if (by < y) bh -= y - by, by = y; - if (bx + bw > x + width) bw = x + width - bx; - if (by + bh > y + height) bh = y + height - by; - if (bw <= 0) continue; - if (bh <= 0) continue; - - intelEmitCopyBlitLocked( intel, - intel->intelScreen->cpp, - src_pitch, src_offset, - pitch, dst_offset, - bx, by, - bx - x, by - y, - bw, bh ); - } - } - UNLOCK_HARDWARE( intel ); - intelFinish( &intel->ctx ); - - return GL_TRUE; -} - -static void -intelReadPixels( GLcontext *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *pack, - GLvoid *pixels ) -{ - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (!intelTryReadPixels( ctx, x, y, width, height, format, type, pack, - pixels)) - _swrast_ReadPixels( ctx, x, y, width, height, format, type, pack, - pixels); -} - - - - -static void do_draw_pix( GLcontext *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLint pitch, - const void *pixels, - GLuint dest ) -{ - intelContextPtr intel = INTEL_CONTEXT(ctx); - __DRIdrawablePrivate *dPriv = intel->driDrawable; - drm_clip_rect_t *box = dPriv->pClipRects; - int nbox = dPriv->numClipRects; - int i; - int src_offset = 0; - int src_pitch = pitch; - - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s\n", __FUNCTION__); - - intelFlush( &intel->ctx ); - LOCK_HARDWARE( intel ); - if (ctx->DrawBuffer) - { - y -= height; /* cope with pixel zoom */ - - if (!intel_clip_to_framebuffer(ctx, ctx->DrawBuffer, - &x, &y, &width, &height)) { - UNLOCK_HARDWARE( intel ); - return; - } - - y = dPriv->h - y - height; /* convert from gl to hardware coords */ - x += dPriv->x; - y += dPriv->y; - - - for (i = 0 ; i < nbox ; i++ ) - { - GLint bx = box[i].x1; - GLint by = box[i].y1; - GLint bw = box[i].x2 - bx; - GLint bh = box[i].y2 - by; - - if (bx < x) bw -= x - bx, bx = x; - if (by < y) bh -= y - by, by = y; - if (bx + bw > x + width) bw = x + width - bx; - if (by + bh > y + height) bh = y + height - by; - if (bw <= 0) continue; - if (bh <= 0) continue; - - intelEmitCopyBlitLocked( intel, - intel->intelScreen->cpp, - src_pitch, src_offset, - intel->intelScreen->front.pitch, - intel->drawOffset, - bx - x, by - y, - bx, by, - bw, bh ); - } - } - UNLOCK_HARDWARE( intel ); - intelFinish( &intel->ctx ); -} - - - - -static GLboolean -intelTryDrawPixels( GLcontext *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels ) -{ - intelContextPtr intel = INTEL_CONTEXT(ctx); - GLint pitch = unpack->RowLength ? unpack->RowLength : width; - GLuint dest; - GLuint cpp = intel->intelScreen->cpp; - GLint size = width * pitch * cpp; - - /* XXX: Need to adjust pixels pointer for unpack->skip pixels/rows - * offsets. - */ - - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s\n", __FUNCTION__); - - switch (format) { - case GL_RGB: - case GL_RGBA: - case GL_BGRA: - dest = intel->drawOffset; - - /* Planemask doesn't have full support in blits. - */ - if (!ctx->Color.ColorMask[RCOMP] || - !ctx->Color.ColorMask[GCOMP] || - !ctx->Color.ColorMask[BCOMP] || - !ctx->Color.ColorMask[ACOMP]) { - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: planemask\n", __FUNCTION__); - return GL_FALSE; - } - - /* Can't do conversions on agp reads/draws. - */ - if ( 1 ) { - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s: not agp memory\n", __FUNCTION__); - return GL_FALSE; - } - - if (!check_color(ctx, type, format, unpack, pixels, size, pitch)) { - return GL_FALSE; - } - if (!intel_check_color_per_fragment_ops(ctx)) { - return GL_FALSE; - } - if (!ctx->Current.RasterPosValid) - return GL_FALSE; - - if (ctx->Pixel.ZoomX != 1.0F || - ctx->Pixel.ZoomY != -1.0F) - return GL_FALSE; - break; - - default: - return GL_FALSE; - } - - if ( 0 ) - { - do_draw_pix( ctx, x, y, width, height, pitch, pixels, - dest ); - return GL_TRUE; - } - else if (0) - { - /* Pixels is in regular memory -- get dma buffers and perform - * upload through them. No point doing this for regular uploads - * but once we remove some of the restrictions above (colormask, - * pixelformat conversion, zoom?, etc), this could be a win. - */ - } - else - return GL_FALSE; -} - -static void -intelDrawPixels( GLcontext *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels ) -{ - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (!intelTryDrawPixels( ctx, x, y, width, height, format, type, - unpack, pixels )) - _swrast_DrawPixels( ctx, x, y, width, height, format, type, - unpack, pixels ); -} - - -struct intel_region *intel_drawbuf_region( struct intel_context *intel ) -{ - switch (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0]) { - case BUFFER_BIT_FRONT_LEFT: - return intel->front_region; - case BUFFER_BIT_BACK_LEFT: - return intel->back_region; - default: - /* Not necessary to fallback - could handle either NONE or - * FRONT_AND_BACK cases below. - */ - return NULL; - } -} - -struct intel_region *intel_readbuf_region( struct intel_context *intel ) -{ - GLcontext *ctx = &intel->ctx; - - /* This will have to change to support EXT_fbo's, but is correct - * for now: - */ - switch (ctx->ReadBuffer->_ColorReadBufferIndex) { - case BUFFER_FRONT_LEFT: - return intel->front_region; - case BUFFER_BACK_LEFT: - return intel->back_region; - default: - assert(0); - return NULL; - } -} - - - - - - -/** - * Implement glCopyPixels for the front color buffer (or back buffer Pixmap) - * for the color buffer. Don't support zooming, pixel transfer, etc. - * We do support copying from one window to another, ala glXMakeCurrentRead. - */ -static GLboolean intelTryCopyPixels( GLcontext *ctx, - GLint srcx, GLint srcy, - GLsizei width, GLsizei height, - GLint dstx, GLint dsty, - GLenum type ) -{ - struct intel_context *intel = intel_context( ctx ); - struct intel_region *dst = intel_drawbuf_region( intel ); - struct intel_region *src = NULL; - - /* Copypixels can be more than a straight copy. Ensure all the - * extra operations are disabled: - */ - if (!intel_check_color_per_fragment_ops(ctx) || - ctx->_ImageTransferState || - ctx->Pixel.ZoomX != 1.0F || - ctx->Pixel.ZoomY != 1.0F) - return GL_FALSE; - - switch (type) { - case GL_COLOR: - src = intel_readbuf_region( intel ); - /* No readbuffer, copypixels is a noop: - */ - if (!src) - return GL_TRUE; - break; - case GL_DEPTH: - /* Don't think this is really possible execpt at 16bpp, when we have no stencil. - */ - if (intel->intelScreen->cpp == 2) - src = intel->depth_region; - break; - case GL_STENCIL: - /* Don't think this is really possible. - */ - break; - case GL_DEPTH_STENCIL_EXT: - /* Does it matter whether it is stencil/depth or depth/stencil? - */ - src = intel->depth_region; - break; - default: - break; - } - - if (!src || !dst) - return GL_FALSE; - - - - intelFlush( &intel->ctx ); - LOCK_HARDWARE( intel ); - intelInstallBatchBuffer( intel ); - { - __DRIdrawablePrivate *dPriv = intel->driDrawable; - drm_clip_rect_t *box = dPriv->pClipRects; - GLint nbox = dPriv->numClipRects; - GLint delta_x = srcx - dstx; - GLint delta_y = srcy - dsty; - GLuint dst_offset = 0; - GLuint src_offset = 0; - GLuint i; - -#if 0 - dsty -= height; /* cope with pixel zoom */ - srcy -= height; /* cope with pixel zoom */ -#endif - if (!ctx->DrawBuffer) - goto out; - - if (!intel_clip_to_framebuffer(ctx, ctx->DrawBuffer, &dstx, &dsty, &width, &height)) - goto out; - - /* Update source for clipped dest. Need to also clip the source rect. - */ - srcx = dstx + delta_x; - srcy = dsty + delta_y; - - if (!intel_clip_to_framebuffer(ctx, ctx->DrawBuffer, &srcx, &srcy, &width, &height)) - goto out; - - /* Update dest for clipped source: - */ - dstx = srcx - delta_x; - dsty = srcy - delta_y; - - - srcy = dPriv->h - srcy - height; /* convert from gl to hardware coords */ - dsty = dPriv->h - dsty - height; /* convert from gl to hardware coords */ - srcx += dPriv->x; - dstx += dPriv->x; - srcy += dPriv->y; - dsty += dPriv->y; - - - bmAddBuffer(intel->buffer_list, dst->buffer, BM_NO_EVICT|BM_NO_UPLOAD|BM_WRITE, - NULL, &dst_offset); - bmAddBuffer(intel->buffer_list, src->buffer, BM_NO_EVICT|BM_NO_UPLOAD|BM_READ, - NULL, &src_offset); - - if (!bmValidateBufferList(intel->bm, intel->buffer_list, BM_MEM_AGP)) - goto out; - - /* Could do slightly more clipping: Eg, take the intersection of - * the existing set of cliprects and those cliprects translated - * by delta_x, delta_y: - * - * This code will not overwrite other windows, but will - * introduce garbage when copying from obscured window regions. - */ - for (i = 0 ; i < nbox ; i++ ) - { - GLint bx = box[i].x1; - GLint by = box[i].y1; - GLint bw = box[i].x2 - bx; - GLint bh = box[i].y2 - by; - - if (bx < dstx) bw -= dstx - bx, bx = dstx; - if (by < dsty) bh -= dsty - by, by = dsty; - if (bx + bw > dstx + width) bw = dstx + width - bx; - if (by + bh > dsty + height) bh = dsty + height - by; - if (bw <= 0) continue; - if (bh <= 0) continue; - - assert(dst_offset == intel->drawOffset); - - intelEmitCopyBlitLocked( intel, - dst->cpp, - src->pitch, src_offset, - dst->pitch, dst_offset, - bx + delta_x, by - delta_y, /* srcx, srcy */ - bx, by, /* dstx, dsty */ - bw, bh ); - } - } - out: - intelFlushBatchLocked( intel, GL_TRUE, GL_FALSE, GL_FALSE); - UNLOCK_HARDWARE( intel ); - return GL_TRUE; -} - - -static void -intelCopyPixels( GLcontext *ctx, - GLint srcx, GLint srcy, GLsizei width, GLsizei height, - GLint destx, GLint desty, GLenum type ) -{ - if (INTEL_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (!intelTryCopyPixels( ctx, srcx, srcy, width, height, destx, desty, type)) { -/* if (INTEL_DEBUG & DEBUG_FALLBACKS) */ - _mesa_printf("fallback to _swrast_CopyPixels\n"); - _swrast_CopyPixels( ctx, srcx, srcy, width, height, destx, desty, type); - } -} @@ -635,3 +134,4 @@ void intelInitPixelFuncs( struct dd_function_table *functions ) functions->DrawPixels = _swrast_DrawPixels; } } + diff --git a/src/mesa/drivers/dri/i915/intel_pixel.h b/src/mesa/drivers/dri/i915/intel_pixel.h new file mode 100644 index 00000000000..de101d7f297 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_pixel.h @@ -0,0 +1,63 @@ +/************************************************************************** + * + * Copyright 2006 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_PIXEL_H +#define INTEL_PIXEL_H + +#include "mtypes.h" + +void intelInitPixelFuncs( struct dd_function_table *functions ); + +GLboolean intel_check_color_per_fragment_ops( const GLcontext *ctx ); + +GLboolean intel_clip_to_framebuffer( GLcontext *ctx, + const GLframebuffer *buffer, + GLint *x, GLint *y, + GLsizei *width, GLsizei *height ); + +void intelReadPixels( GLcontext *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, + GLvoid *pixels ); + +void intelDrawPixels( GLcontext *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, + GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid *pixels ); + +void intelCopyPixels( GLcontext *ctx, + GLint srcx, GLint srcy, + GLsizei width, GLsizei height, + GLint destx, GLint desty, + GLenum type ); + +#endif diff --git a/src/mesa/drivers/dri/i915/intel_pixel_copy.c b/src/mesa/drivers/dri/i915/intel_pixel_copy.c new file mode 100644 index 00000000000..4f4f7fbaa6b --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_pixel_copy.c @@ -0,0 +1,196 @@ +/************************************************************************** + * + * 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 "enums.h" +#include "mtypes.h" +#include "macros.h" +#include "swrast/swrast.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_ioctl.h" +#include "intel_batchbuffer.h" +#include "intel_blit.h" +#include "intel_regions.h" +#include "intel_pixel.h" +#include "bufmgr.h" + + + + +static GLboolean do_texture_copypixels( GLcontext *ctx, + GLint srcx, GLint srcy, + GLsizei width, GLsizei height, + GLint dstx, GLint dsty, + GLenum type ) +{ + return GL_FALSE; +} + + +/** + * CopyPixels with the blitter. Don't support zooming, pixel transfer, etc. + */ +static GLboolean do_blit_copypixels( GLcontext *ctx, + GLint srcx, GLint srcy, + GLsizei width, GLsizei height, + GLint dstx, GLint dsty, + GLenum type ) +{ + struct intel_context *intel = intel_context( ctx ); + struct intel_region *dst = intel_drawbuf_region( intel ); + struct intel_region *src = NULL; + + /* Copypixels can be more than a straight copy. Ensure all the + * extra operations are disabled: + */ + if (!intel_check_color_per_fragment_ops(ctx) || + ctx->Pixel.ZoomX != 1.0F || + ctx->Pixel.ZoomY != 1.0F) + return GL_FALSE; + + switch (type) { + case GL_COLOR: + src = intel_readbuf_region( intel ); + break; + case GL_DEPTH: + /* Don't think this is really possible execpt at 16bpp, when we have no stencil. + */ + if (intel->intelScreen->cpp == 2) + src = intel->depth_region; + break; + case GL_STENCIL: + /* Don't think this is really possible. + */ + break; + case GL_DEPTH_STENCIL_EXT: + /* Does it matter whether it is stencil/depth or depth/stencil? + */ + src = intel->depth_region; + break; + default: + break; + } + + if (!src || !dst) + return GL_FALSE; + + + + intelFlush( &intel->ctx ); + LOCK_HARDWARE( intel ); + { + __DRIdrawablePrivate *dPriv = intel->driDrawable; + drm_clip_rect_t *box = dPriv->pClipRects; + GLint nbox = dPriv->numClipRects; + GLint delta_x = srcx - dstx; + GLint delta_y = srcy - dsty; + GLuint i; + + if (!intel_clip_to_framebuffer(ctx, ctx->DrawBuffer, &dstx, &dsty, &width, &height)) + goto out; + + /* Update source for clipped dest. Need to also clip the source rect. + */ + srcx = dstx + delta_x; + srcy = dsty + delta_y; + + if (!intel_clip_to_framebuffer(ctx, ctx->DrawBuffer, &srcx, &srcy, &width, &height)) + goto out; + + /* Update dest for clipped source: + */ + dstx = srcx - delta_x; + dsty = srcy - delta_y; + + + srcy = dPriv->h - srcy - height; /* convert from gl to hardware coords */ + dsty = dPriv->h - dsty - height; /* convert from gl to hardware coords */ + srcx += dPriv->x; + dstx += dPriv->x; + srcy += dPriv->y; + dsty += dPriv->y; + + + /* Could do slightly more clipping: Eg, take the intersection of + * the existing set of cliprects and those cliprects translated + * by delta_x, delta_y: + * + * This code will not overwrite other windows, but will + * introduce garbage when copying from obscured window regions. + */ + for (i = 0 ; i < nbox ; i++ ) + { + GLint bx = box[i].x1; + GLint by = box[i].y1; + GLint bw = box[i].x2 - bx; + GLint bh = box[i].y2 - by; + + if (bx < dstx) bw -= dstx - bx, bx = dstx; + if (by < dsty) bh -= dsty - by, by = dsty; + if (bx + bw > dstx + width) bw = dstx + width - bx; + if (by + bh > dsty + height) bh = dsty + height - by; + if (bw <= 0) continue; + if (bh <= 0) continue; + + intelEmitCopyBlit( intel, + dst->cpp, + src->pitch, src->buffer, 0, + dst->pitch, dst->buffer, 0, + bx + delta_x, by - delta_y, /* srcx, srcy */ + bx, by, /* dstx, dsty */ + bw, bh ); + } + } + out: + intel_batchbuffer_flush( intel->batch ); + UNLOCK_HARDWARE( intel ); + return GL_TRUE; +} + + +void intelCopyPixels( GLcontext *ctx, + GLint srcx, GLint srcy, + GLsizei width, GLsizei height, + GLint destx, GLint desty, + GLenum type ) +{ + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (do_blit_copypixels( ctx, srcx, srcy, width, height, destx, desty, type)) + return; + + if (do_texture_copypixels( ctx, srcx, srcy, width, height, destx, desty, type)) + return; + + _mesa_printf("fallback to _swrast_CopyPixels\n"); + _swrast_CopyPixels( ctx, srcx, srcy, width, height, destx, desty, type); +} + + diff --git a/src/mesa/drivers/dri/i915/intel_pixel_draw.c b/src/mesa/drivers/dri/i915/intel_pixel_draw.c new file mode 100644 index 00000000000..081e6ba69da --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_pixel_draw.c @@ -0,0 +1,242 @@ +/************************************************************************** + * + * 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 "enums.h" +#include "mtypes.h" +#include "macros.h" +#include "swrast/swrast.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_ioctl.h" +#include "intel_batchbuffer.h" +#include "intel_blit.h" +#include "intel_regions.h" +#include "intel_pixel.h" +#include "bufmgr.h" + + + +static GLboolean do_texture_draw_pixels( struct intel_context *intel, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid *pixels ) +{ +#if 0 + GLint pitch = unpack->RowLength ? unpack->RowLength : width; + __DRIdrawablePrivate *dPriv = intel->driDrawable; + int textureFormat; + GLenum glTextureFormat; + + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + + if ( ctx->_ImageTransferState || + unpack->SwapBytes || + unpack->LsbFirst || + ctx->Texture._EnabledUnits || + ctx->FragmentProgram._Enabled) { + fprintf(stderr, "%s: cannot use texture path\n", __FUNCTION__); + return GL_FALSE; + } + + glGenTextures(); + glTextureImage2D(); + glBindTexture(); + glEnable(GL_TEXTURE_RECTANGLE_NV); + + glDisable(GL_POLYGON_STIPPLE); + glDisable(GL_CULL); + + _mesa_install_vp_passthrough(ctx); + _mesa_push_current(ctx); + + if (intel->Fallback) + goto Fail; + + glBegin(GL_QUADS); + glVertex3f(); + glTexCoord2f(); + glVertex3f(); + glTexCoord2f(); + glVertex3f(); + glTexCoord2f(); + glVertex3f(); + glTexCoord2f(); + glEnd(); + glFinish(); + + ASSIGN_4V(ctx->Current.Atrrib[VERT_ATTRIB_TEX0], tex0); + + fail: + glDisable(GL_TEXTURE_RECTANGLE_NV); + glDeleteTextures(); + glBindTexture(old); + + +#endif + return GL_FALSE; +} + + + + + +/* Pros: + * - no waiting for idle before updating framebuffer. + * + * Cons: + * - if upload is by memcpy, this may actually be slower than fallback path. + * - uploads the whole image even if destination is clipped + * + * Need to benchmark. + */ +static GLboolean do_blit_draw_pixels( struct intel_context *intel, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid *pixels ) +{ +#if 0 + struct intel_region *dest = intel_drawbuf_region(intel); + struct intel_region *src = NULL; + + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (!src || !dest) + return GL_FALSE; + + if (!intel_check_blit_format(dest, src)) + return GL_FALSE; + + if (!intel_check_blit_fragment_ops(ctx)) + return GL_FALSE; + + if (ctx->Pixel.ZoomX != 1.0F) + return GL_FALSE; + + if (ctx->Pixel.ZoomY == -1.0F) + y -= height; + else if (ctx->Pixel.ZoomY == 1.0F) { + src_pitch = -src_pitch; + src_y += height; + } + else + return GL_FALSE; + + + if (unpack->BufferObj->Name) { + src = intel_bufferobj_unpack_region(intel, unpack, + width, height, + format, type, + unpack->BufferObj); + src_offset = (unsigned long)pixels; + } + else { + src = intel_client_unpack_region(intel, unpack, + width, height, + format, type, pixels); + src_offset = 0; + } + + + intelFlush( &intel->ctx ); + LOCK_HARDWARE( intel ); + { + __DRIdrawablePrivate *dPriv = intel->driDrawable; + int nbox = dPriv->numClipRects; + drm_clip_rect_t *box = dPriv->pClipRects; + drm_clip_rect_t rect; + int i; + + y = dPriv->h - y - height; /* convert from gl to hardware coords */ + x += dPriv->x; + y += dPriv->y; + + + for (i = 0 ; i < nbox ; i++ ) + { + if (!intel_intersect_cliprects(rect, db_rect, &box[i])) + continue; + + intelEmitCopyBlit( intel, + intel->intelScreen->cpp, + src->pitch, src->buffer, src_offset, + dst->pitch, dst->buffer, 0, + rect->x1 - x, + rect->y1 - y, + rect->x1, + rect->y1, + rect->x2 - rect->x1, + rect->y2 - rect->y1 ); + } + } + + intel_release_unpack_region( intel, src ); + fence = intel_batchbuffer_flush( intel->batch ); + UNLOCK_HARDWARE( intel ); + + bmWaitFence(intel->bm, fence); + intel_region_release(intel, &src); +#endif + + return GL_FALSE; +} + + + +void intelDrawPixels( GLcontext *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, + GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid *pixels ) +{ + struct intel_context *intel = intel_context(ctx); + + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (do_texture_draw_pixels( intel, x, y, width, height, format, type, + unpack, pixels )) + return; + + if (do_blit_draw_pixels( intel, x, y, width, height, format, type, + unpack, pixels )) + return; + + _swrast_DrawPixels( ctx, x, y, width, height, format, type, + unpack, pixels ); +} + diff --git a/src/mesa/drivers/dri/i915/intel_pixel_read.c b/src/mesa/drivers/dri/i915/intel_pixel_read.c new file mode 100644 index 00000000000..99bbcf69e03 --- /dev/null +++ b/src/mesa/drivers/dri/i915/intel_pixel_read.c @@ -0,0 +1,249 @@ +/************************************************************************** + * + * 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 "enums.h" +#include "mtypes.h" +#include "macros.h" +#include "swrast/swrast.h" + +#include "intel_screen.h" +#include "intel_context.h" +#include "intel_ioctl.h" +#include "intel_batchbuffer.h" +#include "intel_blit.h" +#include "intel_regions.h" +#include "intel_pixel.h" +#include "bufmgr.h" + + + + +static GLboolean +do_texture_readpixels( GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, + struct intel_region *dest_region ) +{ +#if 0 + struct intel_context *intel = intel_context(ctx); + intelScreenPrivate *screen = intel->intelScreen; + GLint pitch = pack->RowLength ? pack->RowLength : width; + __DRIdrawablePrivate *dPriv = intel->driDrawable; + int textureFormat; + GLenum glTextureFormat; + int destFormat, depthFormat, destPitch; + drm_clip_rect_t tmp; + + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + + if ( ctx->_ImageTransferState || + pack->SwapBytes || + pack->LsbFirst || + !pack->Invert) { + fprintf(stderr, "%s: check_color failed\n", __FUNCTION__); + return GL_FALSE; + } + + intel->vtbl.meta_texrect_source(intel, intel_readbuf_region(intel)); + + if (!intel->vtbl.meta_render_dest(intel, + dest_region, + type, format)) + { + fprintf(stderr, "%s: couldn't set dest %s/%s\n", + __FUNCTION__, + _mesa_lookup_enum_by_nr(type), + _mesa_lookup_enum_by_nr(format)); + return GL_FALSE; + } + + LOCK_HARDWARE( intel ); + intel->vtbl.install_meta_state(intel); + intel->vtbl.meta_no_depth_stencil_write(intel); + + if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) { + UNLOCK_HARDWARE( intel ); + SET_STATE(i830, state); + fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__); + return GL_TRUE; + } + + y = dPriv->h - y - height; + x += dPriv->x; + y += dPriv->y; + + + /* Set the frontbuffer up as a large rectangular texture. + */ + intel->vtbl.meta_tex_rect_source( intel, + src_region, + textureFormat ); + + + intel->vtbl.meta_texture_blend_replace( i830, glTextureFormat ); + + + /* Set the 3d engine to draw into the destination region: + */ + + intel->vtbl.meta_draw_region(intel, dest_region); + intel->vtbl.meta_draw_format(intel, destFormat, depthFormat ); /* ?? */ + + + /* Draw a single quad, no cliprects: + */ + intel->vtbl.meta_disable_cliprects(intel); + + intel->vtbl.draw_quad(intel, + 0, width, 0, height, + 0x00ff00ff, + x, x+width, + y, y+height ); + + intel->vtbl.leave_meta_state(intel); + UNLOCK_HARDWARE( intel ); + + intel_region_wait_fence( ctx, dest_region ); /* required by GL */ + return GL_TRUE; +#endif + + return GL_FALSE; +} + + + + +static GLboolean do_blit_readpixels( GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, + GLvoid *pixels ) +{ +#if 0 + struct intel_context *intel = intel_context(ctx); + GLint pitch = pack->RowLength ? pack->RowLength : width; + struct intel_region *src = intel_readbuf_region(intel); + struct intel_client_region *dst = intel_client_pack_region(intel, + pack, + pixels); + + if (ctx->_ImageTransferState || + pack->SwapBytes || + pack->LsbFirst) { + fprintf(stderr, "%s: failed 1\n", __FUNCTION__); + return GL_FALSE; + } + + /* Need GL_PACK_INVERT_MESA to cope with upsidedown results from + * blitter: + */ + if (!pack->Invert) { + fprintf(stderr, "%s: MESA_PACK_INVERT not set\n", __FUNCTION__); + return GL_FALSE; + } + + if (!intel_check_blit_format(src, format, type)) + return GL_FALSE; + + /* Although the blits go on the command buffer, need to do this and + * fire with lock held to guarentee cliprects are correct. + */ + intelFlush( &intel->ctx ); + LOCK_HARDWARE( intel ); + { + __DRIdrawablePrivate *dPriv = intel->driDrawable; + int nbox = dPriv->numClipRects; + drm_clip_rect_t *box = dPriv->pClipRects; + int i; + + y = dPriv->h - y - height; + x += dPriv->x; + y += dPriv->y; + + + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "readpixel blit src_pitch %d dst_pitch %d\n", + src_pitch, pitch); + + for (i = 0 ; i < nbox ; i++) + { + GLint bx = box[i].x1; + GLint by = box[i].y1; + GLint bw = box[i].x2 - bx; + GLint bh = box[i].y2 - by; + + if (bx < x) bw -= x - bx, bx = x; + if (by < y) bh -= y - by, by = y; + if (bx + bw > x + width) bw = x + width - bx; + if (by + bh > y + height) bh = y + height - by; + if (bw <= 0) continue; + if (bh <= 0) continue; + + intelEmitCopyBlit( intel, + src->cpp, + src->pitch, src->buffer, 0, + dst->pitch, dst->buffer, 0, + bx, by, + bx - x, by - y, + bw, bh ); + } + + intel_batchbuffer_flush(intel->batch); + intel_client_region_release(intel, dst); + } + UNLOCK_HARDWARE( intel ); + return GL_TRUE; +#endif + + return GL_FALSE; +} + +void +intelReadPixels( GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, + GLvoid *pixels ) +{ + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + intelFlush( ctx ); + + if (do_blit_readpixels(ctx, x, y, width, height, format, type, pack, pixels)) + return; + + if (do_texture_readpixels(ctx, x, y, width, height, format, type, pack, pixels)) + return; + + _swrast_ReadPixels( ctx, x, y, width, height, format, type, pack, pixels); +} + diff --git a/src/mesa/drivers/dri/i915/intel_regions.c b/src/mesa/drivers/dri/i915/intel_regions.c index f4907256edd..47957feedac 100644 --- a/src/mesa/drivers/dri/i915/intel_regions.c +++ b/src/mesa/drivers/dri/i915/intel_regions.c @@ -90,6 +90,7 @@ void intel_region_reference( struct intel_region **dst, struct intel_region *src) { src->refcount++; + assert(*dst == NULL); *dst = src; } @@ -151,6 +152,7 @@ struct intel_region *intel_region_create_static( struct intel_context *intel, + static void _mesa_copy_rect( GLubyte *dst, GLuint cpp, GLuint dst_pitch, @@ -186,60 +188,6 @@ static void _mesa_copy_rect( GLubyte *dst, } - -/* Could make color a char * to handle deeper buffers. - */ -static void _mesa_fill_rect( GLubyte *dst, - GLuint cpp, - GLuint dst_pitch, - GLuint dst_x, - GLuint dst_y, - GLuint width, - GLuint height, - GLuint color ) -{ - GLuint i,j; - - switch (cpp) { - case 1: - dst += dst_x; - dst += dst_y * dst_pitch; - for (i = 0; i < height; i++) { - memset(dst, color, width); - dst += dst_pitch; - } - break; - case 2: { - GLushort color_short = color & 0xffff; - GLushort *dst_short = (GLushort *)dst; - dst_short += dst_x; - dst_short += dst_y * dst_pitch; - - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) - dst_short[j] = color_short; - } - break; - } - case 4: { - GLuint *dst_int = (GLuint *)dst; - dst_int += dst_x; - dst_int += dst_y * dst_pitch; - - for (i = 0; i < height; i++) { - for (j = 0; j < width; j++) - dst_int[j] = color; - } - break; - } - default: - assert(0); - return; - } -} - - - /* Upload data to a rectangular sub-region. Lots of choices how to do this: * * - memcpy by span to current destination @@ -283,47 +231,17 @@ void intel_region_copy( struct intel_context *intel, GLuint srcx, GLuint srcy, GLuint width, GLuint height ) { - unsigned dst_offset; - unsigned src_offset; - struct bm_buffer_list *list = bmNewBufferList(); - DBG("%s\n", __FUNCTION__); assert(src->cpp == dst->cpp); - LOCK_HARDWARE(intel); - bmAddBuffer(list, dst->buffer, BM_WRITE, NULL, &dst_offset); - bmAddBuffer(list, src->buffer, BM_READ, NULL, &src_offset); - - /* Query if both buffers are already uploaded: - */ - if (bmValidateBufferList(intel->bm, list, BM_NO_EVICT|BM_NO_UPLOAD|BM_MEM_AGP)) { - intelEmitCopyBlitLocked(intel, - dst->cpp, - src->pitch, src_offset, - dst->pitch, dst_offset, - srcx, srcy, - dstx, dsty, - width, height); - - bmFenceBufferList(intel->bm, list); - } - else { - _mesa_copy_rect(intel_region_map(intel, dst), - dst->cpp, - dst->pitch, - dstx, dsty, - width, height, - intel_region_map(intel, src), - srcx, srcy, - src->pitch); - - intel_region_unmap(intel, dst); - intel_region_unmap(intel, src); - } - - bmFreeBufferList(list); - UNLOCK_HARDWARE(intel); + intelEmitCopyBlit(intel, + dst->cpp, + src->pitch, src->buffer, 0, + dst->pitch, dst->buffer, 0, + srcx, srcy, + dstx, dsty, + width, height); } /* Fill a rectangular sub-region. Need better logic about when to @@ -335,37 +253,15 @@ void intel_region_fill( struct intel_context *intel, GLuint width, GLuint height, GLuint color ) { - unsigned dst_offset; - struct bm_buffer_list *list = bmNewBufferList(); - DBG("%s\n", __FUNCTION__); - - LOCK_HARDWARE(intel); - bmAddBuffer(list, dst->buffer, BM_WRITE, NULL, &dst_offset); - - if (bmValidateBufferList(intel->bm, list, BM_NO_EVICT|BM_NO_UPLOAD|BM_MEM_AGP)) { - intelEmitFillBlitLocked(intel, - dst->cpp, - dst->pitch, - dst_offset, - dstx, dsty, - width, height, - color ); - - bmFenceBufferList(intel->bm, list); - } - else { - _mesa_fill_rect(intel_region_map(intel, dst), - dst->cpp, - dst->pitch, - dstx, dsty, - width, height, - color); - - intel_region_unmap(intel, dst); - } - bmFreeBufferList(list); - UNLOCK_HARDWARE(intel); + intelEmitFillBlit(intel, + dst->cpp, + dst->pitch, + dst->buffer, + 0, + dstx, dsty, + width, height, + color ); } diff --git a/src/mesa/drivers/dri/i915/intel_render.c b/src/mesa/drivers/dri/i915/intel_render.c index 1d7811eb696..3dfad52cd1c 100644 --- a/src/mesa/drivers/dri/i915/intel_render.c +++ b/src/mesa/drivers/dri/i915/intel_render.c @@ -106,7 +106,7 @@ static const int scale_prim[GL_POLYGON+1] = { }; -static void intelDmaPrimitive( intelContextPtr intel, GLenum prim ) +static void intelDmaPrimitive( struct intel_context *intel, GLenum prim ) { if (0) fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(prim)); INTEL_FIREVERTICES(intel); @@ -115,7 +115,7 @@ static void intelDmaPrimitive( intelContextPtr intel, GLenum prim ) } -#define LOCAL_VARS intelContextPtr intel = INTEL_CONTEXT(ctx) +#define LOCAL_VARS struct intel_context *intel = intel_context(ctx) #define INIT( prim ) \ do { \ intelDmaPrimitive( intel, prim ); \ @@ -142,7 +142,7 @@ do { \ /* Heuristic to choose between the two render paths: */ -static GLboolean choose_render( intelContextPtr intel, +static GLboolean choose_render( struct intel_context *intel, struct vertex_buffer *VB ) { int vertsz = intel->vertex_size; @@ -194,7 +194,7 @@ static GLboolean choose_render( intelContextPtr intel, static GLboolean intel_run_render( GLcontext *ctx, struct tnl_pipeline_stage *stage ) { - intelContextPtr intel = INTEL_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; GLuint i; diff --git a/src/mesa/drivers/dri/i915/intel_screen.c b/src/mesa/drivers/dri/i915/intel_screen.c index c8acc75d68e..6d8e1e4b7de 100644 --- a/src/mesa/drivers/dri/i915/intel_screen.c +++ b/src/mesa/drivers/dri/i915/intel_screen.c @@ -104,9 +104,9 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv) intelScreen->cpp = gDRIPriv->cpp; switch (gDRIPriv->bitsPerPixel) { - case 15: intelScreen->fbFormat = DV_PF_555; break; case 16: intelScreen->fbFormat = DV_PF_565; break; case 32: intelScreen->fbFormat = DV_PF_8888; break; + default: exit(1); break; } intelScreen->front.pitch = gDRIPriv->fbStride; diff --git a/src/mesa/drivers/dri/i915/intel_span.c b/src/mesa/drivers/dri/i915/intel_span.c index f42e1fbd588..b8155d81cd6 100644 --- a/src/mesa/drivers/dri/i915/intel_span.c +++ b/src/mesa/drivers/dri/i915/intel_span.c @@ -42,7 +42,7 @@ #define DBG 0 #define LOCAL_VARS \ - intelContextPtr intel = INTEL_CONTEXT(ctx); \ + struct intel_context *intel = intel_context(ctx); \ __DRIdrawablePrivate *dPriv = intel->driDrawable; \ driRenderbuffer *drb = (driRenderbuffer *) rb; \ GLuint pitch = drb->pitch * drb->cpp; \ @@ -54,7 +54,7 @@ (void) buf; (void) p #define LOCAL_DEPTH_VARS \ - intelContextPtr intel = INTEL_CONTEXT(ctx); \ + struct intel_context *intel = intel_context(ctx); \ __DRIdrawablePrivate *dPriv = intel->driDrawable; \ driRenderbuffer *drb = (driRenderbuffer *) rb; \ GLuint pitch = drb->pitch * drb->cpp; \ @@ -95,27 +95,6 @@ do { \ #define TAG(x) intel##x##_565 #include "spantmp.h" -/* 15 bit, 555 rgb color spanline and pixel functions - */ -#define WRITE_RGBA( _x, _y, r, g, b, a ) \ - *(GLushort *)(buf + _x*2 + _y*pitch) = (((r & 0xf8) << 7) | \ - ((g & 0xf8) << 3) | \ - ((b & 0xf8) >> 3)) - -#define WRITE_PIXEL( _x, _y, p ) \ - *(GLushort *)(buf + _x*2 + _y*pitch) = p - -#define READ_RGBA( rgba, _x, _y ) \ -do { \ - GLushort p = *(GLushort *)(buf + _x*2 + _y*pitch); \ - rgba[0] = (p >> 7) & 0xf8; \ - rgba[1] = (p >> 3) & 0xf8; \ - rgba[2] = (p << 3) & 0xf8; \ - rgba[3] = 255; \ -} while(0) - -#define TAG(x) intel##x##_555 -#include "spantmp.h" /* 16 bit depthbuffer functions. */ @@ -132,7 +111,7 @@ do { \ #undef LOCAL_VARS #define LOCAL_VARS \ - intelContextPtr intel = INTEL_CONTEXT(ctx); \ + struct intel_context *intel = intel_context(ctx); \ __DRIdrawablePrivate *dPriv = intel->driDrawable; \ driRenderbuffer *drb = (driRenderbuffer *) rb; \ GLuint pitch = drb->pitch * drb->cpp; \ @@ -206,12 +185,11 @@ do { \ */ void intelSpanRenderStart( GLcontext *ctx ) { - intelContextPtr intel = INTEL_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); GLuint i; intelFlush(&intel->ctx); LOCK_HARDWARE(intel); - intelWaitForIdle(intel); /* Just map the framebuffer and all textures. Bufmgr code will * take care of waiting on the necessary fences: @@ -230,7 +208,7 @@ void intelSpanRenderStart( GLcontext *ctx ) void intelSpanRenderFinish( GLcontext *ctx ) { - intelContextPtr intel = INTEL_CONTEXT( ctx ); + struct intel_context *intel = intel_context( ctx ); GLuint i; _swrast_flush( ctx ); @@ -266,10 +244,7 @@ void intelSetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis) { if (drb->Base.InternalFormat == GL_RGBA) { - if (vis->redBits == 5 && vis->greenBits == 5 && vis->blueBits == 5) { - intelInitPointers_555(&drb->Base); - } - else if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) { + if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) { intelInitPointers_565(&drb->Base); } else { diff --git a/src/mesa/drivers/dri/i915/intel_state.c b/src/mesa/drivers/dri/i915/intel_state.c index de40e540fd3..6ced0cb1465 100644 --- a/src/mesa/drivers/dri/i915/intel_state.c +++ b/src/mesa/drivers/dri/i915/intel_state.c @@ -30,6 +30,7 @@ #include "context.h" #include "macros.h" #include "enums.h" +#include "colormac.h" #include "dd.h" #include "intel_screen.h" @@ -165,79 +166,26 @@ int intel_translate_logic_op( GLenum opcode ) } } -static void intelDrawBuffer(GLcontext *ctx, GLenum mode ) -{ - intelContextPtr intel = INTEL_CONTEXT(ctx); - intelScreenPrivate *screen = intel->intelScreen; - int front = 0; - - if (!ctx->DrawBuffer) - return; - - switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0] ) { - case BUFFER_BIT_FRONT_LEFT: - front = 1; - FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE ); - break; - case BUFFER_BIT_BACK_LEFT: - front = 0; - FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE ); - break; - default: - FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE ); - return; - } - - if ( intel->sarea->pf_current_page == 1 ) - front ^= 1; - - intelSetFrontClipRects( intel ); - - - if (front) { - intel->drawOffset = screen->front.offset; - if (intel->draw_region != intel->front_region) { - intel_region_release(intel, &intel->draw_region); - intel_region_reference(&intel->draw_region, intel->front_region); - } - } else { - intel->drawOffset = screen->back.offset; - if (intel->draw_region != intel->back_region) { - intel_region_release(intel, &intel->draw_region); - intel_region_reference(&intel->draw_region, intel->back_region); - } - } - - intel->vtbl.set_draw_offset( intel, intel->drawOffset ); -} - -static void intelReadBuffer( GLcontext *ctx, GLenum mode ) -{ - /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */ -} - static void intelClearColor(GLcontext *ctx, const GLfloat color[4]) { - intelContextPtr intel = INTEL_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); intelScreenPrivate *screen = intel->intelScreen; + GLubyte clear_chan[4]; - CLAMPED_FLOAT_TO_UBYTE(intel->clear_red, color[0]); - CLAMPED_FLOAT_TO_UBYTE(intel->clear_green, color[1]); - CLAMPED_FLOAT_TO_UBYTE(intel->clear_blue, color[2]); - CLAMPED_FLOAT_TO_UBYTE(intel->clear_alpha, color[3]); + UNCLAMPED_FLOAT_TO_RGBA_CHAN(clear_chan, color); intel->ClearColor = INTEL_PACKCOLOR(screen->fbFormat, - intel->clear_red, - intel->clear_green, - intel->clear_blue, - intel->clear_alpha); + clear_chan[0], + clear_chan[1], + clear_chan[2], + clear_chan[3]); } static void intelCalcViewport( GLcontext *ctx ) { - intelContextPtr intel = INTEL_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); const GLfloat *v = ctx->Viewport._WindowMap.m; GLfloat *m = intel->ViewportMatrix.m; GLint h = 0; @@ -273,18 +221,111 @@ static void intelDepthRange( GLcontext *ctx, */ static void intelRenderMode( GLcontext *ctx, GLenum mode ) { - intelContextPtr intel = INTEL_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); FALLBACK( intel, INTEL_FALLBACK_RENDERMODE, (mode != GL_RENDER) ); } void intelInitStateFuncs( struct dd_function_table *functions ) { - functions->DrawBuffer = intelDrawBuffer; - functions->ReadBuffer = intelReadBuffer; functions->RenderMode = intelRenderMode; functions->Viewport = intelViewport; functions->DepthRange = intelDepthRange; functions->ClearColor = intelClearColor; } + + + +void intelInitState( GLcontext *ctx ) +{ + /* Mesa should do this for us: + */ + ctx->Driver.AlphaFunc( ctx, + ctx->Color.AlphaFunc, + ctx->Color.AlphaRef); + + ctx->Driver.BlendColor( ctx, + ctx->Color.BlendColor ); + + ctx->Driver.BlendEquationSeparate( ctx, + ctx->Color.BlendEquationRGB, + ctx->Color.BlendEquationA); + + ctx->Driver.BlendFuncSeparate( ctx, + ctx->Color.BlendSrcRGB, + ctx->Color.BlendDstRGB, + ctx->Color.BlendSrcA, + ctx->Color.BlendDstA); + + ctx->Driver.ColorMask( ctx, + ctx->Color.ColorMask[RCOMP], + ctx->Color.ColorMask[GCOMP], + ctx->Color.ColorMask[BCOMP], + ctx->Color.ColorMask[ACOMP]); + + ctx->Driver.CullFace( ctx, ctx->Polygon.CullFaceMode ); + ctx->Driver.DepthFunc( ctx, ctx->Depth.Func ); + ctx->Driver.DepthMask( ctx, ctx->Depth.Mask ); + + ctx->Driver.Enable( ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled ); + ctx->Driver.Enable( ctx, GL_BLEND, ctx->Color.BlendEnabled ); + ctx->Driver.Enable( ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled ); + ctx->Driver.Enable( ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled ); + ctx->Driver.Enable( ctx, GL_CULL_FACE, ctx->Polygon.CullFlag ); + ctx->Driver.Enable( ctx, GL_DEPTH_TEST, ctx->Depth.Test ); + ctx->Driver.Enable( ctx, GL_DITHER, ctx->Color.DitherFlag ); + ctx->Driver.Enable( ctx, GL_FOG, ctx->Fog.Enabled ); + ctx->Driver.Enable( ctx, GL_LIGHTING, ctx->Light.Enabled ); + ctx->Driver.Enable( ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag ); + ctx->Driver.Enable( ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag ); + ctx->Driver.Enable( ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled ); + ctx->Driver.Enable( ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled ); + ctx->Driver.Enable( ctx, GL_TEXTURE_1D, GL_FALSE ); + ctx->Driver.Enable( ctx, GL_TEXTURE_2D, GL_FALSE ); + ctx->Driver.Enable( ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE ); + ctx->Driver.Enable( ctx, GL_TEXTURE_3D, GL_FALSE ); + ctx->Driver.Enable( ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE ); + + ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color ); + ctx->Driver.Fogfv( ctx, GL_FOG_MODE, 0 ); + ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density ); + ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start ); + ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End ); + + ctx->Driver.FrontFace( ctx, ctx->Polygon.FrontFace ); + + { + GLfloat f = (GLfloat)ctx->Light.Model.ColorControl; + ctx->Driver.LightModelfv( ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f ); + } + + ctx->Driver.LineWidth( ctx, ctx->Line.Width ); + ctx->Driver.LogicOpcode( ctx, ctx->Color.LogicOp ); + ctx->Driver.PointSize( ctx, ctx->Point.Size ); + ctx->Driver.PolygonStipple( ctx, (const GLubyte *)ctx->PolygonStipple ); + ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height ); + ctx->Driver.ShadeModel( ctx, ctx->Light.ShadeModel ); + ctx->Driver.StencilFuncSeparate( ctx, GL_FRONT, + ctx->Stencil.Function[0], + ctx->Stencil.Ref[0], + ctx->Stencil.ValueMask[0] ); + ctx->Driver.StencilFuncSeparate( ctx, GL_BACK, + ctx->Stencil.Function[1], + ctx->Stencil.Ref[1], + ctx->Stencil.ValueMask[1] ); + ctx->Driver.StencilMaskSeparate( ctx, GL_FRONT, ctx->Stencil.WriteMask[0] ); + ctx->Driver.StencilMaskSeparate( ctx, GL_BACK, ctx->Stencil.WriteMask[1] ); + ctx->Driver.StencilOpSeparate( ctx, GL_FRONT, + ctx->Stencil.FailFunc[0], + ctx->Stencil.ZFailFunc[0], + ctx->Stencil.ZPassFunc[0]); + ctx->Driver.StencilOpSeparate( ctx, GL_BACK, + ctx->Stencil.FailFunc[1], + ctx->Stencil.ZFailFunc[1], + ctx->Stencil.ZPassFunc[1]); + + + ctx->Driver.DrawBuffer( ctx, ctx->Color.DrawBuffer[0] ); +} diff --git a/src/mesa/drivers/dri/i915/intel_tex.h b/src/mesa/drivers/dri/i915/intel_tex.h index be64cf03934..7860130c3fb 100644 --- a/src/mesa/drivers/dri/i915/intel_tex.h +++ b/src/mesa/drivers/dri/i915/intel_tex.h @@ -97,20 +97,7 @@ void intelCopyTexSubImage2D( GLcontext *ctx, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height ); - -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 ); - +GLuint intel_finalize_mipmap_tree( struct intel_context *intel, GLuint unit ); void intel_tex_map_images( struct intel_context *intel, struct intel_texture_object *intelObj ); diff --git a/src/mesa/drivers/dri/i915/intel_tex_copy.c b/src/mesa/drivers/dri/i915/intel_tex_copy.c index 50ba017d8bc..cd94f3db6df 100644 --- a/src/mesa/drivers/dri/i915/intel_tex_copy.c +++ b/src/mesa/drivers/dri/i915/intel_tex_copy.c @@ -37,6 +37,7 @@ #include "intel_regions.h" #include "intel_tex.h" #include "intel_blit.h" +#include "intel_pixel.h" #include "bufmgr.h" /* Do the best we can using the blitter. A future project is to use @@ -108,15 +109,13 @@ static GLboolean do_copy_texsubimage( struct intel_context *intel, return GL_FALSE; + intelFlush(ctx); LOCK_HARDWARE(intel); - intelInstallBatchBuffer(intel); { __DRIdrawablePrivate *dPriv = intel->driDrawable; GLuint image_offset = intel_miptree_image_offset(intelImage->mt, intelImage->face, intelImage->level); - GLuint dst_offset = 0; - GLuint src_offset = 0; GLint orig_x = x; GLint orig_y = y; GLuint window_y; @@ -138,35 +137,28 @@ static GLboolean do_copy_texsubimage( struct intel_context *intel, y = window_y + y; - bmAddBuffer(intel->buffer_list, - intelImage->mt->region->buffer, - BM_WRITE, NULL, &dst_offset); - - bmAddBuffer(intel->buffer_list, - src->buffer, - BM_READ, NULL, &src_offset); - - if (!bmValidateBufferList(intel->bm, intel->buffer_list, BM_MEM_AGP)) { - ret = GL_FALSE; - goto out; - } /* A bit of fiddling to get the blitter to work with -ve * pitches. But we get a nice inverted blit this way, so it's * worth it: */ - intelEmitCopyBlitLocked( intel, - intelImage->mt->cpp, - -src->pitch, - src_offset + intel->intelScreen->height * src->pitch * src->cpp, - intelImage->mt->pitch, - dst_offset + image_offset, - x, y + height, - dstx, dsty, - width, height ); + intelEmitCopyBlit( intel, + intelImage->mt->cpp, + + -src->pitch, + src->buffer, + src->height * src->pitch * src->cpp, + + intelImage->mt->pitch, + intelImage->mt->region->buffer, + image_offset, + + x, y + height, + dstx, dsty, + width, height ); out: - intelFlushBatchLocked( intel, GL_TRUE, GL_FALSE, GL_FALSE); + intel_batchbuffer_flush( intel->batch ); } diff --git a/src/mesa/drivers/dri/i915/intel_tex_format.c b/src/mesa/drivers/dri/i915/intel_tex_format.c index a645165fb27..ff02239e588 100644 --- a/src/mesa/drivers/dri/i915/intel_tex_format.c +++ b/src/mesa/drivers/dri/i915/intel_tex_format.c @@ -15,7 +15,7 @@ const struct gl_texture_format * intelChooseTextureFormat( GLcontext *ctx, GLint internalFormat, GLenum format, GLenum type ) { - intelContextPtr intel = INTEL_CONTEXT( ctx ); + struct intel_context *intel = intel_context( ctx ); const GLboolean do32bpt = (intel->intelScreen->cpp == 4); switch ( internalFormat ) { diff --git a/src/mesa/drivers/dri/i915/intel_tex_image.c b/src/mesa/drivers/dri/i915/intel_tex_image.c index c6f6df7c1cf..d14cb3fc65e 100644 --- a/src/mesa/drivers/dri/i915/intel_tex_image.c +++ b/src/mesa/drivers/dri/i915/intel_tex_image.c @@ -153,7 +153,7 @@ static void intelTexImage(GLcontext *ctx, GLint internalFormat, GLint width, GLint height, GLint border, GLenum format, GLenum type, const void *pixels, - const struct gl_pixelstore_attrib *packing, + const struct gl_pixelstore_attrib *unpack, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { @@ -165,11 +165,14 @@ static void intelTexImage(GLcontext *ctx, GLint texelBytes, sizeInBytes; GLuint dstRowStride; + DBG("%s target %s level %d %dx%d border %d\n", __FUNCTION__, _mesa_lookup_enum_by_nr(target), level, width, height, border); + intelFlush(ctx); + intelImage->face = target_to_face( target ); intelImage->level = level; @@ -271,13 +274,11 @@ static void intelTexImage(GLcontext *ctx, */ pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, format, type, - pixels, packing, "glTexImage"); + pixels, unpack, "glTexImage"); if (!pixels) return; - - LOCK_HARDWARE(intel); if (intelImage->mt) { @@ -311,11 +312,11 @@ static void intelTexImage(GLcontext *ctx, 0, 0, 0, /* dstX/Y/Zoffset */ dstRowStride, 0 /* dstImageStride */, width, height, 1, - format, type, pixels, packing)) { + format, type, pixels, unpack)) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); } - _mesa_unmap_teximage_pbo(ctx, packing); + _mesa_unmap_teximage_pbo(ctx, unpack); if (intelImage->mt) { intel_miptree_image_unmap(intel, intelImage->mt); @@ -342,14 +343,14 @@ void intelTexImage2D(GLcontext *ctx, GLint internalFormat, GLint width, GLint height, GLint border, GLenum format, GLenum type, const void *pixels, - const struct gl_pixelstore_attrib *packing, + const struct gl_pixelstore_attrib *unpack, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { intelTexImage( ctx, 2, target, level, internalFormat, width, height, border, format, type, pixels, - packing, texObj, texImage ); + unpack, texObj, texImage ); } void intelTexImage1D(GLcontext *ctx, @@ -357,14 +358,14 @@ void intelTexImage1D(GLcontext *ctx, GLint internalFormat, GLint width, GLint border, GLenum format, GLenum type, const void *pixels, - const struct gl_pixelstore_attrib *packing, + const struct gl_pixelstore_attrib *unpack, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { intelTexImage( ctx, 1, target, level, internalFormat, width, 1, border, format, type, pixels, - packing, texObj, texImage ); + unpack, texObj, texImage ); } diff --git a/src/mesa/drivers/dri/i915/intel_tex_subimage.c b/src/mesa/drivers/dri/i915/intel_tex_subimage.c index c065e0c630d..2f38b901fea 100644 --- a/src/mesa/drivers/dri/i915/intel_tex_subimage.c +++ b/src/mesa/drivers/dri/i915/intel_tex_subimage.c @@ -57,6 +57,8 @@ static void intelTexSubimage (GLcontext *ctx, xoffset, yoffset, width, height); + intelFlush(ctx); + 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 bd225a484d8..a3e61fbc474 100644 --- a/src/mesa/drivers/dri/i915/intel_tex_validate.c +++ b/src/mesa/drivers/dri/i915/intel_tex_validate.c @@ -96,7 +96,7 @@ static void copy_image_data_to_tree( struct intel_context *intel, /* */ -static GLuint intel_finalize_mipmap_tree( struct intel_context *intel, GLuint unit ) +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); @@ -120,7 +120,7 @@ static GLuint intel_finalize_mipmap_tree( struct intel_context *intel, GLuint un if (intelObj->mt) { intel_miptree_release(intel, &intelObj->mt); } - return 0; + return GL_FALSE; } @@ -191,113 +191,6 @@ static GLuint intel_finalize_mipmap_tree( struct intel_context *intel, GLuint un 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_miptree_image_offset(intelObj->mt, 0, intelObj->firstLevel)); -#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; - - DBG("%s\n", __FUNCTION__); - - assert(intel->locked); - - /* Add the color and depth buffers so that fences associated with - * these buffers: - */ - bmAddBuffer(intel->buffer_list, - intel->draw_region->buffer, - BM_WRITE, - NULL, - NULL); - - bmAddBuffer(intel->buffer_list, - intel->depth_region->buffer, - BM_WRITE, - NULL, - NULL); - - /* 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->buffer_list, - intelObj->mt->region->buffer, - BM_READ, - NULL, - &intelObj->textureOffset); - } - } - } - - ok = bmValidateBufferList(intel->bm, intel->buffer_list, BM_MEM_AGP); - assert(ok); - return ok; -} - -void intel_fence_buffers( struct intel_context *intel ) -{ - assert(intel->locked); - assert(intel->buffer_list); -} - - - void intel_tex_map_images( struct intel_context *intel, diff --git a/src/mesa/drivers/dri/i915/intel_tris.c b/src/mesa/drivers/dri/i915/intel_tris.c index 1b0d31f3fdf..77694ac04f3 100644 --- a/src/mesa/drivers/dri/i915/intel_tris.c +++ b/src/mesa/drivers/dri/i915/intel_tris.c @@ -63,10 +63,9 @@ static void intelRasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim ); * of the locked region - vertex buffers, second batch buffer for * primitives, relocation fixups for texture addresses. */ -static void intel_flush_inline_primitive( GLcontext *ctx ) +static void intel_flush_inline_primitive( struct intel_context *intel ) { - intelContextPtr intel = INTEL_CONTEXT( ctx ); - GLuint used = intel->batch.ptr - intel->prim.start_ptr; + GLuint used = intel->batch->ptr - intel->prim.start_ptr; assert(intel->prim.primitive != ~0); @@ -80,9 +79,7 @@ static void intel_flush_inline_primitive( GLcontext *ctx ) goto finished; do_discard: - intel->batch.ptr -= used; - intel->batch.space += used; - assert(intel->batch.space >= 0); + intel->batch->ptr -= used; finished: intel->prim.primitive = ~0; @@ -93,17 +90,19 @@ static void intel_flush_inline_primitive( GLcontext *ctx ) /* Emit a primitive referencing vertices in a vertex buffer. */ -void intelStartInlinePrimitive( intelContextPtr intel, GLuint prim ) +void intelStartInlinePrimitive( struct intel_context *intel, + GLuint prim, + GLuint batch_flags ) { BATCH_LOCALS; /* Emit a slot which will be filled with the inline primitive * command later. */ - BEGIN_BATCH(2); + BEGIN_BATCH(2, batch_flags); OUT_BATCH( 0 ); - intel->prim.start_ptr = batch_ptr; + intel->prim.start_ptr = intel->batch->ptr; intel->prim.primitive = prim; intel->prim.flush = intel_flush_inline_primitive; @@ -112,31 +111,29 @@ void intelStartInlinePrimitive( intelContextPtr intel, GLuint prim ) } -void intelWrapInlinePrimitive( intelContextPtr intel ) +void intelWrapInlinePrimitive( struct intel_context *intel ) { GLuint prim = intel->prim.primitive; + GLuint batchflags = intel->batch->flags; + + intel_flush_inline_primitive(intel); + intel_batchbuffer_flush(intel->batch); - intel_flush_inline_primitive( &intel->ctx ); - intelFlushBatch(intel, GL_TRUE); - intelInstallBatchBuffer( intel ); - intel_validate_buffers( intel ); intel->vtbl.emit_state( intel ); - intelStartInlinePrimitive( intel, prim ); + intelStartInlinePrimitive( intel, prim, batchflags ); /* ??? */ } -GLuint *intelExtendInlinePrimitive( intelContextPtr intel, +GLuint *intelExtendInlinePrimitive( struct intel_context *intel, GLuint dwords ) { GLuint sz = dwords * sizeof(GLuint); GLuint *ptr; - if (intel->batch.space < sz) { + if (intel_batchbuffer_space(intel->batch) < sz) intelWrapInlinePrimitive( intel ); - } - ptr = (GLuint *)intel->batch.ptr; - intel->batch.ptr += sz; - intel->batch.space -= sz; + ptr = (GLuint *)intel->batch->ptr; + intel->batch->ptr += sz; return ptr; } @@ -160,22 +157,18 @@ do { \ #else #define COPY_DWORDS( j, vb, vertsize, v ) \ do { \ - if (0) fprintf(stderr, "\n"); \ for ( j = 0 ; j < vertsize ; j++ ) { \ - if (0) fprintf(stderr, " -- v(%d): %x/%f\n",j, \ - ((GLuint *)v)[j], \ - ((GLfloat *)v)[j]); \ vb[j] = ((GLuint *)v)[j]; \ } \ vb += vertsize; \ } while (0) #endif -static void __inline__ intel_draw_quad( intelContextPtr intel, - intelVertexPtr v0, - intelVertexPtr v1, - intelVertexPtr v2, - intelVertexPtr v3 ) +static void intel_draw_quad( struct intel_context *intel, + intelVertexPtr v0, + intelVertexPtr v1, + intelVertexPtr v2, + intelVertexPtr v3 ) { GLuint vertsize = intel->vertex_size; GLuint *vb = intelExtendInlinePrimitive( intel, 6 * vertsize ); @@ -189,10 +182,10 @@ static void __inline__ intel_draw_quad( intelContextPtr intel, COPY_DWORDS( j, vb, vertsize, v3 ); } -static void __inline__ intel_draw_triangle( intelContextPtr intel, - intelVertexPtr v0, - intelVertexPtr v1, - intelVertexPtr v2 ) +static void intel_draw_triangle( struct intel_context *intel, + intelVertexPtr v0, + intelVertexPtr v1, + intelVertexPtr v2 ) { GLuint vertsize = intel->vertex_size; GLuint *vb = intelExtendInlinePrimitive( intel, 3 * vertsize ); @@ -204,9 +197,9 @@ static void __inline__ intel_draw_triangle( intelContextPtr intel, } -static __inline__ void intel_draw_line( intelContextPtr intel, - intelVertexPtr v0, - intelVertexPtr v1 ) +static void intel_draw_line( struct intel_context *intel, + intelVertexPtr v0, + intelVertexPtr v1 ) { GLuint vertsize = intel->vertex_size; GLuint *vb = intelExtendInlinePrimitive( intel, 2 * vertsize ); @@ -217,8 +210,8 @@ static __inline__ void intel_draw_line( intelContextPtr intel, } -static __inline__ void intel_draw_point( intelContextPtr intel, - intelVertexPtr v0 ) +static void intel_draw_point( struct intel_context *intel, + intelVertexPtr v0 ) { GLuint vertsize = intel->vertex_size; GLuint *vb = intelExtendInlinePrimitive( intel, vertsize ); @@ -237,7 +230,7 @@ static __inline__ void intel_draw_point( intelContextPtr intel, * Fixup for ARB_point_parameters * ***********************************************************************/ -static void intel_atten_point( intelContextPtr intel, intelVertexPtr v0 ) +static void intel_atten_point( struct intel_context *intel, intelVertexPtr v0 ) { GLcontext *ctx = &intel->ctx; GLfloat psz[4], col[4], restore_psz, restore_alpha; @@ -286,7 +279,7 @@ static void intel_atten_point( intelContextPtr intel, intelVertexPtr v0 ) -static void intel_wpos_triangle( intelContextPtr intel, +static void intel_wpos_triangle( struct intel_context *intel, intelVertexPtr v0, intelVertexPtr v1, intelVertexPtr v2 ) @@ -302,7 +295,7 @@ static void intel_wpos_triangle( intelContextPtr intel, } -static void intel_wpos_line( intelContextPtr intel, +static void intel_wpos_line( struct intel_context *intel, intelVertexPtr v0, intelVertexPtr v1 ) { @@ -316,7 +309,7 @@ static void intel_wpos_line( intelContextPtr intel, } -static void intel_wpos_point( intelContextPtr intel, +static void intel_wpos_point( struct intel_context *intel, intelVertexPtr v0 ) { GLuint offset = intel->wpos_offset; @@ -446,7 +439,7 @@ do { \ #define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx] #define LOCAL_VARS(n) \ - intelContextPtr intel = INTEL_CONTEXT(ctx); \ + struct intel_context *intel = intel_context(ctx); \ GLuint color[n], spec[n]; \ GLuint coloroffset = intel->coloroffset; \ GLboolean specoffset = intel->specoffset; \ @@ -578,7 +571,7 @@ static void init_rast_tab( void ) * primitives. */ static void -intel_fallback_tri( intelContextPtr intel, +intel_fallback_tri( struct intel_context *intel, intelVertex *v0, intelVertex *v1, intelVertex *v2 ) @@ -599,7 +592,7 @@ intel_fallback_tri( intelContextPtr intel, static void -intel_fallback_line( intelContextPtr intel, +intel_fallback_line( struct intel_context *intel, intelVertex *v0, intelVertex *v1 ) { @@ -633,7 +626,7 @@ intel_fallback_line( intelContextPtr intel, #define INIT(x) intelRenderPrimitive( ctx, x ) #undef LOCAL_VARS #define LOCAL_VARS \ - intelContextPtr intel = INTEL_CONTEXT(ctx); \ + struct intel_context *intel = intel_context(ctx); \ GLubyte *vertptr = (GLubyte *)intel->verts; \ const GLuint vertsize = intel->vertex_size; \ const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ @@ -659,7 +652,7 @@ intel_fallback_line( intelContextPtr intel, static void intelRenderClippedPoly( GLcontext *ctx, const GLuint *elts, GLuint n ) { - intelContextPtr intel = INTEL_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; GLuint prim = intel->render_primitive; @@ -690,7 +683,7 @@ static void intelRenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj ) static void intelFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, GLuint n ) { - intelContextPtr intel = INTEL_CONTEXT( ctx ); + struct intel_context *intel = intel_context( ctx ); const GLuint vertsize = intel->vertex_size; GLuint *vb = intelExtendInlinePrimitive( intel, (n-2) * 3 * vertsize ); GLubyte *vertptr = (GLubyte *)intel->verts; @@ -717,7 +710,7 @@ static void intelFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, void intelChooseRenderState(GLcontext *ctx) { TNLcontext *tnl = TNL_CONTEXT(ctx); - intelContextPtr intel = INTEL_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); GLuint flags = ctx->_TriangleCaps; struct fragment_program *fprog = ctx->FragmentProgram._Current; GLboolean have_wpos = (fprog && (fprog->Base.InputsRead & FRAG_BIT_WPOS)); @@ -814,7 +807,7 @@ static const GLenum reduced_prim[GL_POLYGON+1] = { static void intelRunPipeline( GLcontext *ctx ) { - intelContextPtr intel = INTEL_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); if (intel->NewGLState) { if (intel->NewGLState & _NEW_TEXTURE) { @@ -836,11 +829,7 @@ static void intelRenderStart( GLcontext *ctx ) { struct intel_context *intel = intel_context(ctx); - intel->vtbl.render_start( INTEL_CONTEXT(ctx) ); - - LOCK_HARDWARE(intel); - intelInstallBatchBuffer( intel ); - intel_validate_buffers( intel ); + intel->vtbl.render_start( intel_context(ctx) ); intel->vtbl.emit_state( intel ); } @@ -852,10 +841,7 @@ static void intelRenderFinish( GLcontext *ctx ) _swrast_flush( ctx ); if (intel->prim.flush) - intel->prim.flush(ctx); - - intelFlushBatch(intel, GL_TRUE); - UNLOCK_HARDWARE(intel); + intel->prim.flush(intel); } @@ -866,7 +852,7 @@ static void intelRenderFinish( GLcontext *ctx ) */ static void intelRasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim ) { - intelContextPtr intel = INTEL_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); if (0) fprintf(stderr, "%s %s %x\n", __FUNCTION__, @@ -877,7 +863,7 @@ static void intelRasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim ) /* Start a new primitive. Arrange to have it flushed later on. */ if (hwprim != intel->prim.primitive) - intelStartInlinePrimitive( intel, hwprim ); + intelStartInlinePrimitive( intel, hwprim, INTEL_BATCH_CLIPRECTS ); } @@ -885,7 +871,7 @@ static void intelRasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim ) */ static void intelRenderPrimitive( GLcontext *ctx, GLenum prim ) { - intelContextPtr intel = INTEL_CONTEXT(ctx); + struct intel_context *intel = intel_context(ctx); if (0) fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(prim)); @@ -938,7 +924,7 @@ static char *getFallbackString(GLuint bit) -void intelFallback( intelContextPtr intel, GLuint bit, GLboolean mode ) +void intelFallback( struct intel_context *intel, GLuint bit, GLboolean mode ) { GLcontext *ctx = &intel->ctx; TNLcontext *tnl = TNL_CONTEXT(ctx); @@ -982,6 +968,70 @@ void intelFallback( intelContextPtr intel, GLuint bit, GLboolean mode ) +/**********************************************************************/ +/* Used only with the metaops callbacks. */ +/**********************************************************************/ +void intel_meta_draw_quad(struct intel_context *intel, + GLfloat x0, GLfloat x1, + GLfloat y0, GLfloat y1, + GLfloat z, + GLuint color, + GLfloat s0, GLfloat s1, + GLfloat t0, GLfloat t1, + GLuint flags) +{ + union fi *vb; + + if (0) + fprintf(stderr, "%s: %f,%f-%f,%f 0x%x %f,%f-%f,%f\n", + __FUNCTION__, + x0,y0,x1,y1,color,s0,t0,s1,t1); + + intel->vtbl.emit_state( intel ); + + intelStartInlinePrimitive( intel, PRIM3D_TRIFAN, flags ); + vb = (union fi *)intelExtendInlinePrimitive( intel, 4 * 6 ); + + + /* initial vertex, left bottom */ + vb[0].f = x0; + vb[1].f = y0; + vb[2].f = z; + vb[3].i = color; + vb[4].f = s0; + vb[5].f = t0; + vb += 6; + + /* right bottom */ + vb[0].f = x1; + vb[1].f = y0; + vb[2].f = z; + vb[3].i = color; + vb[4].f = s1; + vb[5].f = t0; + vb += 6; + + /* right top */ + vb[0].f = x1; + vb[1].f = y1; + vb[2].f = z; + vb[3].i = color; + vb[4].f = s1; + vb[5].f = t1; + vb += 6; + + /* left top */ + vb[0].f = x0; + vb[1].f = y1; + vb[2].f = z; + vb[3].i = color; + vb[4].f = s0; + vb[5].f = t1; + + if (intel->prim.flush) + intel->prim.flush(intel); +} + /**********************************************************************/ /* Initialization. */ diff --git a/src/mesa/drivers/dri/i915/intel_tris.h b/src/mesa/drivers/dri/i915/intel_tris.h index 1a6164f8063..5fe5b2feb99 100644 --- a/src/mesa/drivers/dri/i915/intel_tris.h +++ b/src/mesa/drivers/dri/i915/intel_tris.h @@ -42,16 +42,23 @@ extern void intelInitTriFuncs( GLcontext *ctx ); -extern void intelPrintRenderState( const char *msg, GLuint state ); extern void intelChooseRenderState( GLcontext *ctx ); -extern void intelStartInlinePrimitive( intelContextPtr intel, GLuint prim ); -extern void intelWrapInlinePrimitive( intelContextPtr intel ); -extern GLuint *intelEmitInlinePrimitiveLocked(intelContextPtr intel, - int primitive, int dwords, - int vertex_size); +extern void intelStartInlinePrimitive( struct intel_context *intel, GLuint prim, GLuint flags ); +extern void intelWrapInlinePrimitive( struct intel_context *intel ); -GLuint *intelExtendInlinePrimitive( intelContextPtr intel, +GLuint *intelExtendInlinePrimitive( struct intel_context *intel, GLuint dwords ); + +void intel_meta_draw_quad(struct intel_context *intel, + GLfloat x0, GLfloat x1, + GLfloat y0, GLfloat y1, + GLfloat z, + GLuint color, + GLfloat s0, GLfloat s1, + GLfloat t0, GLfloat t1, + GLuint flags ); + + #endif |