[Mesa3d-dev] gallium: add overlapping blit support to u_blitter
This makes the r300g + X.org state tracker work a bit better, I can start X + xterm + metacity and drag a window around now at least. A full gnome session seems to have other issuess. Dave.From b8f1d1cf45aa23c74b2d150058506a6a27737d25 Mon Sep 17 00:00:00 2001 From: Dave Airlie airl...@redhat.com Date: Thu, 7 Jan 2010 11:45:48 +1000 Subject: [PATCH] gallium: u_blitter add overlapping blit support. the xorg state tracker really wants the driver to handle overlapping blits, and r300 uses u_blitter for blits. This patch adds overlapping blit support via a temporary surface when its required. --- src/gallium/auxiliary/util/u_blitter.c | 158 +--- 1 files changed, 124 insertions(+), 34 deletions(-) diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index 1f794d3..58f0b6d 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -560,45 +560,30 @@ void util_blitter_clear(struct blitter_context *blitter, blitter_restore_CSOs(ctx); } -void util_blitter_copy(struct blitter_context *blitter, - struct pipe_surface *dst, - unsigned dstx, unsigned dsty, - struct pipe_surface *src, - unsigned srcx, unsigned srcy, - unsigned width, unsigned height, - boolean ignore_stencil) +static boolean +is_overlap(int sx1, int sx2, int sy1, int sy2, int dx1, int dx2, int dy1, int dy2) +{ +if (((sx1 = dx1) (sx1 = dx2) (sy1 = dy1) (sy1 = dy2)) || /* TL x1, y1 */ + ((sx2 = dx1) (sx2 = dx2) (sy1 = dy1) (sy1 = dy2)) || /* TR x2, y1 */ + ((sx1 = dx1) (sx1 = dx2) (sy2 = dy1) (sy2 = dy2)) || /* BL x1, y2 */ + ((sx2 = dx1) (sx2 = dx2) (sy2 = dy1) (sy2 = dy2))) /* BR x2, y2 */ + return TRUE; +else + return FALSE; +} + +static void util_blitter_do_copy(struct blitter_context *blitter, + struct pipe_surface *dst, + unsigned dstx, unsigned dsty, + struct pipe_surface *src, + unsigned srcx, unsigned srcy, + unsigned width, unsigned height, + boolean is_depth) { struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; struct pipe_context *pipe = ctx-pipe; - struct pipe_screen *screen = pipe-screen; struct pipe_framebuffer_state fb_state; - boolean is_stencil, is_depth; - unsigned dst_tex_usage; - - /* give up if textures are not set */ - assert(dst-texture src-texture); - if (!dst-texture || !src-texture) - return; - - is_depth = util_format_get_component_bits(src-format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0; - is_stencil = util_format_get_component_bits(src-format, UTIL_FORMAT_COLORSPACE_ZS, 1) != 0; - dst_tex_usage = is_depth || is_stencil ? PIPE_TEXTURE_USAGE_DEPTH_STENCIL : -PIPE_TEXTURE_USAGE_RENDER_TARGET; - - /* check if we can sample from and render to the surfaces */ - /* (assuming copying a stencil buffer is not possible) */ - if ((!ignore_stencil is_stencil) || - !screen-is_format_supported(screen, dst-format, dst-texture-target, -dst_tex_usage, 0) || - !screen-is_format_supported(screen, src-format, src-texture-target, -PIPE_TEXTURE_USAGE_SAMPLER, 0)) { - util_surface_copy(pipe, FALSE, dst, dstx, dsty, src, srcx, srcy, -width, height); - return; - } - /* check whether the states are properly saved */ - blitter_check_saved_CSOs(ctx); assert(blitter-saved_fb_state.nr_cbufs != ~0); assert(blitter-saved_num_textures != ~0); assert(blitter-saved_num_sampler_states != ~0); @@ -656,6 +641,111 @@ void util_blitter_copy(struct blitter_context *blitter, blitter_set_rectangle(ctx, dstx, dsty, dstx+width, dsty+height, 0); blitter_draw_quad(ctx); + +} + +static void util_blitter_overlap_copy(struct blitter_context *blitter, + struct pipe_surface *dst, + unsigned dstx, unsigned dsty, + struct pipe_surface *src, + unsigned srcx, unsigned srcy, + unsigned width, unsigned height) +{ + struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; + struct pipe_context *pipe = ctx-pipe; + struct pipe_screen *screen = pipe-screen; + + struct pipe_texture texTemp; + struct pipe_texture *texture; + struct pipe_surface *tex_surf; + uint level; + + /* check whether the states are properly saved */ + blitter_check_saved_CSOs(ctx); + + memset(texTemp, 0, sizeof(texTemp)); + texTemp.target = PIPE_TEXTURE_2D; + texTemp.format = dst-texture-format; /* XXX verify supported by driver! */ + texTemp.last_level = 0; + texTemp.width0 = width; + texTemp.height0 = height; + texTemp.depth0 = 1; + + texture = screen-texture_create(screen, texTemp); + if (!texture) + return; + + tex_surf = screen-get_tex_surface(screen, texture, 0,
Re: [Mesa3d-dev] gallium: add overlapping blit support to u_blitter
On Wed, Jan 6, 2010 at 6:50 PM, Dave Airlie airl...@linux.ie wrote: This makes the r300g + X.org state tracker work a bit better, I can start X + xterm + metacity and drag a window around now at least. A full gnome session seems to have other issuess. Hi Dave, a couple comments on your patch... diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index 1f794d3..58f0b6d 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -560,10 +560,14 @@ void util_blitter_clear(struct blitter_context *blitter, blitter_restore_CSOs(ctx); } -void util_blitter_copy(struct blitter_context *blitter, - struct pipe_surface *dst, - unsigned dstx, unsigned dsty, - struct pipe_surface *src, - unsigned srcx, unsigned srcy, - unsigned width, unsigned height, - boolean ignore_stencil) +static boolean +is_overlap(int sx1, int sx2, int sy1, int sy2, int dx1, int dx2, int dy1, int dy2) +{ +if (((sx1 = dx1) (sx1 = dx2) (sy1 = dy1) (sy1 = dy2)) || /* TL x1, y1 */ + ((sx2 = dx1) (sx2 = dx2) (sy1 = dy1) (sy1 = dy2)) || /* TR x2, y1 */ + ((sx1 = dx1) (sx1 = dx2) (sy2 = dy1) (sy2 = dy2)) || /* BL x1, y2 */ + ((sx2 = dx1) (sx2 = dx2) (sy2 = dy1) (sy2 = dy2))) /* BR x2, y2 */ + return TRUE; +else + return FALSE; +} If we know that sx1sx2, sy1sy2, dx1dx2, dy1dy2, then I think you can do this instead: static boolean is_overlap(int sx1, int sx2, int sy1, int sy2, int dx1, int dx2, int dy1, int dy2) { return !(sx2 dx1 || sx1 dx2 || sy2 dy1 || sy1 dy2); } And if the -1 terms are removed from the call below, the inequalities can be changed to = and =. + +static void util_blitter_do_copy(struct blitter_context *blitter, +struct pipe_surface *dst, +unsigned dstx, unsigned dsty, +struct pipe_surface *src, +unsigned srcx, unsigned srcy, +unsigned width, unsigned height, +boolean is_depth) { struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; struct pipe_context *pipe = ctx-pipe; - struct pipe_screen *screen = pipe-screen; struct pipe_framebuffer_state fb_state; - boolean is_stencil, is_depth; - unsigned dst_tex_usage; - - /* give up if textures are not set */ - assert(dst-texture src-texture); - if (!dst-texture || !src-texture) - return; - - is_depth = util_format_get_component_bits(src-format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0; - is_stencil = util_format_get_component_bits(src-format, UTIL_FORMAT_COLORSPACE_ZS, 1) != 0; - dst_tex_usage = is_depth || is_stencil ? PIPE_TEXTURE_USAGE_DEPTH_STENCIL : -PIPE_TEXTURE_USAGE_RENDER_TARGET; - - /* check if we can sample from and render to the surfaces */ - /* (assuming copying a stencil buffer is not possible) */ - if ((!ignore_stencil is_stencil) || - !screen-is_format_supported(screen, dst-format, dst-texture-target, -dst_tex_usage, 0) || - !screen-is_format_supported(screen, src-format, src-texture-target, -PIPE_TEXTURE_USAGE_SAMPLER, 0)) { - util_surface_copy(pipe, FALSE, dst, dstx, dsty, src, srcx, srcy, -width, height); - return; - } - /* check whether the states are properly saved */ - blitter_check_saved_CSOs(ctx); assert(blitter-saved_fb_state.nr_cbufs != ~0); assert(blitter-saved_num_textures != ~0); assert(blitter-saved_num_sampler_states != ~0); @@ -656,3 +641,79 @@ void util_blitter_copy(struct blitter_context *blitter, blitter_set_rectangle(ctx, dstx, dsty, dstx+width, dsty+height, 0); blitter_draw_quad(ctx); + +} + +static void util_blitter_overlap_copy(struct blitter_context *blitter, + struct pipe_surface *dst, + unsigned dstx, unsigned dsty, + struct pipe_surface *src, + unsigned srcx, unsigned srcy, + unsigned width, unsigned height) +{ + struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; + struct pipe_context *pipe = ctx-pipe; + struct pipe_screen *screen = pipe-screen; + + struct pipe_texture texTemp; + struct pipe_texture *texture; + struct pipe_surface *tex_surf; + uint level; + + /* check whether the states are properly saved */ + blitter_check_saved_CSOs(ctx); + + memset(texTemp, 0, sizeof(texTemp)); + texTemp.target = PIPE_TEXTURE_2D; + texTemp.format = dst-texture-format; /* XXX verify supported by driver! */ +