r300/compiler: Fix black terrain in Civ4
[mesa.git] / src / mesa / drivers / dri / r300 / compiler / radeon_opcodes.c
1 /*
2 * Copyright (C) 2009 Nicolai Haehnle.
3 *
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial
16 * portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 */
27
28 #include "radeon_opcodes.h"
29 #include "radeon_program.h"
30
31 #include "radeon_program_constants.h"
32
33 struct rc_opcode_info rc_opcodes[MAX_RC_OPCODE] = {
34 {
35 .Opcode = RC_OPCODE_NOP,
36 .Name = "NOP"
37 },
38 {
39 .Opcode = RC_OPCODE_ILLEGAL_OPCODE,
40 .Name = "ILLEGAL OPCODE"
41 },
42 {
43 .Opcode = RC_OPCODE_ABS,
44 .Name = "ABS",
45 .NumSrcRegs = 1,
46 .HasDstReg = 1,
47 .IsComponentwise = 1
48 },
49 {
50 .Opcode = RC_OPCODE_ADD,
51 .Name = "ADD",
52 .NumSrcRegs = 2,
53 .HasDstReg = 1,
54 .IsComponentwise = 1
55 },
56 {
57 .Opcode = RC_OPCODE_ARL,
58 .Name = "ARL",
59 .NumSrcRegs = 1,
60 .HasDstReg = 1
61 },
62 {
63 .Opcode = RC_OPCODE_CEIL,
64 .Name = "CEIL",
65 .NumSrcRegs = 1,
66 .HasDstReg = 1,
67 .IsComponentwise = 1
68 },
69 {
70 .Opcode = RC_OPCODE_CLAMP,
71 .Name = "CLAMP",
72 .NumSrcRegs = 3,
73 .HasDstReg = 1,
74 .IsComponentwise = 1
75 },
76 {
77 .Opcode = RC_OPCODE_CMP,
78 .Name = "CMP",
79 .NumSrcRegs = 3,
80 .HasDstReg = 1,
81 .IsComponentwise = 1
82 },
83 {
84 .Opcode = RC_OPCODE_COS,
85 .Name = "COS",
86 .NumSrcRegs = 1,
87 .HasDstReg = 1,
88 .IsStandardScalar = 1
89 },
90 {
91 .Opcode = RC_OPCODE_DDX,
92 .Name = "DDX",
93 .NumSrcRegs = 2,
94 .HasDstReg = 1,
95 .IsComponentwise = 1
96 },
97 {
98 .Opcode = RC_OPCODE_DDY,
99 .Name = "DDY",
100 .NumSrcRegs = 2,
101 .HasDstReg = 1,
102 .IsComponentwise = 1
103 },
104 {
105 .Opcode = RC_OPCODE_DP2,
106 .Name = "DP2",
107 .NumSrcRegs = 2,
108 .HasDstReg = 1
109 },
110 {
111 .Opcode = RC_OPCODE_DP3,
112 .Name = "DP3",
113 .NumSrcRegs = 2,
114 .HasDstReg = 1
115 },
116 {
117 .Opcode = RC_OPCODE_DP4,
118 .Name = "DP4",
119 .NumSrcRegs = 2,
120 .HasDstReg = 1
121 },
122 {
123 .Opcode = RC_OPCODE_DPH,
124 .Name = "DPH",
125 .NumSrcRegs = 2,
126 .HasDstReg = 1
127 },
128 {
129 .Opcode = RC_OPCODE_DST,
130 .Name = "DST",
131 .NumSrcRegs = 2,
132 .HasDstReg = 1
133 },
134 {
135 .Opcode = RC_OPCODE_EX2,
136 .Name = "EX2",
137 .NumSrcRegs = 1,
138 .HasDstReg = 1,
139 .IsStandardScalar = 1
140 },
141 {
142 .Opcode = RC_OPCODE_EXP,
143 .Name = "EXP",
144 .NumSrcRegs = 1,
145 .HasDstReg = 1
146 },
147 {
148 .Opcode = RC_OPCODE_FLR,
149 .Name = "FLR",
150 .NumSrcRegs = 1,
151 .HasDstReg = 1,
152 .IsComponentwise = 1
153 },
154 {
155 .Opcode = RC_OPCODE_FRC,
156 .Name = "FRC",
157 .NumSrcRegs = 1,
158 .HasDstReg = 1,
159 .IsComponentwise = 1
160 },
161 {
162 .Opcode = RC_OPCODE_KIL,
163 .Name = "KIL",
164 .NumSrcRegs = 1
165 },
166 {
167 .Opcode = RC_OPCODE_LG2,
168 .Name = "LG2",
169 .NumSrcRegs = 1,
170 .HasDstReg = 1,
171 .IsStandardScalar = 1
172 },
173 {
174 .Opcode = RC_OPCODE_LIT,
175 .Name = "LIT",
176 .NumSrcRegs = 1,
177 .HasDstReg = 1
178 },
179 {
180 .Opcode = RC_OPCODE_LOG,
181 .Name = "LOG",
182 .NumSrcRegs = 1,
183 .HasDstReg = 1
184 },
185 {
186 .Opcode = RC_OPCODE_LRP,
187 .Name = "LRP",
188 .NumSrcRegs = 3,
189 .HasDstReg = 1,
190 .IsComponentwise = 1
191 },
192 {
193 .Opcode = RC_OPCODE_MAD,
194 .Name = "MAD",
195 .NumSrcRegs = 3,
196 .HasDstReg = 1,
197 .IsComponentwise = 1
198 },
199 {
200 .Opcode = RC_OPCODE_MAX,
201 .Name = "MAX",
202 .NumSrcRegs = 2,
203 .HasDstReg = 1,
204 .IsComponentwise = 1
205 },
206 {
207 .Opcode = RC_OPCODE_MIN,
208 .Name = "MIN",
209 .NumSrcRegs = 2,
210 .HasDstReg = 1,
211 .IsComponentwise = 1
212 },
213 {
214 .Opcode = RC_OPCODE_MOV,
215 .Name = "MOV",
216 .NumSrcRegs = 1,
217 .HasDstReg = 1,
218 .IsComponentwise = 1
219 },
220 {
221 .Opcode = RC_OPCODE_MUL,
222 .Name = "MUL",
223 .NumSrcRegs = 2,
224 .HasDstReg = 1,
225 .IsComponentwise = 1
226 },
227 {
228 .Opcode = RC_OPCODE_POW,
229 .Name = "POW",
230 .NumSrcRegs = 2,
231 .HasDstReg = 1,
232 .IsStandardScalar = 1
233 },
234 {
235 .Opcode = RC_OPCODE_RCP,
236 .Name = "RCP",
237 .NumSrcRegs = 1,
238 .HasDstReg = 1,
239 .IsStandardScalar = 1
240 },
241 {
242 .Opcode = RC_OPCODE_RSQ,
243 .Name = "RSQ",
244 .NumSrcRegs = 1,
245 .HasDstReg = 1,
246 .IsStandardScalar = 1
247 },
248 {
249 .Opcode = RC_OPCODE_SCS,
250 .Name = "SCS",
251 .NumSrcRegs = 1,
252 .HasDstReg = 1
253 },
254 {
255 .Opcode = RC_OPCODE_SEQ,
256 .Name = "SEQ",
257 .NumSrcRegs = 2,
258 .HasDstReg = 1,
259 .IsComponentwise = 1
260 },
261 {
262 .Opcode = RC_OPCODE_SFL,
263 .Name = "SFL",
264 .NumSrcRegs = 0,
265 .HasDstReg = 1,
266 .IsComponentwise = 1
267 },
268 {
269 .Opcode = RC_OPCODE_SGE,
270 .Name = "SGE",
271 .NumSrcRegs = 2,
272 .HasDstReg = 1,
273 .IsComponentwise = 1
274 },
275 {
276 .Opcode = RC_OPCODE_SGT,
277 .Name = "SGT",
278 .NumSrcRegs = 2,
279 .HasDstReg = 1,
280 .IsComponentwise = 1
281 },
282 {
283 .Opcode = RC_OPCODE_SIN,
284 .Name = "SIN",
285 .NumSrcRegs = 1,
286 .HasDstReg = 1,
287 .IsStandardScalar = 1
288 },
289 {
290 .Opcode = RC_OPCODE_SLE,
291 .Name = "SLE",
292 .NumSrcRegs = 2,
293 .HasDstReg = 1,
294 .IsComponentwise = 1
295 },
296 {
297 .Opcode = RC_OPCODE_SLT,
298 .Name = "SLT",
299 .NumSrcRegs = 2,
300 .HasDstReg = 1,
301 .IsComponentwise = 1
302 },
303 {
304 .Opcode = RC_OPCODE_SNE,
305 .Name = "SNE",
306 .NumSrcRegs = 2,
307 .HasDstReg = 1,
308 .IsComponentwise = 1
309 },
310 {
311 .Opcode = RC_OPCODE_SSG,
312 .Name = "SSG",
313 .NumSrcRegs = 1,
314 .HasDstReg = 1,
315 .IsComponentwise = 1
316 },
317 {
318 .Opcode = RC_OPCODE_SUB,
319 .Name = "SUB",
320 .NumSrcRegs = 2,
321 .HasDstReg = 1,
322 .IsComponentwise = 1
323 },
324 {
325 .Opcode = RC_OPCODE_SWZ,
326 .Name = "SWZ",
327 .NumSrcRegs = 1,
328 .HasDstReg = 1,
329 .IsComponentwise = 1
330 },
331 {
332 .Opcode = RC_OPCODE_XPD,
333 .Name = "XPD",
334 .NumSrcRegs = 2,
335 .HasDstReg = 1
336 },
337 {
338 .Opcode = RC_OPCODE_TEX,
339 .Name = "TEX",
340 .HasTexture = 1,
341 .NumSrcRegs = 1,
342 .HasDstReg = 1
343 },
344 {
345 .Opcode = RC_OPCODE_TXB,
346 .Name = "TXB",
347 .HasTexture = 1,
348 .NumSrcRegs = 1,
349 .HasDstReg = 1
350 },
351 {
352 .Opcode = RC_OPCODE_TXD,
353 .Name = "TXD",
354 .HasTexture = 1,
355 .NumSrcRegs = 3,
356 .HasDstReg = 1
357 },
358 {
359 .Opcode = RC_OPCODE_TXL,
360 .Name = "TXL",
361 .HasTexture = 1,
362 .NumSrcRegs = 1,
363 .HasDstReg = 1
364 },
365 {
366 .Opcode = RC_OPCODE_TXP,
367 .Name = "TXP",
368 .HasTexture = 1,
369 .NumSrcRegs = 1,
370 .HasDstReg = 1
371 },
372 {
373 .Opcode = RC_OPCODE_IF,
374 .Name = "IF",
375 .IsFlowControl = 1,
376 .NumSrcRegs = 1
377 },
378 {
379 .Opcode = RC_OPCODE_ELSE,
380 .Name = "ELSE",
381 .IsFlowControl = 1,
382 .NumSrcRegs = 0
383 },
384 {
385 .Opcode = RC_OPCODE_ENDIF,
386 .Name = "ENDIF",
387 .IsFlowControl = 1,
388 .NumSrcRegs = 0
389 },
390 {
391 .Opcode = RC_OPCODE_BGNLOOP,
392 .Name = "BGNLOOP",
393 .IsFlowControl = 1,
394 .NumSrcRegs = 0
395 },
396 {
397 .Opcode = RC_OPCODE_BRK,
398 .Name = "BRK",
399 .IsFlowControl = 1,
400 .NumSrcRegs = 0
401 },
402 {
403 .Opcode = RC_OPCODE_ENDLOOP,
404 .Name = "ENDLOOP",
405 .IsFlowControl = 1,
406 .NumSrcRegs = 0,
407 },
408 {
409 .Opcode = RC_OPCODE_CONT,
410 .Name = "CONT",
411 .IsFlowControl = 1,
412 .NumSrcRegs = 0
413 },
414 {
415 .Opcode = RC_OPCODE_REPL_ALPHA,
416 .Name = "REPL_ALPHA",
417 .HasDstReg = 1
418 },
419 {
420 .Opcode = RC_OPCODE_BEGIN_TEX,
421 .Name = "BEGIN_TEX"
422 },
423 {
424 .Opcode = RC_OPCODE_KILP,
425 .Name = "KILP",
426 }
427 };
428
429 void rc_compute_sources_for_writemask(
430 const struct rc_instruction *inst,
431 unsigned int writemask,
432 unsigned int *srcmasks)
433 {
434 const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
435 srcmasks[0] = 0;
436 srcmasks[1] = 0;
437 srcmasks[2] = 0;
438
439 if (opcode->Opcode == RC_OPCODE_KIL)
440 srcmasks[0] |= RC_MASK_XYZW;
441 else if (opcode->Opcode == RC_OPCODE_IF)
442 srcmasks[0] |= RC_MASK_X;
443
444 if (!writemask)
445 return;
446
447 if (opcode->IsComponentwise) {
448 for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src)
449 srcmasks[src] |= writemask;
450 } else if (opcode->IsStandardScalar) {
451 for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src)
452 srcmasks[src] |= RC_MASK_X;
453 } else {
454 switch(opcode->Opcode) {
455 case RC_OPCODE_ARL:
456 srcmasks[0] |= RC_MASK_X;
457 break;
458 case RC_OPCODE_DP2:
459 srcmasks[0] |= RC_MASK_XY;
460 srcmasks[1] |= RC_MASK_XY;
461 break;
462 case RC_OPCODE_DP3:
463 case RC_OPCODE_XPD:
464 srcmasks[0] |= RC_MASK_XYZ;
465 srcmasks[1] |= RC_MASK_XYZ;
466 break;
467 case RC_OPCODE_DP4:
468 srcmasks[0] |= RC_MASK_XYZW;
469 srcmasks[1] |= RC_MASK_XYZW;
470 break;
471 case RC_OPCODE_DPH:
472 srcmasks[0] |= RC_MASK_XYZ;
473 srcmasks[1] |= RC_MASK_XYZW;
474 break;
475 case RC_OPCODE_TXB:
476 case RC_OPCODE_TXP:
477 srcmasks[0] |= RC_MASK_W;
478 /* Fall through */
479 case RC_OPCODE_TEX:
480 switch (inst->U.I.TexSrcTarget) {
481 case RC_TEXTURE_1D:
482 srcmasks[0] |= RC_MASK_X;
483 break;
484 case RC_TEXTURE_2D:
485 case RC_TEXTURE_RECT:
486 case RC_TEXTURE_1D_ARRAY:
487 srcmasks[0] |= RC_MASK_XY;
488 break;
489 case RC_TEXTURE_3D:
490 case RC_TEXTURE_CUBE:
491 case RC_TEXTURE_2D_ARRAY:
492 srcmasks[0] |= RC_MASK_XYZ;
493 break;
494 }
495 break;
496 case RC_OPCODE_DST:
497 srcmasks[0] |= RC_MASK_Y | RC_MASK_Z;
498 srcmasks[1] |= RC_MASK_Y | RC_MASK_W;
499 break;
500 case RC_OPCODE_EXP:
501 case RC_OPCODE_LOG:
502 srcmasks[0] |= RC_MASK_XY;
503 break;
504 case RC_OPCODE_LIT:
505 srcmasks[0] |= RC_MASK_X | RC_MASK_Y | RC_MASK_W;
506 break;
507 default:
508 break;
509 }
510 }
511 }