~ubuntu-branches/ubuntu/quantal/mesa-glw/quantal

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/nouveau/nv30_vertprog.c

  • Committer: Bazaar Package Importer
  • Author(s): Morten Kjeldgaard
  • Date: 2008-05-06 16:19:15 UTC
  • Revision ID: james.westby@ubuntu.com-20080506161915-uynz7nftmfixu6bq
Tags: upstream-7.0.3
ImportĀ upstreamĀ versionĀ 7.0.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "nouveau_context.h"
 
2
#include "nouveau_object.h"
 
3
#include "nouveau_fifo.h"
 
4
#include "nouveau_reg.h"
 
5
 
 
6
#include "nouveau_shader.h"
 
7
#include "nv30_shader.h"
 
8
 
 
9
/*****************************************************************************
 
10
 * Support routines
 
11
 */
 
12
static void
 
13
NV30VPUploadToHW(GLcontext *ctx, nouveauShader *nvs)
 
14
{
 
15
   nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
 
16
   int i;
 
17
 
 
18
   /* We can do better here and keep more than one VP on the hardware, and
 
19
    * switch between them with PROGRAM_START_ID..
 
20
    */
 
21
   BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_FROM_ID, 1);
 
22
   OUT_RING(0);
 
23
   for (i=0; i<nvs->program_size; i+=4) {
 
24
      BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_INST0, 4);
 
25
      OUT_RING(nvs->program[i + 0]);
 
26
      OUT_RING(nvs->program[i + 1]);
 
27
      OUT_RING(nvs->program[i + 2]);
 
28
      OUT_RING(nvs->program[i + 3]);
 
29
   }
 
30
   BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_PROGRAM_START_ID, 1);
 
31
   OUT_RING(0);
 
32
 
 
33
   BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_IN_REG, 2);
 
34
   OUT_RING(nvs->card_priv.NV30VP.vp_in_reg);
 
35
   OUT_RING(nvs->card_priv.NV30VP.vp_out_reg);
 
36
 
 
37
   BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_CLIPPING_PLANES, 1);
 
38
   OUT_RING_CACHE  (nvs->card_priv.NV30VP.clip_enables);
 
39
}
 
40
 
 
41
static void
 
42
NV30VPUpdateConst(GLcontext *ctx, nouveauShader *nvs, int id)
 
43
{
 
44
   nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
 
45
   GLfloat *val;
 
46
 
 
47
   val = nvs->params[id].source_val ?
 
48
      nvs->params[id].source_val : nvs->params[id].val;
 
49
 
 
50
   BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_ID, 5);
 
51
   OUT_RING (id);
 
52
   OUT_RINGp(val, 4);
 
53
}
 
54
 
 
55
/*****************************************************************************
 
56
 * Assembly routines
 
57
 */
 
58
static void
 
59
NV30VPSetBranchTarget(nvsFunc *shader, int addr)
 
60
{
 
61
        shader->inst[2] &= ~NV30_VP_INST_IADDR_MASK;
 
62
        shader->inst[2] |= (addr << NV30_VP_INST_IADDR_SHIFT);
 
63
}
 
64
 
 
65
/*****************************************************************************
 
66
 * Disassembly routines
 
67
 */
 
68
static unsigned int
 
69
NV30VPGetOpcodeHW(nvsFunc * shader, int slot)
 
70
{
 
71
   int op;
 
72
 
 
73
   if (slot) {
 
74
      op = (shader->inst[1] & NV30_VP_INST_SCA_OPCODEL_MASK)
 
75
         >> NV30_VP_INST_SCA_OPCODEL_SHIFT;
 
76
      op |= ((shader->inst[0] & NV30_VP_INST_SCA_OPCODEH_MASK)
 
77
             >> NV30_VP_INST_SCA_OPCODEH_SHIFT) << 4;
 
78
   }
 
79
   else {
 
80
      op = (shader->inst[1] & NV30_VP_INST_VEC_OPCODE_MASK)
 
81
         >> NV30_VP_INST_VEC_OPCODE_SHIFT;
 
82
   }
 
83
 
 
84
   return op;
 
85
}
 
