Mesa (master): nvc0: track texture dirty state individually

Christoph Bumiller chrisbmr at kemper.freedesktop.org
Fri Apr 13 15:16:06 PDT 2012


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

Author: Christoph Bumiller <e0425955 at student.tuwien.ac.at>
Date:   Thu Mar  8 15:56:11 2012 +0100

nvc0: track texture dirty state individually

---

 src/gallium/drivers/nvc0/nvc0_context.h        |   29 ++++++++------
 src/gallium/drivers/nvc0/nvc0_state.c          |   32 ++++++++++-----
 src/gallium/drivers/nvc0/nvc0_state_validate.c |    6 +++
 src/gallium/drivers/nvc0/nvc0_surface.c        |    4 ++
 src/gallium/drivers/nvc0/nvc0_tex.c            |   50 ++++++++++++++++--------
 5 files changed, 81 insertions(+), 40 deletions(-)

diff --git a/src/gallium/drivers/nvc0/nvc0_context.h b/src/gallium/drivers/nvc0/nvc0_context.h
index f6a5055..fdb5889 100644
--- a/src/gallium/drivers/nvc0/nvc0_context.h
+++ b/src/gallium/drivers/nvc0/nvc0_context.h
@@ -52,19 +52,20 @@
 #define NVC0_NEW_TFB_TARGETS  (1 << 21)
 #define NVC0_NEW_IDXBUF       (1 << 22)
 
-#define NVC0_BIND_FB          0
-#define NVC0_BIND_VTX         1
-#define NVC0_BIND_VTX_TMP     2
-#define NVC0_BIND_IDX         3
-#define NVC0_BIND_TEX         4
-#define NVC0_BIND_CB(s, i)   (5 + 16 * (s) + (i))
-#define NVC0_BIND_TFB         85
-#define NVC0_BIND_SCREEN      86
-#define NVC0_BIND_TLS         87
-#define NVC0_BIND_COUNT       88
-#define NVC0_BIND_2D          0
-#define NVC0_BIND_M2MF        0
-#define NVC0_BIND_FENCE       1
+#define NVC0_BIND_FB            0
+#define NVC0_BIND_VTX           1
+#define NVC0_BIND_VTX_TMP       2
+#define NVC0_BIND_IDX           3
+#define NVC0_BIND_TEX(s, i)  (  4 + 32 * (s) + (i))
+#define NVC0_BIND_CB(s, i)   (164 + 16 * (s) + (i))
+#define NVC0_BIND_TFB         244
+#define NVC0_BIND_SCREEN      245
+#define NVC0_BIND_TLS         246
+#define NVC0_BIND_COUNT       247
+
+#define NVC0_BIND_2D            0
+#define NVC0_BIND_M2MF          0
+#define NVC0_BIND_FENCE         1
 
 struct nvc0_context {
    struct nouveau_context base;
@@ -121,8 +122,10 @@ struct nvc0_context {
 
    struct pipe_sampler_view *textures[5][PIPE_MAX_SAMPLERS];
    unsigned num_textures[5];
+   uint32_t textures_dirty[5];
    struct nv50_tsc_entry *samplers[5][PIPE_MAX_SAMPLERS];
    unsigned num_samplers[5];
+   uint16_t samplers_dirty[5];
 
    struct pipe_framebuffer_state framebuffer;
    struct pipe_blend_color blend_colour;
diff --git a/src/gallium/drivers/nvc0/nvc0_state.c b/src/gallium/drivers/nvc0/nvc0_state.c
index b2cd54a..d493f6e 100644
--- a/src/gallium/drivers/nvc0/nvc0_state.c
+++ b/src/gallium/drivers/nvc0/nvc0_state.c
@@ -420,13 +420,20 @@ nvc0_stage_sampler_states_bind(struct nvc0_context *nvc0, int s,
    for (i = 0; i < nr; ++i) {
       struct nv50_tsc_entry *old = nvc0->samplers[s][i];
 
+      if (hwcso[i] == old)
+         continue;
+      nvc0->samplers_dirty[s] |= 1 << i;
+
       nvc0->samplers[s][i] = nv50_tsc_entry(hwcso[i]);
       if (old)
          nvc0_screen_tsc_unlock(nvc0->screen, old);
    }
-   for (; i < nvc0->num_samplers[s]; ++i)
-      if (nvc0->samplers[s][i])
+   for (; i < nvc0->num_samplers[s]; ++i) {
+      if (nvc0->samplers[s][i]) {
          nvc0_screen_tsc_unlock(nvc0->screen, nvc0->samplers[s][i]);
+         nvc0->samplers[s][i] = NULL;
+      }
+   }
 
    nvc0->num_samplers[s] = nr;
 
@@ -472,25 +479,30 @@ nvc0_stage_set_sampler_views(struct nvc0_context *nvc0, int s,
 
    for (i = 0; i < nr; ++i) {
       struct nv50_tic_entry *old = nv50_tic_entry(nvc0->textures[s][i]);
-      if (old)
+
+      if (views[i] == nvc0->textures[s][i])
+         continue;
+      nvc0->textures_dirty[s] |= 1 << i;
+
+      if (old) {
+         nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TEX(s, i));
          nvc0_screen_tic_unlock(nvc0->screen, old);
+      }
 
       pipe_sampler_view_reference(&nvc0->textures[s][i], views[i]);
    }
 
    for (i = nr; i < nvc0->num_textures[s]; ++i) {
       struct nv50_tic_entry *old = nv50_tic_entry(nvc0->textures[s][i]);
-      if (!old)
-         continue;
-      nvc0_screen_tic_unlock(nvc0->screen, old);
-
-      pipe_sampler_view_reference(&nvc0->textures[s][i], NULL);
+      if (old) {
+         nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TEX(s, i));
+         nvc0_screen_tic_unlock(nvc0->screen, old);
+         pipe_sampler_view_reference(&nvc0->textures[s][i], NULL);
+      }
    }
 
    nvc0->num_textures[s] = nr;
 
-   nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TEX);
-
    nvc0->dirty |= NVC0_NEW_TEXTURES;
 }
 
