nv50: emit constbuf relocs before uploading constants
[mesa.git] / src / gallium / drivers / nv50 / nv50_shader_state.c
index 5f70df3662ddeab04aaff5b3f65c34e0bddf1144..7d2989da05b83119cd02fc7eb46a5cda30a970e6 100644 (file)
@@ -27,7 +27,6 @@
 #include "util/u_inlines.h"
 
 #include "nv50_context.h"
-#include "nv50_transfer.h"
 
 static void
 nv50_transfer_constbuf(struct nv50_context *nv50,
@@ -44,14 +43,21 @@ nv50_transfer_constbuf(struct nv50_context *nv50,
    if (!map)
       return;
 
-   count = buf->width0; /* MIN2(buf->width0, size); */
+   count = (buf->width0 + 3) / 4;
    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, 2074);
+
+      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);
@@ -78,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, 2074);
+
+         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);
@@ -112,7 +126,7 @@ nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p)
       break;
    default:
       assert(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;
@@ -350,7 +375,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;
@@ -384,7 +409,7 @@ nv50_pntc_replace(struct nv50_context *nv50, uint32_t pntc[8], unsigned m)
             break;
 
       if (j < vp->out_nr) {
-         ubyte en = nv50->rasterizer->pipe.sprite_coord_enable;
+         uint32_t en = nv50->rasterizer->pipe.sprite_coord_enable;
 
          if (!(en & (1 << vp->out[j].si))) {
             m += n;
@@ -547,7 +572,7 @@ nv50_fp_linkage_validate(struct nv50_context *nv50)
    so_method(so, tesla, NV50TCL_NOPERSPECTIVE_BITMAP(0), 4);
    so_datap (so, lin, 4);
 
-   if (nv50->rasterizer->pipe.sprite_coord_enable) {
+   if (nv50->rasterizer->pipe.point_quad_rasterization) {
       so_method(so, tesla, NV50TCL_POINT_SPRITE_CTRL, 1);
       so_data  (so,
                 nv50_pntc_replace(nv50, pntc, (interp >> 8) & 0xff));