From 1a8297139396ec2a6415ef803a3901e1ecef485c Mon Sep 17 00:00:00 2001
From: Christoph Bumiller <e0425955@student.tuwien.ac.at>
Date: Thu, 24 Feb 2011 17:26:44 +0100
Subject: nvc0: set local memory usage info in shader header

Before this, l[] access was a no-op.
---
 src/gallium/drivers/nvc0/nvc0_context.h      |  1 +
 src/gallium/drivers/nvc0/nvc0_program.c      |  9 ++++++++-
 src/gallium/drivers/nvc0/nvc0_program.h      |  1 +
 src/gallium/drivers/nvc0/nvc0_screen.c       |  8 ++++++--
 src/gallium/drivers/nvc0/nvc0_shader_state.c | 15 +++++++++++++++
 src/gallium/drivers/nvc0/nvc0_tgsi_to_nc.c   |  3 +++
 6 files changed, 34 insertions(+), 3 deletions(-)

(limited to 'src/gallium/drivers')

diff --git a/src/gallium/drivers/nvc0/nvc0_context.h b/src/gallium/drivers/nvc0/nvc0_context.h
index 3722f358d89..1ce5554f7b7 100644
--- a/src/gallium/drivers/nvc0/nvc0_context.h
+++ b/src/gallium/drivers/nvc0/nvc0_context.h
@@ -81,6 +81,7 @@ struct nvc0_context {
       uint8_t num_vtxelts;
       uint8_t num_textures[5];
       uint8_t num_samplers[5];
+      uint8_t tls_required; /* bitmask of shader types using l[] */
       uint16_t scissor;
       uint32_t uniform_buffer_bound[5];
    } state;
diff --git a/src/gallium/drivers/nvc0/nvc0_program.c b/src/gallium/drivers/nvc0/nvc0_program.c
index f7ea97ddb1d..0685a842304 100644
--- a/src/gallium/drivers/nvc0/nvc0_program.c
+++ b/src/gallium/drivers/nvc0/nvc0_program.c
@@ -301,9 +301,11 @@ prog_decl(struct nvc0_translation_info *ti,
       ti->sysval_loc[i] = nvc0_system_value_location(sn, si, &ti->sysval_in[i]);
       assert(first == last);
       break;
+   case TGSI_FILE_TEMPORARY:
+      ti->temp128_nr = MAX2(ti->temp128_nr, last + 1);
+      break;
    case TGSI_FILE_NULL:
    case TGSI_FILE_CONSTANT:
-   case TGSI_FILE_TEMPORARY:
    case TGSI_FILE_SAMPLER:
    case TGSI_FILE_ADDRESS:
    case TGSI_FILE_IMMEDIATE:
@@ -644,6 +646,11 @@ nvc0_prog_scan(struct nvc0_translation_info *ti)
       break;
    }
 
+   if (ti->require_stores) {
+      prog->hdr[0] |= 1 << 26;
+      prog->hdr[1] |= ti->temp128_nr * 16; /* l[] size */
+   }
+
    assert(!ret);
    return ret;
 }
diff --git a/src/gallium/drivers/nvc0/nvc0_program.h b/src/gallium/drivers/nvc0/nvc0_program.h
index 3450cec175d..f6fea29780b 100644
--- a/src/gallium/drivers/nvc0/nvc0_program.h
+++ b/src/gallium/drivers/nvc0/nvc0_program.h
@@ -76,6 +76,7 @@ struct nvc0_translation_info {
    uint32_t *immd32;
    ubyte *immd32_ty;
    unsigned immd32_nr;
+   unsigned temp128_nr;
    ubyte edgeflag_out;
    struct nvc0_subroutine *subr;
    unsigned num_subrs;
diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c
index 321d86bdf1a..f7f1fd09a12 100644
--- a/src/gallium/drivers/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nvc0/nvc0_screen.c
@@ -475,7 +475,7 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
       OUT_RING  (chan, (15 << 4) | 1);
    }
 
-   screen->tls_size = 4 * 4 * 32 * 128 * 4;
+   screen->tls_size = (16 * 32) * (NVC0_CAP_MAX_PROGRAM_TEMPS * 16);
    ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17,
                         screen->tls_size, &screen->tls);
    if (ret)
