nv50: add preliminary support for point sprites
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Mon, 14 Sep 2009 19:03:19 +0000 (21:03 +0200)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Tue, 15 Sep 2009 10:13:23 +0000 (12:13 +0200)
src/gallium/drivers/nv50/nv50_program.c
src/gallium/drivers/nv50/nv50_screen.c
src/gallium/drivers/nv50/nv50_state.c

index 58df4a08dc900fcf98e9ee023d3e712a8d555c6e..80a32f58cb75ba0abbac900b167ccc9fecdaea31 100644 (file)
@@ -2704,6 +2704,52 @@ nv50_fragprog_validate(struct nv50_context *nv50)
        so_ref(NULL, &so);
 }
 
+static void
+nv50_pntc_replace(struct nv50_context *nv50, uint32_t pntc[8], unsigned base)
+{
+       struct nv50_program *fp = nv50->fragprog;
+       struct nv50_program *vp = nv50->vertprog;
+       unsigned i, c, m = base;
+
+       /* XXX: This can't work correctly in all cases yet, we either
+        * have to create TGSI_SEMANTIC_PNTC or sprite_coord_mode has
+        * to be per FP input instead of per VP output
+        */
+       memset(pntc, 0, 8 * sizeof(uint32_t));
+
+       for (i = 0; i < fp->cfg.io_nr; i++) {
+               uint8_t sn, si;
+               uint8_t j = fp->cfg.io[i].id_vp, k = fp->cfg.io[i].id_fp;
+               unsigned n = popcnt4(fp->cfg.io[i].mask);
+
+               if (fp->info.input_semantic_name[k] != TGSI_SEMANTIC_GENERIC) {
+                       m += n;
+                       continue;
+               }
+
+               sn = vp->info.input_semantic_name[j];
+               si = vp->info.input_semantic_index[j];
+
+               if (j < fp->cfg.io_nr && sn == TGSI_SEMANTIC_GENERIC) {
+                       ubyte mode =
+                               nv50->rasterizer->pipe.sprite_coord_mode[si];
+
+                       if (mode == PIPE_SPRITE_COORD_NONE) {
+                               m += n;
+                               continue;
+                       }
+               }
+
+               /* this is either PointCoord or replaced by sprite coords */
+               for (c = 0; c < 4; c++) {
+                       if (!(fp->cfg.io[i].mask & (1 << c)))
+                               continue;
+                       pntc[m / 8] |= (c + 1) << ((m % 8) * 4);
+                       ++m;
+               }
+       }
+}
+
 static int
 nv50_sreg4_map(uint32_t *p_map, int mid, uint32_t lin[4],
               struct nv50_sreg4 *fpi, struct nv50_sreg4 *vpo)
@@ -2736,7 +2782,7 @@ nv50_linkage_validate(struct nv50_context *nv50)
        struct nouveau_stateobj *so;
        struct nv50_sreg4 dummy, *vpo;
        int i, n, c, m = 0;
-       uint32_t map[16], lin[4], reg[5];
+       uint32_t map[16], lin[4], reg[5], pcrd[8];
 
        memset(map, 0, sizeof(map));
        memset(lin, 0, sizeof(lin));
@@ -2813,6 +2859,13 @@ nv50_linkage_validate(struct nv50_context *nv50)
        so_method(so, tesla, 0x1540, 4);
        so_datap (so, lin, 4);
 
+       if (nv50->rasterizer->pipe.point_sprite) {
+               nv50_pntc_replace(nv50, pcrd, (reg[4] >> 8) & 0xff);
+
+               so_method(so, tesla, NV50TCL_POINT_COORD_REPLACE_MAP(0), 8);
+               so_datap (so, pcrd, 8);
+       }
+
         so_ref(so, &nv50->state.programs);
         so_ref(NULL, &so);
 }
index c7f80a2203762d2acb65ac38bd19ae77f8ca0f52..7adaaaa135b5b44695b2b8e762ccba8a0ee2ab82 100644 (file)
@@ -92,7 +92,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param)
        case PIPE_CAP_ANISOTROPIC_FILTER:
                return 1;
        case PIPE_CAP_POINT_SPRITE:
-               return 0;
+               return 1;
        case PIPE_CAP_MAX_RENDER_TARGETS:
                return 8;
        case PIPE_CAP_OCCLUSION_QUERY:
index 1de60fed6ecede2c821359c384878bd2e3ead701..81fa3e34c59c00f5a083c008d42957517ed0a13a 100644 (file)
@@ -297,6 +297,9 @@ nv50_rasterizer_state_create(struct pipe_context *pipe,
        so_method(so, tesla, NV50TCL_POINT_SIZE, 1);
        so_data  (so, fui(cso->point_size));
 
+       so_method(so, tesla, NV50TCL_POINT_SPRITE_ENABLE, 1);
+       so_data  (so, cso->point_sprite);
+
        so_method(so, tesla, NV50TCL_POLYGON_MODE_FRONT, 3);
        if (cso->front_winding == PIPE_WINDING_CCW) {
                so_data(so, nvgl_polygon_mode(cso->fill_ccw));