nvc0: implement point coord replacement
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Sun, 23 Jan 2011 20:29:30 +0000 (21:29 +0100)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Sun, 23 Jan 2011 20:35:27 +0000 (21:35 +0100)
But we have to cheat and peek at the GENERIC semantic indices the
state tracker uses for TEXn.
Only outputs from 0x300 to 0x37c can be replaced, and so we have to
know on shader compilation which ones to put there in order to keep
doing separate shader objects properly.

At some point I'll probably create a patch that makes gallium not
force us to discard the information about what is a TexCoord.

src/gallium/drivers/nvc0/nvc0_3d.xml.h
src/gallium/drivers/nvc0/nvc0_program.c
src/gallium/drivers/nvc0/nvc0_program.h
src/gallium/drivers/nvc0/nvc0_state_validate.c

index 61932ff..af6526c 100644 (file)
@@ -814,8 +814,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define NVC0_3D_VERTEX_BASE_LOW                                        0x000015f8
 
 #define NVC0_3D_POINT_COORD_REPLACE                            0x00001604
-#define NVC0_3D_POINT_COORD_REPLACE_BITS__MASK                 0x00001fff
-#define NVC0_3D_POINT_COORD_REPLACE_BITS__SHIFT                        0
+#define NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN__MASK         0x00000004
+#define NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN__SHIFT                2
+#define NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN_LOWER_LEFT    0x00000000
+#define NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN_UPPER_LEFT    0x00000004
+#define NVC0_3D_POINT_COORD_REPLACE_ENABLE__MASK               0x000007f8
+#define NVC0_3D_POINT_COORD_REPLACE_ENABLE__SHIFT              3
 
 #define NVC0_3D_CODE_ADDRESS_HIGH                              0x00001608
 
@@ -864,8 +868,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define NVC0_3D_POINT_RASTER_RULES_OGL                         0x00000000
 #define NVC0_3D_POINT_RASTER_RULES_D3D                         0x00000001
 
-#define NVC0_3D_POINT_SPRITE_CTRL                              0x00001660
-
 #define NVC0_3D_TEX_MISC                                       0x00001664
 #define NVC0_3D_TEX_MISC_SEAMLESS_CUBE_MAP                     0x00000004
 
index aefaf7b..613dc43 100644 (file)
@@ -185,8 +185,17 @@ nvc0_varying_location(unsigned sn, unsigned si)
       return 0x2e0;
       */
    case TGSI_SEMANTIC_GENERIC:
+      /* We'd really like to distinguish between TEXCOORD and GENERIC here,
+       * since only 0x300 to 0x37c can be replaced by sprite coordinates.
+       * Also, gl_PointCoord should be a system value and must be assigned to
+       * address 0x2e0. For now, let's cheat:
+       */
       assert(si < 31);
-      return 0x80 + (si * 16);
+      if (si <= 7)
+         return 0x300 + si * 16;
+      if (si == 9)
+         return 0x2e0;
+      return 0x80 + ((si - 8) * 16);
    case TGSI_SEMANTIC_NORMAL:
       return 0x360;
    case TGSI_SEMANTIC_PRIMID:
@@ -256,12 +265,14 @@ prog_decl(struct nvc0_translation_info *ti,
    case TGSI_FILE_INPUT:
       for (i = first; i <= last; ++i) {
          if (ti->prog->type == PIPE_SHADER_VERTEX) {
-            sn = TGSI_SEMANTIC_GENERIC;
-            si = i;
+            for (c = 0; c < 4; ++c)
+               ti->input_loc[i][c] = 0x80 + i * 16 + c * 4;
+         } else {
+            for (c = 0; c < 4; ++c)
+               ti->input_loc[i][c] = nvc0_varying_location(sn, si) + c * 4;
+            /* for sprite coordinates: */
+            ti->prog->fp.in_pos[i] = ti->input_loc[i][0] / 4;
          }
-         for (c = 0; c < 4; ++c)
-            ti->input_loc[i][c] = nvc0_varying_location(sn, si) + c * 4;
-
          if (ti->prog->type == PIPE_SHADER_FRAGMENT)
             ti->interp_mode[i] = nvc0_interp_mode(decl);
       }
@@ -281,6 +292,8 @@ prog_decl(struct nvc0_translation_info *ti,
          } else {
             for (c = 0; c < 4; ++c)
                ti->output_loc[i][c] = nvc0_varying_location(sn, si) + c * 4;
+            /* for TFB_VARYING_LOCS: */
+            ti->prog->vp.out_pos[i] = ti->output_loc[i][0] / 4;
          }
       }
       break;
