Unfortunately, your patch returns the previous behavior where framebuffer readbacks don&#39;t work sometimes. I think the real issue is somewhere in the buffer management in winsys.<br><br>-Marek<br><br><div class="gmail_quote">

2010/5/14 Michel Dänzer <span dir="ltr">&lt;<a href="mailto:michel@daenzer.net">michel@daenzer.net</a>&gt;</span><br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">

On Don, 2010-05-13 at 12:11 -0700, Marek OlXXXXk wrote:<br>
&gt; Module: Mesa<br>
&gt; Branch: master<br>
&gt; Commit: 60a053510155c119a6927bf7114e597066f8c50a<br>
&gt; URL:    <a href="http://cgit.freedesktop.org/mesa/mesa/commit/?id=60a053510155c119a6927bf7114e597066f8c50a" target="_blank">http://cgit.freedesktop.org/mesa/mesa/commit/?id=60a053510155c119a6927bf7114e597066f8c50a</a><br>


&gt;<br>
&gt; Author: Marek Olšák &lt;<a href="mailto:maraeo@gmail.com">maraeo@gmail.com</a>&gt;<br>
&gt; Date:   Thu May 13 20:32:08 2010 +0200<br>
&gt;<br>
&gt; r300g: fix texture transfers<br>
&gt;<br>
&gt; The regression has first shown up after this state tracker change:<br>
&gt; b0427bedde80e3189524651a327235bdfddbc613.<br>
&gt;<br>
&gt; FDO bug #28082.<br>
<br>
[...]<br>
<br>
&gt; diff --git a/src/gallium/drivers/r300/r300_transfer.c b/src/gallium/drivers/r300/r300_transfer.c<br>
&gt; index 0dae9ef..14a9bfd 100644<br>
&gt; --- a/src/gallium/drivers/r300/r300_transfer.c<br>
&gt; +++ b/src/gallium/drivers/r300/r300_transfer.c<br>
&gt; @@ -127,6 +127,12 @@ r300_texture_get_transfer(struct pipe_context *ctx,<br>
&gt;      struct r300_transfer *trans;<br>
&gt;      struct pipe_resource base;<br>
&gt;<br>
&gt; +    /* XXX Why aren&#39;t flushes taken care of by winsys automatically?<br>
&gt; +     * Winsys seems to sometimes return a cached buffer instead of<br>
&gt; +     * a mapped hardware buffer if this flush is commented out. */<br>
&gt; +    if (ctx-&gt;is_resource_referenced(ctx, texture, sr.face, sr.level))<br>
&gt; +        ctx-&gt;flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);<br>
&gt; +<br>
&gt;      trans = CALLOC_STRUCT(r300_transfer);<br>
&gt;      if (trans) {<br>
&gt;          /* Initialize the transfer object. */<br>
<br>
Presumably the problem is missing flushes before read transfers. Does<br>
something like the patch below work as well? It&#39;s important for st/xorg<br>
at least that write transfers are pipelined.<br>
<br>
Because the state tracker can&#39;t know how the driver implements<br>
transfers, I&#39;m afraid the onus has to be on the driver to flush when<br>
necessary. Maybe there could be helpers for this though.<br>
<br>
<br>
diff --git a/src/gallium/drivers/r300/r300_transfer.c b/src/gallium/drivers/r300/r300_transfer.c<br>
index 14a9bfd..6ff7cf2 100644<br>
--- a/src/gallium/drivers/r300/r300_transfer.c<br>
+++ b/src/gallium/drivers/r300/r300_transfer.c<br>
@@ -126,12 +126,7 @@ r300_texture_get_transfer(struct pipe_context *ctx,<br>
     struct r300_screen *r300screen = r300_screen(ctx-&gt;screen);<br>
     struct r300_transfer *trans;<br>
     struct pipe_resource base;<br>
+    bool referenced = ctx-&gt;is_resource_referenced(ctx, texture, sr.face, sr.level);<br>
<br>
-    /* XXX Why aren&#39;t flushes taken care of by winsys automatically?<br>
-     * Winsys seems to sometimes return a cached buffer instead of<br>
-     * a mapped hardware buffer if this flush is commented out. */<br>
-    if (ctx-&gt;is_resource_referenced(ctx, texture, sr.face, sr.level))<br>
-        ctx-&gt;flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);<br>
-<br>
     trans = CALLOC_STRUCT(r300_transfer);<br>
     if (trans) {<br>
@@ -143,7 +146,8 @@ r300_texture_get_transfer(struct pipe_context *ctx,<br>
<br>
         /* If the texture is tiled, we must create a temporary detiled texture<br>
          * for this transfer. */<br>
-        if (tex-&gt;microtile || tex-&gt;macrotile) {<br>
+        if (tex-&gt;microtile || tex-&gt;macrotile ||<br>
+            (referenced &amp;&amp; !(usage &amp; PIPE_TRANSFER_READ))) {<br>
             trans-&gt;render_target_usage =<br>
                 util_format_is_depth_or_stencil(texture-&gt;format) ?<br>
                 PIPE_BIND_DEPTH_STENCIL :<br>
@@ -193,11 +197,14 @@ r300_texture_get_transfer(struct pipe_context *ctx,<br>
                 /* We cannot map a tiled texture directly because the data is<br>
                  * in a different order, therefore we do detiling using a blit. */<br>
                 r300_copy_from_tiled_texture(ctx, trans);<br>
+                ctx-&gt;flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);<br>
             }<br>
         } else {<br>
             trans-&gt;transfer.stride =<br>
                 r300_texture_get_stride(r300screen, tex, sr.level);<br>
             trans-&gt;offset = r300_texture_get_offset(tex, sr.level, box-&gt;z, sr.face);<br>
+            if (referenced &amp;&amp; (usage &amp; PIPE_TRANSFER_READ))<br>
+                ctx-&gt;flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);<br>
         }<br>
     }<br>
     return &amp;trans-&gt;transfer;<br>
<font color="#888888"><br>
<br>
--<br>
Earthling Michel Dänzer           |                <a href="http://www.vmware.com" target="_blank">http://www.vmware.com</a><br>
Libre software enthusiast         |          Debian, X and DRI developer<br>
</font></blockquote></div><br>