Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / dri / r300 / compiler / r300_fragprog.c
1 /*
2  * Copyright (C) 2005 Ben Skeggs.
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 "r300_fragprog.h"
29
30 #include <stdio.h>
31
32 #include "../r300_reg.h"
33
34 static void presub_string(char out[10], unsigned int inst)
35 {
36         switch(inst & 0x600000){
37         case R300_ALU_SRCP_1_MINUS_2_SRC0:
38                 sprintf(out, "bias");
39                 break;
40         case R300_ALU_SRCP_SRC1_MINUS_SRC0:
41                 sprintf(out, "sub");
42                 break;
43         case R300_ALU_SRCP_SRC1_PLUS_SRC0:
44                 sprintf(out, "add");
45                 break;
46         case R300_ALU_SRCP_1_MINUS_SRC0:
47                 sprintf(out, "inv ");
48                 break;
49         }
50 }
51
52 static int get_msb(unsigned int bit, unsigned int r400_ext_addr)
53 {
54         return (r400_ext_addr & bit) ? 1 << 5 : 0;
55 }
56
57 /* just some random things... */
58 void r300FragmentProgramDump(struct radeon_compiler *c, void *user)
59 {
60         struct r300_fragment_program_compiler *compiler = (struct r300_fragment_program_compiler*)c;
61         struct r300_fragment_program_code *code = &compiler->code->code.r300;
62         int n, i, j;
63         static int pc = 0;
64
65         fprintf(stderr, "pc=%d*************************************\n", pc++);
66
67         fprintf(stderr, "Hardware program\n");
68         fprintf(stderr, "----------------\n");
69         if (c->is_r400) {
70                 fprintf(stderr, "code_offset_ext: %08x\n", code->r400_code_offset_ext);
71         }
72
73         for (n = 0; n <= (code->config & 3); n++) {
74                 uint32_t code_addr = code->code_addr[3 - (code->config & 3) + n];
75                 unsigned int alu_offset = ((code_addr & R300_ALU_START_MASK) >> R300_ALU_START_SHIFT) +
76                                 (((code->r400_code_offset_ext >> (24 - (n * 6))) & 0x7) << 6);
77                 unsigned int alu_end = ((code_addr & R300_ALU_SIZE_MASK) >> R300_ALU_SIZE_SHIFT) +
78                                 (((code->r400_code_offset_ext >> (27 - (n * 6))) & 0x7) << 6);
79                 int tex_offset = (code_addr & R300_TEX_START_MASK) >> R300_TEX_START_SHIFT;
80                 int tex_end = (code_addr & R300_TEX_SIZE_MASK) >> R300_TEX_SIZE_SHIFT;
81
82                 fprintf(stderr, "NODE %d: alu_offset: %u, tex_offset: %d, "
83                         "alu_end: %u, tex_end: %d  (code_addr: %08x)\n", n,
84                         alu_offset, tex_offset, alu_end, tex_end, code_addr);
85
86                 if (n > 0 || (code->config & R300_PFS_CNTL_FIRST_NODE_HAS_TEX)) {
87                         fprintf(stderr, "  TEX:\n");
88                         for (i = tex_offset;
89                              i <= tex_offset + tex_end;
90                              ++i) {
91                                 const char *instr;
92
93                                 switch ((code->tex.
94                                          inst[i] >> R300_TEX_INST_SHIFT) &
95                                         15) {
96                                 case R300_TEX_OP_LD:
97                                         instr = "TEX";
98                                         break;
99                                 case R300_TEX_OP_KIL:
100                                         instr = "KIL";
101                                         break;
102                                 case R300_TEX_OP_TXP:
103                                         instr = "TXP";
104                                         break;
105                                 case R300_TEX_OP_TXB:
106                                         instr = "TXB";
107                                         break;
108                                 default:
109                                         instr = "UNKNOWN";
110                                 }
111
112                                 fprintf(stderr,
113                                         "    %s t%i, %c%i, texture[%i]   (%08x)\n",
114                                         instr,
115                                         (code->tex.
116                                          inst[i] >> R300_DST_ADDR_SHIFT) & 31,
117                                         't',
118                                         (code->tex.
119                                          inst[i] >> R300_SRC_ADDR_SHIFT) & 31,
120                                         (code->tex.
121                                          inst[i] & R300_TEX_ID_MASK) >>
122                                         R300_TEX_ID_SHIFT,
123                                         code->tex.inst[i]);
124                         }
125                 }
126
127                 for (i = alu_offset;
128                      i <= alu_offset + alu_end; ++i) {
129                         char srcc[4][10], dstc[20];
130                         char srca[4][10], dsta[20];
131                         char argc[3][20];
132                         char arga[3][20];
133                         char flags[5], tmp[10];
134
135                         for (j = 0; j < 3; ++j) {
136                                 int regc = code->alu.inst[i].rgb_addr >> (j * 6);
137                                 int rega = code->alu.inst[i].alpha_addr >> (j * 6);
138                                 int msbc = get_msb(R400_ADDR_EXT_RGB_MSB_BIT(j),
139                                         code->alu.inst[i].r400_ext_addr);
140                                 int msba = get_msb(R400_ADDR_EXT_A_MSB_BIT(j),
141                                         code->alu.inst[i].r400_ext_addr);
142
143                                 sprintf(srcc[j], "%c%i",
144                                         (regc & 32) ? 'c' : 't', (regc & 31) | msbc);
145                                 sprintf(srca[j], "%c%i",
146                                         (rega & 32) ? 'c' : 't', (rega & 31) | msba);
147                         }
148
149                         dstc[0] = 0;
150                         sprintf(flags, "%s%s%s",
151                                 (code->alu.inst[i].
152                                  rgb_addr & R300_ALU_DSTC_REG_X) ? "x" : "",
153                                 (code->alu.inst[i].
154                                  rgb_addr & R300_ALU_DSTC_REG_Y) ? "y" : "",
155                                 (code->alu.inst[i].
156                                  rgb_addr & R300_ALU_DSTC_REG_Z) ? "z" : "");
157                         if (flags[0] != 0) {
158                                 unsigned int msb = get_msb(
159                                         R400_ADDRD_EXT_RGB_MSB_BIT,
160                                         code->alu.inst[i].r400_ext_addr);
161
162                                 sprintf(dstc, "t%i.%s ",
163                                         ((code->alu.inst[i].
164                                          rgb_addr >> R300_ALU_DSTC_SHIFT)
165                                          & 31) | msb,
166                                         flags);
167                         }
168                         sprintf(flags, "%s%s%s",
169                                 (code->alu.inst[i].
170                                  rgb_addr & R300_ALU_DSTC_OUTPUT_X) ? "x" : "",
171                                 (code->alu.inst[i].
172                                  rgb_addr & R300_ALU_DSTC_OUTPUT_Y) ? "y" : "",
173                                 (code->alu.inst[i].
174                                  rgb_addr & R300_ALU_DSTC_OUTPUT_Z) ? "z" : "");
175                         if (flags[0] != 0) {
176                                 sprintf(tmp, "o%i.%s",
177                                         (code->alu.inst[i].
178                                          rgb_addr >> 29) & 3,
179                                         flags);
180                                 strcat(dstc, tmp);
181                         }
182                         /* Presub */
183                         presub_string(srcc[3], code->alu.inst[i].rgb_inst);
184                         presub_string(srca[3], code->alu.inst[i].alpha_inst);
185
186                         dsta[0] = 0;
187                         if (code->alu.inst[i].alpha_addr & R300_ALU_DSTA_REG) {
188                                 unsigned int msb = get_msb(
189                                         R400_ADDRD_EXT_A_MSB_BIT,
190                                         code->alu.inst[i].r400_ext_addr);
191                                 sprintf(dsta, "t%i.w ",
192                                         ((code->alu.inst[i].
193                                          alpha_addr >> R300_ALU_DSTA_SHIFT) & 31)
194                                          | msb);
195                         }
196                         if (code->alu.inst[i].alpha_addr & R300_ALU_DSTA_OUTPUT) {
197                                 sprintf(tmp, "o%i.w ",
198                                         (code->alu.inst[i].
199                                          alpha_addr >> 25) & 3);
200                                 strcat(dsta, tmp);
201                         }
202                         if (code->alu.inst[i].alpha_addr & R300_ALU_DSTA_DEPTH) {
203                                 strcat(dsta, "Z");
204                         }
205
206                         fprintf(stderr,
207                                 "%3i: xyz: %3s %3s %3s %5s-> %-20s (%08x)\n"
208                                 "       w: %3s %3s %3s %5s-> %-20s (%08x)\n", i,
209                                 srcc[0], srcc[1], srcc[2], srcc[3], dstc,
210                                 code->alu.inst[i].rgb_addr, srca[0], srca[1],
211                                 srca[2], srca[3], dsta,
212                                 code->alu.inst[i].alpha_addr);
213
214                         for (j = 0; j < 3; ++j) {
215                                 int regc = code->alu.inst[i].rgb_inst >> (j * 7);
216                                 int rega = code->alu.inst[i].alpha_inst >> (j * 7);
217                                 int d;
218                                 char buf[20];
219
220                                 d = regc & 31;
221                                 if (d < 12) {
222                                         switch (d % 4) {
223                                         case R300_ALU_ARGC_SRC0C_XYZ:
224                                                 sprintf(buf, "%s.xyz",
225                                                         srcc[d / 4]);
226                                                 break;
227                                         case R300_ALU_ARGC_SRC0C_XXX:
228                                                 sprintf(buf, "%s.xxx",
229                                                         srcc[d / 4]);
230                                                 break;
231                                         case R300_ALU_ARGC_SRC0C_YYY:
232                                                 sprintf(buf, "%s.yyy",
233                                                         srcc[d / 4]);
234                                                 break;
235                                         case R300_ALU_ARGC_SRC0C_ZZZ:
236                                                 sprintf(buf, "%s.zzz",
237                                                         srcc[d / 4]);
238                                                 break;
239                                         }
240                                 } else if (d < 15) {
241                                         sprintf(buf, "%s.www", srca[d - 12]);
242                                 } else if (d < 20 ) {
243                                         switch(d) {
244                                         case R300_ALU_ARGC_SRCP_XYZ:
245                                                 sprintf(buf, "srcp.xyz");
246                                                 break;
247                                         case R300_ALU_ARGC_SRCP_XXX:
248                                                 sprintf(buf, "srcp.xxx");
249                                                 break;
250                                         case R300_ALU_ARGC_SRCP_YYY:
251                                                 sprintf(buf, "srcp.yyy");
252                                                 break;
253                                         case R300_ALU_ARGC_SRCP_ZZZ:
254                                                 sprintf(buf, "srcp.zzz");
255                                                 break;
256                                         case R300_ALU_ARGC_SRCP_WWW:
257                                                 sprintf(buf, "srcp.www");
258                                                 break;
259                                         }
260                                 } else if (d == 20) {
261                                         sprintf(buf, "0.0");
262                                 } else if (d == 21) {
263                                         sprintf(buf, "1.0");
264                                 } else if (d == 22) {
265                                         sprintf(buf, "0.5");
266                                 } else if (d >= 23 && d < 32) {
267                                         d -= 23;
268                                         switch (d / 3) {
269                                         case 0:
270                                                 sprintf(buf, "%s.yzx",
271                                                         srcc[d % 3]);
272                                                 break;
273                                         case 1:
274                                                 sprintf(buf, "%s.zxy",
275                                                         srcc[d % 3]);
276                                                 break;
277                                         case 2:
278                                                 sprintf(buf, "%s.Wzy",
279                                                         srcc[d % 3]);
280                                                 break;
281                                         }
282                                 } else {
283                                         sprintf(buf, "%i", d);
284                                 }
285
286                                 sprintf(argc[j], "%s%s%s%s",
287                                         (regc & 32) ? "-" : "",
288                                         (regc & 64) ? "|" : "",
289                                         buf, (regc & 64) ? "|" : "");
290
291                                 d = rega & 31;
292                                 if (d < 9) {
293                                         sprintf(buf, "%s.%c", srcc[d / 3],
294                                                 'x' + (char)(d % 3));
295                                 } else if (d < 12) {
296                                         sprintf(buf, "%s.w", srca[d - 9]);
297                                 } else if (d < 16) {
298                                         switch(d) {
299                                         case R300_ALU_ARGA_SRCP_X:
300                                                 sprintf(buf, "srcp.x");
301                                                 break;
302                                         case R300_ALU_ARGA_SRCP_Y:
303                                                 sprintf(buf, "srcp.y");
304                                                 break;
305                                         case R300_ALU_ARGA_SRCP_Z:
306                                                 sprintf(buf, "srcp.z");
307                                                 break;
308                                         case R300_ALU_ARGA_SRCP_W:
309                                                 sprintf(buf, "srcp.w");
310                                                 break;
311                                         }
312                                 } else if (d == 16) {
313                                         sprintf(buf, "0.0");
314                                 } else if (d == 17) {
315                                         sprintf(buf, "1.0");
316                                 } else if (d == 18) {
317                                         sprintf(buf, "0.5");
318                                 } else {
319                                         sprintf(buf, "%i", d);
320                                 }
321
322                                 sprintf(arga[j], "%s%s%s%s",
323                                         (rega & 32) ? "-" : "",
324                                         (rega & 64) ? "|" : "",
325                                         buf, (rega & 64) ? "|" : "");
326                         }
327
328                         fprintf(stderr, "     xyz: %8s %8s %8s    op: %08x %s\n"
329                                 "       w: %8s %8s %8s    op: %08x\n",
330                                 argc[0], argc[1], argc[2],
331                                 code->alu.inst[i].rgb_inst,
332                                 code->alu.inst[i].rgb_inst & R300_ALU_INSERT_NOP ?
333                                 "NOP" : "",
334                                 arga[0], arga[1],arga[2],
335                                 code->alu.inst[i].alpha_inst);
336                 }
337         }
338 }