From 83c3f9658d00e9ede22461b97484e629714a80f9 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Wed, 20 Sep 2006 14:36:49 +0000 Subject: add accelerated glCopyPixels path --- src/mesa/drivers/dri/i965/Makefile | 1 + src/mesa/drivers/dri/i965/intel_context.c | 8 +- src/mesa/drivers/dri/i965/intel_context.h | 31 ++-- src/mesa/drivers/dri/i965/intel_pixel_copy.c | 239 +++++++++++++++++++++++++++ 4 files changed, 256 insertions(+), 23 deletions(-) create mode 100644 src/mesa/drivers/dri/i965/intel_pixel_copy.c diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile index e4fb451cc0..dfa9318a68 100644 --- a/src/mesa/drivers/dri/i965/Makefile +++ b/src/mesa/drivers/dri/i965/Makefile @@ -16,6 +16,7 @@ DRIVER_SOURCES = \ intel_regions.c \ intel_screen.c \ intel_span.c \ + intel_pixel_copy.c \ intel_state.c \ intel_tex.c \ intel_tex_validate.c \ diff --git a/src/mesa/drivers/dri/i965/intel_context.c b/src/mesa/drivers/dri/i965/intel_context.c index 59fc8073ee..eabb98ca23 100644 --- a/src/mesa/drivers/dri/i965/intel_context.c +++ b/src/mesa/drivers/dri/i965/intel_context.c @@ -255,10 +255,14 @@ void intelInitDriverFunctions( struct dd_function_table *functions ) */ functions->Accum = _swrast_Accum; functions->Bitmap = _swrast_Bitmap; - functions->CopyPixels = _swrast_CopyPixels; functions->ReadPixels = _swrast_ReadPixels; functions->DrawPixels = _swrast_DrawPixels; + /* CopyPixels can be accelerated even with the current memory + * manager: + */ + functions->CopyPixels = intelCopyPixels; + intelInitTextureFuncs( functions ); intelInitStateFuncs( functions ); intelInitBufferFuncs( functions ); @@ -446,8 +450,6 @@ GLboolean intelInitContext( struct intel_context *intel, /* DRI_TEXMGR_DO_TEXTURE_RECT ); */ - intel->prim.primitive = ~0; - if (getenv("INTEL_NO_RAST")) { fprintf(stderr, "disabling 3D rasterization\n"); intel->no_rast = 1; diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h index 0328cb900a..f7fe8c1b22 100644 --- a/src/mesa/drivers/dri/i965/intel_context.h +++ b/src/mesa/drivers/dri/i965/intel_context.h @@ -176,16 +176,6 @@ struct intel_context struct intel_batchbuffer *batch; - struct { - GLuint id; - GLuint primitive; - GLubyte *start_ptr; - void (*flush)( struct intel_context * ); - } prim; - - GLboolean locked; - GLboolean strict_conformance; - GLubyte clear_chan[4]; GLuint ClearColor; GLuint ClearDepth; @@ -201,6 +191,10 @@ struct intel_context GLboolean no_hw; GLboolean no_rast; GLboolean thrashing; + GLboolean locked; + GLboolean strict_conformance; + GLboolean need_flush; + /* AGP memory buffer manager: @@ -214,22 +208,12 @@ struct intel_context GLmatrix ViewportMatrix; GLenum render_primitive; GLenum reduced_primitive; - GLuint vertex_size; - GLubyte *verts; /* points to tnl->clipspace.vertex_buf */ - struct intel_region *front_region; struct intel_region *back_region; struct intel_region *draw_region; struct intel_region *depth_region; - - /* Fallback rasterization functions - */ - intel_point_func draw_point; - intel_line_func draw_line; - intel_tri_func draw_tri; - /* These refer to the current draw (front vs. back) buffer: */ int drawX; /* origin of drawable in draw buffer */ @@ -496,6 +480,13 @@ extern GLboolean intel_intersect_cliprects( drm_clip_rect_t *dest, const drm_clip_rect_t *b ); +/* ================================================================ + * intel_pixel_copy.c: + */ +void intelCopyPixels(GLcontext * ctx, + GLint srcx, GLint srcy, + GLsizei width, GLsizei height, + GLint destx, GLint desty, GLenum type); #define _NEW_WINDOW_POS 0x40000000 diff --git a/src/mesa/drivers/dri/i965/intel_pixel_copy.c b/src/mesa/drivers/dri/i965/intel_pixel_copy.c new file mode 100644 index 0000000000..ad27867aea --- /dev/null +++ b/src/mesa/drivers/dri/i965/intel_pixel_copy.c @@ -0,0 +1,239 @@ +/************************************************************************** + * + * 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 "image.h" +#include "mtypes.h" +#include "macros.h" +#include "state.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" + + +static struct intel_region * +copypix_src_region(struct intel_context *intel, GLenum type) +{ + switch (type) { + case GL_COLOR: + return intel_readbuf_region(intel); + case GL_DEPTH: + /* Don't think this is really possible execpt at 16bpp, when we have no stencil. + */ + if (intel->depth_region && intel->depth_region->cpp == 2) + return intel->depth_region; + 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? + */ + return intel->depth_region; + default: + break; + } + + return NULL; +} + + + + +/** + * Check if any fragment operations are in effect which might effect + * glDraw/CopyPixels. + */ +static GLboolean +intel_check_blit_fragment_ops(GLcontext * ctx) +{ + if (ctx->NewState) + _mesa_update_state(ctx); + + /* Could do logicop with the blitter: + */ + return !(ctx->_ImageTransferState || + ctx->Color.AlphaEnabled || + ctx->Depth.Test || + ctx->Fog.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 || + ctx->FragmentProgram._Enabled); +} + + + +/** + * 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 = copypix_src_region(intel, type); + + /* Copypixels can be more than a straight copy. Ensure all the + * extra operations are disabled: + */ + if (!intel_check_blit_fragment_ops(ctx) || + ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F) + return GL_FALSE; + + if (!src || !dst) + return GL_FALSE; + + + + intelFlush(&intel->ctx); + +/* intel->vtbl.render_start(intel); */ +/* intel->vtbl.emit_state(intel); */ + + LOCK_HARDWARE(intel); + + if (intel->driDrawable->numClipRects) { + __DRIdrawablePrivate *dPriv = intel->driDrawable; + drm_clip_rect_t *box = dPriv->pClipRects; + drm_clip_rect_t dest_rect; + GLint nbox = dPriv->numClipRects; + GLint delta_x = 0; + GLint delta_y = 0; + GLuint i; + + /* Do scissoring in GL coordinates: + */ + if (ctx->Scissor.Enabled) + { + GLint x = ctx->Scissor.X; + GLint y = ctx->Scissor.Y; + GLuint w = ctx->Scissor.Width; + GLuint h = ctx->Scissor.Height; + GLint dx = dstx - srcx; + GLint dy = dsty - srcy; + + if (!_mesa_clip_to_region(x, y, x+w, y+h, &dstx, &dsty, &width, &height)) + goto out; + + srcx = dstx - dx; + srcy = dsty - dy; + } + + /* Convert from GL to hardware coordinates: + */ + dsty = dPriv->h - dsty - height; + srcy = dPriv->h - srcy - height; + dstx += dPriv->x; + dsty += dPriv->y; + srcx += dPriv->x; + srcy += dPriv->y; + + /* Clip against the source region. This is the only source + * clipping we do. Dst is clipped with cliprects below. + */ + { + delta_x = srcx - dstx; + delta_y = srcy - dsty; + + if (!_mesa_clip_to_region(0, 0, src->pitch, src->height, + &srcx, &srcy, &width, &height)) + goto out; + + dstx = srcx - delta_x; + dsty = srcy - delta_y; + } + + dest_rect.x1 = dstx; + dest_rect.y1 = dsty; + dest_rect.x2 = dstx + width; + dest_rect.y2 = dsty + height; + +/* intel->vtbl.emit_flush(intel, 0); */ + + /* 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++) { + drm_clip_rect_t rect; + + if (!intel_intersect_cliprects(&rect, &dest_rect, &box[i])) + continue; + + + intelEmitCopyBlit(intel, + dst->cpp, + src->pitch, src->buffer, 0, src->tiled, + dst->pitch, dst->buffer, 0, dst->tiled, + rect.x1 + delta_x, + rect.y1 + delta_y, /* srcx, srcy */ + rect.x1, rect.y1, /* dstx, dsty */ + rect.x2 - rect.x1, rect.y2 - rect.y1); + } + + intel->need_flush = GL_TRUE; + 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 (INTEL_DEBUG & DEBUG_PIXEL) + _mesa_printf("fallback to _swrast_CopyPixels\n"); + + _swrast_CopyPixels(ctx, srcx, srcy, width, height, destx, desty, type); +} -- cgit v1.2.3