This looks good to me.<br><br>Marek<br><br><div class="gmail_quote">On Wed, Mar 9, 2011 at 9:31 PM, Henri Verbeet <span dir="ltr">&lt;<a href="mailto:hverbeet@gmail.com">hverbeet@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">

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