@@ -489,6 +489,8 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
    OUT_RELOCl(chan, screen->tls, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
    OUT_RING  (chan, screen->tls_size >> 32);
    OUT_RING  (chan, screen->tls_size);
+   BEGIN_RING(chan, RING_3D_(0x07a0), 1);
+   OUT_RING  (chan, 0);
    BEGIN_RING(chan, RING_3D(LOCAL_BASE), 1);
    OUT_RING  (chan, 0);
 
@@ -642,8 +644,10 @@ nvc0_screen_make_buffers_resident(struct nvc0_screen *screen)
    nouveau_bo_validate(chan, screen->text, flags);
    nouveau_bo_validate(chan, screen->uniforms, flags);
    nouveau_bo_validate(chan, screen->txc, flags);
-   nouveau_bo_validate(chan, screen->tls, flags);
    nouveau_bo_validate(chan, screen->mp_stack_bo, flags);
+
+   if (screen->cur_ctx && screen->cur_ctx->state.tls_required)
+      nouveau_bo_validate(chan, screen->tls, flags);
 }
 
 int
diff --git a/src/gallium/drivers/nvc0/nvc0_shader_state.c b/src/gallium/drivers/nvc0/nvc0_shader_state.c
index 633641713dc..357f8b80deb 100644
--- a/src/gallium/drivers/nvc0/nvc0_shader_state.c
+++ b/src/gallium/drivers/nvc0/nvc0_shader_state.c
@@ -27,6 +27,16 @@
 
 #include "nvc0_context.h"
 
+static INLINE void
+nvc0_program_update_context_state(struct nvc0_context *nvc0,
+                                  struct nvc0_program *prog, int stage)
+{
+   if (prog->hdr[1])
+      nvc0->state.tls_required |= 1 << stage;
+   else
+      nvc0->state.tls_required &= ~(1 << stage);
+}
+
 static boolean
 nvc0_program_validate(struct nvc0_context *nvc0, struct nvc0_program *prog)
 {
@@ -77,6 +87,7 @@ nvc0_vertprog_validate(struct nvc0_context *nvc0)
 
    if (!nvc0_program_validate(nvc0, vp))
          return;
+   nvc0_program_update_context_state(nvc0, vp, 0);
 
    BEGIN_RING(chan, RING_3D(SP_SELECT(1)), 2);
    OUT_RING  (chan, 0x11);
@@ -98,6 +109,7 @@ nvc0_fragprog_validate(struct nvc0_context *nvc0)
 
    if (!nvc0_program_validate(nvc0, fp))
          return;
+   nvc0_program_update_context_state(nvc0, fp, 4);
 
    BEGIN_RING(chan, RING_3D(EARLY_FRAGMENT_TESTS), 1);
    OUT_RING  (chan, fp->fp.early_z);
@@ -127,6 +139,7 @@ nvc0_tctlprog_validate(struct nvc0_context *nvc0)
    }
    if (!nvc0_program_validate(nvc0, tp))
          return;
+   nvc0_program_update_context_state(nvc0, tp, 1);
 
    BEGIN_RING(chan, RING_3D(SP_SELECT(2)), 2);
    OUT_RING  (chan, 0x21);
@@ -148,6 +161,7 @@ nvc0_tevlprog_validate(struct nvc0_context *nvc0)
    }
    if (!nvc0_program_validate(nvc0, tp))
          return;
+   nvc0_program_update_context_state(nvc0, tp, 2);
 
    BEGIN_RING(chan, RING_3D(TEP_SELECT), 1);
    OUT_RING  (chan, 0x31);
@@ -170,6 +184,7 @@ nvc0_gmtyprog_validate(struct nvc0_context *nvc0)
    }
    if (!nvc0_program_validate(nvc0, gp))
          return;
+   nvc0_program_update_context_state(nvc0, gp, 3);
 
    BEGIN_RING(chan, RING_3D(GP_SELECT), 1);
    OUT_RING  (chan, 0x41);
diff --git a/src/gallium/drivers/nvc0/nvc0_tgsi_to_nc.c b/src/gallium/drivers/nvc0/nvc0_tgsi_to_nc.c
index fc19ef1eb19..f7dff596c28 100644
--- a/src/gallium/drivers/nvc0/nvc0_tgsi_to_nc.c
+++ b/src/gallium/drivers/nvc0/nvc0_tgsi_to_nc.c
@@ -364,6 +364,9 @@ bld_loop_phi(struct bld_context *bld, struct bld_register *reg,
    struct nv_basic_block *bb = bld->pc->current_block;
    struct nv_value *val = NULL;
 
+   if (bld->ti->require_stores) /* XXX: actually only for INDEXABLE_TEMP */
+      return NULL;
+
    if (bld->loop_lvl > 1) {
       --bld->loop_lvl;
       if (!((reg->loop_def | reg->loop_use) & (1 << bld->loop_lvl)))
-- 
cgit v1.2.3