diff options
author | Christoph Bumiller <[email protected]> | 2010-12-09 14:35:26 +0100 |
---|---|---|
committer | Christoph Bumiller <[email protected]> | 2010-12-09 14:35:26 +0100 |
commit | 7fa7229560d1f3be17199685b34ab254afada24f (patch) | |
tree | 353cac34edce676a66f446d6dea20961ae51b624 | |
parent | 5655f8d42d919270791588162399ac7a2c718733 (diff) |
nvc0: upload constants with m2mf for the time being
I get mysterious lockups with the dedicated CB upload ...
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_context.h | 13 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_state_validate.c | 86 |
2 files changed, 72 insertions, 27 deletions
diff --git a/src/gallium/drivers/nvc0/nvc0_context.h b/src/gallium/drivers/nvc0/nvc0_context.h index 1b2f96429b8..61a9b888786 100644 --- a/src/gallium/drivers/nvc0/nvc0_context.h +++ b/src/gallium/drivers/nvc0/nvc0_context.h @@ -79,6 +79,7 @@ struct nvc0_context { uint8_t num_textures[5]; uint8_t num_samplers[5]; uint16_t scissor; + uint8_t uniform_buffer_bound; /* workaround */ } state; struct nvc0_blend_stateobj *blend; @@ -196,9 +197,15 @@ nvc0_create_sampler_view(struct pipe_context *, const struct pipe_sampler_view *); /* nvc0_transfer.c */ -void nvc0_m2mf_push_linear(struct nvc0_context *nvc0, - struct nouveau_bo *dst, unsigned domain, int offset, - unsigned size, void *data); +void +nvc0_m2mf_push_linear(struct nvc0_context *nvc0, + struct nouveau_bo *dst, unsigned domain, int offset, + unsigned size, void *data); +void +nvc0_m2mf_copy_linear(struct nvc0_context *nvc0, + struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom, + struct nouveau_bo *src, unsigned srcoff, unsigned srcdom, + unsigned size); /* nvc0_vbo.c */ void nvc0_draw_vbo(struct pipe_context *, const struct pipe_draw_info *); diff --git a/src/gallium/drivers/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nvc0/nvc0_state_validate.c index a024831d60a..2b38ebc8ba0 100644 --- a/src/gallium/drivers/nvc0/nvc0_state_validate.c +++ b/src/gallium/drivers/nvc0/nvc0_state_validate.c @@ -231,10 +231,13 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0) for (s = 0; s < 5; ++s) { struct nvc0_resource *res; - int i, j; + int i; while (nvc0->constbuf_dirty[s]) { - unsigned offset = 0; + unsigned base = 0; + unsigned offset = 0, words = 0; + boolean rebind = TRUE; + i = ffs(nvc0->constbuf_dirty[s]) - 1; nvc0->constbuf_dirty[s] &= ~(1 << i); @@ -242,33 +245,70 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0) if (!res) { BEGIN_RING(chan, RING_3D(CB_BIND(s)), 1); OUT_RING (chan, (i << 4) | 0); + if (i == 0) + nvc0->state.uniform_buffer_bound &= ~(1 << s); continue; } - if (i == 0 && !nvc0_resource_mapped_by_gpu(&res->base)) { - offset = s << 16; - bo = nvc0->screen->uniforms; + if (!nvc0_resource_mapped_by_gpu(&res->base)) { + if (i == 0) { + base = s << 16; + bo = nvc0->screen->uniforms; + + if (nvc0->state.uniform_buffer_bound & (1 << s)) + rebind = FALSE; + else + nvc0->state.uniform_buffer_bound |= (1 << s); + } else { + bo = res->bo; + } +#if 1 + nvc0_m2mf_push_linear(nvc0, bo, NOUVEAU_BO_VRAM, + base, res->base.width0, res->data); + BEGIN_RING(chan, RING_3D_(0x021c), 1); + OUT_RING (chan, 0x1111); +#else + words = res->base.width0 / 4; +#endif } else { bo = res->bo; + if (i == 0) + nvc0->state.uniform_buffer_bound &= ~(1 << s); + } + + if (bo != nvc0->screen->uniforms) nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_CONSTANT, res, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + + if (rebind) { + BEGIN_RING(chan, RING_3D(CB_SIZE), 3); + OUT_RING (chan, align(res->base.width0, 0x100)); + OUT_RELOCh(chan, bo, base, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(chan, bo, base, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + BEGIN_RING(chan, RING_3D(CB_BIND(s)), 1); + OUT_RING (chan, (i << 4) | 1); } - BEGIN_RING(chan, RING_3D(CB_SIZE), 3); - OUT_RING (chan, align(res->base.width0, 0x100)); - OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - BEGIN_RING(chan, RING_3D(CB_BIND(s)), 1); - OUT_RING (chan, (i << 4) | 1); - - BEGIN_RING(chan, RING_3D(CB_SIZE), 4); - OUT_RING (chan, align(res->base.width0, 0x100)); - OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); - OUT_RING (chan, 0); - BEGIN_RING_NI(chan, RING_3D(CB_DATA(0)), res->base.width0 / 4); - for (j = 0; j < res->base.width0 / 4; ++j) - OUT_RING(chan, ((uint32_t *)res->data)[j]); + while (words) { + unsigned nr = AVAIL_RING(chan); + + if (nr < 16) { + FIRE_RING(chan); + continue; + } + nr = MIN2(MIN2(nr - 6, words), NV04_PFIFO_MAX_PACKET_LEN - 1); + + BEGIN_RING(chan, RING_3D(CB_SIZE), 3); + OUT_RING (chan, align(res->base.width0, 0x100)); + OUT_RELOCh(chan, bo, base, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RELOCl(chan, bo, base, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + BEGIN_RING_1I(chan, RING_3D(CB_POS), nr + 1); + OUT_RING (chan, offset); + OUT_RINGp (chan, &res->data[offset], nr); + + offset += nr * 4; + words -= nr; + } } } } @@ -293,10 +333,10 @@ static struct state_validate { { nvc0_tevlprog_validate, NVC0_NEW_TEVLPROG }, { nvc0_gmtyprog_validate, NVC0_NEW_GMTYPROG }, { nvc0_fragprog_validate, NVC0_NEW_FRAGPROG }, - { nvc0_vertex_arrays_validate, NVC0_NEW_VERTEX | NVC0_NEW_ARRAYS }, + { nvc0_constbufs_validate, NVC0_NEW_CONSTBUF }, { nvc0_validate_textures, NVC0_NEW_TEXTURES }, { nvc0_validate_samplers, NVC0_NEW_SAMPLERS }, - { nvc0_constbufs_validate, NVC0_NEW_CONSTBUF } + { nvc0_vertex_arrays_validate, NVC0_NEW_VERTEX | NVC0_NEW_ARRAYS } }; #define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0])) @@ -311,8 +351,6 @@ nvc0_state_validate(struct nvc0_context *nvc0) nvc0->screen->cur_ctx = nvc0; if (nvc0->dirty) { - FIRE_RING(nvc0->screen->base.channel); - for (i = 0; i < validate_list_len; ++i) { struct state_validate *validate = &validate_list[i]; |