1 #include "nouveau_shader.h"
2 #include "nv40_shader.h"
5 unsigned int NVFP_TX_BOP_COUNT
= 5;
6 struct _op_xlat NVFP_TX_BOP
[64];
9 /*****************************************************************************
11 * - These extend the NV30 routines, which are almost identical. NV40
12 * just has branching hacked into the instruction set.
15 NV40FPSupportsResultScale(nvsFunc
*shader
, nvsScale scale
)
22 case NVS_SCALE_INV_2X
:
23 case NVS_SCALE_INV_4X
:
24 case NVS_SCALE_INV_8X
:
32 NV40FPSetResultScale(nvsFunc
*shader
, nvsScale scale
)
34 shader
->inst
[2] &= ~NV40_FP_OP_DST_SCALE_MASK
;
35 shader
->inst
[2] |= ((unsigned int)scale
<< NV40_FP_OP_DST_SCALE_SHIFT
);
39 NV40FPSetBranchTarget(nvsFunc
*shader
, int addr
)
41 shader
->inst
[2] &= ~NV40_FP_OP_IADDR_MASK
;
42 shader
->inst
[2] |= (addr
<< NV40_FP_OP_IADDR_SHIFT
);
46 NV40FPSetBranchElse(nvsFunc
*shader
, int addr
)
48 shader
->inst
[2] &= ~NV40_FP_OP_ELSE_ID_MASK
;
49 shader
->inst
[2] |= (addr
<< NV40_FP_OP_ELSE_ID_SHIFT
);
53 NV40FPSetBranchEnd(nvsFunc
*shader
, int addr
)
55 shader
->inst
[3] &= ~NV40_FP_OP_END_ID_MASK
;
56 shader
->inst
[3] |= (addr
<< NV40_FP_OP_END_ID_SHIFT
);
60 NV40FPSetLoopParams(nvsFunc
*shader
, int count
, int initial
, int increment
)
62 shader
->inst
[2] &= ~(NV40_FP_OP_LOOP_COUNT_MASK
|
63 NV40_FP_OP_LOOP_INDEX_MASK
|
64 NV40_FP_OP_LOOP_INCR_MASK
);
65 shader
->inst
[2] |= ((count
<< NV40_FP_OP_LOOP_COUNT_SHIFT
) |
66 (initial
<< NV40_FP_OP_LOOP_INDEX_SHIFT
) |
67 (increment
<< NV40_FP_OP_LOOP_INCR_SHIFT
));
70 /*****************************************************************************
71 * Disassembly routines
73 static struct _op_xlat
*
74 NV40FPGetOPTXRec(nvsFunc
* shader
, int merged
)
79 op
= shader
->GetOpcodeHW(shader
, 0);
80 if (shader
->inst
[2] & NV40_FP_OP_OPCODE_IS_BRANCH
) {
82 op
&= ~NV40_FP_OP_OPCODE_IS_BRANCH
;
83 if (op
> NVFP_TX_BOP_COUNT
)
88 if (op
> NVFP_TX_AOP_COUNT
)
92 if (opr
[op
].SOP
== NVS_OP_UNKNOWN
)
98 NV40FPGetSourceID(nvsFunc
* shader
, int merged
, int pos
)
100 switch (shader
->GetSourceFile(shader
, merged
, pos
)) {
101 case NVS_FILE_ATTRIB
:
102 switch ((shader
->inst
[0] & NV40_FP_OP_INPUT_SRC_MASK
)
103 >> NV40_FP_OP_INPUT_SRC_SHIFT
) {
104 case NV40_FP_OP_INPUT_SRC_POSITION
: return NVS_FR_POSITION
;
105 case NV40_FP_OP_INPUT_SRC_COL0
: return NVS_FR_COL0
;
106 case NV40_FP_OP_INPUT_SRC_COL1
: return NVS_FR_COL1
;
107 case NV40_FP_OP_INPUT_SRC_FOGC
: return NVS_FR_FOGCOORD
;
108 case NV40_FP_OP_INPUT_SRC_TC(0) : return NVS_FR_TEXCOORD0
;
109 case NV40_FP_OP_INPUT_SRC_TC(1) : return NVS_FR_TEXCOORD1
;
110 case NV40_FP_OP_INPUT_SRC_TC(2) : return NVS_FR_TEXCOORD2
;
111 case NV40_FP_OP_INPUT_SRC_TC(3) : return NVS_FR_TEXCOORD3
;
112 case NV40_FP_OP_INPUT_SRC_TC(4) : return NVS_FR_TEXCOORD4
;
113 case NV40_FP_OP_INPUT_SRC_TC(5) : return NVS_FR_TEXCOORD5
;
114 case NV40_FP_OP_INPUT_SRC_TC(6) : return NVS_FR_TEXCOORD6
;
115 case NV40_FP_OP_INPUT_SRC_TC(7) : return NVS_FR_TEXCOORD7
;
116 case NV40_FP_OP_INPUT_SRC_FACING
: return NVS_FR_FACING
;
125 src
= shader
->GetSourceHW(shader
, merged
, pos
);
126 return ((src
& NV40_FP_REG_SRC_MASK
) >> NV40_FP_REG_SRC_SHIFT
);
128 case NVS_FILE_CONST
: /* inlined into fragprog */
135 NV40FPGetBranch(nvsFunc
* shader
)
137 return ((shader
->inst
[2] & NV40_FP_OP_IADDR_MASK
)
138 >> NV40_FP_OP_IADDR_SHIFT
);;
142 NV40FPGetBranchElse(nvsFunc
* shader
)
144 return ((shader
->inst
[2] & NV40_FP_OP_ELSE_ID_MASK
)
145 >> NV40_FP_OP_ELSE_ID_SHIFT
);
149 NV40FPGetBranchEnd(nvsFunc
* shader
)
151 return ((shader
->inst
[3] & NV40_FP_OP_END_ID_MASK
)
152 >> NV40_FP_OP_END_ID_SHIFT
);
156 NV40FPGetLoopCount(nvsFunc
* shader
)
158 return ((shader
->inst
[2] & NV40_FP_OP_LOOP_COUNT_MASK
)
159 >> NV40_FP_OP_LOOP_COUNT_SHIFT
);
163 NV40FPGetLoopInitial(nvsFunc
* shader
)
165 return ((shader
->inst
[2] & NV40_FP_OP_LOOP_INDEX_MASK
)
166 >> NV40_FP_OP_LOOP_INDEX_SHIFT
);
170 NV40FPGetLoopIncrement(nvsFunc
* shader
)
172 return ((shader
->inst
[2] & NV40_FP_OP_LOOP_INCR_MASK
)
173 >> NV40_FP_OP_LOOP_INCR_SHIFT
);
177 NV40FPInitShaderFuncs(nvsFunc
* shader
)
179 /* Inherit NV30 FP code, it's mostly the same */
180 NV30FPInitShaderFuncs(shader
);
182 /* Kill off opcodes seen on NV30, but not seen on NV40 - need to find
183 * out if these actually work or not.
185 * update: either LIT/RSQ don't work on nv40, or I generate bad code for
186 * them. haven't tested the others yet
188 MOD_OPCODE(NVFP_TX_AOP
, 0x1B, NVS_OP_UNKNOWN
, -1, -1, -1); /* NV30 RSQ */
189 MOD_OPCODE(NVFP_TX_AOP
, 0x1E, NVS_OP_UNKNOWN
, -1, -1, -1); /* NV30 LIT */
190 MOD_OPCODE(NVFP_TX_AOP
, 0x1F, NVS_OP_UNKNOWN
, -1, -1, -1); /* NV30 LRP */
191 MOD_OPCODE(NVFP_TX_AOP
, 0x26, NVS_OP_UNKNOWN
, -1, -1, -1); /* NV30 POW */
192 MOD_OPCODE(NVFP_TX_AOP
, 0x36, NVS_OP_UNKNOWN
, -1, -1, -1); /* NV30 RFL */
194 /* Extra opcodes supported on NV40 */
195 MOD_OPCODE(NVFP_TX_AOP
, NV40_FP_OP_OPCODE_DIV
, NVS_OP_DIV
, 0, 1, -1);
196 MOD_OPCODE(NVFP_TX_AOP
, NV40_FP_OP_OPCODE_DP2A
, NVS_OP_DP2A
, 0, 1, 2);
197 MOD_OPCODE(NVFP_TX_AOP
, NV40_FP_OP_OPCODE_TXL
, NVS_OP_TXL
, 0, -1, -1);
199 MOD_OPCODE(NVFP_TX_BOP
, NV40_FP_OP_BRA_OPCODE_BRK
, NVS_OP_BRK
, -1, -1, -1);
200 MOD_OPCODE(NVFP_TX_BOP
, NV40_FP_OP_BRA_OPCODE_CAL
, NVS_OP_CAL
, -1, -1, -1);
201 MOD_OPCODE(NVFP_TX_BOP
, NV40_FP_OP_BRA_OPCODE_IF
, NVS_OP_IF
, -1, -1, -1);
202 MOD_OPCODE(NVFP_TX_BOP
, NV40_FP_OP_BRA_OPCODE_LOOP
, NVS_OP_LOOP
, -1, -1, -1);
203 MOD_OPCODE(NVFP_TX_BOP
, NV40_FP_OP_BRA_OPCODE_REP
, NVS_OP_REP
, -1, -1, -1);
204 MOD_OPCODE(NVFP_TX_BOP
, NV40_FP_OP_BRA_OPCODE_RET
, NVS_OP_RET
, -1, -1, -1);
206 shader
->SupportsResultScale
= NV40FPSupportsResultScale
;
207 shader
->SetResultScale
= NV40FPSetResultScale
;
209 /* fragment.facing */
210 shader
->GetSourceID
= NV40FPGetSourceID
;
213 shader
->GetOPTXRec
= NV40FPGetOPTXRec
;
214 shader
->GetBranch
= NV40FPGetBranch
;
215 shader
->GetBranchElse
= NV40FPGetBranchElse
;
216 shader
->GetBranchEnd
= NV40FPGetBranchEnd
;
217 shader
->GetLoopCount
= NV40FPGetLoopCount
;
218 shader
->GetLoopInitial
= NV40FPGetLoopInitial
;
219 shader
->GetLoopIncrement
= NV40FPGetLoopIncrement
;
220 shader
->SetBranchTarget
= NV40FPSetBranchTarget
;
221 shader
->SetBranchElse
= NV40FPSetBranchElse
;
222 shader
->SetBranchEnd
= NV40FPSetBranchEnd
;
223 shader
->SetLoopParams
= NV40FPSetLoopParams
;