From: Roland Scheidegger Date: Mon, 17 May 2010 19:15:20 +0000 (+0200) Subject: gallium/util: adapt util code to interface changes X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=815b75705f5e3f0f7db025368da37bb14395de9a;p=mesa.git gallium/util: adapt util code to interface changes The util blit functions change their interface (apart from some rename) too (in particular util_blit_pixels now also takes a pipe_resource as the src blit argument instead of a surface, as it might just call resource_copy_region). Maybe the blit util code might need a bit more cleanup, it still doesn't feel very clean. In particular it seems that util_blit_pixels_tex should probably disappear, and I think it would be great if the code called by drivers for blitting (u_blitter.c, which isn't really touched by this change) could somehow be merged with the u_blit code. --- diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index e45310b9bb7..9df5f9a9d26 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -192,7 +192,6 @@ get_next_slot( struct blit_state *ctx ) return ctx->vbuf_slot++ * sizeof ctx->vertices; } - @@ -279,10 +278,11 @@ regions_overlap(int srcX0, int srcY0, */ void util_blit_pixels_writemask(struct blit_state *ctx, - struct pipe_surface *src, - struct pipe_sampler_view *src_sampler_view, + struct pipe_resource *src_tex, + struct pipe_subresource srcsub, int srcX0, int srcY0, int srcX1, int srcY1, + int srcZ0, struct pipe_surface *dst, int dstX0, int dstY0, int dstX1, int dstY1, @@ -292,6 +292,7 @@ util_blit_pixels_writemask(struct blit_state *ctx, struct pipe_context *pipe = ctx->pipe; struct pipe_screen *screen = pipe->screen; struct pipe_sampler_view *sampler_view = NULL; + struct pipe_sampler_view sv_templ; struct pipe_framebuffer_state fb; const int srcW = abs(srcX1 - srcX0); const int srcH = abs(srcY1 - srcY0); @@ -302,13 +303,13 @@ util_blit_pixels_writemask(struct blit_state *ctx, assert(filter == PIPE_TEX_MIPFILTER_NEAREST || filter == PIPE_TEX_MIPFILTER_LINEAR); - assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE_2D, - PIPE_BIND_SAMPLER_VIEW, 0)); - assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D, - PIPE_BIND_RENDER_TARGET, 0)); + assert(srcsub.level <= src_tex->last_level); /* do the regions overlap? */ - overlap = util_same_surface(src, dst) && + overlap = src_tex == dst->texture && + dst->face == srcsub.face && + dst->level == srcsub.level && + dst->zslice == srcZ0 && regions_overlap(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1); @@ -317,8 +318,7 @@ util_blit_pixels_writemask(struct blit_state *ctx, * no overlapping. * Filter mode should not matter since there's no stretching. */ - if (pipe->surface_copy && - dst->format == src->format && + if (dst->format == src_tex->format && srcX0 < srcX1 && dstX0 < dstX1 && srcY0 < srcY1 && @@ -326,29 +326,36 @@ util_blit_pixels_writemask(struct blit_state *ctx, (dstX1 - dstX0) == (srcX1 - srcX0) && (dstY1 - dstY0) == (srcY1 - srcY0) && !overlap) { - pipe->surface_copy(pipe, - dst, dstX0, dstY0, /* dest */ - src, srcX0, srcY0, /* src */ - srcW, srcH); /* size */ + struct pipe_subresource subdst; + subdst.face = dst->face; + subdst.level = dst->level; + pipe->resource_copy_region(pipe, + dst->texture, subdst, + dstX0, dstY0, dst->zslice,/* dest */ + src_tex, srcsub, + srcX0, srcY0, srcZ0,/* src */ + srcW, srcH); /* size */ return; } - - assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D, - PIPE_BIND_RENDER_TARGET, 0)); + /* Create a temporary texture when src and dest alias or when src - * is anything other than a single-level 2d texture. + * is anything other than a 2d texture. + * XXX should just use appropriate shader to access 1d / 3d slice / cube face, + * much like the u_blitter code does (should be pretty trivial). * * This can still be improved upon. */ - if (util_same_surface(src, dst) || - src->texture->target != PIPE_TEXTURE_2D || - src->texture->last_level != 0) + if ((src_tex == dst->texture && + dst->face == srcsub.face && + dst->level == srcsub.level && + dst->zslice == srcZ0) || + src_tex->target != PIPE_TEXTURE_2D) { struct pipe_resource texTemp; struct pipe_resource *tex; struct pipe_sampler_view sv_templ; - struct pipe_surface *texSurf; + struct pipe_subresource texsub; const int srcLeft = MIN2(srcX0, srcX1); const int srcTop = MIN2(srcY0, srcY1); @@ -369,7 +376,7 @@ util_blit_pixels_writemask(struct blit_state *ctx, /* create temp texture */ memset(&texTemp, 0, sizeof(texTemp)); texTemp.target = PIPE_TEXTURE_2D; - texTemp.format = src->format; + texTemp.format = src_tex->format; texTemp.last_level = 0; texTemp.width0 = srcW; texTemp.height0 = srcH; @@ -380,49 +387,50 @@ util_blit_pixels_writemask(struct blit_state *ctx, if (!tex) return; - u_sampler_view_default_template(&sv_templ, tex, tex->format); - - sampler_view = ctx->pipe->create_sampler_view(ctx->pipe, tex, &sv_templ); - if (!sampler_view) { - pipe_resource_reference(&tex, NULL); - return; - } - - texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0, - PIPE_BIND_BLIT_DESTINATION); - + texsub.face = 0; + texsub.level = 0; /* load temp texture */ - if (pipe->surface_copy) { - pipe->surface_copy(pipe, - texSurf, 0, 0, /* dest */ - src, srcLeft, srcTop, /* src */ - srcW, srcH); /* size */ - } else { - util_surface_copy(pipe, FALSE, - texSurf, 0, 0, /* dest */ - src, srcLeft, srcTop, /* src */ - srcW, srcH); /* size */ - } + pipe->resource_copy_region(pipe, + tex, texsub, 0, 0, 0, /* dest */ + src_tex, srcsub, srcLeft, srcTop, srcZ0, /* src */ + srcW, srcH); /* size */ - /* free the surface, update the texture if necessary. - */ - pipe_surface_reference(&texSurf, NULL); s0 = 0.0f; s1 = 1.0f; t0 = 0.0f; t1 = 1.0f; + u_sampler_view_default_template(&sv_templ, tex, tex->format); + sampler_view = pipe->create_sampler_view(pipe, tex, &sv_templ); + + if (!sampler_view) { + pipe_resource_reference(&tex, NULL); + return; + } pipe_resource_reference(&tex, NULL); } else { - pipe_sampler_view_reference(&sampler_view, src_sampler_view); - s0 = srcX0 / (float)src->texture->width0; - s1 = srcX1 / (float)src->texture->width0; - t0 = srcY0 / (float)src->texture->height0; - t1 = srcY1 / (float)src->texture->height0; + u_sampler_view_default_template(&sv_templ, src_tex, src_tex->format); + sv_templ.first_level = sv_templ.last_level = srcsub.level; + sampler_view = pipe->create_sampler_view(pipe, src_tex, &sv_templ); + + if (!sampler_view) { + return; + } + + s0 = srcX0 / (float)(u_minify(sampler_view->texture->width0, srcsub.level)); + s1 = srcX1 / (float)(u_minify(sampler_view->texture->width0, srcsub.level)); + t0 = srcY0 / (float)(u_minify(sampler_view->texture->height0, srcsub.level)); + t1 = srcY1 / (float)(u_minify(sampler_view->texture->height0, srcsub.level)); } - + + assert(screen->is_format_supported(screen, sampler_view->format, PIPE_TEXTURE_2D, + sampler_view->texture->nr_samples, + PIPE_BIND_SAMPLER_VIEW, 0)); + assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D, + dst->texture->nr_samples, + PIPE_BIND_RENDER_TARGET, 0)); /* save state (restored below) */ cso_save_blend(ctx->cso); @@ -447,6 +455,9 @@ util_blit_pixels_writemask(struct blit_state *ctx, /* sampler */ ctx->sampler.min_img_filter = filter; ctx->sampler.mag_img_filter = filter; + /* we've limited this already with the sampler view but you never know... */ + ctx->sampler.min_lod = srcsub.level; + ctx->sampler.max_lod = srcsub.level; cso_single_sampler(ctx->cso, 0, &ctx->sampler); cso_single_sampler_done(ctx->cso); @@ -515,18 +526,21 @@ util_blit_pixels_writemask(struct blit_state *ctx, void util_blit_pixels(struct blit_state *ctx, - struct pipe_surface *src, - struct pipe_sampler_view *src_sampler_view, + struct pipe_resource *src_tex, + struct pipe_subresource srcsub, int srcX0, int srcY0, int srcX1, int srcY1, + int srcZ, struct pipe_surface *dst, int dstX0, int dstY0, int dstX1, int dstY1, float z, uint filter ) { - util_blit_pixels_writemask( ctx, src, src_sampler_view, + util_blit_pixels_writemask( ctx, src_tex, + srcsub, srcX0, srcY0, srcX1, srcY1, + srcZ, dst, dstX0, dstY0, dstX1, dstY1, @@ -548,7 +562,6 @@ void util_blit_flush( struct blit_state *ctx ) /** * Copy pixel block from src texture to dst surface. - * Overlapping regions are acceptable. * * XXX Should support selection of level. * XXX need some control over blitting Z and/or stencil. @@ -582,6 +595,7 @@ util_blit_pixels_tex(struct blit_state *ctx, assert(ctx->pipe->screen->is_format_supported(ctx->pipe->screen, dst->format, PIPE_TEXTURE_2D, + dst->texture->nr_samples, PIPE_BIND_RENDER_TARGET, 0)); diff --git a/src/gallium/auxiliary/util/u_blit.h b/src/gallium/auxiliary/util/u_blit.h index 464ff9aaced..ef95134f324 100644 --- a/src/gallium/auxiliary/util/u_blit.h +++ b/src/gallium/auxiliary/util/u_blit.h @@ -52,10 +52,11 @@ util_destroy_blit(struct blit_state *ctx); extern void util_blit_pixels(struct blit_state *ctx, - struct pipe_surface *src, - struct pipe_sampler_view *src_sampler_view, + struct pipe_resource *src_tex, + struct pipe_subresource srcsub, int srcX0, int srcY0, int srcX1, int srcY1, + int srcZ0, struct pipe_surface *dst, int dstX0, int dstY0, int dstX1, int dstY1, @@ -63,10 +64,11 @@ util_blit_pixels(struct blit_state *ctx, void util_blit_pixels_writemask(struct blit_state *ctx, - struct pipe_surface *src, - struct pipe_sampler_view *src_sampler_view, + struct pipe_resource *src_tex, + struct pipe_subresource srcsub, int srcX0, int srcY0, int srcX1, int srcY1, + int srcZ0, struct pipe_surface *dst, int dstX0, int dstY0, int dstX1, int dstY1, diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index 1abe31db466..8e0901104a2 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -743,8 +743,8 @@ static void util_blitter_overlap_copy(struct blitter_context *blitter, return; tex_surf = screen->get_tex_surface(screen, texture, 0, 0, 0, - PIPE_BIND_BLIT_SOURCE | - PIPE_BIND_BLIT_DESTINATION); + PIPE_BIND_SAMPLER_VIEW | + PIPE_BIND_RENDER_TARGET); /* blit from the src to the temp */ util_blitter_do_copy(blitter, tex_surf, 0, 0, @@ -797,9 +797,9 @@ void util_blitter_copy(struct blitter_context *blitter, /* (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) || + dst->texture->nr_samples, dst_tex_usage, 0) || !screen->is_format_supported(screen, src->format, src->texture->target, - PIPE_BIND_SAMPLER_VIEW, 0)) { + src->texture->nr_samples, PIPE_BIND_SAMPLER_VIEW, 0)) { util_surface_copy(pipe, FALSE, dst, dstx, dsty, src, srcx, srcy, width, height); return; @@ -836,6 +836,7 @@ void util_blitter_fill(struct blitter_context *blitter, /* check if we can render to the surface */ if (util_format_is_depth_or_stencil(dst->format) || /* unlikely, but you never know */ !screen->is_format_supported(screen, dst->format, dst->texture->target, + dst->texture->nr_samples, PIPE_BIND_RENDER_TARGET, 0)) { util_surface_fill(pipe, dst, dstx, dsty, width, height, value); return; diff --git a/src/gallium/auxiliary/util/u_caps.c b/src/gallium/auxiliary/util/u_caps.c index c7c1e830e01..294ee37033d 100644 --- a/src/gallium/auxiliary/util/u_caps.c +++ b/src/gallium/auxiliary/util/u_caps.c @@ -68,6 +68,7 @@ util_check_caps_out(struct pipe_screen *screen, const unsigned *list, int *out) if (!screen->is_format_supported(screen, list[i++], PIPE_TEXTURE_2D, + 0, PIPE_BIND_SAMPLER_VIEW, 0)) { *out = i - 2; diff --git a/src/gallium/auxiliary/util/u_clear.h b/src/gallium/auxiliary/util/u_clear.h index 40da2d75a72..31f7fb2169a 100644 --- a/src/gallium/auxiliary/util/u_clear.h +++ b/src/gallium/auxiliary/util/u_clear.h @@ -47,25 +47,24 @@ util_clear(struct pipe_context *pipe, { if (buffers & PIPE_CLEAR_COLOR) { struct pipe_surface *ps = framebuffer->cbufs[0]; + struct pipe_subresource subdst; union util_color uc; + subdst.face = ps->face; + subdst.level = ps->level; util_pack_color(rgba, ps->format, &uc); - if (pipe->surface_fill) { - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, uc.ui); - } else { - util_surface_fill(pipe, ps, 0, 0, ps->width, ps->height, uc.ui); - } + pipe->resource_fill_region(pipe, ps->texture, subdst, 0, 0, ps->zslice, + ps->width, ps->height, uc.ui); } if (buffers & PIPE_CLEAR_DEPTHSTENCIL) { struct pipe_surface *ps = framebuffer->zsbuf; + struct pipe_subresource subdst; - if (pipe->surface_fill) { - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, - util_pack_z_stencil(ps->format, depth, stencil)); - } else { - util_surface_fill(pipe, ps, 0, 0, ps->width, ps->height, - util_pack_z_stencil(ps->format, depth, stencil)); - } + subdst.face = ps->face; + subdst.level = ps->level; + pipe->resource_fill_region(pipe, ps->texture, subdst, 0, 0, ps->zslice, + ps->width, ps->height, + util_pack_z_stencil(ps->format, depth, stencil)); } } diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index eee6030ddcc..48ee0427261 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -1494,7 +1494,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, /* check if we can render in the texture's format */ if (!screen->is_format_supported(screen, psv->format, PIPE_TEXTURE_2D, - PIPE_BIND_RENDER_TARGET, 0)) { + pt->nr_samples, PIPE_BIND_RENDER_TARGET, 0)) { fallback_gen_mipmap(ctx, pt, face, baseLevel, lastLevel); return; } diff --git a/src/gallium/auxiliary/util/u_surface.c b/src/gallium/auxiliary/util/u_surface.c index b47c92ca28f..029bff44eb1 100644 --- a/src/gallium/auxiliary/util/u_surface.c +++ b/src/gallium/auxiliary/util/u_surface.c @@ -70,7 +70,7 @@ util_create_rgba_surface(struct pipe_screen *screen, /* Choose surface format */ for (i = 0; rgbaFormats[i]; i++) { if (screen->is_format_supported(screen, rgbaFormats[i], - target, bind, 0)) { + target, 0, bind, 0)) { format = rgbaFormats[i]; break; } @@ -122,42 +122,42 @@ util_destroy_rgba_surface(struct pipe_resource *texture, /** * Fallback function for pipe->surface_copy(). * Note: (X,Y)=(0,0) is always the upper-left corner. - * if do_flip, flip the image vertically on its way from src rect to dst rect. */ void -util_surface_copy(struct pipe_context *pipe, - boolean do_flip, - struct pipe_surface *dst, - unsigned dst_x, unsigned dst_y, - struct pipe_surface *src, - unsigned src_x, unsigned src_y, - unsigned w, unsigned h) +util_resource_copy_region(struct pipe_context *pipe, + struct pipe_resource *dst, + struct pipe_subresource subdst, + unsigned dst_x, unsigned dst_y, unsigned dst_z, + struct pipe_resource *src, + struct pipe_subresource subsrc, + unsigned src_x, unsigned src_y, unsigned src_z, + unsigned w, unsigned h) { struct pipe_transfer *src_trans, *dst_trans; void *dst_map; const void *src_map; enum pipe_format src_format, dst_format; - assert(src->texture && dst->texture); - if (!src->texture || !dst->texture) + assert(src && dst); + if (!src || !dst) return; - src_format = src->texture->format; - dst_format = dst->texture->format; + src_format = src->format; + dst_format = dst->format; src_trans = pipe_get_transfer(pipe, - src->texture, - src->face, - src->level, - src->zslice, + src, + subsrc.face, + subsrc.level, + src_z, PIPE_TRANSFER_READ, src_x, src_y, w, h); dst_trans = pipe_get_transfer(pipe, - dst->texture, - dst->face, - dst->level, - dst->zslice, + dst, + subdst.face, + subdst.level, + src_z, PIPE_TRANSFER_WRITE, dst_x, dst_y, w, h); @@ -172,16 +172,15 @@ util_surface_copy(struct pipe_context *pipe, assert(dst_map); if (src_map && dst_map) { - /* If do_flip, invert src_y position and pass negative src stride */ util_copy_rect(dst_map, dst_format, dst_trans->stride, 0, 0, w, h, src_map, - do_flip ? -(int) src_trans->stride : src_trans->stride, + src_trans->stride, 0, - do_flip ? h - 1 : 0); + 0); } pipe->transfer_unmap(pipe, src_trans); @@ -200,22 +199,23 @@ util_surface_copy(struct pipe_context *pipe, * Fallback for pipe->surface_fill() function. */ void -util_surface_fill(struct pipe_context *pipe, - struct pipe_surface *dst, - unsigned dstx, unsigned dsty, - unsigned width, unsigned height, unsigned value) +util_resource_fill_region(struct pipe_context *pipe, + struct pipe_resource *dst, + struct pipe_subresource subdst, + unsigned dstx, unsigned dsty, unsigned dstz, + unsigned width, unsigned height, unsigned value) { struct pipe_transfer *dst_trans; void *dst_map; - assert(dst->texture); - if (!dst->texture) + assert(dst); + if (!dst) return; dst_trans = pipe_get_transfer(pipe, - dst->texture, - dst->face, - dst->level, - dst->zslice, + dst, + subdst.face, + subdst.level, + dstz, PIPE_TRANSFER_WRITE, dstx, dsty, width, height); @@ -226,11 +226,11 @@ util_surface_fill(struct pipe_context *pipe, if (dst_map) { assert(dst_trans->stride > 0); - switch (util_format_get_blocksize(dst->texture->format)) { + switch (util_format_get_blocksize(dst->format)) { case 1: case 2: case 4: - util_fill_rect(dst_map, dst->texture->format, + util_fill_rect(dst_map, dst->format, dst_trans->stride, 0, 0, width, height, value); break; diff --git a/src/gallium/auxiliary/util/u_surface.h b/src/gallium/auxiliary/util/u_surface.h index c43169b5278..ccde738ca40 100644 --- a/src/gallium/auxiliary/util/u_surface.h +++ b/src/gallium/auxiliary/util/u_surface.h @@ -33,23 +33,6 @@ #include "pipe/p_state.h" -/** - * Are s1 and s2 the same surface? - * Surfaces are basically views into textures so check if the two surfaces - * name the same part of the same texture. - */ -static INLINE boolean -util_same_surface(const struct pipe_surface *s1, const struct pipe_surface *s2) -{ - return (s1->texture == s2->texture && - s1->face == s2->face && - s1->level == s2->level && - s1->zslice == s2->zslice); -} - - - - extern boolean util_create_rgba_surface(struct pipe_screen *screen, uint width, uint height, uint bind, @@ -64,19 +47,21 @@ util_destroy_rgba_surface(struct pipe_resource *texture, extern void -util_surface_copy(struct pipe_context *pipe, - boolean do_flip, - struct pipe_surface *dst, - unsigned dst_x, unsigned dst_y, - struct pipe_surface *src, - unsigned src_x, unsigned src_y, - unsigned w, unsigned h); +util_resource_copy_region(struct pipe_context *pipe, + struct pipe_resource *dst, + struct pipe_subresource subdst, + unsigned dst_x, unsigned dst_y, unsigned dst_z, + struct pipe_resource *src, + struct pipe_subresource subsrc, + unsigned src_x, unsigned src_y, unsigned src_z, + unsigned w, unsigned h); extern void -util_surface_fill(struct pipe_context *pipe, - struct pipe_surface *dst, - unsigned dstx, unsigned dsty, - unsigned width, unsigned height, unsigned value); +util_resource_fill_region(struct pipe_context *pipe, + struct pipe_resource *dst, + struct pipe_subresource subdst, + unsigned dstx, unsigned dsty, unsigned dstz, + unsigned width, unsigned height, unsigned value);