17ec681f3Smrg
27ec681f3Smrg#ifndef _NINE_FF_H_
37ec681f3Smrg#define _NINE_FF_H_
47ec681f3Smrg
57ec681f3Smrg#include "device9.h"
67ec681f3Smrg#include "vertexdeclaration9.h"
77ec681f3Smrg
87ec681f3Smrgboolean nine_ff_init(struct NineDevice9 *);
97ec681f3Smrgvoid    nine_ff_fini(struct NineDevice9 *);
107ec681f3Smrg
117ec681f3Smrgvoid nine_ff_update(struct NineDevice9 *);
127ec681f3Smrg
137ec681f3Smrgvoid
147ec681f3Smrgnine_d3d_matrix_matrix_mul(D3DMATRIX *, const D3DMATRIX *, const D3DMATRIX *);
157ec681f3Smrg
167ec681f3Smrgvoid
177ec681f3Smrgnine_d3d_vector4_matrix_mul(D3DVECTOR *, const D3DVECTOR *, const D3DMATRIX *);
187ec681f3Smrgvoid
197ec681f3Smrgnine_d3d_vector3_matrix_mul(D3DVECTOR *, const D3DVECTOR *, const D3DMATRIX *);
207ec681f3Smrg
217ec681f3Smrgfloat
227ec681f3Smrgnine_d3d_matrix_det(const D3DMATRIX *);
237ec681f3Smrg
247ec681f3Smrgvoid
257ec681f3Smrgnine_d3d_matrix_inverse(D3DMATRIX *, const D3DMATRIX *);
267ec681f3Smrg
277ec681f3Smrgvoid
287ec681f3Smrgnine_d3d_matrix_transpose(D3DMATRIX *, const D3DMATRIX *);
297ec681f3Smrg
307ec681f3Smrg#define NINED3DTSS_TCI_DISABLE                       0
317ec681f3Smrg#define NINED3DTSS_TCI_PASSTHRU                      1
327ec681f3Smrg#define NINED3DTSS_TCI_CAMERASPACENORMAL             2
337ec681f3Smrg#define NINED3DTSS_TCI_CAMERASPACEPOSITION           3
347ec681f3Smrg#define NINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR   4
357ec681f3Smrg#define NINED3DTSS_TCI_SPHEREMAP                     5
367ec681f3Smrg
377ec681f3Smrgstatic inline unsigned
387ec681f3Smrgnine_decltype_get_dim(BYTE type)
397ec681f3Smrg{
407ec681f3Smrg    switch (type) {
417ec681f3Smrg    case D3DDECLTYPE_FLOAT1: return 1;
427ec681f3Smrg    case D3DDECLTYPE_FLOAT2: return 2;
437ec681f3Smrg    case D3DDECLTYPE_FLOAT3: return 3;
447ec681f3Smrg    case D3DDECLTYPE_FLOAT4: return 4;
457ec681f3Smrg    case D3DDECLTYPE_D3DCOLOR: return 1;
467ec681f3Smrg    case D3DDECLTYPE_UBYTE4: return 4;
477ec681f3Smrg    case D3DDECLTYPE_SHORT2: return 2;
487ec681f3Smrg    case D3DDECLTYPE_SHORT4: return 4;
497ec681f3Smrg    case D3DDECLTYPE_UBYTE4N: return 4;
507ec681f3Smrg    case D3DDECLTYPE_SHORT2N: return 2;
517ec681f3Smrg    case D3DDECLTYPE_SHORT4N: return 4;
527ec681f3Smrg    case D3DDECLTYPE_USHORT2N: return 2;
537ec681f3Smrg    case D3DDECLTYPE_USHORT4N: return 4;
547ec681f3Smrg    case D3DDECLTYPE_UDEC3: return 3;
557ec681f3Smrg    case D3DDECLTYPE_DEC3N: return 3;
567ec681f3Smrg    case D3DDECLTYPE_FLOAT16_2: return 2;
577ec681f3Smrg    case D3DDECLTYPE_FLOAT16_4: return 4;
587ec681f3Smrg    default:
597ec681f3Smrg        assert(!"Implementation error !");
607ec681f3Smrg    }
617ec681f3Smrg    return 0;
627ec681f3Smrg}
637ec681f3Smrg
647ec681f3Smrgstatic inline uint16_t
657ec681f3Smrgnine_ff_get_projected_key(struct nine_context *context, unsigned num_stages)
667ec681f3Smrg{
677ec681f3Smrg    unsigned s, i;
687ec681f3Smrg    uint16_t projected = 0;
697ec681f3Smrg    char input_texture_coord[num_stages];
707ec681f3Smrg    memset(&input_texture_coord, 0, sizeof(input_texture_coord));
717ec681f3Smrg
727ec681f3Smrg    if (context->vdecl) {
737ec681f3Smrg        for (i = 0; i < context->vdecl->nelems; i++) {
747ec681f3Smrg            uint16_t usage = context->vdecl->usage_map[i];
757ec681f3Smrg            if (usage % NINE_DECLUSAGE_COUNT == NINE_DECLUSAGE_TEXCOORD) {
767ec681f3Smrg                s = usage / NINE_DECLUSAGE_COUNT;
777ec681f3Smrg                if (s < num_stages)
787ec681f3Smrg                    input_texture_coord[s] = nine_decltype_get_dim(context->vdecl->decls[i].Type);
797ec681f3Smrg            }
807ec681f3Smrg        }
817ec681f3Smrg    }
827ec681f3Smrg
837ec681f3Smrg    for (s = 0; s < num_stages; ++s) {
847ec681f3Smrg        unsigned gen = (context->ff.tex_stage[s][D3DTSS_TEXCOORDINDEX] >> 16) + 1;
857ec681f3Smrg        unsigned dim = context->ff.tex_stage[s][D3DTSS_TEXTURETRANSFORMFLAGS] & 0x7;
867ec681f3Smrg        unsigned proj = !!(context->ff.tex_stage[s][D3DTSS_TEXTURETRANSFORMFLAGS] & D3DTTFF_PROJECTED);
877ec681f3Smrg
887ec681f3Smrg        if (!context->vs) {
897ec681f3Smrg            if (dim > 4)
907ec681f3Smrg                dim = input_texture_coord[s];
917ec681f3Smrg
927ec681f3Smrg            if (!dim && gen == NINED3DTSS_TCI_PASSTHRU)
937ec681f3Smrg                dim = input_texture_coord[s];
947ec681f3Smrg            else if (!dim)
957ec681f3Smrg                dim = 4;
967ec681f3Smrg
977ec681f3Smrg            if (dim == 1) /* NV behaviour */
987ec681f3Smrg                proj = 0;
997ec681f3Smrg            if (dim > input_texture_coord[s] && gen == NINED3DTSS_TCI_PASSTHRU)
1007ec681f3Smrg                proj = 0;
1017ec681f3Smrg        } else {
1027ec681f3Smrg            dim = 4;
1037ec681f3Smrg        }
1047ec681f3Smrg        if (proj)
1057ec681f3Smrg            projected |= (dim-1) << (2 * s);
1067ec681f3Smrg    }
1077ec681f3Smrg    return projected;
1087ec681f3Smrg}
1097ec681f3Smrg
1107ec681f3Smrgstatic inline uint16_t
1117ec681f3Smrgnine_ff_get_projected_key_ff(struct nine_context *context)
1127ec681f3Smrg{
1137ec681f3Smrg    /* 8 stages */
1147ec681f3Smrg    return nine_ff_get_projected_key(context, 8);
1157ec681f3Smrg}
1167ec681f3Smrg
1177ec681f3Smrgstatic inline uint8_t
1187ec681f3Smrgnine_ff_get_projected_key_programmable(struct nine_context *context)
1197ec681f3Smrg{
1207ec681f3Smrg    /* We only look at the 4 stages because this function
1217ec681f3Smrg     * is used only for ps 1.1-3, where only the first four
1227ec681f3Smrg     * slots are available */
1237ec681f3Smrg    return (uint8_t)nine_ff_get_projected_key(context, 4);
1247ec681f3Smrg}
1257ec681f3Smrg
1267ec681f3Smrg#endif /* _NINE_FF_H_ */
127