nv50: sync textures with render targets ourselves
authorBen Skeggs <bskeggs@redhat.com>
Tue, 1 Mar 2011 03:09:41 +0000 (13:09 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Tue, 1 Mar 2011 04:44:43 +0000 (14:44 +1000)
Port of the nvc0 commit doing the same.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
src/gallium/drivers/nouveau/nouveau_buffer.c
src/gallium/drivers/nouveau/nouveau_buffer.h
src/gallium/drivers/nv50/nv50_3d.xml.h
src/gallium/drivers/nv50/nv50_screen.h
src/gallium/drivers/nv50/nv50_state_validate.c
src/gallium/drivers/nv50/nv50_tex.c
src/gallium/drivers/nv50/nv50_winsys.h

index 4f4b24f..efb1682 100644 (file)
@@ -112,7 +112,7 @@ nouveau_buffer_download(struct pipe_context *pipe, struct nv04_resource *buf,
    memcpy(buf->data + start, bounce->map, size);
    nouveau_bo_unmap(bounce);
 
-   buf->status &= ~NOUVEAU_BUFFER_STATUS_DIRTY;
+   buf->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
 
    nouveau_bo_ref(NULL, &bounce);
    if (mm)
@@ -152,7 +152,7 @@ nouveau_buffer_upload(struct pipe_context *pipe, struct nv04_resource *buf,
       release_allocation(&mm, screen->fence.current);
 
    if (start == 0 && size == buf->base.width0)
-      buf->status &= ~NOUVEAU_BUFFER_STATUS_DIRTY;
+      buf->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
    return TRUE;
 }
 
@@ -174,7 +174,7 @@ nouveau_buffer_transfer_get(struct pipe_context *pipe,
 
    if (buf->domain == NOUVEAU_BO_VRAM) {
       if (usage & PIPE_TRANSFER_READ) {
-         if (buf->status & NOUVEAU_BUFFER_STATUS_DIRTY)
+         if (buf->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING)
             nouveau_buffer_download(pipe, buf, 0, buf->base.width0);
       }
    }
index d75bc4e..c3e0c2c 100644 (file)
@@ -17,7 +17,8 @@ struct nouveau_bo;
  * USER_MEMORY: resource->data is a pointer to client memory and may change
  *  between GL calls
  */
-#define NOUVEAU_BUFFER_STATUS_DIRTY       (1 << 0)
+#define NOUVEAU_BUFFER_STATUS_GPU_READING (1 << 0)
+#define NOUVEAU_BUFFER_STATUS_GPU_WRITING (1 << 1)
 #define NOUVEAU_BUFFER_STATUS_USER_MEMORY (1 << 7)
 
 /* Resources, if mapped into the GPU's address space, are guaranteed to
@@ -84,7 +85,7 @@ nouveau_resource_map_offset(struct pipe_context *pipe,
    nouveau_buffer_adjust_score(pipe, res, -250);
 
    if ((res->domain == NOUVEAU_BO_VRAM) &&
-       (res->status & NOUVEAU_BUFFER_STATUS_DIRTY))
+       (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING))
       nouveau_buffer_download(pipe, res, 0, res->base.width0);
 
    if ((res->domain != NOUVEAU_BO_GART) ||
index eb05bd4..9bb3211 100644 (file)
@@ -74,7 +74,7 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
 
-
+#define NV50_3D_SERIALIZE              0x00000110
 
 #define NV50_3D_DMA_NOTIFY                                     0x00000180
 
index eb9743a..3886d80 100644 (file)
@@ -93,6 +93,11 @@ nv50_resource_validate(struct nv04_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 |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
+      if (flags & NOUVEAU_BO_RD)
+         res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
+
       nv50_resource_fence(res, flags);
    }
 }
index a8f48b2..c979276 100644 (file)
@@ -8,6 +8,7 @@ nv50_validate_fb(struct nv50_context *nv50)
    struct nouveau_channel *chan = nv50->screen->base.channel;
    struct pipe_framebuffer_state *fb = &nv50->framebuffer;
    unsigned i;
+   boolean serialize = FALSE;
 
    nv50_bufctx_reset(nv50, NV50_BUFCTX_FRAME);
 
@@ -37,6 +38,11 @@ nv50_validate_fb(struct nv50_context *nv50)
       BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1);
       OUT_RING  (chan, sf->depth);
 
+      if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING)
+         serialize = TRUE;
+      mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
+      mt->base.status &= NOUVEAU_BUFFER_STATUS_GPU_READING;
+
       nv50_bufctx_add_resident(nv50, NV50_BUFCTX_FRAME, &mt->base,
                                NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
    }
@@ -62,6 +68,11 @@ nv50_validate_fb(struct nv50_context *nv50)
       OUT_RING  (chan, sf->height);
       OUT_RING  (chan, (unk << 16) | sf->depth);
 
+      if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING)
+         serialize = TRUE;
+      mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
+      mt->base.status &= NOUVEAU_BUFFER_STATUS_GPU_READING;
+
       nv50_bufctx_add_resident(nv50, NV50_BUFCTX_FRAME, &mt->base,
                                NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
    } else {
@@ -72,6 +83,11 @@ nv50_validate_fb(struct nv50_context *nv50)
    BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2);
    OUT_RING  (chan, fb->width << 16);
    OUT_RING  (chan, fb->height << 16);
+
+   if (serialize) {
+      BEGIN_RING(chan, RING_3D(SERIALIZE), 1);
+      OUT_RING  (chan, 0);
+   }
 }
 
 static void
index eaee0a1..a76139a 100644 (file)
@@ -212,9 +212,17 @@ nv50_validate_tic(struct nv50_context *nv50, int s)
          OUT_RINGp (chan, &tic->tic[3], 5);
 
          need_flush = TRUE;
+      } else
+      if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) {
+         BEGIN_RING(chan, RING_3D(TEX_CACHE_CTL), 1);
+         OUT_RING  (chan, 0x20); //(tic->id << 4) | 1);
       }
+
       nv50->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32);
 
+      res->status &= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
+      res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
+
       nv50_bufctx_add_resident(nv50, NV50_BUFCTX_TEXTURES, res,
                                NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
 
index 35e7921..afa2a00 100644 (file)
@@ -81,7 +81,7 @@ OUT_RESRCl(struct nouveau_channel *chan, struct nv04_resource *res,
            unsigned delta, unsigned flags)
 {
    if (flags & NOUVEAU_BO_WR)
-      res->status |= NOUVEAU_BUFFER_STATUS_DIRTY;
+      res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
    return OUT_RELOCl(chan, res->bo, res->offset + delta, res->domain | flags);
 }