From 3d96cb7d486db086c6a015df5c7bb0ee24525daf Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 26 Feb 2006 14:37:30 +0000 Subject: [PATCH] First pass at using the texture engine for copypixels. Currently only does the same operations as are accelerated by the blitter, though this will change... --- src/mesa/drivers/dri/i915/i915_metaops.c | 46 +++++--- src/mesa/drivers/dri/i915/intel_context.h | 9 +- src/mesa/drivers/dri/i915/intel_pixel.c | 2 +- src/mesa/drivers/dri/i915/intel_pixel.h | 2 +- src/mesa/drivers/dri/i915/intel_pixel_copy.c | 112 +++++++++---------- src/mesa/drivers/dri/i915/intel_pixel_draw.c | 4 +- src/mesa/drivers/dri/i915/intel_pixel_read.c | 24 +++- 7 files changed, 111 insertions(+), 88 deletions(-) diff --git a/src/mesa/drivers/dri/i915/i915_metaops.c b/src/mesa/drivers/dri/i915/i915_metaops.c index 57f3d3c3e97..524e6c98703 100644 --- a/src/mesa/drivers/dri/i915/i915_metaops.c +++ b/src/mesa/drivers/dri/i915/i915_metaops.c @@ -305,18 +305,23 @@ static void meta_texture_blend_replace( struct intel_context *intel ) * (including the front or back buffer). */ static void meta_tex_rect_source( struct intel_context *intel, - struct intel_region *region, - GLuint textureFormat ) + struct intel_region *region ) { struct i915_context *i915 = i915_context(&intel->ctx); GLuint unit = 0; GLint numLevels = 1; GLuint *state = i915->meta.Tex[0]; + GLuint textureFormat; 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 ); */ + /* XXX: color buffers only: + */ + if (region->cpp == 2) + textureFormat = (MAPSURF_16BIT | MT_16BIT_RGB565); + else + textureFormat = (MAPSURF_32BIT | MT_32BIT_ARGB8888); + intel_region_release(intel, &i915->meta.tex_region[0]); intel_region_reference(&i915->meta.tex_region[0], region); @@ -348,27 +353,32 @@ static void meta_tex_rect_source( struct intel_context *intel, /* Select between front and back draw buffers. */ static void meta_draw_region( struct intel_context *intel, - struct intel_region *draw_region, - struct intel_region *depth_region ) + struct intel_region *draw_region, + struct intel_region *depth_region ) { struct i915_context *i915 = i915_context(&intel->ctx); + GLuint format; + GLuint depth_format = DEPTH_FRMT_16_FIXED; 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_release(intel, &i915->meta.depth_region); intel_region_reference(&i915->meta.depth_region, depth_region); - i915->meta.emitted &= ~I915_UPLOAD_BUFFERS; -} + /* XXX: 555 support? + */ + if (draw_region->cpp == 2) + format = DV_PF_565; + else + format = DV_PF_8888; -/* Setup an arbitary draw format, useful for targeting texture or agp - * memory. - */ -static void set_draw_format( struct intel_context *intel, - GLuint format, - GLuint depth_format) -{ - struct i915_context *i915 = i915_context(&intel->ctx); + if (depth_region) { + if (depth_region->cpp == 2) + depth_format = DEPTH_FRMT_16_FIXED; + else + depth_format = DEPTH_FRMT_24_FIXED_8_OTHER; + } i915->meta.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ DSTORG_VERT_BIAS(0x8) | /* .5 */ @@ -380,6 +390,7 @@ static void set_draw_format( struct intel_context *intel, i915->meta.emitted &= ~I915_UPLOAD_BUFFERS; } + static void set_vertex_format( struct intel_context *intel ) { struct i915_context *i915 = i915_context(&intel->ctx); @@ -443,6 +454,5 @@ void i915InitMetaFuncs( struct i915_context *i915 ) 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; i915->intel.vtbl.meta_import_pixel_state = meta_import_pixel_state; } diff --git a/src/mesa/drivers/dri/i915/intel_context.h b/src/mesa/drivers/dri/i915/intel_context.h index cc9e2528991..2978ec1ba58 100644 --- a/src/mesa/drivers/dri/i915/intel_context.h +++ b/src/mesa/drivers/dri/i915/intel_context.h @@ -157,14 +157,7 @@ struct intel_context void (*meta_import_pixel_state)( 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 ); - - + struct intel_region *region ); } vtbl; diff --git a/src/mesa/drivers/dri/i915/intel_pixel.c b/src/mesa/drivers/dri/i915/intel_pixel.c index 06216596680..4bbd5ef5160 100644 --- a/src/mesa/drivers/dri/i915/intel_pixel.c +++ b/src/mesa/drivers/dri/i915/intel_pixel.c @@ -34,7 +34,7 @@ #include "intel_regions.h" -GLboolean intel_check_blit_fragment_ops( const GLcontext *ctx ) +GLboolean intel_check_blit_fragment_ops( GLcontext *ctx ) { if (ctx->NewState) _mesa_update_state(ctx); diff --git a/src/mesa/drivers/dri/i915/intel_pixel.h b/src/mesa/drivers/dri/i915/intel_pixel.h index 01c0a462427..8f59e4172eb 100644 --- a/src/mesa/drivers/dri/i915/intel_pixel.h +++ b/src/mesa/drivers/dri/i915/intel_pixel.h @@ -32,7 +32,7 @@ void intelInitPixelFuncs( struct dd_function_table *functions ); -GLboolean intel_check_blit_fragment_ops( const GLcontext *ctx ); +GLboolean intel_check_blit_fragment_ops( GLcontext *ctx ); GLboolean intel_check_blit_format( struct intel_region *region, GLenum format, GLenum type ); diff --git a/src/mesa/drivers/dri/i915/intel_pixel_copy.c b/src/mesa/drivers/dri/i915/intel_pixel_copy.c index 8d2bb4ed568..763835ceb26 100644 --- a/src/mesa/drivers/dri/i915/intel_pixel_copy.c +++ b/src/mesa/drivers/dri/i915/intel_pixel_copy.c @@ -37,6 +37,7 @@ #include "intel_batchbuffer.h" #include "intel_blit.h" #include "intel_regions.h" +#include "intel_tris.h" #include "intel_pixel.h" #include "bufmgr.h" @@ -50,7 +51,8 @@ static struct intel_region *copypix_src_region( struct intel_context *intel, case GL_DEPTH: /* Don't think this is really possible execpt at 16bpp, when we have no stencil. */ - if (intel->intelScreen->cpp == 2) + if (intel->depth_region && + intel->depth_region->cpp == 2) return intel->depth_region; case GL_STENCIL: /* Don't think this is really possible. @@ -73,84 +75,82 @@ static GLboolean do_texture_copypixels( GLcontext *ctx, GLint dstx, GLint dsty, GLenum type ) { -#if 0 struct intel_context *intel = intel_context( ctx ); struct intel_region *dst = intel_drawbuf_region( intel ); - struct intel_region *src = copypix_src_region(intel); + struct intel_region *src = copypix_src_region(intel, type); + if (INTEL_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (!src || !dst) + return GL_FALSE; intelFlush( &intel->ctx ); + + intel->vtbl.install_meta_state(intel); + + /* Is this true? Also will need to turn depth testing on according + * to state: + */ + intel->vtbl.meta_no_depth_stencil_write(intel); + + /* Set the 3d engine to draw into the destination region: + */ + intel->vtbl.meta_draw_region(intel, dst, intel->depth_region); + + + /* Set the frontbuffer up as a large rectangular texture. + */ + intel->vtbl.meta_tex_rect_source( intel, src ); + + intel->vtbl.meta_texture_blend_replace( intel ); + + 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. + /* Clip against the source region. This is the only source + * clipping we do. Dst is clipped with cliprects below. + * + * TODO: Scissor? */ - 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; + GLint orig_x = srcx; + GLint orig_y = srcy; - 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; + if (!intel_clip_to_region(ctx, src, &srcx, &srcy, &width, &height)) + goto out; - 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 ); + dstx += srcx - orig_x; + dsty += srcy - orig_y; } + + + /* Just use the regular cliprect mechanism... Does this need to + * even hold the lock??? + */ + intel_meta_draw_quad(intel, + dstx, dstx+width, + dsty, dsty+height, + 0, /* XXX: what z value? */ + 0x00ff00ff, + srcx, srcx+width, + srcy, srcy+height, + INTEL_BATCH_CLIPRECTS); } + out: - intel_batchbuffer_flush( intel->batch ); + intel->vtbl.leave_meta_state(intel); UNLOCK_HARDWARE( intel ); return GL_TRUE; -#endif - - return GL_FALSE; } @@ -258,7 +258,7 @@ void intelCopyPixels( GLcontext *ctx, if (INTEL_DEBUG & DEBUG_PIXEL) fprintf(stderr, "%s\n", __FUNCTION__); - if (do_blit_copypixels( ctx, srcx, srcy, width, height, destx, desty, type)) + if (0 && do_blit_copypixels( ctx, srcx, srcy, width, height, destx, desty, type)) return; if (do_texture_copypixels( ctx, srcx, srcy, width, height, destx, desty, type)) diff --git a/src/mesa/drivers/dri/i915/intel_pixel_draw.c b/src/mesa/drivers/dri/i915/intel_pixel_draw.c index 44b0220b70a..8421f3a9822 100644 --- a/src/mesa/drivers/dri/i915/intel_pixel_draw.c +++ b/src/mesa/drivers/dri/i915/intel_pixel_draw.c @@ -139,7 +139,6 @@ static GLboolean do_blit_draw_pixels( struct intel_context *intel, struct intel_region *dest = intel_drawbuf_region(intel); struct intel_buffer_object *src = intel_buffer_object(unpack->BufferObj); GLuint src_offset; - GLuint src_y = 0; GLuint rowLength; GLuint fence; @@ -164,7 +163,7 @@ static GLboolean do_blit_draw_pixels( struct intel_context *intel, else { /* PBO only for now: */ - _mesa_printf("%s - not PBO\n", __FUNCTION__); +/* _mesa_printf("%s - not PBO\n", __FUNCTION__); */ return GL_FALSE; } @@ -262,7 +261,6 @@ void intelDrawPixels( GLcontext *ctx, { struct intel_context *intel = intel_context(ctx); - if (do_texture_draw_pixels( intel, x, y, width, height, format, type, unpack, pixels )) return; diff --git a/src/mesa/drivers/dri/i915/intel_pixel_read.c b/src/mesa/drivers/dri/i915/intel_pixel_read.c index 6da0b1d6edb..ec993206d1f 100644 --- a/src/mesa/drivers/dri/i915/intel_pixel_read.c +++ b/src/mesa/drivers/dri/i915/intel_pixel_read.c @@ -44,7 +44,27 @@ #include "bufmgr.h" - +/* For many applications, the new ability to pull the source buffers + * back out of the GTT and then do the packing/conversion operations + * in software will be as much of an improvement as trying to get the + * blitter and/or texture engine to do the work. + * + * This step is gated on private backbuffers. + * + * Obviously the frontbuffer can't be pulled back, so that is either + * an argument for blit/texture readpixels, or for blitting to a + * temporary and then pulling that back. + * + * When the destination is a pbo, however, it's not clear if it is + * ever going to be pulled to main memory (though the access param + * will be a good hint). So it sounds like we do want to be able to + * choose between blit/texture implementation on the gpu and pullback + * and cpu-based copying. + * + * Unless you can magically turn client memory into a PBO for the + * duration of this call, there will be a cpu-based copying step in + * any case. + */ static GLboolean @@ -279,6 +299,8 @@ intelReadPixels( GLcontext *ctx, if (do_texture_readpixels(ctx, x, y, width, height, format, type, pack, pixels)) return; + _mesa_printf("%s: fallback to swrast\n", __FUNCTION__); + _swrast_ReadPixels( ctx, x, y, width, height, format, type, pack, pixels); }