1
2#ifndef _NINE_FF_H_
3#define _NINE_FF_H_
4
5#include "device9.h"
6#include "vertexdeclaration9.h"
7
8boolean nine_ff_init(struct NineDevice9 *);
9void    nine_ff_fini(struct NineDevice9 *);
10
11void nine_ff_update(struct NineDevice9 *);
12
13void
14nine_d3d_matrix_matrix_mul(D3DMATRIX *, const D3DMATRIX *, const D3DMATRIX *);
15
16void
17nine_d3d_vector4_matrix_mul(D3DVECTOR *, const D3DVECTOR *, const D3DMATRIX *);
18void
19nine_d3d_vector3_matrix_mul(D3DVECTOR *, const D3DVECTOR *, const D3DMATRIX *);
20
21float
22nine_d3d_matrix_det(const D3DMATRIX *);
23
24void
25nine_d3d_matrix_inverse(D3DMATRIX *, const D3DMATRIX *);
26
27void
28nine_d3d_matrix_transpose(D3DMATRIX *, const D3DMATRIX *);
29
30#define NINED3DTSS_TCI_DISABLE                       0
31#define NINED3DTSS_TCI_PASSTHRU                      1
32#define NINED3DTSS_TCI_CAMERASPACENORMAL             2
33#define NINED3DTSS_TCI_CAMERASPACEPOSITION           3
34#define NINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR   4
35#define NINED3DTSS_TCI_SPHEREMAP                     5
36
37static inline unsigned
38nine_decltype_get_dim(BYTE type)
39{
40    switch (type) {
41    case D3DDECLTYPE_FLOAT1: return 1;
42    case D3DDECLTYPE_FLOAT2: return 2;
43    case D3DDECLTYPE_FLOAT3: return 3;
44    case D3DDECLTYPE_FLOAT4: return 4;
45    case D3DDECLTYPE_D3DCOLOR: return 1;
46    case D3DDECLTYPE_UBYTE4: return 4;
47    case D3DDECLTYPE_SHORT2: return 2;
48    case D3DDECLTYPE_SHORT4: return 4;
49    case D3DDECLTYPE_UBYTE4N: return 4;
50    case D3DDECLTYPE_SHORT2N: return 2;
51    case D3DDECLTYPE_SHORT4N: return 4;
52    case D3DDECLTYPE_USHORT2N: return 2;
53    case D3DDECLTYPE_USHORT4N: return 4;
54    case D3DDECLTYPE_UDEC3: return 3;
55    case D3DDECLTYPE_DEC3N: return 3;
56    case D3DDECLTYPE_FLOAT16_2: return 2;
57    case D3DDECLTYPE_FLOAT16_4: return 4;
58    default:
59        assert(!"Implementation error !");
60    }
61    return 0;
62}
63
64static inline uint16_t
65nine_ff_get_projected_key(struct nine_context *context, unsigned num_stages)
66{
67    unsigned s, i;
68    uint16_t projected = 0;
69    int8_t input_texture_coord[num_stages];
70    memset(&input_texture_coord, 0, sizeof(input_texture_coord));
71
72    if (context->vdecl) {
73        for (i = 0; i < context->vdecl->nelems; i++) {
74            uint16_t usage = context->vdecl->usage_map[i];
75            if (usage % NINE_DECLUSAGE_COUNT == NINE_DECLUSAGE_TEXCOORD) {
76                s = usage / NINE_DECLUSAGE_COUNT;
77                if (s < num_stages)
78                    input_texture_coord[s] = nine_decltype_get_dim(context->vdecl->decls[i].Type);
79            }
80        }
81    }
82
83    for (s = 0; s < num_stages; ++s) {
84        unsigned gen = (context->ff.tex_stage[s][D3DTSS_TEXCOORDINDEX] >> 16) + 1;
85        unsigned dim = context->ff.tex_stage[s][D3DTSS_TEXTURETRANSFORMFLAGS] & 0x7;
86        unsigned proj = !!(context->ff.tex_stage[s][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED);
87
88        if (!context->vs) {
89            if (dim > 4)
90                dim = input_texture_coord[s];
91
92            if (!dim && gen == NINED3DTSS_TCI_PASSTHRU)
93                dim = input_texture_coord[s];
94            else if (!dim)
95                dim = 4;
96
97            if (dim == 1) /* NV behaviour */
98                proj = 0;
99            if (dim > input_texture_coord[s] && gen == NINED3DTSS_TCI_PASSTHRU)
100                proj = 0;
101        } else {
102            dim = 4;
103        }
104        if (proj)
105            projected |= (dim-1) << (2 * s);
106    }
107    return projected;
108}
109
110static inline uint16_t
111nine_ff_get_projected_key_ff(struct nine_context *context)
112{
113    /* 8 stages */
114    return nine_ff_get_projected_key(context, 8);
115}
116
117static inline uint8_t
118nine_ff_get_projected_key_programmable(struct nine_context *context)
119{
120    /* We only look at the 4 stages because this function
121     * is used only for ps 1.1-3, where only the first four
122     * slots are available */
123    return (uint8_t)nine_ff_get_projected_key(context, 4);
124}
125
126#endif /* _NINE_FF_H_ */
127