[Mesa-dev] [PATCH] u_blitter: Do blits in linear color space.

Marek Olšák maraeo at gmail.com
Thu Mar 10 10:32:30 PST 2011


This looks good to me.

Marek

On Wed, Mar 9, 2011 at 9:31 PM, Henri Verbeet <hverbeet at gmail.com> wrote:

> Blits between sRGB and linear formats should happen in linear color space.
> This fixes piglit fbo/fbo-srgb-blit.
> ---
>  src/gallium/auxiliary/util/u_blit.c    |   57
> ++++++++++++++++++++------------
>  src/gallium/auxiliary/util/u_blitter.c |    3 +-
>  src/mesa/state_tracker/st_cb_texture.c |    2 +-
>  3 files changed, 39 insertions(+), 23 deletions(-)
>
> diff --git a/src/gallium/auxiliary/util/u_blit.c
> b/src/gallium/auxiliary/util/u_blit.c
> index 76bd7ac..3618353 100644
> --- a/src/gallium/auxiliary/util/u_blit.c
> +++ b/src/gallium/auxiliary/util/u_blit.c
> @@ -304,8 +304,10 @@ util_blit_pixels_writemask(struct blit_state *ctx,
>  {
>    struct pipe_context *pipe = ctx->pipe;
>    struct pipe_screen *screen = pipe->screen;
> +   enum pipe_format src_format, dst_format;
>    struct pipe_sampler_view *sampler_view = NULL;
>    struct pipe_sampler_view sv_templ;
> +   struct pipe_surface *dst_surface;
>    struct pipe_framebuffer_state fb;
>    const int srcW = abs(srcX1 - srcX0);
>    const int srcH = abs(srcY1 - srcY0);
> @@ -326,12 +328,15 @@ util_blit_pixels_writemask(struct blit_state *ctx,
>       regions_overlap(srcX0, srcY0, srcX1, srcY1,
>                       dstX0, dstY0, dstX1, dstY1);
>
> +   src_format = util_format_linear(src_tex->format);
> +   dst_format = util_format_linear(dst->format);
> +
>    /*
>     * Check for simple case:  no format conversion, no flipping, no
> stretching,
>     * no overlapping.
>     * Filter mode should not matter since there's no stretching.
>     */
> -   if (dst->format == src_tex->format &&
> +   if (dst_format == src_format &&
>        srcX0 < srcX1 &&
>        dstX0 < dstX1 &&
>        srcY0 < srcY1 &&
> @@ -354,6 +359,14 @@ util_blit_pixels_writemask(struct blit_state *ctx,
>        return;
>    }
>
> +   if (dst_format == dst->format) {
> +      dst_surface = dst;
> +   } else {
> +      struct pipe_surface templ = *dst;
> +      templ.format = dst_format;
> +      dst_surface = pipe->create_surface(pipe, dst->texture, &templ);
> +   }
> +
>    /* Create a temporary texture when src and dest alias or when src
>     * is anything other than a 2d texture.
>     * XXX should just use appropriate shader to access 1d / 3d slice / cube
> face,
> @@ -361,9 +374,9 @@ util_blit_pixels_writemask(struct blit_state *ctx,
>     *
>     * This can still be improved upon.
>     */
> -   if ((src_tex == dst->texture &&
> -       dst->u.tex.level == src_level &&
> -       dst->u.tex.first_layer == srcZ0) ||
> +   if ((src_tex == dst_surface->texture &&
> +       dst_surface->u.tex.level == src_level &&
> +       dst_surface->u.tex.first_layer == srcZ0) ||
>        (src_tex->target != PIPE_TEXTURE_2D &&
>        src_tex->target != PIPE_TEXTURE_2D &&
>        src_tex->target != PIPE_TEXTURE_RECT))
> @@ -392,7 +405,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
>       /* create temp texture */
>       memset(&texTemp, 0, sizeof(texTemp));
>       texTemp.target = ctx->internal_target;
> -      texTemp.format = src_tex->format;
> +      texTemp.format = src_format;
>       texTemp.last_level = 0;
>       texTemp.width0 = srcW;
>       texTemp.height0 = srcH;
> @@ -439,7 +452,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
>       pipe_resource_reference(&tex, NULL);
>    }
>    else {
> -      u_sampler_view_default_template(&sv_templ, src_tex,
> src_tex->format);
> +      u_sampler_view_default_template(&sv_templ, src_tex, src_format);
>       sampler_view = pipe->create_sampler_view(pipe, src_tex, &sv_templ);
>
>       if (!sampler_view) {
> @@ -460,13 +473,13 @@ util_blit_pixels_writemask(struct blit_state *ctx,
>       }
>    }
>
> -   dst_is_depth = util_format_is_depth_or_stencil(dst->format);
> +   dst_is_depth = util_format_is_depth_or_stencil(dst_format);
>
>    assert(screen->is_format_supported(screen, sampler_view->format,
> ctx->internal_target,
>                                       sampler_view->texture->nr_samples,
>                                       PIPE_BIND_SAMPLER_VIEW, 0));
> -   assert(screen->is_format_supported(screen, dst->format,
> ctx->internal_target,
> -                                      dst->texture->nr_samples,
> +   assert(screen->is_format_supported(screen, dst_format,
> ctx->internal_target,
> +                                      dst_surface->texture->nr_samples,
>                                       dst_is_depth ?
> PIPE_BIND_DEPTH_STENCIL :
>
>  PIPE_BIND_RENDER_TARGET, 0));
>    /* save state (restored below) */
> @@ -502,12 +515,12 @@ util_blit_pixels_writemask(struct blit_state *ctx,
>    cso_single_sampler_done(ctx->cso);
>
>    /* viewport */
> -   ctx->viewport.scale[0] = 0.5f * dst->width;
> -   ctx->viewport.scale[1] = 0.5f * dst->height;
> +   ctx->viewport.scale[0] = 0.5f * dst_surface->width;
> +   ctx->viewport.scale[1] = 0.5f * dst_surface->height;
>    ctx->viewport.scale[2] = 0.5f;
>    ctx->viewport.scale[3] = 1.0f;
> -   ctx->viewport.translate[0] = 0.5f * dst->width;
> -   ctx->viewport.translate[1] = 0.5f * dst->height;
> +   ctx->viewport.translate[0] = 0.5f * dst_surface->width;
> +   ctx->viewport.translate[1] = 0.5f * dst_surface->height;
>    ctx->viewport.translate[2] = 0.5f;
>    ctx->viewport.translate[3] = 0.0f;
>    cso_set_viewport(ctx->cso, &ctx->viewport);
> @@ -536,22 +549,22 @@ util_blit_pixels_writemask(struct blit_state *ctx,
>
>    /* drawing dest */
>    memset(&fb, 0, sizeof(fb));
> -   fb.width = dst->width;
> -   fb.height = dst->height;
> +   fb.width = dst_surface->width;
> +   fb.height = dst_surface->height;
>    if (dst_is_depth) {
> -      fb.zsbuf = dst;
> +      fb.zsbuf = dst_surface;
>    } else {
>       fb.nr_cbufs = 1;
> -      fb.cbufs[0] = dst;
> +      fb.cbufs[0] = dst_surface;
>    }
>    cso_set_framebuffer(ctx->cso, &fb);
>
>    /* draw quad */
>    offset = setup_vertex_data_tex(ctx,
> -                                  (float) dstX0 / dst->width * 2.0f -
> 1.0f,
> -                                  (float) dstY0 / dst->height * 2.0f -
> 1.0f,
> -                                  (float) dstX1 / dst->width * 2.0f -
> 1.0f,
> -                                  (float) dstY1 / dst->height * 2.0f -
> 1.0f,
> +                                  (float) dstX0 / dst_surface->width *
> 2.0f - 1.0f,
> +                                  (float) dstY0 / dst_surface->height *
> 2.0f - 1.0f,
> +                                  (float) dstX1 / dst_surface->width *
> 2.0f - 1.0f,
> +                                  (float) dstY1 / dst_surface->height *
> 2.0f - 1.0f,
>                                   s0, t0,
>                                   s1, t1,
>                                   z);
> @@ -576,6 +589,8 @@ util_blit_pixels_writemask(struct blit_state *ctx,
>    cso_restore_vertex_buffers(ctx->cso);
>
>    pipe_sampler_view_reference(&sampler_view, NULL);
> +   if (dst_surface != dst)
> +      pipe_surface_reference(&dst_surface, NULL);
>  }
>
>
> diff --git a/src/gallium/auxiliary/util/u_blitter.c
> b/src/gallium/auxiliary/util/u_blitter.c
> index fd1c2b7..287f5da 100644
> --- a/src/gallium/auxiliary/util/u_blitter.c
> +++ b/src/gallium/auxiliary/util/u_blitter.c
> @@ -785,6 +785,7 @@ void util_blitter_copy_region(struct blitter_context
> *blitter,
>    /* Get surface. */
>    memset(&surf_templ, 0, sizeof(surf_templ));
>    u_surface_default_template(&surf_templ, dst, bind);
> +   surf_templ.format = util_format_linear(dst->format);
>    surf_templ.u.tex.level = dstlevel;
>    surf_templ.u.tex.first_layer = dstz;
>    surf_templ.u.tex.last_layer = dstz;
> @@ -823,7 +824,7 @@ void util_blitter_copy_region(struct blitter_context
> *blitter,
>    normalized = src->target != PIPE_TEXTURE_RECT;
>
>    /* Initialize sampler view. */
> -   u_sampler_view_default_template(&viewTempl, src, src->format);
> +   u_sampler_view_default_template(&viewTempl, src,
> util_format_linear(src->format));
>    view = pipe->create_sampler_view(pipe, src, &viewTempl);
>
>    /* Set rasterizer state, shaders, and textures. */
> diff --git a/src/mesa/state_tracker/st_cb_texture.c
> b/src/mesa/state_tracker/st_cb_texture.c
> index 3f98ffd..ab2d645 100644
> --- a/src/mesa/state_tracker/st_cb_texture.c
> +++ b/src/mesa/state_tracker/st_cb_texture.c
> @@ -1533,7 +1533,7 @@ st_copy_texsubimage(struct gl_context *ctx,
>          GLint srcY0, srcY1;
>          struct pipe_surface surf_tmpl;
>          memset(&surf_tmpl, 0, sizeof(surf_tmpl));
> -         surf_tmpl.format = stImage->pt->format;
> +         surf_tmpl.format = util_format_linear(stImage->pt->format);
>          surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
>          surf_tmpl.u.tex.level = stImage->level;
>          surf_tmpl.u.tex.first_layer = stImage->face + destZ;
> --
> 1.7.2.3
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20110310/c2e59d2a/attachment.html>


More information about the mesa-dev mailing list