diff options
| -rw-r--r-- | src/gallium/drivers/nvc0/nvc0_context.h | 13 | ||||
| -rw-r--r-- | src/gallium/drivers/nvc0/nvc0_state_validate.c | 84 | 
2 files changed, 71 insertions, 26 deletions
| diff --git a/src/gallium/drivers/nvc0/nvc0_context.h b/src/gallium/drivers/nvc0/nvc0_context.h index 1b2f96429b..61a9b88878 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 a024831d60..2b38ebc8ba 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); +         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); -         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]); +            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]; | 