86
 
 
87
static nvsRegFile
 
88
NV30VPGetDestFile(nvsFunc * shader, int merged)
 
89
{
 
90
   switch (shader->GetOpcode(shader, merged)) {
 
91
   case NVS_OP_ARL:
 
92
   case NVS_OP_ARR:
 
93
   case NVS_OP_ARA:
 
94
      return NVS_FILE_ADDRESS;
 
95
   default:
 
96
      /*FIXME: This probably isn't correct.. */
 
97
      if ((shader->inst[3] & NV30_VP_INST_VDEST_WRITEMASK_MASK) != 0)
 
98
         return NVS_FILE_RESULT;
 
99
      if ((shader->inst[3] & NV30_VP_INST_SDEST_WRITEMASK_MASK) != 0)
 
100
         return NVS_FILE_RESULT;
 
101
      return NVS_FILE_TEMP;
 
102
   }
 
103
}
 
104
 
 
105
static unsigned int
 
106
NV30VPGetDestID(nvsFunc * shader, int merged)
 
107
{
 
108
   int id;
 
109
 
 
110
   switch (shader->GetDestFile(shader, merged)) {
 
111
   case NVS_FILE_RESULT:
 
112
      id = ((shader->inst[3] & NV30_VP_INST_DEST_ID_MASK)
 
113
            >> NV30_VP_INST_DEST_ID_SHIFT);
 
114
      switch (id) {
 
115
      case NV30_VP_INST_DEST_POS  : return NVS_FR_POSITION;
 
116
      case NV30_VP_INST_DEST_COL0 : return NVS_FR_COL0;
 
117
      case NV30_VP_INST_DEST_COL1 : return NVS_FR_COL1;
 
118
      case NV30_VP_INST_DEST_TC(0): return NVS_FR_TEXCOORD0;
 
119
      case NV30_VP_INST_DEST_TC(1): return NVS_FR_TEXCOORD1;
 
120
      case NV30_VP_INST_DEST_TC(2): return NVS_FR_TEXCOORD2;
 
121
      case NV30_VP_INST_DEST_TC(3): return NVS_FR_TEXCOORD3;
 
122
      case NV30_VP_INST_DEST_TC(4): return NVS_FR_TEXCOORD4;
 
123
      case NV30_VP_INST_DEST_TC(5): return NVS_FR_TEXCOORD5;
 
124
      case NV30_VP_INST_DEST_TC(6): return NVS_FR_TEXCOORD6;
 
125
      case NV30_VP_INST_DEST_TC(7): return NVS_FR_TEXCOORD7;
 
126
      default:
 
127
         return -1;
 
128
      }
 
129
   case NVS_FILE_ADDRESS:
 
130
   case NVS_FILE_TEMP:
 
131
      return (shader->inst[0] & NV30_VP_INST_DEST_TEMP_ID_MASK)
 
132
         >> NV30_VP_INST_DEST_TEMP_ID_SHIFT;
 
133
   default:
 
134
      return -1;
 
135
   }
 
136
}
 
137
 
 
138
static unsigned int
 
139
NV30VPGetDestMask(nvsFunc * shader, int merged)
 
