nvc0: sync textures with render targets ourselves
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Thu, 24 Feb 2011 16:04:49 +0000 (17:04 +0100)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Thu, 24 Feb 2011 16:35:35 +0000 (17:35 +0100)
Fixes for example piglit/fbo-flushing and nexuiz' bloom effect.

src/gallium/drivers/nvc0/nvc0_buffer.c
src/gallium/drivers/nvc0/nvc0_resource.h
src/gallium/drivers/nvc0/nvc0_screen.h
src/gallium/drivers/nvc0/nvc0_state_validate.c
src/gallium/drivers/nvc0/nvc0_tex.c
src/gallium/drivers/nvc0/nvc0_winsys.h

index f16671ac7ffad28fe695f01404f1b2f8300e2366..aa949bdfa36018d15f983028e8216638b87ca07e 100644 (file)
@@ -117,7 +117,7 @@ nvc0_buffer_download(struct nvc0_context *nvc0, struct nvc0_resource *buf,
    memcpy(buf->data + start, bounce->map, size);
    nouveau_bo_unmap(bounce);
 
-   buf->status &= ~NVC0_BUFFER_STATUS_DIRTY;
+   buf->status &= ~NVC0_BUFFER_STATUS_GPU_WRITING;
 
    nouveau_bo_ref(NULL, &bounce);
    if (mm)
@@ -156,7 +156,7 @@ nvc0_buffer_upload(struct nvc0_context *nvc0, struct nvc0_resource *buf,
       release_allocation(&mm, nvc0->screen->fence.current);
 
    if (start == 0 && size == buf->base.width0)
-      buf->status &= ~NVC0_BUFFER_STATUS_DIRTY;
+      buf->status &= ~NVC0_BUFFER_STATUS_GPU_WRITING;
    return TRUE;
 }
 
@@ -179,7 +179,7 @@ nvc0_buffer_transfer_get(struct pipe_context *pipe,
 
    if (buf->domain == NOUVEAU_BO_VRAM) {
       if (usage & PIPE_TRANSFER_READ) {
-         if (buf->status & NVC0_BUFFER_STATUS_DIRTY)
+         if (buf->status & NVC0_BUFFER_STATUS_GPU_WRITING)
             nvc0_buffer_download(nvc0_context(pipe), buf, 0, buf->base.width0);
       }
    }
index 709e6157f55e00061e9b565554d8348b5dedb971..599823c0dc9b69b057943df44317a05910d81f67 100644 (file)
@@ -24,7 +24,8 @@ struct nvc0_context;
  * USER_MEMORY: resource->data is a pointer to client memory and may change
  *  between GL calls
  */
-#define NVC0_BUFFER_STATUS_DIRTY       (1 << 0)
+#define NVC0_BUFFER_STATUS_GPU_READING (1 << 0)
+#define NVC0_BUFFER_STATUS_GPU_WRITING (1 << 1)
 #define NVC0_BUFFER_STATUS_USER_MEMORY (1 << 7)
 
 /* Resources, if mapped into the GPU's address space, are guaranteed to
@@ -90,7 +91,7 @@ nvc0_resource_map_offset(struct nvc0_context *nvc0,
    nvc0_buffer_adjust_score(nvc0, res, -250);
 
    if ((res->domain == NOUVEAU_BO_VRAM) &&
-       (res->status & NVC0_BUFFER_STATUS_DIRTY))
+       (res->status & NVC0_BUFFER_STATUS_GPU_WRITING))
       nvc0_buffer_download(nvc0, res, 0, res->base.width0);
 
    if ((res->domain != NOUVEAU_BO_GART) ||
index 5af96cbacea791c487abb6bd4ead7000f5fb7834..d952ff1f9b13894ecc36fe046b01e389aff2c3a7 100644 (file)
@@ -131,6 +131,11 @@ nvc0_resource_validate(struct nvc0_resource *res, uint32_t flags)
    if (likely(res->bo)) {
       nouveau_bo_validate(screen->base.channel, res->bo, flags);
 
+      if (flags & NOUVEAU_BO_WR)
+         res->status |= NVC0_BUFFER_STATUS_GPU_WRITING;
+      if (flags & NOUVEAU_BO_RD)
+         res->status |= NVC0_BUFFER_STATUS_GPU_READING;
+
       nvc0_resource_fence(res, flags);
    }
 }
index 96c1198d4cb0a1f057d432d2e1c230cb1be8fca5..0cc0a0c623685acdc67bbdfc4af7616e46f0f8b8 100644 (file)
@@ -58,6 +58,7 @@ nvc0_validate_fb(struct nvc0_context *nvc0)
     struct nouveau_channel *chan = nvc0->screen->base.channel;
     struct pipe_framebuffer_state *fb = &nvc0->framebuffer;
     unsigned i;
+    boolean serialize = FALSE;
 
     nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_FRAME);
 
@@ -86,6 +87,11 @@ nvc0_validate_fb(struct nvc0_context *nvc0)
         OUT_RING  (chan, sf->depth);
         OUT_RING  (chan, mt->layer_stride >> 2);
 
+        if (mt->base.status & NVC0_BUFFER_STATUS_GPU_READING)
+           serialize = TRUE;
+        mt->base.status |=  NVC0_BUFFER_STATUS_GPU_WRITING;
+        mt->base.status &= ~NVC0_BUFFER_STATUS_GPU_READING;
+
         nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_FRAME, &mt->base,
                                  NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
     }
@@ -111,12 +117,22 @@ nvc0_validate_fb(struct nvc0_context *nvc0)
         OUT_RING  (chan, sf->height);
         OUT_RING  (chan, (unk << 16) | sf->depth);
 
+        if (mt->base.status & NVC0_BUFFER_STATUS_GPU_READING)
+           serialize = TRUE;
+        mt->base.status |=  NVC0_BUFFER_STATUS_GPU_WRITING;
+        mt->base.status &= ~NVC0_BUFFER_STATUS_GPU_READING;
+
         nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_FRAME, &mt->base,
                                  NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
     } else {
         BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
         OUT_RING  (chan, 0);
     }
+
+    if (serialize) {
+       BEGIN_RING(chan, RING_3D(SERIALIZE), 1);
+       OUT_RING  (chan, 0);
+    }
 }
 
 static void
index b219f82c903cf504e54e1d723b1154a3c862a57f..968558a5869d12ac27f922af40aeb28e5a931655 100644 (file)
@@ -196,9 +196,16 @@ nvc0_validate_tic(struct nvc0_context *nvc0, int s)
          OUT_RINGp (chan, &tic->tic[3], 5);
 
          need_flush = TRUE;
+      } else
+      if (res->status & NVC0_BUFFER_STATUS_GPU_WRITING) {
+         BEGIN_RING(chan, RING_3D(TEX_CACHE_CTL), 1);
+         OUT_RING  (chan, (tic->id << 4) | 1);
       }
       nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32);
 
+      res->status &= ~NVC0_BUFFER_STATUS_GPU_WRITING;
+      res->status |=  NVC0_BUFFER_STATUS_GPU_READING;
+
       nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_TEXTURES, res,
                                NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
 
index 1544fb7a1de20a6bd87b8bbff9dc0d7653cee02e..45f71967eff9b573ee6894d066654b49808c6e57 100644 (file)
@@ -95,7 +95,7 @@ OUT_RESRCl(struct nouveau_channel *chan, struct nvc0_resource *res,
            unsigned delta, unsigned flags)
 {
    if (flags & NOUVEAU_BO_WR)
-      res->status |= NVC0_BUFFER_STATUS_DIRTY;
+      res->status |= NVC0_BUFFER_STATUS_GPU_WRITING;
    return OUT_RELOCl(chan, res->bo, res->offset + delta, res->domain | flags);
 }