Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Copyright © 2007-2011 Intel Corporation
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21.  * SOFTWARE.
  22.  *
  23.  * Authors:
  24.  *    Eric Anholt <eric@anholt.net>
  25.  *    Chris Wilson <chris@chris-wilson.co.uk>
  26.  *
  27.  */
  28.  
  29. #ifdef HAVE_CONFIG_H
  30. #include "config.h"
  31. #endif
  32.  
  33. #include <assert.h>
  34.  
  35. #include "sna.h"
  36. #include "sna_reg.h"
  37.  
  38. #include "gen3_render.h"
  39.  
  40. #include "kgem_debug.h"
  41.  
  42. enum type {
  43.         T_FLOAT32,
  44.         T_FLOAT16,
  45. };
  46.  
  47. static struct state {
  48.         struct vertex_buffer {
  49.                 int handle;
  50.                 void *base;
  51.                 const char *ptr;
  52.                 int pitch;
  53.  
  54.                 struct kgem_bo *current;
  55.         } vb;
  56.         struct vertex_elements {
  57.                 int offset;
  58.                 bool valid;
  59.                 enum type type;
  60.                 int size;
  61.                 uint8_t swizzle[4];
  62.         } ve[33];
  63.         int num_ve;
  64. } state;
  65.  
  66. static float int_as_float(int i)
  67. {
  68.         union {
  69.                 float f;
  70.                 int i;
  71.         } x;
  72.         x.i = i;
  73.         return x.f;
  74. }
  75.  
  76. static void gen3_update_vertex_buffer_addr(struct kgem *kgem,
  77.                                            uint32_t offset)
  78. {
  79.         uint32_t handle;
  80.         struct kgem_bo *bo = NULL;
  81.         void *base, *ptr;
  82.         int i;
  83.  
  84.         offset *= sizeof(uint32_t);
  85.  
  86.         for (i = 0; i < kgem->nreloc; i++)
  87.                 if (kgem->reloc[i].offset == offset)
  88.                         break;
  89.         assert(i < kgem->nreloc);
  90.         handle = kgem->reloc[i].target_handle;
  91.  
  92.         if (handle == 0) {
  93.                 base = kgem->batch;
  94.         } else {
  95.                 list_for_each_entry(bo, &kgem->next_request->buffers, request)
  96.                         if (bo->handle == handle)
  97.                                 break;
  98.                 assert(&bo->request != &kgem->next_request->buffers);
  99.                 base = kgem_bo_map__debug(kgem, bo);
  100.         }
  101.         ptr = (char *)base + kgem->reloc[i].delta;
  102.  
  103.         state.vb.current = bo;
  104.         state.vb.base = base;
  105.         state.vb.ptr = ptr;
  106. }
  107.  
  108. static void gen3_update_vertex_buffer_pitch(struct kgem *kgem,
  109.                                            uint32_t offset)
  110. {
  111.         state.vb.pitch = kgem->batch[offset] >> 16 & 0x3f;
  112.         state.vb.pitch *= sizeof(uint32_t);
  113. }
  114.  
  115. static void gen3_update_vertex_elements(struct kgem *kgem, uint32_t data)
  116. {
  117.         state.ve[1].valid = 1;
  118.  
  119.         switch ((data >> 6) & 7) {
  120.         case 1:
  121.                 state.ve[1].type = T_FLOAT32;
  122.                 state.ve[1].size = 3;
  123.                 state.ve[1].swizzle[0] = 1;
  124.                 state.ve[1].swizzle[1] = 1;
  125.                 state.ve[1].swizzle[2] = 1;
  126.                 state.ve[1].swizzle[3] = 3;
  127.                 break;
  128.         case 2:
  129.                 state.ve[1].type = T_FLOAT32;
  130.                 state.ve[1].size = 4;
  131.                 state.ve[1].swizzle[0] = 1;
  132.                 state.ve[1].swizzle[1] = 1;
  133.                 state.ve[1].swizzle[2] = 1;
  134.                 state.ve[1].swizzle[3] = 1;
  135.                 break;
  136.         case 3:
  137.                 state.ve[1].type = T_FLOAT32;
  138.                 state.ve[1].size = 2;
  139.                 state.ve[1].swizzle[0] = 1;
  140.                 state.ve[1].swizzle[1] = 1;
  141.                 state.ve[1].swizzle[2] = 2;
  142.                 state.ve[1].swizzle[3] = 3;
  143.                 break;
  144.         case 4:
  145.                 state.ve[1].type = T_FLOAT32;
  146.                 state.ve[1].size = 3;
  147.                 state.ve[1].swizzle[0] = 1;
  148.                 state.ve[1].swizzle[1] = 1;
  149.                 state.ve[1].swizzle[2] = 3;
  150.                 state.ve[1].swizzle[3] = 1;
  151.                 break;
  152.         }
  153.  
  154.         state.ve[2].valid = 0;
  155.         state.ve[3].valid = 0;
  156. }
  157.  
  158. static void gen3_update_vertex_texcoords(struct kgem *kgem, uint32_t data)
  159. {
  160.         int id;
  161.         for (id = 0; id < 8; id++) {
  162.                 uint32_t fmt = (data >> (id*4)) & 0xf;
  163.                 int width;
  164.  
  165.                 state.ve[id+4].valid = fmt != 0xf;
  166.  
  167.                 width = 0;
  168.                 switch (fmt) {
  169.                 case 0:
  170.                         state.ve[id+4].type = T_FLOAT32;
  171.                         width = state.ve[id+4].size = 2;
  172.                         break;
  173.                 case 1:
  174.                         state.ve[id+4].type = T_FLOAT32;
  175.                         width = state.ve[id+4].size = 3;
  176.                         break;
  177.                 case 2:
  178.                         state.ve[id+4].type = T_FLOAT32;
  179.                         width = state.ve[id+4].size = 4;
  180.                         break;
  181.                 case 3:
  182.                         state.ve[id+4].type = T_FLOAT32;
  183.                         width = state.ve[id+4].size = 1;
  184.                         break;
  185.                 case 4:
  186.                         state.ve[id+4].type = T_FLOAT16;
  187.                         width = state.ve[id+4].size = 2;
  188.                         break;
  189.                 case 5:
  190.                         state.ve[id+4].type = T_FLOAT16;
  191.                         width = state.ve[id+4].size = 4;
  192.                         break;
  193.                 }
  194.  
  195.                 state.ve[id+4].swizzle[0] = width > 0 ? 1 : 2;
  196.                 state.ve[id+4].swizzle[1] = width > 1 ? 1 : 2;
  197.                 state.ve[id+4].swizzle[2] = width > 2 ? 1 : 2;
  198.                 state.ve[id+4].swizzle[3] = width > 3 ? 1 : 2;
  199.         }
  200. }
  201.  
  202. static void gen3_update_vertex_elements_offsets(struct kgem *kgem)
  203. {
  204.         int i, offset;
  205.  
  206.         for (i = offset = 0; i < ARRAY_SIZE(state.ve); i++) {
  207.                 if (!state.ve[i].valid)
  208.                         continue;
  209.  
  210.                 state.ve[i].offset = offset;
  211.                 offset += 4 * state.ve[i].size;
  212.                 state.num_ve = i;
  213.         }
  214. }
  215.  
  216. static void vertices_float32_out(const struct vertex_elements *ve, const float *f, int max)
  217. {
  218.         int c;
  219.  
  220.         ErrorF("(");
  221.         for (c = 0; c < max; c++) {
  222.                 switch (ve->swizzle[c]) {
  223.                 case 0: ErrorF("#"); break;
  224.                 case 1: ErrorF("%f", f[c]); break;
  225.                 case 2: ErrorF("0.0"); break;
  226.                 case 3: ErrorF("1.0"); break;
  227.                 case 4: ErrorF("0x1"); break;
  228.                 case 5: break;
  229.                 default: ErrorF("?");
  230.                 }
  231.                 if (c < max-1)
  232.                         ErrorF(", ");
  233.         }
  234.         ErrorF(")");
  235. }
  236.  
  237. static void ve_out(const struct vertex_elements *ve, const void *ptr)
  238. {
  239.         switch (ve->type) {
  240.         case T_FLOAT32:
  241.                 vertices_float32_out(ve, ptr, ve->size);
  242.                 break;
  243.         case T_FLOAT16:
  244.                 //vertices_float16_out(ve, ptr, ve->size);
  245.                 break;
  246.         }
  247. }
  248.  
  249. static void indirect_vertex_out(struct kgem *kgem, uint32_t v)
  250. {
  251.         const struct vertex_buffer *vb = &state.vb;
  252.         int i = 1;
  253.  
  254.         do {
  255.                 const struct vertex_elements *ve = &state.ve[i];
  256.                 const void *ptr = vb->ptr + v * vb->pitch + ve->offset;
  257.  
  258.                 if (!ve->valid)
  259.                         continue;
  260.  
  261.                 ve_out(ve, ptr);
  262.  
  263.                 while (++i <= state.num_ve && !state.ve[i].valid)
  264.                         ;
  265.  
  266.                 if (i <= state.num_ve)
  267.                         ErrorF(", ");
  268.         } while (i <= state.num_ve);
  269. }
  270.  
  271. static int inline_vertex_out(struct kgem *kgem, void *base)
  272. {
  273.         const struct vertex_buffer *vb = &state.vb;
  274.         int i = 1;
  275.  
  276.         do {
  277.                 const struct vertex_elements *ve = &state.ve[i];
  278.                 const void *ptr = (char *)base + ve->offset;
  279.  
  280.                 if (!ve->valid)
  281.                         continue;
  282.  
  283.                 ve_out(ve, ptr);
  284.  
  285.                 while (++i <= state.num_ve && !state.ve[i].valid)
  286.                         ;
  287.  
  288.                 if (i <= state.num_ve)
  289.                         ErrorF(", ");
  290.         } while (i <= state.num_ve);
  291.  
  292.         return vb->pitch;
  293. }
  294.  
  295. static int
  296. gen3_decode_3d_1c(struct kgem *kgem, uint32_t offset)
  297. {
  298.         uint32_t *data = kgem->batch + offset;
  299.         uint32_t opcode;
  300.  
  301.         opcode = (data[0] & 0x00f80000) >> 19;
  302.  
  303.         switch (opcode) {
  304.         case 0x11:
  305.                 kgem_debug_print(data, offset, 0, "3DSTATE_DEPTH_SUBRECTANGLE_DISABLE\n");
  306.                 return 1;
  307.         case 0x10:
  308.                 kgem_debug_print(data, offset, 0, "3DSTATE_SCISSOR_ENABLE %s\n",
  309.                           data[0]&1?"enabled":"disabled");
  310.                 return 1;
  311.         case 0x01:
  312.                 kgem_debug_print(data, offset, 0, "3DSTATE_MAP_COORD_SET_I830\n");
  313.                 return 1;
  314.         case 0x0a:
  315.                 kgem_debug_print(data, offset, 0, "3DSTATE_MAP_CUBE_I830\n");
  316.                 return 1;
  317.         case 0x05:
  318.                 kgem_debug_print(data, offset, 0, "3DSTATE_MAP_TEX_STREAM_I830\n");
  319.                 return 1;
  320.         }
  321.  
  322.         kgem_debug_print(data, offset, 0, "3D UNKNOWN: 3d_1c opcode = 0x%x\n",
  323.                   opcode);
  324.         assert(0);
  325.         return 1;
  326. }
  327.  
  328. /** Sets the string dstname to describe the destination of the PS instruction */
  329. static void
  330. gen3_get_instruction_dst(uint32_t *data, int i, char *dstname, int do_mask)
  331. {
  332.     uint32_t a0 = data[i];
  333.     int dst_nr = (a0 >> 14) & 0xf;
  334.     char dstmask[8];
  335.     const char *sat;
  336.  
  337.     if (do_mask) {
  338.         if (((a0 >> 10) & 0xf) == 0xf) {
  339.             dstmask[0] = 0;
  340.         } else {
  341.             int dstmask_index = 0;
  342.  
  343.             dstmask[dstmask_index++] = '.';
  344.             if (a0 & (1 << 10))
  345.                 dstmask[dstmask_index++] = 'x';
  346.             if (a0 & (1 << 11))
  347.                 dstmask[dstmask_index++] = 'y';
  348.             if (a0 & (1 << 12))
  349.                 dstmask[dstmask_index++] = 'z';
  350.             if (a0 & (1 << 13))
  351.                 dstmask[dstmask_index++] = 'w';
  352.             dstmask[dstmask_index++] = 0;
  353.         }
  354.  
  355.         if (a0 & (1 << 22))
  356.             sat = ".sat";
  357.         else
  358.             sat = "";
  359.     } else {
  360.         dstmask[0] = 0;
  361.         sat = "";
  362.     }
  363.  
  364.     switch ((a0 >> 19) & 0x7) {
  365.     case 0:
  366.             assert(dst_nr <= 15);
  367.         sprintf(dstname, "R%d%s%s", dst_nr, dstmask, sat);
  368.         break;
  369.     case 4:
  370.         assert(dst_nr == 0);
  371.         sprintf(dstname, "oC%s%s", dstmask, sat);
  372.         break;
  373.     case 5:
  374.         assert(dst_nr == 0);
  375.         sprintf(dstname, "oD%s%s",  dstmask, sat);
  376.         break;
  377.     case 6:
  378.         assert(dst_nr <= 3);
  379.         sprintf(dstname, "U%d%s%s", dst_nr, dstmask, sat);
  380.         break;
  381.     default:
  382.         sprintf(dstname, "RESERVED");
  383.         break;
  384.     }
  385. }
  386.  
  387. static const char *
  388. gen3_get_channel_swizzle(uint32_t select)
  389. {
  390.     switch (select & 0x7) {
  391.     case 0:
  392.         return (select & 8) ? "-x" : "x";
  393.     case 1:
  394.         return (select & 8) ? "-y" : "y";
  395.     case 2:
  396.         return (select & 8) ? "-z" : "z";
  397.     case 3:
  398.         return (select & 8) ? "-w" : "w";
  399.     case 4:
  400.         return (select & 8) ? "-0" : "0";
  401.     case 5:
  402.         return (select & 8) ? "-1" : "1";
  403.     default:
  404.         return (select & 8) ? "-bad" : "bad";
  405.     }
  406. }
  407.  
  408. static void
  409. gen3_get_instruction_src_name(uint32_t src_type, uint32_t src_nr, char *name)
  410. {
  411.         switch (src_type) {
  412.         case 0:
  413.                 sprintf(name, "R%d", src_nr);
  414.                 assert(src_nr <= 15);
  415.                 break;
  416.         case 1:
  417.                 if (src_nr < 8)
  418.                         sprintf(name, "T%d", src_nr);
  419.                 else if (src_nr == 8)
  420.                         sprintf(name, "DIFFUSE");
  421.                 else if (src_nr == 9)
  422.                         sprintf(name, "SPECULAR");
  423.                 else if (src_nr == 10)
  424.                         sprintf(name, "FOG");
  425.                 else {
  426.                         assert(0);
  427.                         sprintf(name, "RESERVED");
  428.                 }
  429.                 break;
  430.         case 2:
  431.                 sprintf(name, "C%d", src_nr);
  432.                 assert(src_nr <= 31);
  433.                 break;
  434.         case 4:
  435.                 sprintf(name, "oC");
  436.                 assert(src_nr == 0);
  437.                 break;
  438.         case 5:
  439.                 sprintf(name, "oD");
  440.                 assert(src_nr == 0);
  441.                 break;
  442.         case 6:
  443.                 sprintf(name, "U%d", src_nr);
  444.                 assert(src_nr <= 3);
  445.                 break;
  446.         default:
  447.                 sprintf(name, "RESERVED");
  448.                 assert(0);
  449.                 break;
  450.         }
  451. }
  452.  
  453. static void
  454. gen3_get_instruction_src0(uint32_t *data, int i, char *srcname)
  455. {
  456.     uint32_t a0 = data[i];
  457.     uint32_t a1 = data[i + 1];
  458.     int src_nr = (a0 >> 2) & 0x1f;
  459.     const char *swizzle_x = gen3_get_channel_swizzle((a1 >> 28) & 0xf);
  460.     const char *swizzle_y = gen3_get_channel_swizzle((a1 >> 24) & 0xf);
  461.     const char *swizzle_z = gen3_get_channel_swizzle((a1 >> 20) & 0xf);
  462.     const char *swizzle_w = gen3_get_channel_swizzle((a1 >> 16) & 0xf);
  463.     char swizzle[100];
  464.  
  465.     gen3_get_instruction_src_name((a0 >> 7) & 0x7, src_nr, srcname);
  466.     sprintf(swizzle, ".%s%s%s%s", swizzle_x, swizzle_y, swizzle_z, swizzle_w);
  467.     if (strcmp(swizzle, ".xyzw") != 0)
  468.         strcat(srcname, swizzle);
  469. }
  470.  
  471. static void
  472. gen3_get_instruction_src1(uint32_t *data, int i, char *srcname)
  473. {
  474.     uint32_t a1 = data[i + 1];
  475.     uint32_t a2 = data[i + 2];
  476.     int src_nr = (a1 >> 8) & 0x1f;
  477.     const char *swizzle_x = gen3_get_channel_swizzle((a1 >> 4) & 0xf);
  478.     const char *swizzle_y = gen3_get_channel_swizzle((a1 >> 0) & 0xf);
  479.     const char *swizzle_z = gen3_get_channel_swizzle((a2 >> 28) & 0xf);
  480.     const char *swizzle_w = gen3_get_channel_swizzle((a2 >> 24) & 0xf);
  481.     char swizzle[100];
  482.  
  483.     gen3_get_instruction_src_name((a1 >> 13) & 0x7, src_nr, srcname);
  484.     sprintf(swizzle, ".%s%s%s%s", swizzle_x, swizzle_y, swizzle_z, swizzle_w);
  485.     if (strcmp(swizzle, ".xyzw") != 0)
  486.         strcat(srcname, swizzle);
  487. }
  488.  
  489. static void
  490. gen3_get_instruction_src2(uint32_t *data, int i, char *srcname)
  491. {
  492.     uint32_t a2 = data[i + 2];
  493.     int src_nr = (a2 >> 16) & 0x1f;
  494.     const char *swizzle_x = gen3_get_channel_swizzle((a2 >> 12) & 0xf);
  495.     const char *swizzle_y = gen3_get_channel_swizzle((a2 >> 8) & 0xf);
  496.     const char *swizzle_z = gen3_get_channel_swizzle((a2 >> 4) & 0xf);
  497.     const char *swizzle_w = gen3_get_channel_swizzle((a2 >> 0) & 0xf);
  498.     char swizzle[100];
  499.  
  500.     gen3_get_instruction_src_name((a2 >> 21) & 0x7, src_nr, srcname);
  501.     sprintf(swizzle, ".%s%s%s%s", swizzle_x, swizzle_y, swizzle_z, swizzle_w);
  502.     if (strcmp(swizzle, ".xyzw") != 0)
  503.         strcat(srcname, swizzle);
  504. }
  505.  
  506. static void
  507. gen3_get_instruction_addr(uint32_t src_type, uint32_t src_nr, char *name)
  508. {
  509.         switch (src_type) {
  510.         case 0:
  511.                 sprintf(name, "R%d", src_nr);
  512.                 assert(src_nr <= 15);
  513.                 break;
  514.         case 1:
  515.                 if (src_nr < 8)
  516.                         sprintf(name, "T%d", src_nr);
  517.                 else if (src_nr == 8)
  518.                         sprintf(name, "DIFFUSE");
  519.                 else if (src_nr == 9)
  520.                         sprintf(name, "SPECULAR");
  521.                 else if (src_nr == 10)
  522.                         sprintf(name, "FOG");
  523.                 else {
  524.                         assert(0);
  525.                         sprintf(name, "RESERVED");
  526.                 }
  527.                 break;
  528.         case 4:
  529.                 sprintf(name, "oC");
  530.                 assert(src_nr == 0);
  531.                 break;
  532.         case 5:
  533.                 sprintf(name, "oD");
  534.                 assert(src_nr == 0);
  535.                 break;
  536.         default:
  537.                 assert(0);
  538.                 sprintf(name, "RESERVED");
  539.                 break;
  540.         }
  541. }
  542.  
  543. static void
  544. gen3_decode_alu1(uint32_t *data, uint32_t offset,
  545.                  int i, char *instr_prefix, const char *op_name)
  546. {
  547.     char dst[100], src0[100];
  548.  
  549.     gen3_get_instruction_dst(data, i, dst, 1);
  550.     gen3_get_instruction_src0(data, i, src0);
  551.  
  552.     kgem_debug_print(data, offset, i++, "%s: %s %s, %s\n", instr_prefix,
  553.               op_name, dst, src0);
  554.     kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
  555.     kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
  556. }
  557.  
  558. static void
  559. gen3_decode_alu2(uint32_t *data, uint32_t offset,
  560.                  int i, char *instr_prefix, const char *op_name)
  561. {
  562.     char dst[100], src0[100], src1[100];
  563.  
  564.     gen3_get_instruction_dst(data, i, dst, 1);
  565.     gen3_get_instruction_src0(data, i, src0);
  566.     gen3_get_instruction_src1(data, i, src1);
  567.  
  568.     kgem_debug_print(data, offset, i++, "%s: %s %s, %s, %s\n", instr_prefix,
  569.               op_name, dst, src0, src1);
  570.     kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
  571.     kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
  572. }
  573.  
  574. static void
  575. gen3_decode_alu3(uint32_t *data, uint32_t offset,
  576.                  int i, char *instr_prefix, const char *op_name)
  577. {
  578.     char dst[100], src0[100], src1[100], src2[100];
  579.  
  580.     gen3_get_instruction_dst(data, i, dst, 1);
  581.     gen3_get_instruction_src0(data, i, src0);
  582.     gen3_get_instruction_src1(data, i, src1);
  583.     gen3_get_instruction_src2(data, i, src2);
  584.  
  585.     kgem_debug_print(data, offset, i++, "%s: %s %s, %s, %s, %s\n", instr_prefix,
  586.               op_name, dst, src0, src1, src2);
  587.     kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
  588.     kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
  589. }
  590.  
  591. static void
  592. gen3_decode_tex(uint32_t *data, uint32_t offset, int i, char *instr_prefix,
  593.                 const char *tex_name)
  594. {
  595.     uint32_t t0 = data[i];
  596.     uint32_t t1 = data[i + 1];
  597.     char dst_name[100];
  598.     char addr_name[100];
  599.     int sampler_nr;
  600.  
  601.     gen3_get_instruction_dst(data, i, dst_name, 0);
  602.     gen3_get_instruction_addr((t1 >> 24) & 0x7,
  603.                               (t1 >> 17) & 0xf,
  604.                               addr_name);
  605.     sampler_nr = t0 & 0xf;
  606.  
  607.     kgem_debug_print(data, offset, i++, "%s: %s %s, S%d, %s\n", instr_prefix,
  608.               tex_name, dst_name, sampler_nr, addr_name);
  609.     kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
  610.     kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
  611. }
  612.  
  613. static void
  614. gen3_decode_dcl(uint32_t *data, uint32_t offset, int i, char *instr_prefix)
  615. {
  616.         uint32_t d0 = data[i];
  617.         const char *sampletype;
  618.         int dcl_nr = (d0 >> 14) & 0xf;
  619.         const char *dcl_x = d0 & (1 << 10) ? "x" : "";
  620.         const char *dcl_y = d0 & (1 << 11) ? "y" : "";
  621.         const char *dcl_z = d0 & (1 << 12) ? "z" : "";
  622.         const char *dcl_w = d0 & (1 << 13) ? "w" : "";
  623.         char dcl_mask[10];
  624.  
  625.         switch ((d0 >> 19) & 0x3) {
  626.         case 1:
  627.                 sprintf(dcl_mask, ".%s%s%s%s", dcl_x, dcl_y, dcl_z, dcl_w);
  628.                 assert (strcmp(dcl_mask, "."));
  629.  
  630.                 assert(dcl_nr <= 10);
  631.                 if (dcl_nr < 8) {
  632.                         if (strcmp(dcl_mask, ".x") != 0 &&
  633.                             strcmp(dcl_mask, ".xy") != 0 &&
  634.                             strcmp(dcl_mask, ".xz") != 0 &&
  635.                             strcmp(dcl_mask, ".w") != 0 &&
  636.                             strcmp(dcl_mask, ".xyzw") != 0) {
  637.                                 assert(0);
  638.                         }
  639.                         kgem_debug_print(data, offset, i++, "%s: DCL T%d%s\n", instr_prefix,
  640.                                   dcl_nr, dcl_mask);
  641.                 } else {
  642.                         if (strcmp(dcl_mask, ".xz") == 0)
  643.                                 assert(0);
  644.                         else if (strcmp(dcl_mask, ".xw") == 0)
  645.                                 assert(0);
  646.                         else if (strcmp(dcl_mask, ".xzw") == 0)
  647.                                 assert(0);
  648.  
  649.                         if (dcl_nr == 8) {
  650.                                 kgem_debug_print(data, offset, i++, "%s: DCL DIFFUSE%s\n", instr_prefix,
  651.                                           dcl_mask);
  652.                         } else if (dcl_nr == 9) {
  653.                                 kgem_debug_print(data, offset, i++, "%s: DCL SPECULAR%s\n", instr_prefix,
  654.                                           dcl_mask);
  655.                         } else if (dcl_nr == 10) {
  656.                                 kgem_debug_print(data, offset, i++, "%s: DCL FOG%s\n", instr_prefix,
  657.                                           dcl_mask);
  658.                         }
  659.                 }
  660.                 kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
  661.                 kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
  662.                 break;
  663.         case 3:
  664.                 switch ((d0 >> 22) & 0x3) {
  665.                 case 0:
  666.                         sampletype = "2D";
  667.                         break;
  668.                 case 1:
  669.                         sampletype = "CUBE";
  670.                         break;
  671.                 case 2:
  672.                         sampletype = "3D";
  673.                         break;
  674.                 default:
  675.                         sampletype = "RESERVED";
  676.                         break;
  677.                 }
  678.                 assert(dcl_nr <= 15);
  679.                 kgem_debug_print(data, offset, i++, "%s: DCL S%d %s\n", instr_prefix,
  680.                           dcl_nr, sampletype);
  681.                 kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
  682.                 kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
  683.                 break;
  684.         default:
  685.                 kgem_debug_print(data, offset, i++, "%s: DCL RESERVED%d\n", instr_prefix, dcl_nr);
  686.                 kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
  687.                 kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
  688.         }
  689. }
  690.  
  691. static void
  692. gen3_decode_instruction(uint32_t *data, uint32_t offset,
  693.                         int i, char *instr_prefix)
  694. {
  695.     switch ((data[i] >> 24) & 0x1f) {
  696.     case 0x0:
  697.         kgem_debug_print(data, offset, i++, "%s: NOP\n", instr_prefix);
  698.         kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
  699.         kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
  700.         break;
  701.     case 0x01:
  702.         gen3_decode_alu2(data, offset, i, instr_prefix, "ADD");
  703.         break;
  704.     case 0x02:
  705.         gen3_decode_alu1(data, offset, i, instr_prefix, "MOV");
  706.         break;
  707.     case 0x03:
  708.         gen3_decode_alu2(data, offset, i, instr_prefix, "MUL");
  709.         break;
  710.     case 0x04:
  711.         gen3_decode_alu3(data, offset, i, instr_prefix, "MAD");
  712.         break;
  713.     case 0x05:
  714.         gen3_decode_alu3(data, offset, i, instr_prefix, "DP2ADD");
  715.         break;
  716.     case 0x06:
  717.         gen3_decode_alu2(data, offset, i, instr_prefix, "DP3");
  718.         break;
  719.     case 0x07:
  720.         gen3_decode_alu2(data, offset, i, instr_prefix, "DP4");
  721.         break;
  722.     case 0x08:
  723.         gen3_decode_alu1(data, offset, i, instr_prefix, "FRC");
  724.         break;
  725.     case 0x09:
  726.         gen3_decode_alu1(data, offset, i, instr_prefix, "RCP");
  727.         break;
  728.     case 0x0a:
  729.         gen3_decode_alu1(data, offset, i, instr_prefix, "RSQ");
  730.         break;
  731.     case 0x0b:
  732.         gen3_decode_alu1(data, offset, i, instr_prefix, "EXP");
  733.         break;
  734.     case 0x0c:
  735.         gen3_decode_alu1(data, offset, i, instr_prefix, "LOG");
  736.         break;
  737.     case 0x0d:
  738.         gen3_decode_alu2(data, offset, i, instr_prefix, "CMP");
  739.         break;
  740.     case 0x0e:
  741.         gen3_decode_alu2(data, offset, i, instr_prefix, "MIN");
  742.         break;
  743.     case 0x0f:
  744.         gen3_decode_alu2(data, offset, i, instr_prefix, "MAX");
  745.         break;
  746.     case 0x10:
  747.         gen3_decode_alu1(data, offset, i, instr_prefix, "FLR");
  748.         break;
  749.     case 0x11:
  750.         gen3_decode_alu1(data, offset, i, instr_prefix, "MOD");
  751.         break;
  752.     case 0x12:
  753.         gen3_decode_alu1(data, offset, i, instr_prefix, "TRC");
  754.         break;
  755.     case 0x13:
  756.         gen3_decode_alu2(data, offset, i, instr_prefix, "SGE");
  757.         break;
  758.     case 0x14:
  759.         gen3_decode_alu2(data, offset, i, instr_prefix, "SLT");
  760.         break;
  761.     case 0x15:
  762.         gen3_decode_tex(data, offset, i, instr_prefix, "TEXLD");
  763.         break;
  764.     case 0x16:
  765.         gen3_decode_tex(data, offset, i, instr_prefix, "TEXLDP");
  766.         break;
  767.     case 0x17:
  768.         gen3_decode_tex(data, offset, i, instr_prefix, "TEXLDB");
  769.         break;
  770.     case 0x19:
  771.         gen3_decode_dcl(data, offset, i, instr_prefix);
  772.         break;
  773.     default:
  774.         kgem_debug_print(data, offset, i++, "%s: unknown\n", instr_prefix);
  775.         kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
  776.         kgem_debug_print(data, offset, i++, "%s\n", instr_prefix);
  777.         break;
  778.     }
  779. }
  780.  
  781. static const char *
  782. gen3_decode_compare_func(uint32_t op)
  783. {
  784.         switch (op&0x7) {
  785.         case 0: return "always";
  786.         case 1: return "never";
  787.         case 2: return "less";
  788.         case 3: return "equal";
  789.         case 4: return "lequal";
  790.         case 5: return "greater";
  791.         case 6: return "notequal";
  792.         case 7: return "gequal";
  793.         }
  794.         return "";
  795. }
  796.  
  797. static const char *
  798. gen3_decode_stencil_op(uint32_t op)
  799. {
  800.         switch (op&0x7) {
  801.         case 0: return "keep";
  802.         case 1: return "zero";
  803.         case 2: return "replace";
  804.         case 3: return "incr_sat";
  805.         case 4: return "decr_sat";
  806.         case 5: return "greater";
  807.         case 6: return "incr";
  808.         case 7: return "decr";
  809.         }
  810.         return "";
  811. }
  812.  
  813. #if 0
  814. /* part of MODES_4 */
  815. static const char *
  816. gen3_decode_logic_op(uint32_t op)
  817. {
  818.         switch (op&0xf) {
  819.         case 0: return "clear";
  820.         case 1: return "nor";
  821.         case 2: return "and_inv";
  822.         case 3: return "copy_inv";
  823.         case 4: return "and_rvrse";
  824.         case 5: return "inv";
  825.         case 6: return "xor";
  826.         case 7: return "nand";
  827.         case 8: return "and";
  828.         case 9: return "equiv";
  829.         case 10: return "noop";
  830.         case 11: return "or_inv";
  831.         case 12: return "copy";
  832.         case 13: return "or_rvrse";
  833.         case 14: return "or";
  834.         case 15: return "set";
  835.         }
  836.         return "";
  837. }
  838. #endif
  839.  
  840. static const char *
  841. gen3_decode_blend_fact(uint32_t op)
  842. {
  843.         switch (op&0xf) {
  844.         case 1: return "zero";
  845.         case 2: return "one";
  846.         case 3: return "src_colr";
  847.         case 4: return "inv_src_colr";
  848.         case 5: return "src_alpha";
  849.         case 6: return "inv_src_alpha";
  850.         case 7: return "dst_alpha";
  851.         case 8: return "inv_dst_alpha";
  852.         case 9: return "dst_colr";
  853.         case 10: return "inv_dst_colr";
  854.         case 11: return "src_alpha_sat";
  855.         case 12: return "cnst_colr";
  856.         case 13: return "inv_cnst_colr";
  857.         case 14: return "cnst_alpha";
  858.         case 15: return "inv_const_alpha";
  859.         }
  860.         return "";
  861. }
  862.  
  863. static const char *
  864. decode_tex_coord_mode(uint32_t mode)
  865. {
  866.     switch (mode&0x7) {
  867.     case 0: return "wrap";
  868.     case 1: return "mirror";
  869.     case 2: return "clamp_edge";
  870.     case 3: return "cube";
  871.     case 4: return "clamp_border";
  872.     case 5: return "mirror_once";
  873.     }
  874.     return "";
  875. }
  876.  
  877. static const char *
  878. gen3_decode_sample_filter(uint32_t mode)
  879. {
  880.         switch (mode&0x7) {
  881.         case 0: return "nearest";
  882.         case 1: return "linear";
  883.         case 2: return "anisotropic";
  884.         case 3: return "4x4_1";
  885.         case 4: return "4x4_2";
  886.         case 5: return "4x4_flat";
  887.         case 6: return "6x5_mono";
  888.         }
  889.         return "";
  890. }
  891.  
  892. static int
  893. gen3_decode_load_state_immediate_1(struct kgem *kgem, uint32_t offset)
  894. {
  895.         const uint32_t *data = kgem->batch + offset;
  896.         int len, i, word;
  897.  
  898.         kgem_debug_print(data, offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_1\n");
  899.         len = (data[0] & 0x0000000f) + 2;
  900.         i = 1;
  901.         for (word = 0; word <= 8; word++) {
  902.                 if (data[0] & (1 << (4 + word))) {
  903.                         switch (word) {
  904.                         case 0:
  905.                                 kgem_debug_print(data, offset, i, "S0: vbo offset: 0x%08x%s\n",
  906.                                           data[i]&(~1),data[i]&1?", auto cache invalidate disabled":"");
  907.                                 gen3_update_vertex_buffer_addr(kgem, offset + i);
  908.                                 break;
  909.                         case 1:
  910.                                 kgem_debug_print(data, offset, i, "S1: vertex width: %i, vertex pitch: %i\n",
  911.                                           (data[i]>>24)&0x3f,(data[i]>>16)&0x3f);
  912.                                 gen3_update_vertex_buffer_pitch(kgem, offset + i);
  913.                                 break;
  914.                         case 2:
  915.                                 {
  916.                                         char buf[200];
  917.                                         int len = 0;
  918.                                         int tex_num;
  919.                                         for (tex_num = 0; tex_num < 8; tex_num++) {
  920.                                                 switch((data[i]>>tex_num*4)&0xf) {
  921.                                                 case 0: len += sprintf(buf + len, "%i=2D ", tex_num); break;
  922.                                                 case 1: len += sprintf(buf + len, "%i=3D ", tex_num); break;
  923.                                                 case 2: len += sprintf(buf + len, "%i=4D ", tex_num); break;
  924.                                                 case 3: len += sprintf(buf + len, "%i=1D ", tex_num); break;
  925.                                                 case 4: len += sprintf(buf + len, "%i=2D_16 ", tex_num); break;
  926.                                                 case 5: len += sprintf(buf + len, "%i=4D_16 ", tex_num); break;
  927.                                                 case 0xf: len += sprintf(buf + len, "%i=NP ", tex_num); break;
  928.                                                 }
  929.                                         }
  930.                                         kgem_debug_print(data, offset, i, "S2: texcoord formats: %s\n", buf);
  931.                                         gen3_update_vertex_texcoords(kgem, data[i]);
  932.                                 }
  933.  
  934.                                 break;
  935.                         case 3:
  936.                                 kgem_debug_print(data, offset, i, "S3: not documented\n");
  937.                                 break;
  938.                         case 4:
  939.                                 {
  940.                                         const char *cullmode = "";
  941.                                         const char *vfmt_xyzw = "";
  942.                                         switch((data[i]>>13)&0x3) {
  943.                                         case 0: cullmode = "both"; break;
  944.                                         case 1: cullmode = "none"; break;
  945.                                         case 2: cullmode = "cw"; break;
  946.                                         case 3: cullmode = "ccw"; break;
  947.                                         }
  948.                                         switch(data[i] & (7<<6 | 1<<2)) {
  949.                                         case 1<<6: vfmt_xyzw = "XYZ,"; break;
  950.                                         case 2<<6: vfmt_xyzw = "XYZW,"; break;
  951.                                         case 3<<6: vfmt_xyzw = "XY,"; break;
  952.                                         case 4<<6: vfmt_xyzw = "XYW,"; break;
  953.                                         case 1<<6 | 1<<2: vfmt_xyzw = "XYZF,"; break;
  954.                                         case 2<<6 | 1<<2: vfmt_xyzw = "XYZWF,"; break;
  955.                                         case 3<<6 | 1<<2: vfmt_xyzw = "XYF,"; break;
  956.                                         case 4<<6 | 1<<2: vfmt_xyzw = "XYWF,"; break;
  957.                                         }
  958.                                         kgem_debug_print(data, offset, i, "S4: point_width=%i, line_width=%.1f,"
  959.                                                   "%s%s%s%s%s cullmode=%s, vfmt=%s%s%s%s%s%s%s%s "
  960.                                                   "%s%s%s\n",
  961.                                                   (data[i]>>23)&0x1ff,
  962.                                                   ((data[i]>>19)&0xf) / 2.0,
  963.                                                   data[i]&(0xf<<15)?" flatshade=":"",
  964.                                                   data[i]&(1<<18)?"Alpha,":"",
  965.                                                   data[i]&(1<<17)?"Fog,":"",
  966.                                                   data[i]&(1<<16)?"Specular,":"",
  967.                                                   data[i]&(1<<15)?"Color,":"",
  968.                                                   cullmode,
  969.                                                   data[i]&(1<<12)?"PointWidth,":"",
  970.                                                   data[i]&(1<<11)?"SpecFog,":"",
  971.                                                   data[i]&(1<<10)?"Color,":"",
  972.                                                   data[i]&(1<<9)?"DepthOfs,":"",
  973.                                                   vfmt_xyzw,
  974.                                                   data[i]&(1<<9)?"FogParam,":"",
  975.                                                   data[i]&(1<<5)?"force default diffuse, ":"",
  976.                                                   data[i]&(1<<4)?"force default specular, ":"",
  977.                                                   data[i]&(1<<3)?"local depth ofs enable, ":"",
  978.                                                   data[i]&(1<<1)?"point sprite enable, ":"",
  979.                                                   data[i]&(1<<0)?"line AA enable, ":"");
  980.                                         gen3_update_vertex_elements(kgem, data[i]);
  981.                                         break;
  982.                                 }
  983.                         case 5:
  984.                                 {
  985.                                         kgem_debug_print(data, offset, i, "S5:%s%s%s%s%s"
  986.                                                   "%s%s%s%s stencil_ref=0x%x, stencil_test=%s, "
  987.                                                   "stencil_fail=%s, stencil_pass_z_fail=%s, "
  988.                                                   "stencil_pass_z_pass=%s, %s%s%s%s\n",
  989.                                                   data[i]&(0xf<<28)?" write_disable=":"",
  990.                                                   data[i]&(1<<31)?"Alpha,":"",
  991.                                                   data[i]&(1<<30)?"Red,":"",
  992.                                                   data[i]&(1<<29)?"Green,":"",
  993.                                                   data[i]&(1<<28)?"Blue,":"",
  994.                                                   data[i]&(1<<27)?" force default point size,":"",
  995.                                                   data[i]&(1<<26)?" last pixel enable,":"",
  996.                                                   data[i]&(1<<25)?" global depth ofs enable,":"",
  997.                                                   data[i]&(1<<24)?" fog enable,":"",
  998.                                                   (data[i]>>16)&0xff,
  999.                                                   gen3_decode_compare_func(data[i]>>13),
  1000.                                                   gen3_decode_stencil_op(data[i]>>10),
  1001.                                                   gen3_decode_stencil_op(data[i]>>7),
  1002.                                                   gen3_decode_stencil_op(data[i]>>4),
  1003.                                                   data[i]&(1<<3)?"stencil write enable, ":"",
  1004.                                                   data[i]&(1<<2)?"stencil test enable, ":"",
  1005.                                                   data[i]&(1<<1)?"color dither enable, ":"",
  1006.                                                   data[i]&(1<<0)?"logicop enable, ":"");
  1007.                                 }
  1008.                                 break;
  1009.                         case 6:
  1010.                                 kgem_debug_print(data, offset, i, "S6: %salpha_test=%s, alpha_ref=0x%x, "
  1011.                                           "depth_test=%s, %ssrc_blnd_fct=%s, dst_blnd_fct=%s, "
  1012.                                           "%s%stristrip_provoking_vertex=%i\n",
  1013.                                           data[i]&(1<<31)?"alpha test enable, ":"",
  1014.                                           gen3_decode_compare_func(data[i]>>28),
  1015.                                           data[i]&(0xff<<20),
  1016.                                           gen3_decode_compare_func(data[i]>>16),
  1017.                                           data[i]&(1<<15)?"cbuf blend enable, ":"",
  1018.                                           gen3_decode_blend_fact(data[i]>>8),
  1019.                                           gen3_decode_blend_fact(data[i]>>4),
  1020.                                           data[i]&(1<<3)?"depth write enable, ":"",
  1021.                                           data[i]&(1<<2)?"cbuf write enable, ":"",
  1022.                                           data[i]&(0x3));
  1023.                                 break;
  1024.                         case 7:
  1025.                                 kgem_debug_print(data, offset, i, "S7: depth offset constant: 0x%08x\n", data[i]);
  1026.                                 break;
  1027.                         }
  1028.                         i++;
  1029.                 }
  1030.         }
  1031.  
  1032.         assert(len == i);
  1033.         return len;
  1034. }
  1035.  
  1036. static int
  1037. gen3_decode_3d_1d(struct kgem *kgem, uint32_t offset)
  1038. {
  1039.         uint32_t *data = kgem->batch + offset;
  1040.         unsigned int len, i, c, idx, word, map, sampler, instr;
  1041.         const char *format, *zformat, *type;
  1042.         uint32_t opcode;
  1043.         static const struct {
  1044.                 uint32_t opcode;
  1045.                 int min_len;
  1046.                 int max_len;
  1047.                 const char *name;
  1048.         } opcodes_3d_1d[] = {
  1049.                 { 0x86, 4, 4, "3DSTATE_CHROMA_KEY" },
  1050.                 { 0x88, 2, 2, "3DSTATE_CONSTANT_BLEND_COLOR" },
  1051.                 { 0x99, 2, 2, "3DSTATE_DEFAULT_DIFFUSE" },
  1052.                 { 0x9a, 2, 2, "3DSTATE_DEFAULT_SPECULAR" },
  1053.                 { 0x98, 2, 2, "3DSTATE_DEFAULT_Z" },
  1054.                 { 0x97, 2, 2, "3DSTATE_DEPTH_OFFSET_SCALE" },
  1055.                 { 0x9d, 65, 65, "3DSTATE_FILTER_COEFFICIENTS_4X4" },
  1056.                 { 0x9e, 4, 4, "3DSTATE_MONO_FILTER" },
  1057.                 { 0x89, 4, 4, "3DSTATE_FOG_MODE" },
  1058.                 { 0x8f, 2, 16, "3DSTATE_MAP_PALLETE_LOAD_32" },
  1059.                 { 0x83, 2, 2, "3DSTATE_SPAN_STIPPLE" },
  1060.         }, *opcode_3d_1d;
  1061.  
  1062.         opcode = (data[0] & 0x00ff0000) >> 16;
  1063.  
  1064.         switch (opcode) {
  1065.         case 0x07:
  1066.                 /* This instruction is unusual.  A 0 length means just 1 DWORD instead of
  1067.                  * 2.  The 0 length is specified in one place to be unsupported, but
  1068.                  * stated to be required in another, and 0 length LOAD_INDIRECTs appear
  1069.                  * to cause no harm at least.
  1070.                  */
  1071.                 kgem_debug_print(data, offset, 0, "3DSTATE_LOAD_INDIRECT\n");
  1072.                 len = (data[0] & 0x000000ff) + 1;
  1073.                 i = 1;
  1074.                 if (data[0] & (0x01 << 8)) {
  1075.                         kgem_debug_print(data, offset, i++, "SIS.0\n");
  1076.                         kgem_debug_print(data, offset, i++, "SIS.1\n");
  1077.                 }
  1078.                 if (data[0] & (0x02 << 8)) {
  1079.                         kgem_debug_print(data, offset, i++, "DIS.0\n");
  1080.                 }
  1081.                 if (data[0] & (0x04 << 8)) {
  1082.                         kgem_debug_print(data, offset, i++, "SSB.0\n");
  1083.                         kgem_debug_print(data, offset, i++, "SSB.1\n");
  1084.                 }
  1085.                 if (data[0] & (0x08 << 8)) {
  1086.                         kgem_debug_print(data, offset, i++, "MSB.0\n");
  1087.                         kgem_debug_print(data, offset, i++, "MSB.1\n");
  1088.                 }
  1089.                 if (data[0] & (0x10 << 8)) {
  1090.                         kgem_debug_print(data, offset, i++, "PSP.0\n");
  1091.                         kgem_debug_print(data, offset, i++, "PSP.1\n");
  1092.                 }
  1093.                 if (data[0] & (0x20 << 8)) {
  1094.                         kgem_debug_print(data, offset, i++, "PSC.0\n");
  1095.                         kgem_debug_print(data, offset, i++, "PSC.1\n");
  1096.                 }
  1097.                 assert(len == i);
  1098.                 return len;
  1099.         case 0x04:
  1100.                 return gen3_decode_load_state_immediate_1(kgem, offset);
  1101.         case 0x03:
  1102.                 kgem_debug_print(data, offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_2\n");
  1103.                 len = (data[0] & 0x0000000f) + 2;
  1104.                 i = 1;
  1105.                 for (word = 6; word <= 14; word++) {
  1106.                         if (data[0] & (1 << word)) {
  1107.                                 if (word == 6)
  1108.                                         kgem_debug_print(data, offset, i++, "TBCF\n");
  1109.                                 else if (word >= 7 && word <= 10) {
  1110.                                         kgem_debug_print(data, offset, i++, "TB%dC\n", word - 7);
  1111.                                         kgem_debug_print(data, offset, i++, "TB%dA\n", word - 7);
  1112.                                 } else if (word >= 11 && word <= 14) {
  1113.                                         kgem_debug_print(data, offset, i, "TM%dS0: offset=0x%08x, %s\n",
  1114.                                                   word - 11,
  1115.                                                   data[i]&0xfffffffe,
  1116.                                                   data[i]&1?"use fence":"");
  1117.                                         i++;
  1118.                                         kgem_debug_print(data, offset, i, "TM%dS1: height=%i, width=%i, %s\n",
  1119.                                                   word - 11,
  1120.                                                   data[i]>>21, (data[i]>>10)&0x3ff,
  1121.                                                   data[i]&2?(data[i]&1?"y-tiled":"x-tiled"):"");
  1122.                                         i++;
  1123.                                         kgem_debug_print(data, offset, i, "TM%dS2: pitch=%i, \n",
  1124.                                                   word - 11,
  1125.                                                   ((data[i]>>21) + 1)*4);
  1126.                                         i++;
  1127.                                         kgem_debug_print(data, offset, i++, "TM%dS3\n", word - 11);
  1128.                                         kgem_debug_print(data, offset, i++, "TM%dS4: dflt color\n", word - 11);
  1129.                                 }
  1130.                         }
  1131.                 }
  1132.                 assert(len == i);
  1133.                 return len;
  1134.         case 0x00:
  1135.                 kgem_debug_print(data, offset, 0, "3DSTATE_MAP_STATE\n");
  1136.                 len = (data[0] & 0x0000003f) + 2;
  1137.                 kgem_debug_print(data, offset, 1, "mask\n");
  1138.  
  1139.                 i = 2;
  1140.                 for (map = 0; map <= 15; map++) {
  1141.                         if (data[1] & (1 << map)) {
  1142.                                 int width, height, pitch, dword;
  1143.                                 struct drm_i915_gem_relocation_entry *reloc;
  1144.                                 const char *tiling;
  1145.  
  1146.                                 reloc = kgem_debug_get_reloc_entry(kgem, &data[i] - kgem->batch);
  1147.                                 assert(reloc->target_handle);
  1148.  
  1149.                                 dword = data[i];
  1150.                                 kgem_debug_print(data, offset, i++, "map %d MS2 %s%s%s, handle=%d\n", map,
  1151.                                           dword&(1<<31)?"untrusted surface, ":"",
  1152.                                           dword&(1<<1)?"vertical line stride enable, ":"",
  1153.                                           dword&(1<<0)?"vertical ofs enable, ":"",
  1154.                                           reloc->target_handle);
  1155.  
  1156.                                 dword = data[i];
  1157.                                 width = ((dword >> 10) & ((1 << 11) - 1))+1;
  1158.                                 height = ((dword >> 21) & ((1 << 11) - 1))+1;
  1159.  
  1160.                                 tiling = "none";
  1161.                                 if (dword & (1 << 2))
  1162.                                         tiling = "fenced";
  1163.                                 else if (dword & (1 << 1))
  1164.                                         tiling = dword & (1 << 0) ? "Y" : "X";
  1165.                                 type = " BAD";
  1166.                                 format = " (invalid)";
  1167.                                 switch ((dword>>7) & 0x7) {
  1168.                                 case 1:
  1169.                                         type = "8";
  1170.                                         switch ((dword>>3) & 0xf) {
  1171.                                         case 0: format = "I"; break;
  1172.                                         case 1: format = "L"; break;
  1173.                                         case 4: format = "A"; break;
  1174.                                         case 5: format = " mono"; break;
  1175.                                         }
  1176.                                         break;
  1177.                                 case 2:
  1178.                                         type = "16";
  1179.                                         switch ((dword>>3) & 0xf) {
  1180.                                         case 0: format = " rgb565"; break;
  1181.                                         case 1: format = " argb1555"; break;
  1182.                                         case 2: format = " argb4444"; break;
  1183.                                         case 3: format = " ay88"; break;
  1184.                                         case 5: format = " 88dvdu"; break;
  1185.                                         case 6: format = " bump655"; break;
  1186.                                         case 7: format = "I"; break;
  1187.                                         case 8: format = "L"; break;
  1188.                                         case 9: format = "A"; break;
  1189.                                         }
  1190.                                         break;
  1191.                                 case 3:
  1192.                                         type = "32";
  1193.                                         switch ((dword>>3) & 0xf) {
  1194.                                         case 0: format = " argb8888"; break;
  1195.                                         case 1: format = " abgr8888"; break;
  1196.                                         case 2: format = " xrgb8888"; break;
  1197.                                         case 3: format = " xbgr8888"; break;
  1198.                                         case 4: format = " qwvu8888"; break;
  1199.                                         case 5: format = " axvu8888"; break;
  1200.                                         case 6: format = " lxvu8888"; break;
  1201.                                         case 7: format = " xlvu8888"; break;
  1202.                                         case 8: format = " argb2101010"; break;
  1203.                                         case 9: format = " abgr2101010"; break;
  1204.                                         case 10: format = " awvu2101010"; break;
  1205.                                         case 11: format = " gr1616"; break;
  1206.                                         case 12: format = " vu1616"; break;
  1207.                                         case 13: format = " xI824"; break;
  1208.                                         case 14: format = " xA824"; break;
  1209.                                         case 15: format = " xL824"; break;
  1210.                                         }
  1211.                                         break;
  1212.                                 case 5:
  1213.                                         type = "422";
  1214.                                         switch ((dword>>3) & 0xf) {
  1215.                                         case 0: format = " yuv_swapy"; break;
  1216.                                         case 1: format = " yuv"; break;
  1217.                                         case 2: format = " yuv_swapuv"; break;
  1218.                                         case 3: format = " yuv_swapuvy"; break;
  1219.                                         }
  1220.                                         break;
  1221.                                 case 6:
  1222.                                         type = "compressed";
  1223.                                         switch ((dword>>3) & 0x7) {
  1224.                                         case 0: format = " dxt1"; break;
  1225.                                         case 1: format = " dxt2_3"; break;
  1226.                                         case 2: format = " dxt4_5"; break;
  1227.                                         case 3: format = " fxt1"; break;
  1228.                                         case 4: format = " dxt1_rb"; break;
  1229.                                         }
  1230.                                         break;
  1231.                                 case 7:
  1232.                                         type = "4b indexed";
  1233.                                         switch ((dword>>3) & 0xf) {
  1234.                                         case 7: format = " argb8888"; break;
  1235.                                         }
  1236.                                         break;
  1237.                                 default:
  1238.                                         format = "BAD";
  1239.                                         break;
  1240.                                 }
  1241.                                 dword = data[i];
  1242.                                 kgem_debug_print(data, offset, i++, "map %d MS3 [width=%d, height=%d, format=%s%s, tiling=%s%s]\n",
  1243.                                           map, width, height, type, format, tiling,
  1244.                                           dword&(1<<9)?" palette select":"");
  1245.  
  1246.                                 dword = data[i];
  1247.                                 pitch = 4*(((dword >> 21) & ((1 << 11) - 1))+1);
  1248.                                 kgem_debug_print(data, offset, i++, "map %d MS4 [pitch=%d, max_lod=%i, vol_depth=%i, cube_face_ena=%x, %s]\n",
  1249.                                           map, pitch,
  1250.                                           (dword>>9)&0x3f, dword&0xff, (dword>>15)&0x3f,
  1251.                                           dword&(1<<8)?"miplayout legacy":"miplayout right");
  1252.                         }
  1253.                 }
  1254.                 assert(len == i);
  1255.                 return len;
  1256.         case 0x06:
  1257.                 kgem_debug_print(data, offset, 0, "3DSTATE_PIXEL_SHADER_CONSTANTS\n");
  1258.                 len = (data[0] & 0x000000ff) + 2;
  1259.  
  1260.                 i = 2;
  1261.                 for (c = 0; c <= 31; c++) {
  1262.                         if (data[1] & (1 << c)) {
  1263.                                 kgem_debug_print(data, offset, i, "C%d.X = %f\n",
  1264.                                           c, int_as_float(data[i]));
  1265.                                 i++;
  1266.                                 kgem_debug_print(data, offset, i, "C%d.Y = %f\n",
  1267.                                           c, int_as_float(data[i]));
  1268.                                 i++;
  1269.                                 kgem_debug_print(data, offset, i, "C%d.Z = %f\n",
  1270.                                           c, int_as_float(data[i]));
  1271.                                 i++;
  1272.                                 kgem_debug_print(data, offset, i, "C%d.W = %f\n",
  1273.                                           c, int_as_float(data[i]));
  1274.                                 i++;
  1275.                         }
  1276.                 }
  1277.                 assert(len == i);
  1278.                 return len;
  1279.         case 0x05:
  1280.                 kgem_debug_print(data, offset, 0, "3DSTATE_PIXEL_SHADER_PROGRAM\n");
  1281.                 len = (data[0] & 0x000000ff) + 2;
  1282.                 assert(((len-1) % 3) == 0);
  1283.                 assert(len <= 370);
  1284.                 i = 1;
  1285.                 for (instr = 0; instr < (len - 1) / 3; instr++) {
  1286.                         char instr_prefix[10];
  1287.  
  1288.                         sprintf(instr_prefix, "PS%03d", instr);
  1289.                         gen3_decode_instruction(data, offset, i, instr_prefix);
  1290.                         i += 3;
  1291.                 }
  1292.                 return len;
  1293.         case 0x01:
  1294.                 kgem_debug_print(data, offset, 0, "3DSTATE_SAMPLER_STATE\n");
  1295.                 kgem_debug_print(data, offset, 1, "mask\n");
  1296.                 len = (data[0] & 0x0000003f) + 2;
  1297.                 i = 2;
  1298.                 for (sampler = 0; sampler <= 15; sampler++) {
  1299.                         if (data[1] & (1 << sampler)) {
  1300.                                 uint32_t dword;
  1301.                                 const char *mip_filter = "";
  1302.                                 dword = data[i];
  1303.                                 switch ((dword>>20)&0x3) {
  1304.                                 case 0: mip_filter = "none"; break;
  1305.                                 case 1: mip_filter = "nearest"; break;
  1306.                                 case 3: mip_filter = "linear"; break;
  1307.                                 }
  1308.                                 kgem_debug_print(data, offset, i++, "sampler %d SS2:%s%s%s "
  1309.                                           "base_mip_level=%i, mip_filter=%s, mag_filter=%s, min_filter=%s "
  1310.                                           "lod_bias=%.2f,%s max_aniso=%i, shadow_func=%s\n", sampler,
  1311.                                           dword&(1<<31)?" reverse gamma,":"",
  1312.                                           dword&(1<<30)?" packed2planar,":"",
  1313.                                           dword&(1<<29)?" colorspace conversion,":"",
  1314.                                           (dword>>22)&0x1f,
  1315.                                           mip_filter,
  1316.                                           gen3_decode_sample_filter(dword>>17),
  1317.                                           gen3_decode_sample_filter(dword>>14),
  1318.                                           ((dword>>5)&0x1ff)/(0x10*1.0),
  1319.                                           dword&(1<<4)?" shadow,":"",
  1320.                                           dword&(1<<3)?4:2,
  1321.                                           gen3_decode_compare_func(dword));
  1322.                                 dword = data[i];
  1323.                                 kgem_debug_print(data, offset, i++, "sampler %d SS3: min_lod=%.2f,%s "
  1324.                                           "tcmode_x=%s, tcmode_y=%s, tcmode_z=%s,%s texmap_idx=%i,%s\n",
  1325.                                           sampler, ((dword>>24)&0xff)/(0x10*1.0),
  1326.                                           dword&(1<<17)?" kill pixel enable,":"",
  1327.                                           decode_tex_coord_mode(dword>>12),
  1328.                                           decode_tex_coord_mode(dword>>9),
  1329.                                           decode_tex_coord_mode(dword>>6),
  1330.                                           dword&(1<<5)?" normalized coords,":"",
  1331.                                           (dword>>1)&0xf,
  1332.                                           dword&(1<<0)?" deinterlacer,":"");
  1333.                                 kgem_debug_print(data, offset, i++, "sampler %d SS4: border color\n",
  1334.                                           sampler);
  1335.                         }
  1336.                 }
  1337.                 assert(len == i);
  1338.                 return len;
  1339.         case 0x85:
  1340.                 len = (data[0] & 0x0000000f) + 2;
  1341.                 assert(len == 2);
  1342.  
  1343.                 kgem_debug_print(data, offset, 0,
  1344.                           "3DSTATE_DEST_BUFFER_VARIABLES\n");
  1345.  
  1346.                 switch ((data[1] >> 8) & 0xf) {
  1347.                 case 0x0: format = "g8"; break;
  1348.                 case 0x1: format = "x1r5g5b5"; break;
  1349.                 case 0x2: format = "r5g6b5"; break;
  1350.                 case 0x3: format = "a8r8g8b8"; break;
  1351.                 case 0x4: format = "ycrcb_swapy"; break;
  1352.                 case 0x5: format = "ycrcb_normal"; break;
  1353.                 case 0x6: format = "ycrcb_swapuv"; break;
  1354.                 case 0x7: format = "ycrcb_swapuvy"; break;
  1355.                 case 0x8: format = "a4r4g4b4"; break;
  1356.                 case 0x9: format = "a1r5g5b5"; break;
  1357.                 case 0xa: format = "a2r10g10b10"; break;
  1358.                 default: format = "BAD"; break;
  1359.                 }
  1360.                 switch ((data[1] >> 2) & 0x3) {
  1361.                 case 0x0: zformat = "u16"; break;
  1362.                 case 0x1: zformat = "f16"; break;
  1363.                 case 0x2: zformat = "u24x8"; break;
  1364.                 default: zformat = "BAD"; break;
  1365.                 }
  1366.                 kgem_debug_print(data, offset, 1, "%s format, %s depth format, early Z %sabled\n",
  1367.                           format, zformat,
  1368.                           (data[1] & (1 << 31)) ? "en" : "dis");
  1369.                 return len;
  1370.  
  1371.         case 0x8e:
  1372.                 {
  1373.                         const char *name, *tiling;
  1374.  
  1375.                         len = (data[0] & 0x0000000f) + 2;
  1376.                         assert(len == 3);
  1377.  
  1378.                         switch((data[1] >> 24) & 0x7) {
  1379.                         case 0x3: name = "color"; break;
  1380.                         case 0x7: name = "depth"; break;
  1381.                         default: name = "unknown"; break;
  1382.                         }
  1383.  
  1384.                         tiling = "none";
  1385.                         if (data[1] & (1 << 23))
  1386.                                 tiling = "fenced";
  1387.                         else if (data[1] & (1 << 22))
  1388.                                 tiling = data[1] & (1 << 21) ? "Y" : "X";
  1389.  
  1390.                         kgem_debug_print(data, offset, 0, "3DSTATE_BUFFER_INFO\n");
  1391.                         kgem_debug_print(data, offset, 1, "%s, tiling = %s, pitch=%d\n", name, tiling, data[1]&0xffff);
  1392.  
  1393.                         kgem_debug_print(data, offset, 2, "address\n");
  1394.                         return len;
  1395.                 }
  1396.         case 0x81:
  1397.                 len = (data[0] & 0x0000000f) + 2;
  1398.                 assert(len == 3);
  1399.  
  1400.                 kgem_debug_print(data, offset, 0,
  1401.                           "3DSTATE_SCISSOR_RECTANGLE\n");
  1402.                 kgem_debug_print(data, offset, 1, "(%d,%d)\n",
  1403.                           data[1] & 0xffff, data[1] >> 16);
  1404.                 kgem_debug_print(data, offset, 2, "(%d,%d)\n",
  1405.                           data[2] & 0xffff, data[2] >> 16);
  1406.  
  1407.                 return len;
  1408.         case 0x80:
  1409.                 len = (data[0] & 0x0000000f) + 2;
  1410.                 assert(len == 5);
  1411.  
  1412.                 kgem_debug_print(data, offset, 0,
  1413.                           "3DSTATE_DRAWING_RECTANGLE\n");
  1414.                 kgem_debug_print(data, offset, 1, "%s\n",
  1415.                           data[1]&(1<<30)?"depth ofs disabled ":"");
  1416.                 kgem_debug_print(data, offset, 2, "(%d,%d)\n",
  1417.                           data[2] & 0xffff, data[2] >> 16);
  1418.                 kgem_debug_print(data, offset, 3, "(%d,%d)\n",
  1419.                           data[3] & 0xffff, data[3] >> 16);
  1420.                 kgem_debug_print(data, offset, 4, "(%d,%d)\n",
  1421.                           (int16_t)(data[4] & 0xffff),
  1422.                           (int16_t)(data[4] >> 16));
  1423.  
  1424.                 return len;
  1425.         case 0x9c:
  1426.                 len = (data[0] & 0x0000000f) + 2;
  1427.                 assert(len == 7);
  1428.  
  1429.                 kgem_debug_print(data, offset, 0,
  1430.                           "3DSTATE_CLEAR_PARAMETERS\n");
  1431.                 kgem_debug_print(data, offset, 1, "prim_type=%s, clear=%s%s%s\n",
  1432.                           data[1]&(1<<16)?"CLEAR_RECT":"ZONE_INIT",
  1433.                           data[1]&(1<<2)?"color,":"",
  1434.                           data[1]&(1<<1)?"depth,":"",
  1435.                           data[1]&(1<<0)?"stencil,":"");
  1436.                 kgem_debug_print(data, offset, 2, "clear color\n");
  1437.                 kgem_debug_print(data, offset, 3, "clear depth/stencil\n");
  1438.                 kgem_debug_print(data, offset, 4, "color value (rgba8888)\n");
  1439.                 kgem_debug_print(data, offset, 5, "depth value %f\n",
  1440.                           int_as_float(data[5]));
  1441.                 kgem_debug_print(data, offset, 6, "clear stencil\n");
  1442.                 return len;
  1443.         }
  1444.  
  1445.         for (idx = 0; idx < ARRAY_SIZE(opcodes_3d_1d); idx++) {
  1446.                 opcode_3d_1d = &opcodes_3d_1d[idx];
  1447.                 if (((data[0] & 0x00ff0000) >> 16) == opcode_3d_1d->opcode) {
  1448.                         len = (data[0] & 0xf) + 2;
  1449.                         kgem_debug_print(data, offset, 0, "%s\n", opcode_3d_1d->name);
  1450.                         for (i = 1; i < len; i++)
  1451.                                 kgem_debug_print(data, offset, i, "dword %d\n", i);
  1452.  
  1453.                         return len;
  1454.                 }
  1455.         }
  1456.  
  1457.         kgem_debug_print(data, offset, 0, "3D UNKNOWN: 3d_1d opcode = 0x%x\n", opcode);
  1458.         assert(0);
  1459.         return 1;
  1460. }
  1461.  
  1462. #define VERTEX_OUT(fmt, ...) do {                                       \
  1463.         kgem_debug_print(data, offset, i, " V%d."fmt"\n", vertex, __VA_ARGS__); \
  1464.         i++;                                                            \
  1465. } while (0)
  1466.  
  1467. static int
  1468. gen3_decode_3d_primitive(struct kgem *kgem, uint32_t offset)
  1469. {
  1470.         uint32_t *data = kgem->batch + offset;
  1471.         char immediate = (data[0] & (1 << 23)) == 0;
  1472.         unsigned int len, i, ret;
  1473.         const char *primtype;
  1474.         unsigned int vertex = 0;
  1475.  
  1476.         switch ((data[0] >> 18) & 0xf) {
  1477.         case 0x0: primtype = "TRILIST"; break;
  1478.         case 0x1: primtype = "TRISTRIP"; break;
  1479.         case 0x2: primtype = "TRISTRIP_REVERSE"; break;
  1480.         case 0x3: primtype = "TRIFAN"; break;
  1481.         case 0x4: primtype = "POLYGON"; break;
  1482.         case 0x5: primtype = "LINELIST"; break;
  1483.         case 0x6: primtype = "LINESTRIP"; break;
  1484.         case 0x7: primtype = "RECTLIST"; break;
  1485.         case 0x8: primtype = "POINTLIST"; break;
  1486.         case 0x9: primtype = "DIB"; break;
  1487.         case 0xa: primtype = "CLEAR_RECT"; assert(0); break;
  1488.         default: primtype = "unknown"; break;
  1489.         }
  1490.  
  1491.         gen3_update_vertex_elements_offsets(kgem);
  1492.  
  1493.         /* XXX: 3DPRIM_DIB not supported */
  1494.         if (immediate) {
  1495.                 len = (data[0] & 0x0003ffff) + 2;
  1496.                 kgem_debug_print(data, offset, 0, "3DPRIMITIVE inline %s\n", primtype);
  1497.                 for (i = 1; i < len; ) {
  1498.                         ErrorF("    [%d]: ", vertex);
  1499.                         i += inline_vertex_out(kgem, data + i) / sizeof(uint32_t);
  1500.                         ErrorF("\n");
  1501.                         vertex++;
  1502.                 }
  1503.  
  1504.                 ret = len;
  1505.         } else {
  1506.                 /* indirect vertices */
  1507.                 len = data[0] & 0x0000ffff; /* index count */
  1508.                 if (data[0] & (1 << 17)) {
  1509.                         /* random vertex access */
  1510.                         kgem_debug_print(data, offset, 0,
  1511.                                   "3DPRIMITIVE random indirect %s (%d)\n", primtype, len);
  1512.                         assert(0);
  1513.                         if (len == 0) {
  1514.                                 /* vertex indices continue until 0xffff is found */
  1515.                         } else {
  1516.                                 /* fixed size vertex index buffer */
  1517.                         }
  1518.                         ret = (len + 1) / 2 + 1;
  1519.                         goto out;
  1520.                 } else {
  1521.                         /* sequential vertex access */
  1522.                         vertex = data[1] & 0xffff;
  1523.                         kgem_debug_print(data, offset, 0,
  1524.                                   "3DPRIMITIVE sequential indirect %s, %d starting from "
  1525.                                   "%d\n", primtype, len, vertex);
  1526.                         kgem_debug_print(data, offset, 1, "  start\n");
  1527.                         for (i = 0; i < len; i++) {
  1528.                                 ErrorF("    [%d]: ", vertex);
  1529.                                 indirect_vertex_out(kgem, vertex++);
  1530.                                 ErrorF("\n");
  1531.                         }
  1532.                         ret = 2;
  1533.                         goto out;
  1534.                 }
  1535.         }
  1536.  
  1537. out:
  1538.         return ret;
  1539. }
  1540.  
  1541. int kgem_gen3_decode_3d(struct kgem *kgem, uint32_t offset)
  1542. {
  1543.     static const struct {
  1544.         uint32_t opcode;
  1545.         int min_len;
  1546.         int max_len;
  1547.         const char *name;
  1548.     } opcodes[] = {
  1549.         { 0x06, 1, 1, "3DSTATE_ANTI_ALIASING" },
  1550.         { 0x08, 1, 1, "3DSTATE_BACKFACE_STENCIL_OPS" },
  1551.         { 0x09, 1, 1, "3DSTATE_BACKFACE_STENCIL_MASKS" },
  1552.         { 0x16, 1, 1, "3DSTATE_COORD_SET_BINDINGS" },
  1553.         { 0x15, 1, 1, "3DSTATE_FOG_COLOR" },
  1554.         { 0x0b, 1, 1, "3DSTATE_INDEPENDENT_ALPHA_BLEND" },
  1555.         { 0x0d, 1, 1, "3DSTATE_MODES_4" },
  1556.         { 0x0c, 1, 1, "3DSTATE_MODES_5" },
  1557.         { 0x07, 1, 1, "3DSTATE_RASTERIZATION_RULES" },
  1558.     };
  1559.     uint32_t *data = kgem->batch + offset;
  1560.     uint32_t opcode;
  1561.     unsigned int idx;
  1562.  
  1563.     opcode = (data[0] & 0x1f000000) >> 24;
  1564.  
  1565.     switch (opcode) {
  1566.     case 0x1f:
  1567.         return gen3_decode_3d_primitive(kgem, offset);
  1568.     case 0x1d:
  1569.         return gen3_decode_3d_1d(kgem, offset);
  1570.     case 0x1c:
  1571.         return gen3_decode_3d_1c(kgem, offset);
  1572.     }
  1573.  
  1574.     for (idx = 0; idx < ARRAY_SIZE(opcodes); idx++) {
  1575.         if (opcode == opcodes[idx].opcode) {
  1576.             unsigned int len = 1, i;
  1577.  
  1578.             kgem_debug_print(data, offset, 0, "%s\n", opcodes[idx].name);
  1579.             if (opcodes[idx].max_len > 1) {
  1580.                 len = (data[0] & 0xff) + 2;
  1581.                 assert(len >= opcodes[idx].min_len ||
  1582.                        len <= opcodes[idx].max_len);
  1583.             }
  1584.  
  1585.             for (i = 1; i < len; i++)
  1586.                 kgem_debug_print(data, offset, i, "dword %d\n", i);
  1587.             return len;
  1588.         }
  1589.     }
  1590.  
  1591.     kgem_debug_print(data, offset, 0, "3D UNKNOWN: 3d opcode = 0x%x\n", opcode);
  1592.     return 1;
  1593. }
  1594.  
  1595.  
  1596. void kgem_gen3_finish_state(struct kgem *kgem)
  1597. {
  1598.         memset(&state, 0, sizeof(state));
  1599. }
  1600.