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