| @@ -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 \ | |||
| @@ -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) | |||
| @@ -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 ); | |||
| @@ -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; | |||
| @@ -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); | |||
| @@ -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; | |||
| } | |||
| @@ -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)) | |||
| @@ -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 */ | |||
| @@ -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; | |||
| @@ -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; | |||
| @@ -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(); | |||
| @@ -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: | |||
| @@ -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 ); | |||
| /*====================================================================== | |||
| @@ -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; | |||
| @@ -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; | |||
| } | |||
| @@ -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; | |||
| @@ -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 ); | |||
| @@ -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)) | |||
| @@ -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; | |||
| @@ -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 */ | |||
| @@ -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; | |||
| @@ -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; | |||
| @@ -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; | |||
| } | |||
| @@ -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; | |||
| } | |||
| @@ -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 | |||
| @@ -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 ); | |||
| } | |||
| @@ -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 | |||
| @@ -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; | |||
| } | |||
| @@ -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] ); | |||
| } | |||
| @@ -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 | |||
| @@ -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 ); | |||
| } | |||
| @@ -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 | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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 | |||
| @@ -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); | |||
| } | |||
| @@ -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 ); | |||
| } | |||
| @@ -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); | |||
| } | |||
| @@ -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 ); | |||
| } | |||
| @@ -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; | |||
| @@ -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; | |||
| @@ -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 { | |||
| @@ -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] ); | |||
| } | |||
| @@ -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 ); | |||
| @@ -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 ); | |||
| } | |||
| @@ -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 ) { | |||
| @@ -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 ); | |||
| } | |||
| @@ -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) | |||
| @@ -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, | |||
| @@ -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. */ | |||
| @@ -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 | |||