140
{
 
141
   int hwmask, mask = 0;
 
142
 
 
143
   if (shader->GetDestFile(shader, merged) == NVS_FILE_RESULT)
 
144
      if (shader->GetOpcodeSlot(shader, merged))
 
145
         hwmask = (shader->inst[3] & NV30_VP_INST_SDEST_WRITEMASK_MASK)
 
146
            >> NV30_VP_INST_SDEST_WRITEMASK_SHIFT;
 
147
      else
 
148
         hwmask = (shader->inst[3] & NV30_VP_INST_VDEST_WRITEMASK_MASK)
 
149
            >> NV30_VP_INST_VDEST_WRITEMASK_SHIFT;
 
150
   else if (shader->GetOpcodeSlot(shader, merged))
 
151
      hwmask = (shader->inst[3] & NV30_VP_INST_STEMP_WRITEMASK_MASK)
 
152
         >> NV30_VP_INST_STEMP_WRITEMASK_SHIFT;
 
153
   else
 
154
      hwmask = (shader->inst[3] & NV30_VP_INST_VTEMP_WRITEMASK_MASK)
 
155
         >> NV30_VP_INST_VTEMP_WRITEMASK_SHIFT;
 
156
 
 
157
   if (hwmask & (1 << 3)) mask |= SMASK_X;
 
158
   if (hwmask & (1 << 2)) mask |= SMASK_Y;
 
159
   if (hwmask & (1 << 1)) mask |= SMASK_Z;
 
160
   if (hwmask & (1 << 0)) mask |= SMASK_W;
 
161
 
 
162
   return mask;
 
163
}
 
164
 
 
165
static int
 
166
NV30VPGetSourceID(nvsFunc * shader, int merged, int pos)
 
167
{
 
168
   unsigned int src;
 
169
 
 
170
   switch (shader->GetSourceFile(shader, merged, pos)) {
 
171
   case NVS_FILE_TEMP:
 
172
      src = shader->GetSourceHW(shader, merged, pos);
 
173
      return ((src & NV30_VP_SRC_REG_TEMP_ID_MASK) >>
 
174
              NV30_VP_SRC_REG_TEMP_ID_SHIFT);
 
175
   case NVS_FILE_CONST:
 
176
      return ((shader->inst[1] & NV30_VP_INST_CONST_SRC_MASK)
 
177
              >> NV30_VP_INST_CONST_SRC_SHIFT);
 
178
   case NVS_FILE_ATTRIB:
 
179
      src = ((shader->inst[1] & NV30_VP_INST_INPUT_SRC_MASK)
 
180
             >> NV30_VP_INST_INPUT_SRC_SHIFT);
 
181
      switch (src) {
 
182
      case NV30_VP_INST_IN_POS  : return NVS_FR_POSITION;
 
183
      case NV30_VP_INST_IN_COL0 : return NVS_FR_COL0;
 
184
      case NV30_VP_INST_IN_COL1 : return NVS_FR_COL1;
 
185
      case NV30_VP_INST_IN_TC(0): return NVS_FR_TEXCOORD0;
 
186
      case NV30_VP_INST_IN_TC(1): return NVS_FR_TEXCOORD1;
 
187
      case NV30_VP_INST_IN_TC(2): return NVS_FR_TEXCOORD2;
 
188
      case NV30_VP_INST_IN_TC(3): return NVS_FR_TEXCOORD3;
 
189
      case NV30_VP_INST_IN_TC(4): return NVS_FR_TEXCOORD4;
 
190
      case NV30_VP_INST_IN_TC(5): return NVS_FR_TEXCOORD5;
 
191
      case NV30_VP_INST_IN_TC(6): return NVS_FR_TEXCOORD6;
 
192
      case NV30_VP_INST_IN_TC(7): return NVS_FR_TEXCOORD7;
 
193
      default:
 
194
         return NVS_FR_UNKNOWN;
 
195
      }
 
196
   default:
 
197
      return -1;
 
198
   }
 
199
}
 
200
 
 
201
static int
 
202
NV30VPGetSourceAbs(nvsFunc * shader, int merged, int pos)
 
203
{
 
204
   struct _op_xlat *opr;
 
205
   static unsigned int abspos[3] = {
 
206
      NV30_VP_INST_SRC0_ABS,
 
207
      NV30_VP_INST_SRC1_ABS,
 
208
      NV30_VP_INST_SRC2_ABS,
 
209
   };
 
210
 
 
211
   opr = shader->GetOPTXRec(shader, merged);
 
212
   if (!opr || opr->srcpos[pos] == -1 || opr->srcpos[pos] > 2)
 
213
      return 0;
 
214
 
 
215
   return ((shader->inst[0] & abspos[opr->srcpos[pos]]) ? 1 : 0);
 
216
}
 
