Unfortunately, your patch returns the previous behavior where framebuffer readbacks don'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"><<a href="mailto:michel@daenzer.net">michel@daenzer.net</a>></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>
> Module: Mesa<br>
> Branch: master<br>
> Commit: 60a053510155c119a6927bf7114e597066f8c50a<br>
> 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>
><br>
> Author: Marek Olšák <<a href="mailto:maraeo@gmail.com">maraeo@gmail.com</a>><br>
> Date: Thu May 13 20:32:08 2010 +0200<br>
><br>
> r300g: fix texture transfers<br>
><br>
> The regression has first shown up after this state tracker change:<br>
> b0427bedde80e3189524651a327235bdfddbc613.<br>
><br>
> FDO bug #28082.<br>
<br>
[...]<br>
<br>
> diff --git a/src/gallium/drivers/r300/r300_transfer.c b/src/gallium/drivers/r300/r300_transfer.c<br>
> index 0dae9ef..14a9bfd 100644<br>
> --- a/src/gallium/drivers/r300/r300_transfer.c<br>
> +++ b/src/gallium/drivers/r300/r300_transfer.c<br>
> @@ -127,6 +127,12 @@ r300_texture_get_transfer(struct pipe_context *ctx,<br>
> struct r300_transfer *trans;<br>
> struct pipe_resource base;<br>
><br>
> + /* XXX Why aren'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->is_resource_referenced(ctx, texture, sr.face, sr.level))<br>
> + ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);<br>
> +<br>
> trans = CALLOC_STRUCT(r300_transfer);<br>
> if (trans) {<br>
> /* 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's important for st/xorg<br>
at least that write transfers are pipelined.<br>
<br>
Because the state tracker can't know how the driver implements<br>
transfers, I'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->screen);<br>
struct r300_transfer *trans;<br>
struct pipe_resource base;<br>
+ bool referenced = ctx->is_resource_referenced(ctx, texture, sr.face, sr.level);<br>
<br>
- /* XXX Why aren'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->is_resource_referenced(ctx, texture, sr.face, sr.level))<br>
- ctx->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->microtile || tex->macrotile) {<br>
+ if (tex->microtile || tex->macrotile ||<br>
+ (referenced && !(usage & PIPE_TRANSFER_READ))) {<br>
trans->render_target_usage =<br>
util_format_is_depth_or_stencil(texture->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->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);<br>
}<br>
} else {<br>
trans->transfer.stride =<br>
r300_texture_get_stride(r300screen, tex, sr.level);<br>
trans->offset = r300_texture_get_offset(tex, sr.level, box->z, sr.face);<br>
+ if (referenced && (usage & PIPE_TRANSFER_READ))<br>
+ ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);<br>
}<br>
}<br>
return &trans->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>