~mmach/netext73/mesa-ryzen

« back to all changes in this revision

Viewing changes to src/gallium/frontends/nine/nine_shader.c

  • Committer: mmach
  • Date: 2023-11-02 21:31:35 UTC
  • Revision ID: netbit73@gmail.com-20231102213135-18d4tzh7tj0uz752
2023-11-02 22:11:57

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
#include "nine_state.h"
29
29
#include "vertexdeclaration9.h"
30
30
 
 
31
#include "util/bitscan.h"
31
32
#include "util/macros.h"
32
33
#include "util/u_memory.h"
33
34
#include "util/u_inlines.h"
449
450
    unsigned num_consti_allowed;
450
451
    unsigned num_constb_allowed;
451
452
 
452
 
    boolean native_integers;
453
 
    boolean inline_subroutines;
454
 
    boolean want_texcoord;
455
 
    boolean shift_wpos;
456
 
    boolean wpos_is_sysval;
457
 
    boolean face_is_sysval_integer;
458
 
    boolean mul_zero_wins;
 
453
    bool native_integers;
 
454
    bool inline_subroutines;
 
455
    bool want_texcoord;
 
456
    bool shift_wpos;
 
457
    bool wpos_is_sysval;
 
458
    bool face_is_sysval_integer;
 
459
    bool mul_zero_wins;
 
460
    bool always_output_pointsize;
 
461
    bool no_vs_window_space;
459
462
    unsigned texcoord_sn;
460
463
 
461
464
    struct sm1_instruction insn; /* current instruction */
463
466
    struct {
464
467
        struct ureg_dst *r;
465
468
        struct ureg_dst oPos;
466
 
        struct ureg_dst oPos_out; /* the real output when doing streamout */
 
469
        struct ureg_dst oPos_out; /* the real output when doing streamout or clipplane emulation */
467
470
        struct ureg_dst oFog;
468
471
        struct ureg_dst oPts;
469
472
        struct ureg_dst oCol[4];
495
498
    unsigned cond_depth;
496
499
    unsigned loop_labels[NINE_MAX_LOOP_DEPTH];
497
500
    unsigned cond_labels[NINE_MAX_COND_DEPTH];
498
 
    boolean loop_or_rep[NINE_MAX_LOOP_DEPTH]; /* true: loop, false: rep */
499
 
    boolean predicated_activated;
 
501
    bool loop_or_rep[NINE_MAX_LOOP_DEPTH]; /* true: loop, false: rep */
 
502
    bool predicated_activated;
500
503
 
501
504
    unsigned *inst_labels; /* LABEL op */
502
505
    unsigned num_inst_labels;
510
513
    struct sm1_local_const *lconstb;
511
514
    unsigned num_lconstb;
512
515
 
513
 
    boolean slots_used[NINE_MAX_CONST_ALL];
 
516
    bool slots_used[NINE_MAX_CONST_ALL_VS];
514
517
    unsigned *slot_map;
515
518
    unsigned num_slots;
516
519
 
517
 
    boolean indirect_const_access;
518
 
    boolean failure;
 
520
    bool indirect_const_access;
 
521
    bool failure;
519
522
 
520
523
    struct nine_vs_output_info output_info[16];
521
524
    int num_outputs;
577
580
    }
578
581
 
579
582
    if (!tx->info->swvp_on)
580
 
        tx->slots_used[idx] = TRUE;
 
583
        tx->slots_used[idx] = true;
581
584
    if (tx->info->const_float_slots < (idx + 1))
582
585
        tx->info->const_float_slots = idx + 1;
583
586
    if (tx->num_slots < (idx + 1))
599
602
            slot_idx = tx->slot_map[slot_idx];
600
603
        src = ureg_src_register(TGSI_FILE_CONSTANT, slot_idx);
601
604
        src = ureg_src_dimension(src, 0);
602
 
        tx->slots_used[slot_idx] = TRUE;
603
 
        tx->info->int_slots_used[idx] = TRUE;
 
605
        tx->slots_used[slot_idx] = true;
 
606
        tx->info->int_slots_used[idx] = true;
604
607
        if (tx->num_slots < (slot_idx + 1))
605
608
            tx->num_slots = slot_idx + 1;
606
609
    }
627
630
            slot_idx = tx->slot_map[slot_idx];
628
631
        src = ureg_src_register(TGSI_FILE_CONSTANT, slot_idx);
629
632
        src = ureg_src_dimension(src, 0);
630
 
        tx->slots_used[slot_idx] = TRUE;
631
 
        tx->info->bool_slots_used[idx] = TRUE;
 
633
        tx->slots_used[slot_idx] = true;
 
634
        tx->info->bool_slots_used[idx] = true;
632
635
        if (tx->num_slots < (slot_idx + 1))
633
636
            tx->num_slots = slot_idx + 1;
634
637
    }
640
643
    return src;
641
644
}
642
645
 
643
 
static boolean
 
646
static struct ureg_src nine_special_constant_src(struct shader_translator *tx, int idx)
 