217
 
 
218
static int
 
219
NV30VPGetRelAddressRegID(nvsFunc * shader)
 
220
{
 
221
   return ((shader->inst[0] & NV30_VP_INST_ADDR_REG_SELECT_1) ? 1 : 0);
 
222
}
 
223
 
 
224
static nvsSwzComp
 
225
NV30VPGetRelAddressSwizzle(nvsFunc * shader)
 
226
{
 
227
   nvsSwzComp swz;
 
228
 
 
229
   swz = NV20VP_TX_SWIZZLE[(shader->inst[0] & NV30_VP_INST_ADDR_SWZ_MASK)
 
230
                           >> NV30_VP_INST_ADDR_SWZ_SHIFT];
 
231
   return swz;
 
232
}
 
233
 
 
234
static int
 
235
NV30VPSupportsConditional(nvsFunc * shader)
 
236
{
 
237
   /*FIXME: Is this true of all ops? */
 
238
   return 1;
 
239
}
 
240
 
 
241
static int
 
242
NV30VPGetConditionUpdate(nvsFunc * shader)
 
243
{
 
244
   return ((shader->inst[0] & NV30_VP_INST_COND_UPDATE_ENABLE) ? 1 : 0);
 
245
}
 
246
 
 
247
static int
 
248
NV30VPGetConditionTest(nvsFunc * shader)
 
249
{
 
250
   int op;
 
251
 
 
252
   /* The condition test is unconditionally enabled on some
 
253
    * instructions. ie: the condition test bit does *NOT* have
 
254
    * to be set.
 
255
    *
 
256
    * FIXME: check other relevant ops for this situation.
 
257
    */
 
258
   op = shader->GetOpcodeHW(shader, 1);
 
259
   switch (op) {
 
260
   case NV30_VP_INST_OP_BRA:
 
261
      return 1;
 
262
   default:
 
263
      return ((shader->inst[0] & NV30_VP_INST_COND_TEST_ENABLE) ? 1 : 0);
 
264
   }
 
265
}
 
266
 
 
267
static nvsCond
 
268
NV30VPGetCondition(nvsFunc * shader)
 
269
{
 
270
   int cond;
 
271
 
 
272
   cond = ((shader->inst[0] & NV30_VP_INST_COND_MASK)
 
273
           >> NV30_VP_INST_COND_SHIFT);
 
274
 
 
275
   switch (cond) {
 
276
   case NV30_VP_INST_COND_FL: return NVS_COND_FL;
 
277
   case NV30_VP_INST_COND_LT: return NVS_COND_LT;
 
278
   case NV30_VP_INST_COND_EQ: return NVS_COND_EQ;
 
279
   case NV30_VP_INST_COND_LE: return NVS_COND_LE;
 
280
   case NV30_VP_INST_COND_GT: return NVS_COND_GT;
 
281
   case NV30_VP_INST_COND_NE: return NVS_COND_NE;
 
282
   case NV30_VP_INST_COND_GE: return NVS_COND_GE;
 
283
   case NV30_VP_INST_COND_TR: return NVS_COND_TR;
 
284
   default:
 
285
      return NVS_COND_UNKNOWN;
 
286
   }
 
287
}
 
288
 
 
289
static void
 
290
NV30VPGetCondRegSwizzle(nvsFunc * shader, nvsSwzComp *swz)
 
291
{
 
292
   int swzbits;
 
293
 
 
294
   swzbits = (shader->inst[0] & NV30_VP_INST_COND_SWZ_ALL_MASK)
 
295
      >> NV30_VP_INST_COND_SWZ_ALL_SHIFT;
 
296
   NV20VPTXSwizzle(swzbits, swz);
 
297
}
 
298
 
 
299
static int
 
300
NV30VPGetCondRegID(nvsFunc * shader)
 
301
{
 
302
   return 0;
 
303
}
 
