📄 radeon_sanity.c
字号:
"prim flags", prim, ((prim & 0x30) == RADEON_CP_VC_CNTL_PRIM_WALK_IND) ? "IND," : "", ((prim & 0x30) == RADEON_CP_VC_CNTL_PRIM_WALK_LIST) ? "LIST," : "", ((prim & 0x30) == RADEON_CP_VC_CNTL_PRIM_WALK_RING) ? "RING," : "", (prim & RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA) ? "RGBA," : "BGRA, ", (prim & RADEON_CP_VC_CNTL_MAOS_ENABLE) ? "MAOS," : "", (prim & RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE) ? "RADEON," : "", (prim & RADEON_CP_VC_CNTL_TCL_ENABLE) ? "TCL," : ""); if ((prim & 0xf) > RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST) { fprintf(stderr, " *** Bad primitive: %x\n", prim & 0xf); return -1; } numverts = prim>>16; if (NORMAL) fprintf(stderr, " prim: %s numverts %d\n", primname[prim&0xf], numverts); switch (prim & 0xf) { case RADEON_CP_VC_CNTL_PRIM_TYPE_NONE: case RADEON_CP_VC_CNTL_PRIM_TYPE_POINT: if (numverts < 1) { fprintf(stderr, "Bad nr verts for line %d\n", numverts); return -1; } break; case RADEON_CP_VC_CNTL_PRIM_TYPE_LINE: if ((numverts & 1) || numverts == 0) { fprintf(stderr, "Bad nr verts for line %d\n", numverts); return -1; } break; case RADEON_CP_VC_CNTL_PRIM_TYPE_LINE_STRIP: if (numverts < 2) { fprintf(stderr, "Bad nr verts for line_strip %d\n", numverts); return -1; } break; case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST: case RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_POINT_LIST: case RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST: case RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST: if (numverts % 3 || numverts == 0) { fprintf(stderr, "Bad nr verts for tri %d\n", numverts); return -1; } break; case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN: case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP: if (numverts < 3) { fprintf(stderr, "Bad nr verts for strip/fan %d\n", numverts); return -1; } break; default: fprintf(stderr, "Bad primitive\n"); return -1; } return 0;}/* build in knowledge about each packet type */static int radeon_emit_packet3( drm_radeon_cmd_buffer_t *cmdbuf ){ int cmdsz; int *cmd = (int *)cmdbuf->buf; int *tmp; int i, stride, size, start; cmdsz = 2 + ((cmd[0] & RADEON_CP_PACKET_COUNT_MASK) >> 16); if ((cmd[0] & RADEON_CP_PACKET_MASK) != RADEON_CP_PACKET3 || cmdsz * 4 > cmdbuf->bufsz || cmdsz > RADEON_CP_PACKET_MAX_DWORDS) { fprintf(stderr, "Bad packet\n"); return -EINVAL; } switch( cmd[0] & ~RADEON_CP_PACKET_COUNT_MASK ) { case RADEON_CP_PACKET3_NOP: if (NORMAL) fprintf(stderr, "PACKET3_NOP, %d dwords\n", cmdsz); break; case RADEON_CP_PACKET3_NEXT_CHAR: if (NORMAL) fprintf(stderr, "PACKET3_NEXT_CHAR, %d dwords\n", cmdsz); break; case RADEON_CP_PACKET3_PLY_NEXTSCAN: if (NORMAL) fprintf(stderr, "PACKET3_PLY_NEXTSCAN, %d dwords\n", cmdsz); break; case RADEON_CP_PACKET3_SET_SCISSORS: if (NORMAL) fprintf(stderr, "PACKET3_SET_SCISSORS, %d dwords\n", cmdsz); break; case RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM: if (NORMAL) fprintf(stderr, "PACKET3_3D_RNDR_GEN_INDX_PRIM, %d dwords\n", cmdsz); break; case RADEON_CP_PACKET3_LOAD_MICROCODE: if (NORMAL) fprintf(stderr, "PACKET3_LOAD_MICROCODE, %d dwords\n", cmdsz); break; case RADEON_CP_PACKET3_WAIT_FOR_IDLE: if (NORMAL) fprintf(stderr, "PACKET3_WAIT_FOR_IDLE, %d dwords\n", cmdsz); break; case RADEON_CP_PACKET3_3D_DRAW_VBUF: if (NORMAL) fprintf(stderr, "PACKET3_3D_DRAW_VBUF, %d dwords\n", cmdsz); print_vertex_format(cmd[1]); print_prim_and_flags(cmd[2]); break; case RADEON_CP_PACKET3_3D_DRAW_IMMD: if (NORMAL) fprintf(stderr, "PACKET3_3D_DRAW_IMMD, %d dwords\n", cmdsz); break; case RADEON_CP_PACKET3_3D_DRAW_INDX: { int neltdwords; if (NORMAL) fprintf(stderr, "PACKET3_3D_DRAW_INDX, %d dwords\n", cmdsz); print_vertex_format(cmd[1]); print_prim_and_flags(cmd[2]); neltdwords = cmd[2]>>16; neltdwords += neltdwords & 1; neltdwords /= 2; if (neltdwords + 3 != cmdsz) fprintf(stderr, "Mismatch in DRAW_INDX, %d vs cmdsz %d\n", neltdwords, cmdsz); break; } case RADEON_CP_PACKET3_LOAD_PALETTE: if (NORMAL) fprintf(stderr, "PACKET3_LOAD_PALETTE, %d dwords\n", cmdsz); break; case RADEON_CP_PACKET3_3D_LOAD_VBPNTR: if (NORMAL) { fprintf(stderr, "PACKET3_3D_LOAD_VBPNTR, %d dwords\n", cmdsz); fprintf(stderr, " nr arrays: %d\n", cmd[1]); } if (cmd[1]/2 + cmd[1]%2 != cmdsz - 3) { fprintf(stderr, " ****** MISMATCH %d/%d *******\n", cmd[1]/2 + cmd[1]%2 + 3, cmdsz); return -EINVAL; } if (NORMAL) { tmp = cmd+2; for (i = 0 ; i < cmd[1] ; i++) { if (i & 1) { stride = (tmp[0]>>24) & 0xff; size = (tmp[0]>>16) & 0xff; start = tmp[2]; tmp += 3; } else { stride = (tmp[0]>>8) & 0xff; size = (tmp[0]) & 0xff; start = tmp[1]; } fprintf(stderr, " array %d: start 0x%x vsize %d vstride %d\n", i, start, size, stride ); } } break; case RADEON_CP_PACKET3_CNTL_PAINT: if (NORMAL) fprintf(stderr, "PACKET3_CNTL_PAINT, %d dwords\n", cmdsz); break; case RADEON_CP_PACKET3_CNTL_BITBLT: if (NORMAL) fprintf(stderr, "PACKET3_CNTL_BITBLT, %d dwords\n", cmdsz); break; case RADEON_CP_PACKET3_CNTL_SMALLTEXT: if (NORMAL) fprintf(stderr, "PACKET3_CNTL_SMALLTEXT, %d dwords\n", cmdsz); break; case RADEON_CP_PACKET3_CNTL_HOSTDATA_BLT: if (NORMAL) fprintf(stderr, "PACKET3_CNTL_HOSTDATA_BLT, %d dwords\n", cmdsz); break; case RADEON_CP_PACKET3_CNTL_POLYLINE: if (NORMAL) fprintf(stderr, "PACKET3_CNTL_POLYLINE, %d dwords\n", cmdsz); break; case RADEON_CP_PACKET3_CNTL_POLYSCANLINES: if (NORMAL) fprintf(stderr, "PACKET3_CNTL_POLYSCANLINES, %d dwords\n", cmdsz); break; case RADEON_CP_PACKET3_CNTL_PAINT_MULTI: if (NORMAL) fprintf(stderr, "PACKET3_CNTL_PAINT_MULTI, %d dwords\n", cmdsz); break; case RADEON_CP_PACKET3_CNTL_BITBLT_MULTI: if (NORMAL) fprintf(stderr, "PACKET3_CNTL_BITBLT_MULTI, %d dwords\n", cmdsz); break; case RADEON_CP_PACKET3_CNTL_TRANS_BITBLT: if (NORMAL) fprintf(stderr, "PACKET3_CNTL_TRANS_BITBLT, %d dwords\n", cmdsz); break; default: fprintf(stderr, "UNKNOWN PACKET, %d dwords\n", cmdsz); break; } cmdbuf->buf += cmdsz * 4; cmdbuf->bufsz -= cmdsz * 4; return 0;}/* Check cliprects for bounds, then pass on to above: */static int radeon_emit_packet3_cliprect( drm_radeon_cmd_buffer_t *cmdbuf ){ drm_clip_rect_t *boxes = cmdbuf->boxes; int i = 0; if (VERBOSE && total_changed) { dump_state(); total_changed = 0; } else fprintf(stderr, "total_changed zero\n"); if (NORMAL) { do { if ( i < cmdbuf->nbox ) { fprintf(stderr, "Emit box %d/%d %d,%d %d,%d\n", i, cmdbuf->nbox, boxes[i].x1, boxes[i].y1, boxes[i].x2, boxes[i].y2); } } while ( ++i < cmdbuf->nbox ); } if (cmdbuf->nbox == 1) cmdbuf->nbox = 0; return radeon_emit_packet3( cmdbuf );}int radeonSanityCmdBuffer( radeonContextPtr rmesa, int nbox, drm_clip_rect_t *boxes ){ int idx; drm_radeon_cmd_buffer_t cmdbuf; drm_radeon_cmd_header_t header; static int inited = 0; if (!inited) { init_regs(); inited = 1; } cmdbuf.buf = rmesa->store.cmd_buf; cmdbuf.bufsz = rmesa->store.cmd_used; cmdbuf.boxes = boxes; cmdbuf.nbox = nbox; while ( cmdbuf.bufsz >= sizeof(header) ) { header.i = *(int *)cmdbuf.buf; cmdbuf.buf += sizeof(header); cmdbuf.bufsz -= sizeof(header); switch (header.header.cmd_type) { case RADEON_CMD_PACKET: if (radeon_emit_packets( header, &cmdbuf )) { fprintf(stderr,"radeon_emit_packets failed\n"); return -EINVAL; } break; case RADEON_CMD_SCALARS: if (radeon_emit_scalars( header, &cmdbuf )) { fprintf(stderr,"radeon_emit_scalars failed\n"); return -EINVAL; } break; case RADEON_CMD_SCALARS2: if (radeon_emit_scalars2( header, &cmdbuf )) { fprintf(stderr,"radeon_emit_scalars failed\n"); return -EINVAL; } break; case RADEON_CMD_VECTORS: if (radeon_emit_vectors( header, &cmdbuf )) { fprintf(stderr,"radeon_emit_vectors failed\n"); return -EINVAL; } break; case RADEON_CMD_DMA_DISCARD: idx = header.dma.buf_idx; if (NORMAL) fprintf(stderr, "RADEON_CMD_DMA_DISCARD buf %d\n", idx); bufs++; break; case RADEON_CMD_PACKET3: if (radeon_emit_packet3( &cmdbuf )) { fprintf(stderr,"radeon_emit_packet3 failed\n"); return -EINVAL; } break; case RADEON_CMD_PACKET3_CLIP: if (radeon_emit_packet3_cliprect( &cmdbuf )) { fprintf(stderr,"radeon_emit_packet3_clip failed\n"); return -EINVAL; } break; case RADEON_CMD_WAIT: break; default: fprintf(stderr,"bad cmd_type %d at %p\n", header.header.cmd_type, cmdbuf.buf - sizeof(header)); return -EINVAL; } } if (0) { static int n = 0; n++; if (n == 10) { fprintf(stderr, "Bufs %d Total emitted %d real changes %d (%.2f%%)\n", bufs, total, total_changed, ((float)total_changed/(float)total*100.0)); fprintf(stderr, "Total emitted per buf: %.2f\n", (float)total/(float)bufs); fprintf(stderr, "Real changes per buf: %.2f\n", (float)total_changed/(float)bufs); bufs = n = total = total_changed = 0; } } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -