nine: allow fragment shader POSITION and FACE to be system values
authorMarek Olšák <marek.olsak@amd.com>
Fri, 8 Jan 2016 01:11:16 +0000 (02:11 +0100)
committerMarek Olšák <marek.olsak@amd.com>
Fri, 8 Jan 2016 19:07:16 +0000 (20:07 +0100)
Reported-by: Axel Davy <axel.davy@ens.fr>
src/gallium/state_trackers/nine/nine_ff.c
src/gallium/state_trackers/nine/nine_shader.c

index fe26086ef3d3131229bd79b1f75353ceff9db273..0feaeab73303b11cc359c2d786b693019effddb5 100644 (file)
@@ -1391,7 +1391,15 @@ nine_ff_build_ps(struct NineDevice9 *device, struct nine_ff_ps_key *key)
     /* Fog.
      */
     if (key->fog_mode) {
-        struct ureg_src vPos = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_POSITION, 0, TGSI_INTERPOLATE_LINEAR);
+        struct ureg_src vPos;
+        if (device->screen->get_param(device->screen,
+                                      PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL)) {
+            vPos = ureg_DECL_system_value(ureg, TGSI_SEMANTIC_POSITION, 0);
+        } else {
+            vPos = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_POSITION, 0,
+                                      TGSI_INTERPOLATE_LINEAR);
+        }
+
         struct ureg_dst rFog = ureg_writemask(ps.rTmp, TGSI_WRITEMASK_X);
         if (key->fog_mode == D3DFOG_EXP) {
             ureg_MUL(ureg, rFog, _ZZZZ(vPos), _ZZZZ(_CONST(22)));
index 28f27870dc80e9db1d45cd89981cab221ecfdd65..ed431738abc7f17b11de79ac5f33edeb5982bd9d 100644 (file)
@@ -462,6 +462,8 @@ struct shader_translator
     boolean lower_preds;
     boolean want_texcoord;
     boolean shift_wpos;
+    boolean wpos_is_sysval;
+    boolean face_is_sysval_integer;
     unsigned texcoord_sn;
 
     struct sm1_instruction insn; /* current instruction */
@@ -945,10 +947,16 @@ tx_src_param(struct shader_translator *tx, const struct sm1_src_param *param)
     case D3DSPR_MISCTYPE:
         switch (param->idx) {
         case D3DSMO_POSITION:
-           if (ureg_src_is_undef(tx->regs.vPos))
-               tx->regs.vPos = ureg_DECL_fs_input(ureg,
-                                                  TGSI_SEMANTIC_POSITION, 0,
-                                                  TGSI_INTERPOLATE_LINEAR);
+           if (ureg_src_is_undef(tx->regs.vPos)) {
+              if (tx->wpos_is_sysval) {
+                  tx->regs.vPos =
+                      ureg_DECL_system_value(ureg, TGSI_SEMANTIC_POSITION, 0);
+              } else {
+                  tx->regs.vPos =
+                      ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_POSITION, 0,
+                                         TGSI_INTERPOLATE_LINEAR);
+              }
+           }
            if (tx->shift_wpos) {
                /* TODO: do this only once */
                struct ureg_dst wpos = tx_scratch(tx);
@@ -961,9 +969,20 @@ tx_src_param(struct shader_translator *tx, const struct sm1_src_param *param)
            break;
         case D3DSMO_FACE:
            if (ureg_src_is_undef(tx->regs.vFace)) {
-               tx->regs.vFace = ureg_DECL_fs_input(ureg,
-                                                   TGSI_SEMANTIC_FACE, 0,
-                                                   TGSI_INTERPOLATE_CONSTANT);
+               if (tx->face_is_sysval_integer) {
+                   tmp = tx_scratch(tx);
+                   tx->regs.vFace =
+                       ureg_DECL_system_value(ureg, TGSI_SEMANTIC_FACE, 0);
+
+                   /* convert bool to float */
+                   ureg_UCMP(ureg, tmp, ureg_scalar(tx->regs.vFace, TGSI_SWIZZLE_X),
+                             ureg_imm1f(ureg, 1), ureg_imm1f(ureg, -1));
+                   tx->regs.vFace = ureg_src(tmp);
+               } else {
+                   tx->regs.vFace = ureg_DECL_fs_input(ureg,
+                                                       TGSI_SEMANTIC_FACE, 0,
+                                                       TGSI_INTERPOLATE_CONSTANT);
+               }
                tx->regs.vFace = ureg_scalar(tx->regs.vFace, TGSI_SWIZZLE_X);
            }
            src = tx->regs.vFace;
@@ -3259,10 +3278,15 @@ shader_add_ps_fog_stage(struct shader_translator *tx, struct ureg_src src_col)
         return;
     }
 
-    if (tx->info->fog_mode != D3DFOG_NONE)
-        depth = ureg_scalar(ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_POSITION, 0,
-                                              TGSI_INTERPOLATE_LINEAR),
-                                              TGSI_SWIZZLE_Z);
+    if (tx->info->fog_mode != D3DFOG_NONE) {
+        if (tx->wpos_is_sysval) {
+            depth = ureg_DECL_system_value(ureg, TGSI_SEMANTIC_POSITION, 0);
+        } else {
+            depth = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_POSITION, 0,
+                                       TGSI_INTERPOLATE_LINEAR);
+        }
+        depth = ureg_scalar(depth, TGSI_SWIZZLE_Z);
+    }
 
     nine_info_mark_const_f_used(tx->info, 33);
     fog_color = NINE_CONSTANT_SRC(32);
@@ -3344,6 +3368,8 @@ nine_translate_shader(struct NineDevice9 *device, struct nine_shader_info *info)
     tx->shift_wpos = !GET_CAP(TGSI_FS_COORD_PIXEL_CENTER_INTEGER);
     tx->texcoord_sn = tx->want_texcoord ?
         TGSI_SEMANTIC_TEXCOORD : TGSI_SEMANTIC_GENERIC;
+    tx->wpos_is_sysval = GET_CAP(TGSI_FS_POSITION_IS_SYSVAL);
+    tx->face_is_sysval_integer = GET_CAP(TGSI_FS_FACE_IS_INTEGER_SYSVAL);
 
     if (IS_VS) {
         tx->num_constf_allowed = NINE_MAX_CONST_F;