Module: Mesa
Branch: master
Commit: fba2eabe13b8a3f8c1396c5949db3daab0192156
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=fba2eabe13b8a3f8c1396c5949db3daab0192156

Author: Christoph Bumiller <[email protected]>
Date:   Sat Oct 10 13:13:16 2009 +0200

nv50: use SIFC for TIC, TSC upload

Add proper flushes for TIC and TSC and remove
the costly 2D.0110 flush in nv50_flush.

Correct TIC and TSC bo sizes.

---

 src/gallium/drivers/nv50/nv50_context.c        |    7 ---
 src/gallium/drivers/nv50/nv50_context.h        |    5 ++
 src/gallium/drivers/nv50/nv50_screen.c         |   25 ++---------
 src/gallium/drivers/nv50/nv50_state_validate.c |   54 ++++++++++++++++++++---
 src/gallium/drivers/nv50/nv50_tex.c            |   34 +++++++++------
 src/gallium/drivers/nv50/nv50_vbo.c            |    4 --
 6 files changed, 77 insertions(+), 52 deletions(-)

diff --git a/src/gallium/drivers/nv50/nv50_context.c 
b/src/gallium/drivers/nv50/nv50_context.c
index 7ef27bb..219e7a7 100644
--- a/src/gallium/drivers/nv50/nv50_context.c
+++ b/src/gallium/drivers/nv50/nv50_context.c
@@ -33,13 +33,6 @@ nv50_flush(struct pipe_context *pipe, unsigned flags,
 {
        struct nv50_context *nv50 = nv50_context(pipe);
        struct nouveau_channel *chan = nv50->screen->base.channel;
-       struct nouveau_grobj *eng2d = nv50->screen->eng2d;
-
-       /* We need this in the ddx for reliable composite, not sure what we're
-        * actually flushing. We generate all our own flushes with flags = 0. */
-       WAIT_RING(chan, 2);
-       BEGIN_RING(chan, eng2d, 0x0110, 1);
-       OUT_RING  (chan, 0);
 
        if (flags & PIPE_FLUSH_FRAME)
                FIRE_RING(chan);
diff --git a/src/gallium/drivers/nv50/nv50_context.h 
b/src/gallium/drivers/nv50/nv50_context.h
index fd2dab8..75cb65d 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -199,6 +199,11 @@ extern void nv50_program_destroy(struct nv50_context 
*nv50, struct nv50_program
 extern boolean nv50_state_validate(struct nv50_context *nv50);
 extern void nv50_state_flush_notify(struct nouveau_channel *chan);
 
+extern void nv50_so_init_sifc(struct nv50_context *nv50,
+                             struct nouveau_stateobj *so,
+                             struct nouveau_bo *bo, unsigned reloc,
+                             unsigned size);
+
 /* nv50_tex.c */
 extern void nv50_tex_validate(struct nv50_context *);
 
diff --git a/src/gallium/drivers/nv50/nv50_screen.c 
b/src/gallium/drivers/nv50/nv50_screen.c
index dd7baec..66361dc 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -364,48 +364,31 @@ nv50_screen_create(struct pipe_winsys *ws, struct 
nouveau_device *dev)
        so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
        so_data  (so, 0x00000131 | (NV50_CB_PFP << 12));
 
-       /* Texture sampler/image unit setup - we abuse the constant buffer
-        * upload mechanism for the moment to upload data to the tex config
-        * blocks.  At some point we *may* want to go the NVIDIA way of doing
-        * things?
-        */
-       ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 32*8*4, &screen->tic);
+       ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 64*8*4, &screen->tic);
        if (ret) {
                nv50_screen_destroy(pscreen);
                return NULL;
        }
 
-       so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
-       so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM |
-                 NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
-       so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM |
-                 NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
-       so_data  (so, (NV50_CB_TIC << 16) | 0x0800);
        so_method(so, screen->tesla, NV50TCL_TIC_ADDRESS_HIGH, 3);
        so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM |
                  NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
        so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM |
                  NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
-       so_data  (so, 0x00000800);
+       so_data  (so, 0x000007ff);
 
-       ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 32*8*4, &screen->tsc);
+       ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 64*8*4, &screen->tsc);
        if (ret) {
                nv50_screen_destroy(pscreen);
                return NULL;
        }
 
-       so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
-       so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM |
-                 NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
-       so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM |
-                 NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
-       so_data  (so, (NV50_CB_TSC << 16) | 0x0800);
        so_method(so, screen->tesla, NV50TCL_TSC_ADDRESS_HIGH, 3);
        so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM |
                  NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
        so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM |
                  NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
