nvc0: set local memory usage info in shader header

Before this, l[] access was a no-op.
This commit is contained in:
Christoph Bumiller 2011-02-24 17:26:44 +01:00
parent b5f04b2008
commit 1a82971393
6 changed files with 34 additions and 3 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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)))