647
{
 
648
    struct ureg_src src;
 
649
 
 
650
    unsigned slot_idx = idx + (IS_PS ? NINE_MAX_CONST_PS_SPE_OFFSET :
 
651
        (tx->info->swvp_on ? NINE_MAX_CONST_SWVP_SPE_OFFSET : NINE_MAX_CONST_VS_SPE_OFFSET));
 
652
 
 
653
    if (!tx->info->swvp_on && tx->slot_map)
 
654
        slot_idx = tx->slot_map[slot_idx];
 
655
    src = ureg_src_register(TGSI_FILE_CONSTANT, slot_idx);
 
656
    src = ureg_src_dimension(src, 0);
 
657
 
 
658
    if (!tx->info->swvp_on)
 
659
        tx->slots_used[slot_idx] = true;
 
660
    if (tx->num_slots < (slot_idx + 1))
 
661
        tx->num_slots = slot_idx + 1;
 
662
 
 
663
    return src;
 
664
}
 
665
 
 
666
static bool
644
667
tx_lconstf(struct shader_translator *tx, struct ureg_src *src, INT index)
645
668
{
646
669
   INT i;
647
670
 
648
671
   if (index < 0 || index >= tx->num_constf_allowed) {
649
 
       tx->failure = TRUE;
650
 
       return FALSE;
 
672
       tx->failure = true;
 
673
       return false;
651
674
   }
652
675
   for (i = 0; i < tx->num_lconstf; ++i) {
653
676
      if (tx->lconstf[i].idx == index) {
654
677
         *src = tx->lconstf[i].reg;
655
 
         return TRUE;
 
678
         return true;
656
679
      }
657
680
   }
658
 
   return FALSE;
 
681
   return false;
659
682
}
660
 
static boolean
 
683
static bool
661
684
tx_lconsti(struct shader_translator *tx, struct ureg_src *src, INT index)
662
685
{
663
686
   int i;
664
687
 
665
688
   if (index < 0 || index >= tx->num_consti_allowed) {
666
 
       tx->failure = TRUE;
667
 
       return FALSE;
 
689
       tx->failure = true;
 
690
       return false;
668
691
   }
669
692
   for (i = 0; i < tx->num_lconsti; ++i) {
670
693
      if (tx->lconsti[i].idx == index) {
671
694
         *src = tx->lconsti[i].reg;
672
 
         return TRUE;
 
695
         return true;
673
696
      }
674
697
   }
675
 
   return FALSE;
 
698
   return false;
676
699
}
677
 
static boolean
 
700
static bool
678
701
tx_lconstb(struct shader_translator *tx, struct ureg_src *src, INT index)
679
702
{
680
703
   int i;
681
704
 
682
705
   if (index < 0 || index >= tx->num_constb_allowed) {
683
 
       tx->failure = TRUE;
684
 
       return FALSE;
 
706
       tx->failure = true;
 
707
       return false;
685
708
   }
686
709
   for (i = 0; i < tx->num_lconstb; ++i) {
687
710
      if (tx->lconstb[i].idx == index) {
688
711
         *src = tx->lconstb[i].reg;
689
 
         return TRUE;
 
712
         return true;
690
713
      }
691
714
   }
692
 
   return FALSE;
 
715
   return false;
693
716
}
694
717
 