diff --git a/src/gallium/drivers/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nvc0/nvc0_state_validate.c
index 4211fcd..3533a5e 100644
--- a/src/gallium/drivers/nvc0/nvc0_state_validate.c
+++ b/src/gallium/drivers/nvc0/nvc0_state_validate.c
@@ -459,12 +459,18 @@ static void
 nvc0_switch_pipe_context(struct nvc0_context *ctx_to)
 {
    struct nvc0_context *ctx_from = ctx_to->screen->cur_ctx;
+   unsigned s;
 
    if (ctx_from)
       ctx_to->state = ctx_from->state;
 
    ctx_to->dirty = ~0;
 
+   for (s = 0; s < 5; ++s) {
+      ctx_to->samplers_dirty[s] = ~0;
+      ctx_to->textures_dirty[s] = ~0;
+   }
+
    if (!ctx_to->vertex)
       ctx_to->dirty &= ~(NVC0_NEW_VERTEX | NVC0_NEW_ARRAYS);
 
diff --git a/src/gallium/drivers/nvc0/nvc0_surface.c b/src/gallium/drivers/nvc0/nvc0_surface.c
index cb5091a..d1a233f 100644
--- a/src/gallium/drivers/nvc0/nvc0_surface.c
+++ b/src/gallium/drivers/nvc0/nvc0_surface.c
@@ -769,6 +769,8 @@ nvc0_blitctx_pre_blit(struct nvc0_blitctx *blit, struct nvc0_context *nvc0)
    for (s = 0; s <= 4; ++s) {
       blit->saved.num_textures[s] = nvc0->num_textures[s];
       blit->saved.num_samplers[s] = nvc0->num_samplers[s];
+      nvc0->textures_dirty[s] = ~0;
+      nvc0->samplers_dirty[s] = ~0;
    }
    blit->saved.texture = nvc0->textures[4][0];
    blit->saved.sampler = nvc0->samplers[4][0];
@@ -811,6 +813,8 @@ nvc0_blitctx_post_blit(struct nvc0_context *nvc0, struct nvc0_blitctx *blit)
    for (s = 0; s <= 4; ++s) {
       nvc0->num_textures[s] = blit->saved.num_textures[s];
       nvc0->num_samplers[s] = blit->saved.num_samplers[s];
+      nvc0->textures_dirty[s] = ~0;
+      nvc0->samplers_dirty[s] = ~0;
    }
    nvc0->textures[4][0] = blit->saved.texture;
    nvc0->samplers[4][0] = blit->saved.sampler;
diff --git a/src/gallium/drivers/nvc0/nvc0_tex.c b/src/gallium/drivers/nvc0/nvc0_tex.c
index fd58f80..f6c4ab3 100644
--- a/src/gallium/drivers/nvc0/nvc0_tex.c
+++ b/src/gallium/drivers/nvc0/nvc0_tex.c
@@ -206,18 +206,21 @@ nvc0_create_sampler_view(struct pipe_context *pipe,
 static boolean
 nvc0_validate_tic(struct nvc0_context *nvc0, int s)
 {
+   uint32_t commands[32];
    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    struct nouveau_bo *txc = nvc0->screen->txc;
    unsigned i;
+   unsigned n = 0;
    boolean need_flush = FALSE;
 
    for (i = 0; i < nvc0->num_textures[s]; ++i) {
       struct nv50_tic_entry *tic = nv50_tic_entry(nvc0->textures[s][i]);
       struct nv04_resource *res;
+      const boolean dirty = !!(nvc0->textures_dirty[s] & (1 << i));
 
       if (!tic) {
-         BEGIN_NVC0(push, NVC0_3D(BIND_TIC(s)), 1);
-         PUSH_DATA (push, (i << 1) | 0);
+         if (dirty)
+            commands[n++] = (i << 1) | 0;
          continue;
       }
       res = nv04_resource(tic->pipe.texture);
@@ -248,17 +251,23 @@ nvc0_validate_tic(struct nvc0_context *nvc0, int s)
       res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
       res->status |=  NOUVEAU_BUFFER_STATUS_GPU_READING;
 
-      BCTX_REFN(nvc0->bufctx_3d, TEX, res, RD);
+      if (!dirty)
+         continue;
+      commands[n++] = (tic->id << 9) | (i << 1) | 1;
 
-      BEGIN_NVC0(push, NVC0_3D(BIND_TIC(s)), 1);
-      PUSH_DATA (push, (tic->id << 9) | (i << 1) | 1);
-   }
-   for (; i < nvc0->state.num_textures[s]; ++i) {
-      BEGIN_NVC0(push, NVC0_3D(BIND_TIC(s)), 1);
-      PUSH_DATA (push, (i << 1) | 0);
+      BCTX_REFN(nvc0->bufctx_3d, TEX(s, i), res, RD);
    }
+   for (; i < nvc0->state.num_textures[s]; ++i)
+      commands[n++] = (i << 1) | 0;
+
    nvc0->state.num_textures[s] = nvc0->num_textures[s];
 
+   if (n) {
+      BEGIN_NIC0(push, NVC0_3D(BIND_TIC(s)), n);
+      PUSH_DATAp(push, commands, n);
+   }
+   nvc0->textures_dirty[s] = 0;
+
    return need_flush;
 }
 
@@ -279,16 +288,19 @@ void nvc0_validate_textures(struct nvc0_context *nvc0)
 static boolean
 nvc0_validate_tsc(struct nvc0_context *nvc0, int s)
 {
+   uint32_t commands[16];
    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    unsigned i;
+   unsigned n = 0;
    boolean need_flush = FALSE;
 
    for (i = 0; i < nvc0->num_samplers[s]; ++i) {
       struct nv50_tsc_entry *tsc = nv50_tsc_entry(nvc0->samplers[s][i]);
 
+      if (!(nvc0->samplers_dirty[s] & (1 << i)))
+         continue;
       if (!tsc) {
-         BEGIN_NVC0(push, NVC0_3D(BIND_TSC(s)), 1);
-         PUSH_DATA (push, (i << 4) | 0);
+         commands[n++] = (i << 4) | 0;
          continue;
       }
       if (tsc->id < 0) {
@@ -301,15 +313,19 @@ nvc0_validate_tsc(struct nvc0_context *nvc0, int s)
       }
       nvc0->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32);
 
-      BEGIN_NVC0(push, NVC0_3D(BIND_TSC(s)), 1);
-      PUSH_DATA (push, (tsc->id << 12) | (i << 4) | 1);
-   }
-   for (; i < nvc0->state.num_samplers[s]; ++i) {
-      BEGIN_NVC0(push, NVC0_3D(BIND_TSC(s)), 1);
-      PUSH_DATA (push, (i << 4) | 0);
+      commands[n++] = (tsc->id << 12) | (i << 4) | 1;
    }
+   for (; i < nvc0->state.num_samplers[s]; ++i)
+      commands[n++] = (i << 4) | 0;
+
    nvc0->state.num_samplers[s] = nvc0->num_samplers[s];
 
+   if (n) {
+      BEGIN_NIC0(push, NVC0_3D(BIND_TSC(s)), n);
+      PUSH_DATAp(push, commands, n);
+   }
+   nvc0->samplers_dirty[s] = 0;
+
    return need_flush;
 }
 



More information about the mesa-commit mailing list