-       so_data  (so, 0x00000800);
+       so_data  (so, 0x00000000);
 
 
        /* Vertex array limits - max them out */
diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c 
b/src/gallium/drivers/nv50/nv50_state_validate.c
index 9079de9..012911f 100644
--- a/src/gallium/drivers/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nv50/nv50_state_validate.c
@@ -222,6 +222,9 @@ nv50_state_flush_notify(struct nouveau_channel *chan)
 {
        struct nv50_context *nv50 = chan->user_private;
 
+       if (nv50->state.tic_upload && !(nv50->dirty & NV50_NEW_TEXTURE))
+               so_emit(chan, nv50->state.tic_upload);
+
        so_emit_reloc_markers(chan, nv50->state.fb);
        so_emit_reloc_markers(chan, nv50->state.vertprog);
        so_emit_reloc_markers(chan, nv50->state.fragprog);
@@ -233,6 +236,7 @@ boolean
 nv50_state_validate(struct nv50_context *nv50)
 {
        struct nouveau_grobj *tesla = nv50->screen->tesla;
+       struct nouveau_grobj *eng2d = nv50->screen->eng2d;
        struct nouveau_stateobj *so;
        unsigned i;
 
@@ -354,19 +358,25 @@ scissor_uptodate:
 viewport_uptodate:
 
        if (nv50->dirty & NV50_NEW_SAMPLER) {
-               int i;
+               unsigned i;
+
+               so = so_new(nv50->sampler_nr * 9 + 23 + 4, 2);
+
+               nv50_so_init_sifc(nv50, so, nv50->screen->tsc, NOUVEAU_BO_VRAM,
+                                 nv50->sampler_nr * 8 * 4);
 
-               so = so_new(nv50->sampler_nr * 11, 0);
                for (i = 0; i < nv50->sampler_nr; i++) {
                        if (!nv50->sampler[i])
                                continue;
-
-                       so_method(so, tesla, NV50TCL_CB_ADDR, 1);
-                       so_data  (so, ((i * 8) << NV50TCL_CB_ADDR_ID_SHIFT) |
-                                     NV50_CB_TSC);
-                       so_method(so, tesla, NV50TCL_CB_DATA(0) | (2<<29), 8);
+                       so_method(so, eng2d, NV50_2D_SIFC_DATA | (2 << 29), 8);
                        so_datap (so, nv50->sampler[i]->tsc, 8);
                }
+
+               so_method(so, tesla, 0x1440, 1); /* sync SIFC */
+               so_data  (so, 0);
+               so_method(so, tesla, 0x1334, 1); /* flush TSC */
+               so_data  (so, 0);
+
                so_ref(so, &nv50->state.tsc_upload);
                so_ref(NULL, &so);
        }
@@ -384,3 +394,33 @@ viewport_uptodate:
        return TRUE;
 }
 
+void nv50_so_init_sifc(struct nv50_context *nv50,
+                      struct nouveau_stateobj *so,
+                      struct nouveau_bo *bo, unsigned reloc, unsigned size)
+{
+       struct nouveau_grobj *eng2d = nv50->screen->eng2d;
+
+       so_method(so, eng2d, NV50_2D_DST_FORMAT, 2);
+       so_data  (so, NV50_2D_DST_FORMAT_R8_UNORM);
+       so_data  (so, 1);
+       so_method(so, eng2d, NV50_2D_DST_PITCH, 5);
+       so_data  (so, 262144);
+       so_data  (so, 65536);
+       so_data  (so, 1);
+       so_reloc (so, bo, 0, reloc | NOUVEAU_BO_WR | NOUVEAU_BO_HIGH, 0, 0);
+       so_reloc (so, bo, 0, reloc | NOUVEAU_BO_WR | NOUVEAU_BO_LOW, 0, 0);
+       so_method(so, eng2d, NV50_2D_SIFC_UNK0800, 2);
+       so_data  (so, 0);
+       so_data  (so, NV50_2D_SIFC_FORMAT_R8_UNORM);
+       so_method(so, eng2d, NV50_2D_SIFC_WIDTH, 10);
+       so_data  (so, size);
+       so_data  (so, 1);
+       so_data  (so, 0);
+       so_data  (so, 1);
+       so_data  (so, 0);
+       so_data  (so, 1);
+       so_data  (so, 0);
+       so_data  (so, 0);
+       so_data  (so, 0);
+       so_data  (so, 0);
+}
diff --git a/src/gallium/drivers/nv50/nv50_tex.c 
b/src/gallium/drivers/nv50/nv50_tex.c
index 81e0432..e12a6ad 100644
--- a/src/gallium/drivers/nv50/nv50_tex.c
+++ b/src/gallium/drivers/nv50/nv50_tex.c
@@ -98,24 +98,24 @@ nv50_tex_construct(struct nv50_context *nv50, struct 
nouveau_stateobj *so,
 void
 nv50_tex_validate(struct nv50_context *nv50)
 {
+       struct nouveau_grobj *eng2d = nv50->screen->eng2d;
        struct nouveau_grobj *tesla = nv50->screen->tesla;
        struct nouveau_stateobj *so;
-       int unit, push;
+       unsigned i, unit, push;
 
-       push  = nv50->miptree_nr * 11;
-       push += MAX2(nv50->miptree_nr, nv50->state.miptree_nr) * 2;
+       push = MAX2(nv50->miptree_nr, nv50->state.miptree_nr) * 2 + 23 + 6;
+       so = so_new(nv50->miptree_nr * 9 + push, nv50->miptree_nr + 2);
 
-       so = so_new(push, nv50->miptree_nr * 2);
-       for (unit = 0; unit < nv50->miptree_nr; unit++) {
+       nv50_so_init_sifc(nv50, so, nv50->screen->tic, NOUVEAU_BO_VRAM,
+                         nv50->miptree_nr * 8 * 4);
+
+       for (i = 0, unit = 0; unit < nv50->miptree_nr; ++unit) {
                struct nv50_miptree *mt = nv50->miptree[unit];
 
                if (!mt)
                        continue;
 
-               so_method(so, tesla, NV50TCL_CB_ADDR, 1);
-               so_data  (so, ((unit * 8) << NV50TCL_CB_ADDR_ID_SHIFT) |
-                             NV50_CB_TIC);
-               so_method(so, tesla, NV50TCL_CB_DATA(0) | 0x40000000, 8);
+               so_method(so, eng2d, NV50_2D_SIFC_DATA | (2 << 29), 8);
                if (nv50_tex_construct(nv50, so, mt, unit)) {
                        NOUVEAU_ERR("failed tex validate\n");
                        so_ref(NULL, &so);
@@ -123,17 +123,25 @@ nv50_tex_validate(struct nv50_context *nv50)
                }
 
                so_method(so, tesla, NV50TCL_SET_SAMPLER_TEX, 1);
-               so_data  (so, (unit << NV50TCL_SET_SAMPLER_TEX_TIC_SHIFT) |
-                       (unit << NV50TCL_SET_SAMPLER_TEX_SAMPLER_SHIFT) |
-                       NV50TCL_SET_SAMPLER_TEX_VALID);
+               so_data  (so, (i++ << NV50TCL_SET_SAMPLER_TEX_TIC_SHIFT) |
+                         (unit << NV50TCL_SET_SAMPLER_TEX_SAMPLER_SHIFT) |
+                         NV50TCL_SET_SAMPLER_TEX_VALID);
        }
 
        for (; unit < nv50->state.miptree_nr; unit++) {
                so_method(so, tesla, NV50TCL_SET_SAMPLER_TEX, 1);
                so_data  (so,
-                       (unit << NV50TCL_SET_SAMPLER_TEX_SAMPLER_SHIFT) | 0);
+                         (unit << NV50TCL_SET_SAMPLER_TEX_SAMPLER_SHIFT) | 0);
        }
 
+       /* not sure if the following really do what I think: */
+       so_method(so, tesla, 0x1440, 1); /* sync SIFC */
+       so_data  (so, 0);
+       so_method(so, tesla, 0x1330, 1); /* flush TIC */
+       so_data  (so, 0);
+       so_method(so, tesla, 0x1338, 1); /* flush texture caches */
+       so_data  (so, 0x20);
+
        so_ref(so, &nv50->state.tic_upload);
        so_ref(NULL, &so);
        nv50->state.miptree_nr = nv50->miptree_nr;
diff --git a/src/gallium/drivers/nv50/nv50_vbo.c 
b/src/gallium/drivers/nv50/nv50_vbo.c
index eeed148..8b0fbf0 100644
--- a/src/gallium/drivers/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nv50/nv50_vbo.c
@@ -139,10 +139,6 @@ nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, 
unsigned start,
        OUT_RING  (chan, 0);
        BEGIN_RING(chan, tesla, 0x142c, 1);
        OUT_RING  (chan, 0);
-       BEGIN_RING(chan, tesla, 0x1440, 1);
-       OUT_RING  (chan, 0);
-       BEGIN_RING(chan, tesla, 0x1334, 1);
-       OUT_RING  (chan, 0);
 
        BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
        OUT_RING  (chan, nv50_prim(mode));

_______________________________________________
mesa-commit mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to