695
718
static void
771
794
tx_scratch(struct shader_translator *tx)
772
795
{
773
796
    if (tx->num_scratch >= ARRAY_SIZE(tx->regs.t)) {
774
 
        tx->failure = TRUE;
 
797
        tx->failure = true;
775
798
        return tx->regs.t[0];
776
799
    }
777
800
    if (ureg_dst_is_undef(tx->regs.t[tx->num_scratch]))
875
898
{
876
899
    unsigned dim = 1 + ((tx->info->projected >> (2 * idx)) & 3);
877
900
    struct ureg_dst tmp;
878
 
    boolean shadow = !!(tx->info->sampler_mask_shadow & (1 << idx));
 
901
    bool shadow = !!(tx->info->sampler_mask_shadow & (1 << idx));
879
902
 
880
903
    /* dim == 1: no projection
881
904
     * Looks like must be disabled when it makes no
923
946
}
924
947
 
925
948
static struct ureg_dst
926
 
tx_get_loopctr(struct shader_translator *tx, boolean loop_or_rep)
 
949
tx_get_loopctr(struct shader_translator *tx, bool loop_or_rep)
927
950
{
928
951
    const unsigned l = tx->loop_depth - 1;
929
952
 
1052
1075
            if (tx->version.major < 3) {
1053
1076
                src = ureg_DECL_fs_input_centroid(
1054
1077
                    ureg, TGSI_SEMANTIC_COLOR, param->idx,
1055
 
                    TGSI_INTERPOLATE_COLOR,
 
1078
                    tx->info->color_flatshade ? TGSI_INTERPOLATE_CONSTANT : TGSI_INTERPOLATE_PERSPECTIVE,
1056
1079
                    tx->info->force_color_in_centroid ?
1057
1080
                      TGSI_INTERPOLATE_LOC_CENTROID : 0,
1058
1081
                    0, 1);
1091
1114
    case D3DSPR_PREDICATE:
1092
1115
        if (ureg_dst_is_undef(tx->regs.predicate)) {
1093
1116
            /* Forbidden to use the predicate register before being set */
1094
 
            tx->failure = TRUE;
 
1117
            tx->failure = true;
1095
1118
            tx->regs.predicate = ureg_DECL_temporary(tx->ureg);
1096
1119
        }
1097
1120
        src = ureg_src(tx->regs.predicate);
1105
1128
        if (param->rel || !tx_lconstf(tx, &src, param->idx)) {
1106
1129
            src = nine_float_constant_src(tx, param->idx);
1107
1130
            if (param->rel) {
1108
 
                tx->indirect_const_access = TRUE;
 
1131
                tx->indirect_const_access = true;
1109
1132
                src = ureg_src_indirect(src, tx_src_param(tx, param->rel));
1110
1133
            }
1111
1134
        }
1317
1340
        assert(!param->rel);
1318
1341
        switch (param->idx) {
1319
1342
        case 0:
1320
 
            if (ureg_dst_is_undef(tx->regs.oPos))
1321
 
                tx->regs.oPos =
1322
 
                    ureg_DECL_output(tx->ureg, TGSI_SEMANTIC_POSITION, 0);
 
1343
            if (ureg_dst_is_undef(tx->regs.oPos)) {
 
1344
                if (tx->info->clip_plane_emulation > 0) {
 
1345
                    tx->regs.oPos = ureg_DECL_temporary(tx->ureg);
 
1346
                } else {
 
1347
                    tx->regs.oPos = tx->regs.oPos_out;
 
1348
                }
 
1349
            }
1323
1350
            dst = tx->regs.oPos;
1324
1351
            break;
1325
1352
        case 1:
1355
1382
        assert(!param->rel);
1356
1383
        tx->info->rt_mask |= 1 << param->idx;
1357
1384
        if (ureg_dst_is_undef(tx->regs.oCol[param->idx])) {
1358
 
            /* ps < 3: oCol[0] will have fog blending afterward */
1359
 
            if (!IS_VS && tx->version.major < 3 && param->idx == 0) {
 
1385
            /* ps < 3: oCol[0] will have fog blending afterward
 
1386
             * ps: oCol[0] might have alphatest afterward */
 
1387
            if (!IS_VS && param->idx == 0) {
1360
1388
                tx->regs.oCol[0] = ureg_DECL_temporary(tx->ureg);
1361
1389
            } else {
1362
1390
                tx->regs.oCol[param->idx] =
1799
1827
    struct ureg_src ctrx;
1800
1828
 
1801
1829
    label = tx_bgnloop(tx);
1802
 
    ctr = tx_get_loopctr(tx, TRUE);
 
1830
    ctr = tx_get_loopctr(tx, true);
1803
1831
    aL = tx_get_loopal(tx);
1804
1832
    ctrx = ureg_scalar(ureg_src(ctr), TGSI_SWIZZLE_X);
1805
1833
 
1846
1874
DECL_SPECIAL(ENDLOOP)
1847
1875
{
1848
1876
    struct ureg_program *ureg = tx->ureg;
1849
 
    struct ureg_dst ctr = tx_get_loopctr(tx, TRUE);
 
1877
    struct ureg_dst ctr = tx_get_loopctr(tx, true);
1850
1878
    struct ureg_dst al = tx_get_loopal(tx);
1851
1879
    struct ureg_dst dst_ctrx, dst_al;
1852
1880
    struct ureg_src src_ctr, al_counter;
1922
1950
    struct ureg_src ctrx;
1923
1951
 
1924
1952
    label = tx_bgnloop(tx);
1925
 
    ctr = ureg_writemask(tx_get_loopctr(tx, FALSE), NINED3DSP_WRITEMASK_0);
 
1953
    ctr = ureg_writemask(tx_get_loopctr(tx, false), NINED3DSP_WRITEMASK_0);
1926
1954
    ctrx = ureg_scalar(ureg_src(ctr), TGSI_SWIZZLE_X);
1927
1955
 
1928
1956
    /* NOTE: rep must be constant, so we don't have to save the count */
1956
1984
DECL_SPECIAL(ENDREP)
1957
1985
{
1958
1986
    struct ureg_program *ureg = tx->ureg;
1959
 
    struct ureg_dst ctr = tx_get_loopctr(tx, FALSE);
 
1987
    struct ureg_dst ctr = tx_get_loopctr(tx, false);
1960
1988
    struct ureg_dst dst_ctrx = ureg_writemask(ctr, NINED3DSP_WRITEMASK_0);
1961
1989
    struct ureg_src src_ctr = ureg_src(ctr);
1962
1990
 
2064
2092
 
2065
2093
static void
2066
2094
sm1_declusage_to_tgsi(struct tgsi_declaration_semantic *sem,
2067
 
                      boolean tc,
 
2095
                      bool tc,
2068
2096
                      struct sm1_semantic *dcl)
2069
2097
{
2070
2098
    BYTE index = dcl->usage_idx;
2195
2223
static inline unsigned
2196
2224
ps1x_sampler_type(const struct nine_shader_info *info, unsigned stage)
2197
2225
{
2198
 
    boolean shadow = !!(info->sampler_mask_shadow & (1 << stage));
 
2226
    bool shadow = !!(info->sampler_mask_shadow & (1 << stage));
2199
2227
    switch ((info->sampler_ps1xtypes >> (stage * 2)) & 0x3) {
2200
2228
    case 1: return shadow ? TGSI_TEXTURE_SHADOW1D : TGSI_TEXTURE_1D;
2201
2229
    case 0: return shadow ? TGSI_TEXTURE_SHADOW2D : TGSI_TEXTURE_2D;
2251
2279
DECL_SPECIAL(DCL)
2252
2280
{
2253
2281
    struct ureg_program *ureg = tx->ureg;
2254
 
    boolean is_input;
2255
 
    boolean is_sampler;
 
2282
    bool is_input;
 
2283
    bool is_sampler;
2256
2284
    struct tgsi_declaration_semantic tgsi;
2257
2285
    struct sm1_semantic sem;
2258
2286
    sm1_read_semantic(tx, &sem);
2298
2326
            /* SM2 output semantic determined by file */
2299
2327
            assert(sem.reg.mask != 0);
2300
2328
            if (sem.usage == D3DDECLUSAGE_POSITIONT)
2301
 
                tx->info->position_t = TRUE;
 
2329
                tx->info->position_t = true;
2302
2330
            assert(sem.reg.idx < ARRAY_SIZE(tx->regs.o));
2303
2331
            assert(ureg_dst_is_undef(tx->regs.o[sem.reg.idx]) && "Nine doesn't support yet packing");
2304
2332
            tx->regs.o[sem.reg.idx] = ureg_DECL_output_masked(
2305
2333
                ureg, tgsi.Name, tgsi.Index, sem.reg.mask, 0, 1);
2306
2334
            nine_record_outputs(tx, sem.usage, sem.usage_idx, sem.reg.mask, sem.reg.idx);
2307
 
            if (tx->info->process_vertices && sem.usage == D3DDECLUSAGE_POSITION && sem.usage_idx == 0) {
2308
 
                tx->regs.oPos_out = tx->regs.o[sem.reg.idx];
 
2335
            if ((tx->info->process_vertices || tx->info->clip_plane_emulation > 0) &&
 
2336
                sem.usage == D3DDECLUSAGE_POSITION && sem.usage_idx == 0) {
 
2337
                tx->regs.oPos_out = tx->regs.o[sem.reg.idx]; /* TODO: probably not good declare it twice */
2309
2338
                tx->regs.o[sem.reg.idx] = ureg_DECL_temporary(ureg);
2310
2339
                tx->regs.oPos = tx->regs.o[sem.reg.idx];
2311
2340
            }
2317
2346
        }
2318
2347
    } else {
2319
2348
        if (is_input && tx->version.major >= 3) {
 
2349
            unsigned interp_flag;
2320
2350
            unsigned interp_location = 0;
2321
2351
            /* SM3 only, SM2 input semantic determined by file */
2322
2352
            assert(sem.reg.idx < ARRAY_SIZE(tx->regs.v));
2337
2367
            if (sem.reg.mod & NINED3DSPDM_CENTROID ||
2338
2368
                (tgsi.Name == TGSI_SEMANTIC_COLOR && tx->info->force_color_in_centroid))
2339
2369
                interp_location = TGSI_INTERPOLATE_LOC_CENTROID;
 
2370
            interp_flag = nine_tgsi_to_interp_mode(&tgsi);
 
2371
            /* We replace TGSI_INTERPOLATE_COLOR because some drivers don't support it,
 
2372
             * and those who support it do the same replacement we do */
 
2373
            if (interp_flag == TGSI_INTERPOLATE_COLOR)
 
2374
                interp_flag = tx->info->color_flatshade ? TGSI_INTERPOLATE_CONSTANT : TGSI_INTERPOLATE_PERSPECTIVE;
2340
2375
 
2341
2376
            tx->regs.v[sem.reg.idx] = ureg_DECL_fs_input_centroid(
2342
2377
                ureg, tgsi.Name, tgsi.Index,
2343
 
                nine_tgsi_to_interp_mode(&tgsi),
 
2378
                interp_flag,
2344
2379
                interp_location, 0, 1);
2345
2380
        } else
2346
2381
        if (!is_input && 0) { /* declare in COLOROUT/DEPTHOUT case */
2378
2413
        tx_src_param(tx, &tx->insn.src[0]),
2379
2414
        tx_src_param(tx, &tx->insn.src[1])
2380
2415
    };
2381
 
    ureg_POW(tx->ureg, dst, ureg_abs(src[0]), src[1]);
 
2416
    /* Anything^0 is 1, including 0^0.
 
2417
     * Assume mul_zero_wins drivers already have
 
2418
     * this behaviour. Emulate for the others. */
 
2419
    if (tx->mul_zero_wins) {
 
2420
        ureg_POW(tx->ureg, dst, ureg_abs(src[0]), src[1]);
 
2421
    } else {
 
2422
        struct ureg_dst tmp = tx_scratch_scalar(tx);
 
2423
        ureg_POW(tx->ureg, tmp, ureg_abs(src[0]), src[1]);
 
2424
        ureg_CMP(tx->ureg, dst,
 
2425
             ureg_negate(ureg_abs(ureg_scalar(src[1], TGSI_SWIZZLE_X))),
 
2426
             tx_src_scalar(tmp), ureg_imm1f(tx->ureg, 1.0f));
 
2427
    }
2382
2428
    return D3D_OK;
2383
2429
}
2384
2430
 
2572
2618
     * 10 is Z
2573
2619
     * 11 is W
2574
2620
     */
2575
 
    c8m = nine_float_constant_src(tx, 8+m);
2576
 
    c16m2 = nine_float_constant_src(tx, 8+8+m/2);
 
2621
    c8m = nine_special_constant_src(tx, m);
 
2622
    c16m2 = nine_special_constant_src(tx, 8+m/2);
2577
2623
 
2578
2624
    m00 = NINE_APPLY_SWIZZLE(c8m, X);
2579
2625
    m01 = NINE_APPLY_SWIZZLE(c8m, Y);
2925
2971
     * 10 is Z
2926
2972
     * 11 is W
2927
2973
     */
2928
 
    c8m = nine_float_constant_src(tx, 8+m);
 
2974
    c8m = nine_special_constant_src(tx, m);
2929
2975
    m00 = NINE_APPLY_SWIZZLE(c8m, X);
2930
2976
    m01 = NINE_APPLY_SWIZZLE(c8m, Y);
2931
2977
    m10 = NINE_APPLY_SWIZZLE(c8m, Z);
3270
3316
    }
3271
3317
}
3272
3318
 
3273
 
static inline boolean
 
3319
static inline bool
3274
3320
sm1_parse_eof(struct shader_translator *tx)
3275
3321
{
3276
3322
    return TOKEN_PEEK(tx) == NINED3DSP_END;
3473
3519
    const struct sm1_op_info *info = NULL;
3474
3520
    unsigned i;
3475
3521
 
3476
 
    sm1_parse_comments(tx, TRUE);
 
3522
    sm1_parse_comments(tx, true);
3477
3523
    sm1_parse_get_skip(tx);
3478
3524
 
3479
3525
    tok = TOKEN_NEXT(tx);
3555
3601
    }
3556
3602
 
3557
3603
    if (hr != D3D_OK)
3558
 
        tx->failure = TRUE;
 
3604
        tx->failure = true;
3559
3605
    tx->num_scratch = 0; /* reset */
3560
3606
 
3561
3607
    TOKEN_JUMP(tx);
3582
3628
        info->input_map[i] = NINE_DECLUSAGE_NONE;
3583
3629
    info->num_inputs = 0;
3584
3630
 
3585
 
    info->position_t = FALSE;
3586
 
    info->point_size = FALSE;
 
3631
    info->position_t = false;
 
3632
    info->point_size = false;
3587
3633
 
3588
3634
    memset(tx->slots_used, 0, sizeof(tx->slots_used));
3589
3635
    memset(info->int_slots_used, 0, sizeof(info->int_slots_used));
3640
3686
        TGSI_SEMANTIC_TEXCOORD : TGSI_SEMANTIC_GENERIC;
3641
3687
    tx->wpos_is_sysval = GET_CAP(FS_POSITION_IS_SYSVAL);
3642
3688
    tx->face_is_sysval_integer = GET_CAP(FS_FACE_IS_INTEGER_SYSVAL);
 
3689
    tx->no_vs_window_space = !GET_CAP(VS_WINDOW_SPACE_POSITION);
 
3690
    tx->mul_zero_wins = GET_CAP(LEGACY_MATH_RULES);
 
3691
 
 
3692
    if (info->emulate_features) {
 
3693
        tx->shift_wpos = true;
 
3694
        tx->no_vs_window_space = true;
 
3695
        tx->mul_zero_wins = false;
 
3696
    }
3643
3697
 
3644
3698
    if (IS_VS) {
3645
3699
        tx->num_constf_allowed = NINE_MAX_CONST_F;
3670
3724
     * (Some drivers like nv50 are buggy and rely on that.)
3671
3725
     */
3672
3726
    if (IS_VS) {
3673
 
        tx->regs.oPos = ureg_DECL_output(tx->ureg, TGSI_SEMANTIC_POSITION, 0);
 
3727
        tx->regs.oPos_out = ureg_DECL_output(tx->ureg, TGSI_SEMANTIC_POSITION, 0);
3674
3728
    } else {
3675
3729
        ureg_property(tx->ureg, TGSI_PROPERTY_FS_COORD_ORIGIN, TGSI_FS_COORD_ORIGIN_UPPER_LEFT);
3676
3730
        if (!tx->shift_wpos)
3677
3731
            ureg_property(tx->ureg, TGSI_PROPERTY_FS_COORD_PIXEL_CENTER, TGSI_FS_COORD_PIXEL_CENTER_INTEGER);
3678
3732
    }
3679
3733
 
3680
 
    tx->mul_zero_wins = GET_CAP(LEGACY_MATH_RULES);
3681
3734
    if (tx->mul_zero_wins)
3682
3735
       ureg_property(tx->ureg, TGSI_PROPERTY_LEGACY_MATH_RULES, 1);
3683
3736
 
3742
3795
}
3743
3796
 
3744
3797
static void
3745
 
shader_add_ps_fog_stage(struct shader_translator *tx, struct ureg_src src_col)
 
3798
shader_add_ps_fog_stage(struct shader_translator *tx, struct ureg_dst dst_col, struct ureg_src src_col)
3746
3799
{
3747
3800
    struct ureg_program *ureg = tx->ureg;
3748
 
    struct ureg_dst oCol0 = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
3749
3801
    struct ureg_src fog_end, fog_coeff, fog_density, fog_params;
3750
3802
    struct ureg_src fog_vs, fog_color;
3751
3803
    struct ureg_dst fog_factor, depth;
3752
3804
 
3753
3805
    if (!tx->info->fog_enable) {
3754
 
        ureg_MOV(ureg, oCol0, src_col);
 
3806
        ureg_MOV(ureg, dst_col, src_col);
3755
3807
        return;
3756
3808
    }
3757
3809
 
3758
3810
    if (tx->info->fog_mode != D3DFOG_NONE) {
3759
3811
        depth = tx_scratch_scalar(tx);
3760
 
        /* Depth used for fog is perspective interpolated */
3761
 
        ureg_RCP(ureg, depth, ureg_scalar(nine_get_position_input(tx), TGSI_SWIZZLE_W));
3762
 
        ureg_MUL(ureg, depth, ureg_src(depth), ureg_scalar(nine_get_position_input(tx), TGSI_SWIZZLE_Z));
 
3812
        if (tx->info->zfog)
 
3813
            ureg_MOV(ureg, depth, ureg_scalar(nine_get_position_input(tx), TGSI_SWIZZLE_Z));
 
3814
        else /* wfog: use w. position's w contains 1/w */
 
3815
            ureg_RCP(ureg, depth, ureg_scalar(nine_get_position_input(tx), TGSI_SWIZZLE_W));
3763
3816
    }
3764
3817
 
3765
 
    fog_color = nine_float_constant_src(tx, 32);
3766
 
    fog_params = nine_float_constant_src(tx, 33);
 
3818
    fog_color = nine_special_constant_src(tx, 12);
 
3819
    fog_params = nine_special_constant_src(tx, 13);
3767
3820
    fog_factor = tx_scratch_scalar(tx);
3768
3821
 
3769
3822
    if (tx->info->fog_mode == D3DFOG_LINEAR) {
3789
3842
        ureg_MOV(ureg, fog_factor, fog_vs);
3790
3843
    }
3791
3844
 
3792
 
    ureg_LRP(ureg, ureg_writemask(oCol0, TGSI_WRITEMASK_XYZ),
 
3845
    ureg_LRP(ureg, ureg_writemask(dst_col, TGSI_WRITEMASK_XYZ),
3793
3846
             tx_src_scalar(fog_factor), src_col, fog_color);
3794
 
    ureg_MOV(ureg, ureg_writemask(oCol0, TGSI_WRITEMASK_W), src_col);
 
3847
    ureg_MOV(ureg, ureg_writemask(dst_col, TGSI_WRITEMASK_W), src_col);
 
3848
}
 
3849
 
 
3850
static void
 
3851
shader_add_ps_alpha_test_stage(struct shader_translator *tx, struct ureg_src src_color)
 
3852
{
 
3853
    struct ureg_program *ureg = tx->ureg;
 
3854
    unsigned cmp_op;
 
3855
    struct ureg_src src[2];
 
3856
    struct ureg_dst tmp = tx_scratch(tx);
 
3857
    if (tx->info->alpha_test_emulation == PIPE_FUNC_ALWAYS)
 
3858
        return;
 
3859
    if (tx->info->alpha_test_emulation == PIPE_FUNC_NEVER) {
 
3860
        ureg_KILL(ureg);
 
3861
        return;
 
3862
    }
 
3863
    cmp_op = pipe_comp_to_tgsi_opposite(tx->info->alpha_test_emulation);
 
3864
    src[0] = ureg_scalar(src_color, TGSI_SWIZZLE_W); /* Read color alpha channel */
 
3865
    src[1] = ureg_scalar(nine_special_constant_src(tx, 14), TGSI_SWIZZLE_X); /* Read alphatest */
 
3866
    ureg_insn(tx->ureg, cmp_op, &tmp, 1, src, 2, 0);
 
3867
    ureg_KILL_IF(tx->ureg, ureg_negate(ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X))); /* if opposite test passes, discard */
3795
3868
}
3796
3869
 
3797
3870
static void parse_shader(struct shader_translator *tx)
3805
3878
    if (tx->failure)
3806
3879
        return;
3807
3880
 
3808
 
    if (IS_PS && tx->version.major < 3) {
3809
 
        if (tx->version.major < 2) {
3810
 
            assert(tx->num_temp); /* there must be color output */
3811
 
            info->rt_mask |= 0x1;
3812
 
            shader_add_ps_fog_stage(tx, ureg_src(tx->regs.r[0]));
 
3881
    if (IS_PS) {
 
3882
        struct ureg_dst oCol0 = ureg_DECL_output(tx->ureg, TGSI_SEMANTIC_COLOR, 0);
 
3883
        struct ureg_dst tmp_oCol0;
 
3884
        if (tx->version.major < 3) {
 
3885
            tmp_oCol0 = ureg_DECL_temporary(tx->ureg);
 
3886
            if (tx->version.major < 2) {
 
3887
                assert(tx->num_temp); /* there must be color output */
 
3888
                info->rt_mask |= 0x1;
 
3889
                shader_add_ps_fog_stage(tx, tmp_oCol0, ureg_src(tx->regs.r[0]));
 
3890
            } else {
 
3891
                shader_add_ps_fog_stage(tx, tmp_oCol0, ureg_src(tx->regs.oCol[0]));
 
3892
            }
3813
3893
        } else {
3814
 
            shader_add_ps_fog_stage(tx, ureg_src(tx->regs.oCol[0]));
 
3894
            assert(!ureg_dst_is_undef(tx->regs.oCol[0]));
 
3895
            tmp_oCol0 = tx->regs.oCol[0];
3815
3896
        }
 
3897
        shader_add_ps_alpha_test_stage(tx, ureg_src(tmp_oCol0));
 
3898
        ureg_MOV(tx->ureg, oCol0, ureg_src(tmp_oCol0));
3816
3899
    }
3817
3900
 
3818
3901
    if (IS_VS && tx->version.major < 3 && ureg_dst_is_undef(tx->regs.oFog) && info->fog_enable) {
3820
3903
        ureg_MOV(tx->ureg, ureg_writemask(tx->regs.oFog, TGSI_WRITEMASK_X), ureg_imm1f(tx->ureg, 0.0f));
3821
3904
    }
3822
3905
 
3823
 
    if (info->position_t)
3824
 
        ureg_property(tx->ureg, TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION, TRUE);
 
3906
    if (info->position_t) {
 
3907
        if (tx->no_vs_window_space) {
 
3908
            ERR("POSITIONT is not yet implemented for your device.\n");
 
3909
        } else {
 
3910
            ureg_property(tx->ureg, TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION, true);
 
3911
        }
 
3912
    }
3825
3913
 
3826
3914
    if (IS_VS && !ureg_dst_is_undef(tx->regs.oPts)) {
3827
3915
        struct ureg_dst oPts = ureg_DECL_output(tx->ureg, TGSI_SEMANTIC_PSIZE, 0);
3828
 
        ureg_MAX(tx->ureg, tx->regs.oPts, ureg_src(tx->regs.oPts), ureg_imm1f(tx->ureg, info->point_size_min));
3829
 
        ureg_MIN(tx->ureg, oPts, ureg_src(tx->regs.oPts), ureg_imm1f(tx->ureg, info->point_size_max));
3830
 
        info->point_size = TRUE;
 
3916
        ureg_MAX(tx->ureg, ureg_writemask(tx->regs.oPts, TGSI_WRITEMASK_X), ureg_src(tx->regs.oPts), ureg_imm1f(tx->ureg, info->point_size_min));
 
3917
        ureg_MIN(tx->ureg, ureg_writemask(oPts, TGSI_WRITEMASK_X), ureg_src(tx->regs.oPts), ureg_imm1f(tx->ureg, info->point_size_max));
 
3918
        info->point_size = true;
 
3919
    } else if (IS_VS && tx->always_output_pointsize) {
 
3920
        struct ureg_dst oPts = ureg_DECL_output(tx->ureg, TGSI_SEMANTIC_PSIZE, 0);
 
3921
        ureg_MOV(tx->ureg, ureg_writemask(oPts, TGSI_WRITEMASK_X), nine_special_constant_src(tx, 8));
 
3922
        info->point_size = true;
 
3923
    }
 
3924
 
 
3925
    if (IS_VS && tx->info->clip_plane_emulation > 0) {
 
3926
        struct ureg_dst clipdist[2] = {ureg_dst_undef(), ureg_dst_undef()};
 
3927
        int num_clipdist = ffs(tx->info->clip_plane_emulation);
 
3928
        int i;
 
3929
        /* TODO: handle undefined channels of oPos (w is not always written to I think. default is 1) *
 
3930
         * Note in d3d9 it's not possible to output clipvert, so we don't need to check
 
3931
         * for its existence */
 
3932
        clipdist[0] = ureg_DECL_output_masked(tx->ureg, TGSI_SEMANTIC_CLIPDIST, 0, ((1 << num_clipdist) - 1) & 0xf, 0, 1);
 
3933
        if (num_clipdist >= 5)
 
3934
            clipdist[1] = ureg_DECL_output_masked(tx->ureg, TGSI_SEMANTIC_CLIPDIST, 1, ((1 << (num_clipdist - 4)) - 1) & 0xf, 0, 1);
 
3935
        ureg_property(tx->ureg, TGSI_PROPERTY_NUM_CLIPDIST_ENABLED, num_clipdist);
 
3936
        for (i = 0; i < num_clipdist; i++) {
 
3937
            assert(!ureg_dst_is_undef(clipdist[i>>2]));
 
3938
            if (!(tx->info->clip_plane_emulation & (1 << i)))
 
3939
                ureg_MOV(tx->ureg, ureg_writemask(clipdist[i>>2], 1 << (i & 0x2)), ureg_imm1f(tx->ureg, 0.f));
 
3940
            else
 
3941
                ureg_DP4(tx->ureg, ureg_writemask(clipdist[i>>2], 1 << (i & 0x2)),
 
3942
                         ureg_src(tx->regs.oPos), nine_special_constant_src(tx, i));
 
3943
        }
 
3944
 
 
3945
        ureg_MOV(tx->ureg, tx->regs.oPos_out, ureg_src(tx->regs.oPos));
3831
3946
    }
3832
3947
 
3833
3948
    if (info->process_vertices)
3836
3951
    ureg_END(tx->ureg);
3837
3952
}
3838
3953
 
3839
 
#define NINE_SHADER_DEBUG_OPTION_NIR_VS           (1 << 0)
3840
 
#define NINE_SHADER_DEBUG_OPTION_NIR_PS           (1 << 1)
3841
3954
#define NINE_SHADER_DEBUG_OPTION_NO_NIR_VS        (1 << 2)
3842
3955
#define NINE_SHADER_DEBUG_OPTION_NO_NIR_PS        (1 << 3)
3843
3956
#define NINE_SHADER_DEBUG_OPTION_DUMP_NIR         (1 << 4)
3844
3957
#define NINE_SHADER_DEBUG_OPTION_DUMP_TGSI        (1 << 5)
3845
3958
 
3846
3959
static const struct debug_named_value nine_shader_debug_options[] = {
3847
 
    { "nir_vs", NINE_SHADER_DEBUG_OPTION_NIR_VS, "Use NIR for vertex shaders even if the driver doesn't prefer it." },
3848
 
    { "nir_ps", NINE_SHADER_DEBUG_OPTION_NIR_PS, "Use NIR for pixel shaders even if the driver doesn't prefer it." },
3849
3960
    { "no_nir_vs", NINE_SHADER_DEBUG_OPTION_NO_NIR_VS, "Never use NIR for vertex shaders even if the driver prefers it." },
3850
3961
    { "no_nir_ps", NINE_SHADER_DEBUG_OPTION_NO_NIR_PS, "Never use NIR for pixel shaders even if the driver prefers it." },
3851
3962
    { "dump_nir", NINE_SHADER_DEBUG_OPTION_DUMP_NIR, "Print translated NIR shaders." },
3853
3964
    DEBUG_NAMED_VALUE_END /* must be last */
3854
3965
};
3855
3966
 
3856
 
static inline boolean
 
3967
static inline bool
3857
3968
nine_shader_get_debug_flag(uint64_t flag)
3858
3969
{
3859
3970
    static uint64_t flags = 0;
3860
 
    static boolean first_run = TRUE;
 
3971
    static bool first_run = true;
3861
3972
 
3862
3973
    if (unlikely(first_run)) {
3863
 
        first_run = FALSE;
 
3974
        first_run = false;
3864
3975
        flags = debug_get_flags_option("NINE_SHADER", nine_shader_debug_options, 0);
3865
3976
 
3866
3977
        // Check old TGSI dump envvar too
3867
 
        if (debug_get_bool_option("NINE_TGSI_DUMP", FALSE)) {
 
3978
        if (debug_get_bool_option("NINE_TGSI_DUMP", false)) {
3868
3979
            flags |= NINE_SHADER_DEBUG_OPTION_DUMP_TGSI;
3869
3980
        }
3870
3981
    }
3904
4015
    assert(((struct tgsi_header *) &tgsi_tokens[0])->HeaderSize >= 2);
3905
4016
    enum pipe_shader_type shader_type = ((struct tgsi_processor *) &tgsi_tokens[1])->Processor;
3906
4017
 
3907
 
    int preferred_ir = screen->get_shader_param(screen, shader_type, PIPE_SHADER_CAP_PREFERRED_IR);
3908
 
    bool prefer_nir = (preferred_ir == PIPE_SHADER_IR_NIR);
3909
 
    bool use_nir = prefer_nir ||
3910
 
        ((shader_type == PIPE_SHADER_VERTEX) && nine_shader_get_debug_flag(NINE_SHADER_DEBUG_OPTION_NIR_VS)) ||
3911
 
        ((shader_type == PIPE_SHADER_FRAGMENT) && nine_shader_get_debug_flag(NINE_SHADER_DEBUG_OPTION_NIR_PS));
 
4018
    bool use_nir = true;
3912
4019
 
3913
4020
    /* Allow user to override preferred IR, this is very useful for debugging */
3914
4021
    if (unlikely(shader_type == PIPE_SHADER_VERTEX && nine_shader_get_debug_flag(NINE_SHADER_DEBUG_OPTION_NO_NIR_VS)))
3916
4023
    if (unlikely(shader_type == PIPE_SHADER_FRAGMENT && nine_shader_get_debug_flag(NINE_SHADER_DEBUG_OPTION_NO_NIR_PS)))
3917
4024
        use_nir = false;
3918
4025
 
3919
 
    DUMP("shader type: %s, preferred IR: %s, selected IR: %s\n",
 
4026
    DUMP("shader type: %s, selected IR: %s\n",
3920
4027
         shader_type == PIPE_SHADER_VERTEX ? "VS" : "PS",
3921
 
         prefer_nir ? "NIR" : "TGSI",
3922
4028
         use_nir ? "NIR" : "TGSI");
3923
4029
 
3924
4030
    if (use_nir) {
3968
4074
    if (!tx)
3969
4075
        return E_OUTOFMEMORY;
3970
4076
 
 
4077
    info->emulate_features = device->driver_caps.shader_emulate_features;
 
4078
 
3971
4079
    if (tx_ctor(tx, screen, info) == E_OUTOFMEMORY) {
3972
4080
        hr = E_OUTOFMEMORY;
3973
4081
        goto out;
3974
4082
    }
 
4083
    tx->always_output_pointsize = device->driver_caps.always_output_pointsize;
3975
4084
 
3976
4085
    assert(IS_VS || !info->swvp_on);
3977
4086
 
4017
4126
 
4018
4127
        num_ranges = 0;
4019
4128
        prev = -2;
4020
 
        for (i = 0; i < NINE_MAX_CONST_ALL; i++) {
 
4129
        for (i = 0; i < NINE_MAX_CONST_ALL_VS; i++) {
4021
4130
            if (tx->slots_used[i]) {
4022
4131
                if (prev != i - 1)
4023
4132
                    num_ranges++;
4024
4133
                prev = i;
4025
4134
            }
4026
4135
        }
4027
 
        slot_map = MALLOC(NINE_MAX_CONST_ALL * sizeof(unsigned));
 
4136
        slot_map = MALLOC(NINE_MAX_CONST_ALL_VS * sizeof(unsigned));
4028
4137
        const_ranges = CALLOC(num_ranges + 1, 2 * sizeof(unsigned)); /* ranges stop when last is of size 0 */
4029
4138
        if (!slot_map || !const_ranges) {
4030
4139
            hr = E_OUTOFMEMORY;
4033
4142
        c = 0;
4034
4143
        j = -1;
4035
4144
        prev = -2;
4036
 
        for (i = 0; i < NINE_MAX_CONST_ALL; i++) {
 
4145
        for (i = 0; i < NINE_MAX_CONST_ALL_VS; i++) {
4037
4146
            if (tx->slots_used[i]) {
4038
4147
                if (prev != i - 1)
4039
4148
                    j++;
4050
4159
            hr = E_OUTOFMEMORY;
4051
4160
            goto out;
4052
4161
        }
 
4162
        tx->always_output_pointsize = device->driver_caps.always_output_pointsize;
4053
4163
        tx->slot_map = slot_map;
4054
4164
        parse_shader(tx);
4055
4165
        assert(!tx->failure);