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 } 339