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 61932ff2b6a2ccfce1ba159d077a84e278306423..af6526c8759464a317098f7d00c287bec50d5f0f 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 aefaf7b98ad026862ba13c916f5e3aad8077cb4d..613dc431bfdbc1249732fc70103f83d2a1c62e17 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 e6b210d135522e6a4839d89a516fc97b114aacd5..3450cec175d3b328f192c66ed941f6e6f42bdb30 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 b41ca056b6ae5cefd875e42389285a0fc206432f..6419011132acbde65482d4bdddfb69173d9f520e 100644 (file)
@@ -285,6 +285,34 @@ nvc0_validate_rasterizer(struct nvc0_context *nvc0)
    OUT_RINGp(chan, nvc0->rast->state, nvc0->rast->size);
 }
 
+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)
 {
@@ -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 },