Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * 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, sub license, 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 portions
  16.  * of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21.  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
  22.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  *
  26.  **************************************************************************/
  27.  
  28. #include <stdio.h>
  29.  
  30. #include "i915_reg.h"
  31. #include "i915_debug.h"
  32. #include "main/imports.h"
  33.  
  34. static const char *opcodes[0x20] = {
  35.    "NOP",
  36.    "ADD",
  37.    "MOV",
  38.    "MUL",
  39.    "MAD",
  40.    "DP2ADD",
  41.    "DP3",
  42.    "DP4",
  43.    "FRC",
  44.    "RCP",
  45.    "RSQ",
  46.    "EXP",
  47.    "LOG",
  48.    "CMP",
  49.    "MIN",
  50.    "MAX",
  51.    "FLR",
  52.    "MOD",
  53.    "TRC",
  54.    "SGE",
  55.    "SLT",
  56.    "TEXLD",
  57.    "TEXLDP",
  58.    "TEXLDB",
  59.    "TEXKILL",
  60.    "DCL",
  61.    "0x1a",
  62.    "0x1b",
  63.    "0x1c",
  64.    "0x1d",
  65.    "0x1e",
  66.    "0x1f",
  67. };
  68.  
  69.  
  70. static const int args[0x20] = {
  71.    0,                           /* 0 nop */
  72.    2,                           /* 1 add */
  73.    1,                           /* 2 mov */
  74.    2,                           /* 3 m ul */
  75.    3,                           /* 4 mad */
  76.    3,                           /* 5 dp2add */
  77.    2,                           /* 6 dp3 */
  78.    2,                           /* 7 dp4 */
  79.    1,                           /* 8 frc */
  80.    1,                           /* 9 rcp */
  81.    1,                           /* a rsq */
  82.    1,                           /* b exp */
  83.    1,                           /* c log */
  84.    3,                           /* d cmp */
  85.    2,                           /* e min */
  86.    2,                           /* f max */
  87.    1,                           /* 10 flr */
  88.    1,                           /* 11 mod */
  89.    1,                           /* 12 trc */
  90.    2,                           /* 13 sge */
  91.    2,                           /* 14 slt */
  92.    1,
  93.    1,
  94.    1,
  95.    1,
  96.    0,
  97.    0,
  98.    0,
  99.    0,
  100.    0,
  101.    0,
  102.    0,
  103. };
  104.  
  105.  
  106. static const char *regname[0x8] = {
  107.    "R",
  108.    "T",
  109.    "CONST",
  110.    "S",
  111.    "OC",
  112.    "OD",
  113.    "U",
  114.    "UNKNOWN",
  115. };
  116.  
  117. static void
  118. print_reg_type_nr(GLuint type, GLuint nr)
  119. {
  120.    switch (type) {
  121.    case REG_TYPE_T:
  122.       switch (nr) {
  123.       case T_DIFFUSE:
  124.          printf("T_DIFFUSE");
  125.          return;
  126.       case T_SPECULAR:
  127.          printf("T_SPECULAR");
  128.          return;
  129.       case T_FOG_W:
  130.          printf("T_FOG_W");
  131.          return;
  132.       default:
  133.          printf("T_TEX%d", nr);
  134.          return;
  135.       }
  136.    case REG_TYPE_OC:
  137.       if (nr == 0) {
  138.          printf("oC");
  139.          return;
  140.       }
  141.       break;
  142.    case REG_TYPE_OD:
  143.       if (nr == 0) {
  144.          printf("oD");
  145.          return;
  146.       }
  147.       break;
  148.    default:
  149.       break;
  150.    }
  151.  
  152.    printf("%s[%d]", regname[type], nr);
  153. }
  154.  
  155. #define REG_SWIZZLE_MASK 0x7777
  156. #define REG_NEGATE_MASK 0x8888
  157.  
  158. #define REG_SWIZZLE_XYZW ((SRC_X << A2_SRC2_CHANNEL_X_SHIFT) |  \
  159.                       (SRC_Y << A2_SRC2_CHANNEL_Y_SHIFT) |      \
  160.                       (SRC_Z << A2_SRC2_CHANNEL_Z_SHIFT) |      \
  161.                       (SRC_W << A2_SRC2_CHANNEL_W_SHIFT))
  162.  
  163.  
  164. static void
  165. print_reg_neg_swizzle(GLuint reg)
  166. {
  167.    int i;
  168.  
  169.    if ((reg & REG_SWIZZLE_MASK) == REG_SWIZZLE_XYZW &&
  170.        (reg & REG_NEGATE_MASK) == 0)
  171.       return;
  172.  
  173.    printf(".");
  174.  
  175.    for (i = 3; i >= 0; i--) {
  176.       if (reg & (1 << ((i * 4) + 3)))
  177.          printf("-");
  178.  
  179.       switch ((reg >> (i * 4)) & 0x7) {
  180.       case 0:
  181.          printf("x");
  182.          break;
  183.       case 1:
  184.          printf("y");
  185.          break;
  186.       case 2:
  187.          printf("z");
  188.          break;
  189.       case 3:
  190.          printf("w");
  191.          break;
  192.       case 4:
  193.          printf("0");
  194.          break;
  195.       case 5:
  196.          printf("1");
  197.          break;
  198.       default:
  199.          printf("?");
  200.          break;
  201.       }
  202.    }
  203. }
  204.  
  205.  
  206. static void
  207. print_src_reg(GLuint dword)
  208. {
  209.    GLuint nr = (dword >> A2_SRC2_NR_SHIFT) & REG_NR_MASK;
  210.    GLuint type = (dword >> A2_SRC2_TYPE_SHIFT) & REG_TYPE_MASK;
  211.    print_reg_type_nr(type, nr);
  212.    print_reg_neg_swizzle(dword);
  213. }
  214.  
  215.  
  216. static void
  217. print_dest_reg(GLuint dword)
  218. {
  219.    GLuint nr = (dword >> A0_DEST_NR_SHIFT) & REG_NR_MASK;
  220.    GLuint type = (dword >> A0_DEST_TYPE_SHIFT) & REG_TYPE_MASK;
  221.    print_reg_type_nr(type, nr);
  222.    if ((dword & A0_DEST_CHANNEL_ALL) == A0_DEST_CHANNEL_ALL)
  223.       return;
  224.    printf(".");
  225.    if (dword & A0_DEST_CHANNEL_X)
  226.       printf("x");
  227.    if (dword & A0_DEST_CHANNEL_Y)
  228.       printf("y");
  229.    if (dword & A0_DEST_CHANNEL_Z)
  230.       printf("z");
  231.    if (dword & A0_DEST_CHANNEL_W)
  232.       printf("w");
  233. }
  234.  
  235.  
  236. #define GET_SRC0_REG(r0, r1) ((r0<<14)|(r1>>A1_SRC0_CHANNEL_W_SHIFT))
  237. #define GET_SRC1_REG(r0, r1) ((r0<<8)|(r1>>A2_SRC1_CHANNEL_W_SHIFT))
  238. #define GET_SRC2_REG(r)      (r)
  239.  
  240.  
  241. static void
  242. print_arith_op(GLuint opcode, const GLuint * program)
  243. {
  244.    if (opcode != A0_NOP) {
  245.       print_dest_reg(program[0]);
  246.       if (program[0] & A0_DEST_SATURATE)
  247.          printf(" = SATURATE ");
  248.       else
  249.          printf(" = ");
  250.    }
  251.  
  252.    printf("%s ", opcodes[opcode]);
  253.  
  254.    print_src_reg(GET_SRC0_REG(program[0], program[1]));
  255.    if (args[opcode] == 1) {
  256.       printf("\n");
  257.       return;
  258.    }
  259.  
  260.    printf(", ");
  261.    print_src_reg(GET_SRC1_REG(program[1], program[2]));
  262.    if (args[opcode] == 2) {
  263.       printf("\n");
  264.       return;
  265.    }
  266.  
  267.    printf(", ");
  268.    print_src_reg(GET_SRC2_REG(program[2]));
  269.    printf("\n");
  270.    return;
  271. }
  272.  
  273.  
  274. static void
  275. print_tex_op(GLuint opcode, const GLuint * program)
  276. {
  277.    print_dest_reg(program[0] | A0_DEST_CHANNEL_ALL);
  278.    printf(" = ");
  279.  
  280.    printf("%s ", opcodes[opcode]);
  281.  
  282.    printf("S[%d],", program[0] & T0_SAMPLER_NR_MASK);
  283.  
  284.    print_reg_type_nr((program[1] >> T1_ADDRESS_REG_TYPE_SHIFT) &
  285.                      REG_TYPE_MASK,
  286.                      (program[1] >> T1_ADDRESS_REG_NR_SHIFT) & REG_NR_MASK);
  287.    printf("\n");
  288. }
  289.  
  290. static void
  291. print_dcl_op(GLuint opcode, const GLuint * program)
  292. {
  293.    printf("%s ", opcodes[opcode]);
  294.    print_dest_reg(program[0] | A0_DEST_CHANNEL_ALL);
  295.    printf("\n");
  296. }
  297.  
  298.  
  299. void
  300. i915_disassemble_program(const GLuint * program, GLuint sz)
  301. {
  302.    GLuint size = program[0] & 0x1ff;
  303.    GLint i;
  304.  
  305.    printf("\t\tBEGIN\n");
  306.  
  307.    assert(size + 2 == sz);
  308.  
  309.    program++;
  310.    for (i = 1; i < sz; i += 3, program += 3) {
  311.       GLuint opcode = program[0] & (0x1f << 24);
  312.  
  313.       printf("\t\t");
  314.  
  315.       if ((GLint) opcode >= A0_NOP && opcode <= A0_SLT)
  316.          print_arith_op(opcode >> 24, program);
  317.       else if (opcode >= T0_TEXLD && opcode <= T0_TEXKILL)
  318.          print_tex_op(opcode >> 24, program);
  319.       else if (opcode == D0_DCL)
  320.          print_dcl_op(opcode >> 24, program);
  321.       else
  322.          printf("Unknown opcode 0x%x\n", opcode);
  323.    }
  324.  
  325.    printf("\t\tEND\n\n");
  326. }
  327.  
  328.  
  329.