304
 
 
305
 
 
306
static int
 
307
NV30VPGetBranch(nvsFunc * shader)
 
308
{
 
309
   return ((shader->inst[2] & NV30_VP_INST_IADDR_MASK)
 
310
           >> NV30_VP_INST_IADDR_SHIFT);
 
311
}
 
312
 
 
313
void
 
314
NV30VPInitShaderFuncs(nvsFunc * shader)
 
315
{
 
316
   /* Inherit NV20 code, a lot of it is the same */
 
317
   NV20VPInitShaderFuncs(shader);
 
318
 
 
319
   /* Increase max valid opcode ID, and add new instructions */
 
320
   NVVP_TX_VOP_COUNT = NVVP_TX_NVS_OP_COUNT = 32;
 
321
 
 
322
   MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_FRC, NVS_OP_FRC,  0, -1, -1);
 
323
   MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_FLR, NVS_OP_FLR,  0, -1, -1);
 
324
   MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SEQ, NVS_OP_SEQ,  0,  1, -1);
 
325
   MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SFL, NVS_OP_SFL,  0,  1, -1);
 
326
   MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SGT, NVS_OP_SGT,  0,  1, -1);
 
327
   MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SLE, NVS_OP_SLE,  0,  1, -1);
 
328
   MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SNE, NVS_OP_SNE,  0,  1, -1);
 
329
   MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_STR, NVS_OP_STR,  0,  1, -1);
 
330
   MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_SSG, NVS_OP_SSG,  0, -1, -1);
 
331
   MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_ARR, NVS_OP_ARR,  0, -1, -1);
 
332
   MOD_OPCODE(NVVP_TX_VOP, NV30_VP_INST_OP_ARA, NVS_OP_ARA,  3, -1, -1);
 
333
 
 
334
   MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_BRA, NVS_OP_BRA, -1, -1, -1);
 
335
   MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_CAL, NVS_OP_CAL, -1, -1, -1);
 
336
   MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_RET, NVS_OP_RET, -1, -1, -1);
 
337
   MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_LG2, NVS_OP_LG2,  2, -1, -1);
 
338
   MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_EX2, NVS_OP_EX2,  2, -1, -1);
 
339
   MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_SIN, NVS_OP_SIN,  2, -1, -1);
 
340
   MOD_OPCODE(NVVP_TX_SOP, NV30_VP_INST_OP_COS, NVS_OP_COS,  2, -1, -1);
 
341
 
 
342
   shader->UploadToHW           = NV30VPUploadToHW;
 
343
   shader->UpdateConst          = NV30VPUpdateConst;
 
344
 
 
345
   shader->GetOpcodeHW          = NV30VPGetOpcodeHW;
 
346
 
 
347
   shader->GetDestFile          = NV30VPGetDestFile;
 
348
   shader->GetDestID            = NV30VPGetDestID;
 
349
   shader->GetDestMask          = NV30VPGetDestMask;
 
350
 
 
351
   shader->GetSourceID          = NV30VPGetSourceID;
 
352
   shader->GetSourceAbs         = NV30VPGetSourceAbs;
 
353
 
 
354
   shader->GetRelAddressRegID   = NV30VPGetRelAddressRegID;
 
355
   shader->GetRelAddressSwizzle = NV30VPGetRelAddressSwizzle;
 
356
 
 
357
   shader->SupportsConditional  = NV30VPSupportsConditional;
 
358
   shader->GetConditionUpdate   = NV30VPGetConditionUpdate;
 
359
   shader->GetConditionTest     = NV30VPGetConditionTest;
 
360
   shader->GetCondition         = NV30VPGetCondition;
 
361
   shader->GetCondRegSwizzle    = NV30VPGetCondRegSwizzle;
 
362
   shader->GetCondRegID         = NV30VPGetCondRegID;
 
363
 
 
364
   shader->GetBranch            = NV30VPGetBranch;
 
365
   shader->SetBranchTarget      = NV30VPSetBranchTarget;
 
366
}
 
367