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