@@ -518,6 +531,8 @@ nvc0_fp_gen_header(struct nvc0_program *fp, struct nvc0_translation_info *ti)
          if (!ti->input_access[i][c])
             continue;
          a = ti->input_loc[i][c] / 2;
+         if (ti->input_loc[i][c] >= 0x2c0)
+            a -= 32;
          if ((a & ~7) == 0x70/2)
             fp->hdr[5] |= 1 << (28 + (a & 7) / 2); /* FRAG_COORD_UMASK */
          else
index e6b210d..3450cec 100644 (file)
@@ -21,16 +21,18 @@ struct nvc0_program {
    unsigned code_size;
    unsigned parm_size;
 
-   uint32_t hdr[20];
+   uint32_t hdr[20]; /* TODO: move this into code to save space */
 
    uint32_t flags[2];
 
    struct {
       uint8_t edgeflag;
       uint8_t num_ucps;
+      uint8_t out_pos[PIPE_MAX_SHADER_OUTPUTS];
    } vp;
    struct {
       uint8_t early_z;
+      uint8_t in_pos[PIPE_MAX_SHADER_INPUTS];
    } fp;
 
    void *relocs;
index b41ca05..6419011 100644 (file)
@@ -286,6 +286,34 @@ nvc0_validate_rasterizer(struct nvc0_context *nvc0)
 }
 
 static void
+nvc0_validate_sprite_coords(struct nvc0_context *nvc0)
+{
+   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   uint32_t reg;
+
+   if (nvc0->rast->pipe.sprite_coord_mode == PIPE_SPRITE_COORD_UPPER_LEFT)
+      reg = NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN_UPPER_LEFT;
+   else
+      reg = NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN_LOWER_LEFT;
+
+   if (nvc0->rast->pipe.point_quad_rasterization) {
+      uint32_t en = nvc0->rast->pipe.sprite_coord_enable;
+      int i;
+      struct nvc0_program *prog = nvc0->fragprog;
+
+      while (en) {
+         i = ffs(en) - 1;
+         en &= ~(1 << i);
+         if (prog->fp.in_pos[i] >= 0xc0 && prog->fp.in_pos[i] < 0xe0)
+            reg |= 8 << ((prog->fp.in_pos[i] - 0xc0) / 4);
+      }
+   }
+
+   BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE), 1);
+   OUT_RING  (chan, reg);
+}
+
+static void
 nvc0_constbufs_validate(struct nvc0_context *nvc0)
 {
    struct nouveau_channel *chan = nvc0->screen->base.channel;
@@ -404,6 +432,7 @@ static struct state_validate {
     { nvc0_tevlprog_validate,      NVC0_NEW_TEVLPROG },
     { nvc0_gmtyprog_validate,      NVC0_NEW_GMTYPROG },
     { nvc0_fragprog_validate,      NVC0_NEW_FRAGPROG },
+    { nvc0_validate_sprite_coords, NVC0_NEW_RASTERIZER | NVC0_NEW_FRAGPROG },
     { nvc0_constbufs_validate,     NVC0_NEW_CONSTBUF },
     { nvc0_validate_textures,      NVC0_NEW_TEXTURES },
     { nvc0_validate_samplers,      NVC0_NEW_SAMPLERS },