Subversion Repositories Kolibri OS

Rev

Rev 4304 | Blame | Compare with Previous | Last modification | View Log | 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. #include "gen7_render.h"
  38.  
  39. #include "kgem_debug.h"
  40.  
  41. static struct state {
  42.         struct vertex_buffer {
  43.                 int handle;
  44.                 void *base;
  45.                 const char *ptr;
  46.                 int pitch;
  47.  
  48.                 struct kgem_bo *current;
  49.         } vb[33];
  50.         struct vertex_elements {
  51.                 int buffer;
  52.                 int offset;
  53.                 bool valid;
  54.                 uint32_t type;
  55.                 uint8_t swizzle[4];
  56.         } ve[33];
  57.         int num_ve;
  58.  
  59.         struct dynamic_state {
  60.                 struct kgem_bo *current;
  61.                 void *base, *ptr;
  62.         } dynamic_state;
  63. } state;
  64.  
  65. static void gen7_update_vertex_buffer(struct kgem *kgem, const uint32_t *data)
  66. {
  67.         uint32_t reloc = sizeof(uint32_t) * (&data[1] - kgem->batch);
  68.         struct kgem_bo *bo = NULL;
  69.         void *base, *ptr;
  70.         int i;
  71.  
  72.         for (i = 0; i < kgem->nreloc; i++)
  73.                 if (kgem->reloc[i].offset == reloc)
  74.                         break;
  75.         assert(i < kgem->nreloc);
  76.         reloc = kgem->reloc[i].target_handle;
  77.  
  78.         if (reloc == 0) {
  79.                 base = kgem->batch;
  80.         } else {
  81.                 list_for_each_entry(bo, &kgem->next_request->buffers, request)
  82.                         if (bo->handle == reloc)
  83.                                 break;
  84.                 assert(&bo->request != &kgem->next_request->buffers);
  85.                 base = kgem_bo_map__debug(kgem, bo);
  86.         }
  87.         ptr = (char *)base + kgem->reloc[i].delta;
  88.  
  89.         i = data[0] >> 26;
  90.  
  91.         state.vb[i].current = bo;
  92.         state.vb[i].base = base;
  93.         state.vb[i].ptr = ptr;
  94.         state.vb[i].pitch = data[0] & 0x7ff;
  95. }
  96.  
  97. static void gen7_update_dynamic_buffer(struct kgem *kgem, const uint32_t offset)
  98. {
  99.         uint32_t reloc = sizeof(uint32_t) * offset;
  100.         struct kgem_bo *bo = NULL;
  101.         void *base, *ptr;
  102.         int i;
  103.  
  104.         if ((kgem->batch[offset] & 1) == 0)
  105.                 return;
  106.  
  107.         for (i = 0; i < kgem->nreloc; i++)
  108.                 if (kgem->reloc[i].offset == reloc)
  109.                         break;
  110.         if(i < kgem->nreloc) {
  111.                 reloc = kgem->reloc[i].target_handle;
  112.  
  113.                 if (reloc == 0) {
  114.                         base = kgem->batch;
  115.                 } else {
  116.                         list_for_each_entry(bo, &kgem->next_request->buffers, request)
  117.                                 if (bo->handle == reloc)
  118.                                         break;
  119.                         assert(&bo->request != &kgem->next_request->buffers);
  120.                         base = kgem_bo_map__debug(kgem, bo);
  121.                 }
  122.                 ptr = (char *)base + (kgem->reloc[i].delta & ~1);
  123.         } else {
  124.                 bo = NULL;
  125.                 base = NULL;
  126.                 ptr = NULL;
  127.         }
  128.  
  129.         state.dynamic_state.current = bo;
  130.         state.dynamic_state.base = base;
  131.         state.dynamic_state.ptr = ptr;
  132. }
  133.  
  134. static uint32_t
  135. get_ve_component(uint32_t data, int component)
  136. {
  137.         return (data >> (16 + (3 - component) * 4)) & 0x7;
  138. }
  139.  
  140. static void gen7_update_vertex_elements(struct kgem *kgem, int id, const uint32_t *data)
  141. {
  142.         state.ve[id].buffer = data[0] >> 26;
  143.         state.ve[id].valid = !!(data[0] & (1 << 25));
  144.         state.ve[id].type = (data[0] >> 16) & 0x1ff;
  145.         state.ve[id].offset = data[0] & 0x7ff;
  146.         state.ve[id].swizzle[0] = get_ve_component(data[1], 0);
  147.         state.ve[id].swizzle[1] = get_ve_component(data[1], 1);
  148.         state.ve[id].swizzle[2] = get_ve_component(data[1], 2);
  149.         state.ve[id].swizzle[3] = get_ve_component(data[1], 3);
  150. }
  151.  
  152. static void gen7_update_sf_state(struct kgem *kgem, uint32_t *data)
  153. {
  154.         state.num_ve = 1 + ((data[1] >> 22) & 0x3f);
  155. }
  156.  
  157. static void vertices_sint16_out(const struct vertex_elements *ve, const int16_t *v, int max)
  158. {
  159.         int c;
  160.  
  161.         ErrorF("(");
  162.         for (c = 0; c < max; c++) {
  163.                 switch (ve->swizzle[c]) {
  164.                 case 0: ErrorF("#"); break;
  165.                 case 1: ErrorF("%d", v[c]); break;
  166.                 case 2: ErrorF("0.0"); break;
  167.                 case 3: ErrorF("1.0"); break;
  168.                 case 4: ErrorF("0x1"); break;
  169.                 case 5: break;
  170.                 default: ErrorF("?");
  171.                 }
  172.                 if (c < 3)
  173.                         ErrorF(", ");
  174.         }
  175.         for (; c < 4; c++) {
  176.                 switch (ve->swizzle[c]) {
  177.                 case 0: ErrorF("#"); break;
  178.                 case 1: ErrorF("1.0"); break;
  179.                 case 2: ErrorF("0.0"); break;
  180.                 case 3: ErrorF("1.0"); break;
  181.                 case 4: ErrorF("0x1"); break;
  182.                 case 5: break;
  183.                 default: ErrorF("?");
  184.                 }
  185.                 if (c < 3)
  186.                         ErrorF(", ");
  187.         }
  188.         ErrorF(")");
  189. }
  190.  
  191. static void vertices_float_out(const struct vertex_elements *ve, const float *f, int max)
  192. {
  193.         int c, o;
  194.  
  195.         ErrorF("(");
  196.         for (c = o = 0; c < 4 && o < max; c++) {
  197.                 switch (ve->swizzle[c]) {
  198.                 case 0: ErrorF("#"); break;
  199.                 case 1: ErrorF("%f", f[o++]); break;
  200.                 case 2: ErrorF("0.0"); break;
  201.                 case 3: ErrorF("1.0"); break;
  202.                 case 4: ErrorF("0x1"); break;
  203.                 case 5: break;
  204.                 default: ErrorF("?");
  205.                 }
  206.                 if (c < 3)
  207.                         ErrorF(", ");
  208.         }
  209.         for (; c < 4; c++) {
  210.                 switch (ve->swizzle[c]) {
  211.                 case 0: ErrorF("#"); break;
  212.                 case 1: ErrorF("1.0"); break;
  213.                 case 2: ErrorF("0.0"); break;
  214.                 case 3: ErrorF("1.0"); break;
  215.                 case 4: ErrorF("0x1"); break;
  216.                 case 5: break;
  217.                 default: ErrorF("?");
  218.                 }
  219.                 if (c < 3)
  220.                         ErrorF(", ");
  221.         }
  222.         ErrorF(")");
  223. }
  224.  
  225. static void ve_out(const struct vertex_elements *ve, const void *ptr)
  226. {
  227.         switch (ve->type) {
  228.         case GEN7_SURFACEFORMAT_R32_FLOAT:
  229.                 vertices_float_out(ve, ptr, 1);
  230.                 break;
  231.         case GEN7_SURFACEFORMAT_R32G32_FLOAT:
  232.                 vertices_float_out(ve, ptr, 2);
  233.                 break;
  234.         case GEN7_SURFACEFORMAT_R32G32B32_FLOAT:
  235.                 vertices_float_out(ve, ptr, 3);
  236.                 break;
  237.         case GEN7_SURFACEFORMAT_R32G32B32A32_FLOAT:
  238.                 vertices_float_out(ve, ptr, 4);
  239.                 break;
  240.         case GEN7_SURFACEFORMAT_R16_SINT:
  241.                 vertices_sint16_out(ve, ptr, 1);
  242.                 break;
  243.         case GEN7_SURFACEFORMAT_R16G16_SINT:
  244.                 vertices_sint16_out(ve, ptr, 2);
  245.                 break;
  246.         case GEN7_SURFACEFORMAT_R16G16B16A16_SINT:
  247.                 vertices_sint16_out(ve, ptr, 4);
  248.                 break;
  249.         case GEN7_SURFACEFORMAT_R16_SSCALED:
  250.                 vertices_sint16_out(ve, ptr, 1);
  251.                 break;
  252.         case GEN7_SURFACEFORMAT_R16G16_SSCALED:
  253.                 vertices_sint16_out(ve, ptr, 2);
  254.                 break;
  255.         case GEN7_SURFACEFORMAT_R16G16B16A16_SSCALED:
  256.                 vertices_sint16_out(ve, ptr, 4);
  257.                 break;
  258.         }
  259. }
  260.  
  261. static void indirect_vertex_out(struct kgem *kgem, uint32_t v)
  262. {
  263.         int i = 1;
  264.  
  265.         do {
  266.                 const struct vertex_elements *ve = &state.ve[i];
  267.                 const struct vertex_buffer *vb = &state.vb[ve->buffer];
  268.                 const void *ptr = vb->ptr + v * vb->pitch + ve->offset;
  269.  
  270.                 if (!ve->valid)
  271.                         continue;
  272.  
  273.                 ve_out(ve, ptr);
  274.  
  275.                 while (++i <= state.num_ve && !state.ve[i].valid)
  276.                         ;
  277.  
  278.                 if (i <= state.num_ve)
  279.                         ErrorF(", ");
  280.         } while (i <= state.num_ve);
  281. }
  282.  
  283. static void primitive_out(struct kgem *kgem, uint32_t *data)
  284. {
  285.         int n;
  286.  
  287.         assert((data[0] & (1<<15)) == 0); /* XXX index buffers */
  288.  
  289.         for (n = 0; n < data[2]; n++) {
  290.                 int v = data[3] + n;
  291.                 ErrorF("        [%d:%d] = ", n, v);
  292.                 indirect_vertex_out(kgem, v);
  293.                 ErrorF("\n");
  294.         }
  295. }
  296.  
  297. static void finish_state(struct kgem *kgem)
  298. {
  299.         memset(&state, 0, sizeof(state));
  300. }
  301.  
  302. static void
  303. state_base_out(uint32_t *data, uint32_t offset, unsigned int index,
  304.                const char *name)
  305. {
  306.     if (data[index] & 1)
  307.         kgem_debug_print(data, offset, index,
  308.                   "%s state base address 0x%08x\n",
  309.                   name, data[index] & ~1);
  310.     else
  311.         kgem_debug_print(data, offset, index,
  312.                   "%s state base not updated\n",
  313.                   name);
  314. }
  315.  
  316. static void
  317. state_max_out(uint32_t *data, uint32_t offset, unsigned int index,
  318.               const char *name)
  319. {
  320.         if (data[index] == 1)
  321.                 kgem_debug_print(data, offset, index,
  322.                           "%s state upper bound disabled\n", name);
  323.         else if (data[index] & 1)
  324.                 kgem_debug_print(data, offset, index,
  325.                           "%s state upper bound 0x%08x\n",
  326.                           name, data[index] & ~1);
  327.         else
  328.                 kgem_debug_print(data, offset, index,
  329.                           "%s state upper bound not updated\n",
  330.                           name);
  331. }
  332.  
  333. static const char *
  334. get_965_surfacetype(unsigned int surfacetype)
  335. {
  336.         switch (surfacetype) {
  337.         case 0: return "1D";
  338.         case 1: return "2D";
  339.         case 2: return "3D";
  340.         case 3: return "CUBE";
  341.         case 4: return "BUFFER";
  342.         case 7: return "NULL";
  343.         default: return "unknown";
  344.         }
  345. }
  346.  
  347. static const char *
  348. get_965_depthformat(unsigned int depthformat)
  349. {
  350.         switch (depthformat) {
  351.         case 0: return "s8_z24float";
  352.         case 1: return "z32float";
  353.         case 2: return "z24s8";
  354.         case 5: return "z16";
  355.         default: return "unknown";
  356.         }
  357. }
  358.  
  359. static const char *
  360. get_element_component(uint32_t data, int component)
  361. {
  362.         uint32_t component_control = (data >> (16 + (3 - component) * 4)) & 0x7;
  363.  
  364.         switch (component_control) {
  365.         case 0:
  366.                 return "nostore";
  367.         case 1:
  368.                 switch (component) {
  369.                 case 0: return "X";
  370.                 case 1: return "Y";
  371.                 case 2: return "Z";
  372.                 case 3: return "W";
  373.                 default: return "fail";
  374.                 }
  375.         case 2:
  376.                 return "0.0";
  377.         case 3:
  378.                 return "1.0";
  379.         case 4:
  380.                 return "0x1";
  381.         case 5:
  382.                 return "VID";
  383.         default:
  384.                 return "fail";
  385.         }
  386. }
  387.  
  388. static const char *
  389. get_prim_type(uint32_t data)
  390. {
  391.         uint32_t primtype = data & 0x1f;
  392.  
  393.         switch (primtype) {
  394.         case 0x01: return "point list";
  395.         case 0x02: return "line list";
  396.         case 0x03: return "line strip";
  397.         case 0x04: return "tri list";
  398.         case 0x05: return "tri strip";
  399.         case 0x06: return "tri fan";
  400.         case 0x07: return "quad list";
  401.         case 0x08: return "quad strip";
  402.         case 0x09: return "line list adj";
  403.         case 0x0a: return "line strip adj";
  404.         case 0x0b: return "tri list adj";
  405.         case 0x0c: return "tri strip adj";
  406.         case 0x0d: return "tri strip reverse";
  407.         case 0x0e: return "polygon";
  408.         case 0x0f: return "rect list";
  409.         case 0x10: return "line loop";
  410.         case 0x11: return "point list bf";
  411.         case 0x12: return "line strip cont";
  412.         case 0x13: return "line strip bf";
  413.         case 0x14: return "line strip cont bf";
  414.         case 0x15: return "tri fan no stipple";
  415.         default: return "fail";
  416.         }
  417. }
  418.  
  419. struct reloc {
  420.         struct kgem_bo *bo;
  421.         void *base;
  422. };
  423.  
  424. static void *
  425. get_reloc(struct kgem *kgem,
  426.           void *base, const uint32_t *reloc,
  427.           struct reloc *r)
  428. {
  429.         uint32_t delta = *reloc;
  430.  
  431.         memset(r, 0, sizeof(*r));
  432.  
  433.         if (base == 0) {
  434.                 uint32_t handle = sizeof(uint32_t) * (reloc - kgem->batch);
  435.                 struct kgem_bo *bo = NULL;
  436.                 int i;
  437.  
  438.                 for (i = 0; i < kgem->nreloc; i++)
  439.                         if (kgem->reloc[i].offset == handle)
  440.                                 break;
  441.                 assert(i < kgem->nreloc);
  442.                 handle = kgem->reloc[i].target_handle;
  443.                 delta = kgem->reloc[i].delta;
  444.  
  445.                 if (handle == 0) {
  446.                         base = kgem->batch;
  447.                 } else {
  448.                         list_for_each_entry(bo, &kgem->next_request->buffers, request)
  449.                                 if (bo->handle == handle)
  450.                                         break;
  451.                         assert(&bo->request != &kgem->next_request->buffers);
  452.                         base = kgem_bo_map__debug(kgem, bo);
  453.                         r->bo = bo;
  454.                         r->base = base;
  455.                 }
  456.         }
  457.  
  458.         return (char *)base + (delta & ~3);
  459. }
  460.  
  461. static const char *
  462. gen7_filter_to_string(uint32_t filter)
  463. {
  464.         switch (filter) {
  465.         default:
  466.         case GEN7_MAPFILTER_NEAREST: return "nearest";
  467.         case GEN7_MAPFILTER_LINEAR: return "linear";
  468.         }
  469. }
  470.  
  471. static const char *
  472. gen7_repeat_to_string(uint32_t repeat)
  473. {
  474.         switch (repeat) {
  475.         default:
  476.         case GEN7_TEXCOORDMODE_CLAMP_BORDER: return "border";
  477.         case GEN7_TEXCOORDMODE_WRAP: return "wrap";
  478.         case GEN7_TEXCOORDMODE_CLAMP: return "clamp";
  479.         case GEN7_TEXCOORDMODE_MIRROR: return "mirror";
  480.         }
  481. }
  482.  
  483. static void
  484. gen7_decode_sampler_state(struct kgem *kgem, const uint32_t *reloc)
  485. {
  486.         const struct gen7_sampler_state *ss;
  487.         struct reloc r;
  488.         const char *min, *mag;
  489.         const char *s_wrap, *t_wrap, *r_wrap;
  490.  
  491.         ss = get_reloc(kgem, state.dynamic_state.ptr, reloc, &r);
  492.  
  493.         min = gen7_filter_to_string(ss->ss0.min_filter);
  494.         mag = gen7_filter_to_string(ss->ss0.mag_filter);
  495.  
  496.         s_wrap = gen7_repeat_to_string(ss->ss3.s_wrap_mode);
  497.         t_wrap = gen7_repeat_to_string(ss->ss3.t_wrap_mode);
  498.         r_wrap = gen7_repeat_to_string(ss->ss3.r_wrap_mode);
  499.  
  500.         ErrorF("  Sampler 0:\n");
  501.         ErrorF("    filter: min=%s, mag=%s\n", min, mag);
  502.         ErrorF("    wrap: s=%s, t=%s, r=%s\n", s_wrap, t_wrap, r_wrap);
  503.  
  504.         ss++;
  505.         min = gen7_filter_to_string(ss->ss0.min_filter);
  506.         mag = gen7_filter_to_string(ss->ss0.mag_filter);
  507.  
  508.         s_wrap = gen7_repeat_to_string(ss->ss3.s_wrap_mode);
  509.         t_wrap = gen7_repeat_to_string(ss->ss3.t_wrap_mode);
  510.         r_wrap = gen7_repeat_to_string(ss->ss3.r_wrap_mode);
  511.  
  512.         ErrorF("  Sampler 1:\n");
  513.         ErrorF("    filter: min=%s, mag=%s\n", min, mag);
  514.         ErrorF("    wrap: s=%s, t=%s, r=%s\n", s_wrap, t_wrap, r_wrap);
  515. }
  516.  
  517. static const char *
  518. gen7_blend_factor_to_string(uint32_t v)
  519. {
  520.         switch (v) {
  521. #define C(x) case GEN7_BLENDFACTOR_##x: return #x;
  522.                 C(ONE);
  523.                 C(SRC_COLOR);
  524.                 C(SRC_ALPHA);
  525.                 C(DST_ALPHA);
  526.                 C(DST_COLOR);
  527.                 C(SRC_ALPHA_SATURATE);
  528.                 C(CONST_COLOR);
  529.                 C(CONST_ALPHA);
  530.                 C(SRC1_COLOR);
  531.                 C(SRC1_ALPHA);
  532.                 C(ZERO);
  533.                 C(INV_SRC_COLOR);
  534.                 C(INV_SRC_ALPHA);
  535.                 C(INV_DST_ALPHA);
  536.                 C(INV_DST_COLOR);
  537.                 C(INV_CONST_COLOR);
  538.                 C(INV_CONST_ALPHA);
  539.                 C(INV_SRC1_COLOR);
  540.                 C(INV_SRC1_ALPHA);
  541. #undef C
  542.         default: return "???";
  543.         }
  544. }
  545.  
  546. static const char *
  547. gen7_blend_function_to_string(uint32_t v)
  548. {
  549.         switch (v) {
  550. #define C(x) case GEN7_BLENDFUNCTION_##x: return #x;
  551.                 C(ADD);
  552.                 C(SUBTRACT);
  553.                 C(REVERSE_SUBTRACT);
  554.                 C(MIN);
  555.                 C(MAX);
  556. #undef C
  557.         default: return "???";
  558.         }
  559. }
  560.  
  561. static void
  562. gen7_decode_blend(struct kgem *kgem, const uint32_t *reloc)
  563. {
  564.         const struct gen7_blend_state *blend;
  565.         struct reloc r;
  566.         const char *dst, *src;
  567.         const char *func;
  568.  
  569.         blend = get_reloc(kgem, state.dynamic_state.ptr, reloc, &r);
  570.  
  571.         dst = gen7_blend_factor_to_string(blend->blend0.dest_blend_factor);
  572.         src = gen7_blend_factor_to_string(blend->blend0.source_blend_factor);
  573.         func = gen7_blend_function_to_string(blend->blend0.blend_func);
  574.  
  575.         ErrorF("  Blend (%s): function %s, src=%s, dst=%s\n",
  576.                blend->blend0.blend_enable ? "enabled" : "disabled",
  577.                func, src, dst);
  578. }
  579.  
  580. int kgem_gen7_decode_3d(struct kgem *kgem, uint32_t offset)
  581. {
  582.         static const struct {
  583.                 uint32_t opcode;
  584.                 int min_len;
  585.                 int max_len;
  586.                 const char *name;
  587.         } opcodes[] = {
  588.                 { 0x6101, 6, 6, "STATE_BASE_ADDRESS" },
  589.                 { 0x6102, 2, 2 , "STATE_SIP" },
  590.                 { 0x6104, 1, 1, "3DSTATE_PIPELINE_SELECT" },
  591.                 { 0x780a, 3, 3, "3DSTATE_INDEX_BUFFER" },
  592.                 { 0x7900, 4, 4, "3DSTATE_DRAWING_RECTANGLE" },
  593.         };
  594.         uint32_t *data = kgem->batch + offset;
  595.         uint32_t op;
  596.         unsigned int len;
  597.         int i;
  598.         const char *name;
  599.  
  600.         len = (data[0] & 0xff) + 2;
  601.         op = (data[0] & 0xffff0000) >> 16;
  602.         switch (op) {
  603.         case 0x6101:
  604.                 i = 0;
  605.                 kgem_debug_print(data, offset, i++, "STATE_BASE_ADDRESS\n");
  606.                 assert(len == 10);
  607.  
  608.                 state_base_out(data, offset, i++, "general");
  609.                 state_base_out(data, offset, i++, "surface");
  610.                 state_base_out(data, offset, i++, "dynamic");
  611.                 state_base_out(data, offset, i++, "indirect");
  612.                 state_base_out(data, offset, i++, "instruction");
  613.  
  614.                 state_max_out(data, offset, i++, "general");
  615.                 state_max_out(data, offset, i++, "dynamic");
  616.                 state_max_out(data, offset, i++, "indirect");
  617.                 state_max_out(data, offset, i++, "instruction");
  618.  
  619.                 gen7_update_dynamic_buffer(kgem, offset + 3);
  620.  
  621.                 return len;
  622.  
  623.         case 0x7808:
  624.                 assert((len - 1) % 4 == 0);
  625.                 kgem_debug_print(data, offset, 0, "3DSTATE_VERTEX_BUFFERS\n");
  626.  
  627.                 for (i = 1; i < len;) {
  628.                         gen7_update_vertex_buffer(kgem, data + i);
  629.  
  630.                         kgem_debug_print(data, offset, i, "buffer %d: %s, pitch %db\n",
  631.                                   data[i] >> 26,
  632.                                   data[i] & (1 << 20) ? "random" : "sequential",
  633.                                   data[i] & 0x07ff);
  634.                         i++;
  635.                         kgem_debug_print(data, offset, i++, "buffer address\n");
  636.                         kgem_debug_print(data, offset, i++, "max index\n");
  637.                         kgem_debug_print(data, offset, i++, "mbz\n");
  638.                 }
  639.                 return len;
  640.  
  641.         case 0x7809:
  642.                 assert((len + 1) % 2 == 0);
  643.                 kgem_debug_print(data, offset, 0, "3DSTATE_VERTEX_ELEMENTS\n");
  644.  
  645.                 for (i = 1; i < len;) {
  646.                         gen7_update_vertex_elements(kgem, (i - 1)/2, data + i);
  647.  
  648.                         kgem_debug_print(data, offset, i, "buffer %d: %svalid, type 0x%04x, "
  649.                                   "src offset 0x%04x bytes\n",
  650.                                   data[i] >> 26,
  651.                                   data[i] & (1 << 25) ? "" : "in",
  652.                                   (data[i] >> 16) & 0x1ff,
  653.                                   data[i] & 0x07ff);
  654.                         i++;
  655.                         kgem_debug_print(data, offset, i, "(%s, %s, %s, %s), "
  656.                                   "dst offset 0x%02x bytes\n",
  657.                                   get_element_component(data[i], 0),
  658.                                   get_element_component(data[i], 1),
  659.                                   get_element_component(data[i], 2),
  660.                                   get_element_component(data[i], 3),
  661.                                   (data[i] & 0xff) * 4);
  662.                         i++;
  663.                 }
  664.                 return len;
  665.  
  666.         case 0x780a:
  667.                 assert(len == 3);
  668.                 kgem_debug_print(data, offset, 0, "3DSTATE_INDEX_BUFFER\n");
  669.                 kgem_debug_print(data, offset, 1, "beginning buffer address\n");
  670.                 kgem_debug_print(data, offset, 2, "ending buffer address\n");
  671.                 return len;
  672.  
  673.         case 0x7b00:
  674.                 assert(len == 7);
  675.                 kgem_debug_print(data, offset, 0, "3DPRIMITIVE\n");
  676.                 kgem_debug_print(data, offset, 1, "type %s, %s\n",
  677.                           get_prim_type(data[1]),
  678.                           (data[1] & (1 << 15)) ? "random" : "sequential");
  679.                 kgem_debug_print(data, offset, 2, "vertex count\n");
  680.                 kgem_debug_print(data, offset, 3, "start vertex\n");
  681.                 kgem_debug_print(data, offset, 4, "instance count\n");
  682.                 kgem_debug_print(data, offset, 5, "start instance\n");
  683.                 kgem_debug_print(data, offset, 6, "index bias\n");
  684.                 primitive_out(kgem, data);
  685.                 return len;
  686.         }
  687.  
  688.         /* For the rest, just dump the bytes */
  689.         name = NULL;
  690.         for (i = 0; i < ARRAY_SIZE(opcodes); i++)
  691.                 if (op == opcodes[i].opcode) {
  692.                         name = opcodes[i].name;
  693.                         break;
  694.                 }
  695.  
  696.         len = (data[0] & 0xff) + 2;
  697.         if (name == NULL) {
  698.                 kgem_debug_print(data, offset, 0, "unknown\n");
  699.         } else {
  700.                 kgem_debug_print(data, offset, 0, "%s\n", opcodes[i].name);
  701.                 if (opcodes[i].max_len > 1) {
  702.                         assert(len >= opcodes[i].min_len &&
  703.                                         len <= opcodes[i].max_len);
  704.                 }
  705.         }
  706.         for (i = 1; i < len; i++)
  707.                 kgem_debug_print(data, offset, i, "dword %d\n", i);
  708.  
  709.         return len;
  710. }
  711.  
  712. void kgem_gen7_finish_state(struct kgem *kgem)
  713. {
  714.         finish_state(kgem);
  715. }
  716.