diff options
Diffstat (limited to 'src/gallium/drivers/nv50/nv50_shader_state.c')
-rw-r--r-- | src/gallium/drivers/nv50/nv50_shader_state.c | 49 |
1 files changed, 39 insertions, 10 deletions
diff --git a/src/gallium/drivers/nv50/nv50_shader_state.c b/src/gallium/drivers/nv50/nv50_shader_state.c index 8c1a5999cfe..6c41e8f4561 100644 --- a/src/gallium/drivers/nv50/nv50_shader_state.c +++ b/src/gallium/drivers/nv50/nv50_shader_state.c @@ -47,10 +47,17 @@ nv50_transfer_constbuf(struct nv50_context *nv50, start = 0; while (count) { - unsigned nr = count; - nr = MIN2(nr, 2047); + unsigned nr = AVAIL_RING(chan); + + if (nr < 8) { + FIRE_RING(chan); + continue; + } + nr = MIN2(count, nr - 7); + nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN); + + nv50_screen_reloc_constbuf(nv50->screen, cbi); - /* FIXME: emit relocs for unsuiTed MM */ BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 1); OUT_RING (chan, (start << 8) | cbi); BEGIN_RING_NI(chan, tesla, NV50TCL_CB_DATA(0), nr); @@ -77,8 +84,16 @@ nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p) unsigned start = 0; while (count) { - unsigned nr = count; - nr = MIN2(nr, 2047); + unsigned nr = AVAIL_RING(chan); + + if (nr < 8) { + FIRE_RING(chan); + continue; + } + nr = MIN2(count, nr - 7); + nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN); + + nv50_screen_reloc_constbuf(nv50->screen, NV50_CB_PMISC); BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 1); OUT_RING (chan, (start << 8) | NV50_CB_PMISC); @@ -111,8 +126,7 @@ nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p) break; default: assert(0); - cbi = 0; - break; + return; } nv50_transfer_constbuf(nv50, nv50->constbuf[p->type], p->parm_size, cbi); @@ -281,6 +295,17 @@ nv50_program_validate(struct nv50_program *p) return p->translated; } +static INLINE void +nv50_program_validate_common(struct nv50_context *nv50, struct nv50_program *p) +{ + nv50_program_validate_code(nv50, p); + + if (p->uses_lmem) + nv50->req_lmem |= 1 << p->type; + else + nv50->req_lmem &= ~(1 << p->type); +} + struct nouveau_stateobj * nv50_vertprog_validate(struct nv50_context *nv50) { @@ -300,7 +325,7 @@ nv50_vertprog_validate(struct nv50_context *nv50) if (!(nv50->dirty & NV50_NEW_VERTPROG)) return NULL; - nv50_program_validate_code(nv50, p); + nv50_program_validate_common(nv50, p); so_ref(p->so, &so); return so; @@ -325,7 +350,7 @@ nv50_fragprog_validate(struct nv50_context *nv50) if (!(nv50->dirty & NV50_NEW_FRAGPROG)) return NULL; - nv50_program_validate_code(nv50, p); + nv50_program_validate_common(nv50, p); so_ref(p->so, &so); return so; @@ -337,6 +362,10 @@ nv50_geomprog_validate(struct nv50_context *nv50) struct nv50_program *p = nv50->geomprog; struct nouveau_stateobj *so = NULL; + /* GP may be NULL, but VP and FP may not */ + if (!p) + return NULL; /* GP is deactivated in linkage validation */ + if (!p->translated) { if (nv50_program_validate(p)) nv50_gp_update_stateobj(nv50, p); @@ -350,7 +379,7 @@ nv50_geomprog_validate(struct nv50_context *nv50) if (!(nv50->dirty & NV50_NEW_GEOMPROG)) return NULL; - nv50_program_validate_code(nv50, p); + nv50_program_validate_common(nv50, p); so_ref(p->so, &so); return so; |