diff options
| author | Eric Anholt <eric@anholt.net> | 2010-07-08 12:12:54 -0700 | 
|---|---|---|
| committer | Eric Anholt <eric@anholt.net> | 2010-07-08 12:12:54 -0700 | 
| commit | e72b87736d8453e79bb6da48ba4cfcc2e97c8e14 (patch) | |
| tree | fd1f59bd2d911763e7465cbda3819247b237b476 | |
| parent | b273928140479f089d45cd2dbc30708306b97ee0 (diff) | |
intel: Update intel_decode.c from intel-gpu-tools.
This came from commit cf255e382d147fe3ca450f0dcec3525190e7dcbc
| -rw-r--r-- | src/mesa/drivers/dri/intel/intel_batchbuffer.c | 2 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/intel/intel_chipset.h | 3 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/intel/intel_decode.c | 612 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/intel/intel_decode.h | 4 | 
4 files changed, 432 insertions, 189 deletions
| diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c index 698445c526..ff741fc39a 100644 --- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c +++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c @@ -102,7 +102,7 @@ do_flush_locked(struct intel_batchbuffer *batch, GLuint used)     if (INTEL_DEBUG & DEBUG_BATCH) {        drm_intel_bo_map(batch->buf, GL_FALSE);        intel_decode(batch->buf->virtual, used / 4, batch->buf->offset, -		   intel->intelScreen->deviceID); +		   intel->intelScreen->deviceID, GL_TRUE);        drm_intel_bo_unmap(batch->buf);        if (intel->vtbl.debug_batch != NULL) diff --git a/src/mesa/drivers/dri/intel/intel_chipset.h b/src/mesa/drivers/dri/intel/intel_chipset.h index cd614c59e5..72a74322ee 100644 --- a/src/mesa/drivers/dri/intel/intel_chipset.h +++ b/src/mesa/drivers/dri/intel/intel_chipset.h @@ -115,6 +115,9 @@  				 devid == PCI_CHIP_I946_GZ || \  				 IS_G4X(devid)) +/* Compat macro for intel_decode.c */ +#define IS_IRONLAKE(devid)	IS_GEN5(devid) +  #define IS_GEN6(devid)		(devid == PCI_CHIP_SANDYBRIDGE || \  				 devid == PCI_CHIP_SANDYBRIDGE_M) diff --git a/src/mesa/drivers/dri/intel/intel_decode.c b/src/mesa/drivers/dri/intel/intel_decode.c index 650010ac9c..25b4131594 100644 --- a/src/mesa/drivers/dri/intel/intel_decode.c +++ b/src/mesa/drivers/dri/intel/intel_decode.c @@ -1,48 +1,21 @@ -/* -*- c-basic-offset: 4 -*- */ -/* - * Copyright © 2007 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - *    Eric Anholt <eric@anholt.net> - * - */ - -/** @file intel_decode.c - * This file contains code to print out batchbuffer contents in a - * human-readable format. - * - * The current version only supports i915 packets, and only pretty-prints a - * subset of them.  The intention is for it to make just a best attempt to - * decode, but never crash in the process. - */ - +#include <stdint.h>  #include <stdio.h>  #include <stdarg.h>  #include <string.h> -#include <inttypes.h>  #include "intel_decode.h"  #include "intel_chipset.h" +static FILE *out; +static uint32_t saved_s2 = 0, saved_s4 = 0; +static char saved_s2_set = 0, saved_s4_set = 0; +static uint32_t head_offset = 0xffffffff; /* undefined */ +static uint32_t tail_offset = 0xffffffff; /* undefined */ + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(A) (sizeof(A)/sizeof(A[0])) +#endif +  #define BUFFER_FAIL(_count, _len, _name) do {			\      fprintf(out, "Buffer size too small in %s (%d < %d)\n",	\  	    (_name), (_count), (_len));				\ @@ -50,9 +23,6 @@      return count;						\  } while (0) -static FILE *out; -static uint32_t saved_s2 = 0, saved_s4 = 0; -static char saved_s2_set = 0, saved_s4_set = 0;  static float  int_as_float(uint32_t intval) @@ -71,15 +41,24 @@ instr_out(uint32_t *data, uint32_t hw_offset, unsigned int index,  	  char *fmt, ...)  {      va_list va; +    char *parseinfo; +    uint32_t offset = hw_offset + index * 4; -    fprintf(out, "0x%08x: 0x%08x:%s ", hw_offset + index * 4, data[index], -	    index == 0 ? "" : "  "); +    if (offset == head_offset) +	parseinfo = "HEAD"; +    else if (offset == tail_offset) +	parseinfo = "TAIL"; +    else +	parseinfo = "    "; + +    fprintf(out, "0x%08x: %s 0x%08x: %s", offset, parseinfo, +	    data[index], +	    index == 0 ? "" : "   ");      va_start(va, fmt);      vfprintf(out, fmt, va);      va_end(va);  } -  static int  decode_mi(uint32_t *data, int count, uint32_t hw_offset, int *failures)  { @@ -94,10 +73,11 @@ decode_mi(uint32_t *data, int count, uint32_t hw_offset, int *failures)      } opcodes_mi[] = {  	{ 0x08, 0, 1, 1, "MI_ARB_ON_OFF" },  	{ 0x0a, 0, 1, 1, "MI_BATCH_BUFFER_END" }, +	{ 0x30, 0x3f, 3, 3, "MI_BATCH_BUFFER" },  	{ 0x31, 0x3f, 2, 2, "MI_BATCH_BUFFER_START" },  	{ 0x14, 0x3f, 3, 3, "MI_DISPLAY_BUFFER_INFO" },  	{ 0x04, 0, 1, 1, "MI_FLUSH" }, -	{ 0x22, 0, 3, 3, "MI_LOAD_REGISTER_IMM" }, +	{ 0x22, 0x1f, 3, 3, "MI_LOAD_REGISTER_IMM" },  	{ 0x13, 0x3f, 2, 2, "MI_LOAD_SCAN_LINES_EXCL" },  	{ 0x12, 0x3f, 2, 2, "MI_LOAD_SCAN_LINES_INCL" },  	{ 0x00, 0, 1, 1, "MI_NOOP" }, @@ -111,6 +91,11 @@ decode_mi(uint32_t *data, int count, uint32_t hw_offset, int *failures)  	{ 0x03, 0, 1, 1, "MI_WAIT_FOR_EVENT" },      }; +    switch ((data[0] & 0x1f800000) >> 23) { +    case 0x0a: +	instr_out(data, hw_offset, 0, "MI_BATCH_BUFFER_END\n"); +	return -1; +    }      for (opcode = 0; opcode < sizeof(opcodes_mi) / sizeof(opcodes_mi[0]);  	 opcode++) { @@ -305,9 +290,13 @@ decode_2d(uint32_t *data, int count, uint32_t hw_offset, int *failures)  static int  decode_3d_1c(uint32_t *data, int count, uint32_t hw_offset, int *failures)  { -    switch ((data[0] & 0x00f80000) >> 19) { +    uint32_t opcode; + +    opcode = (data[0] & 0x00f80000) >> 19; + +    switch (opcode) {      case 0x11: -	instr_out(data, hw_offset, 0, "3DSTATE_DEPTH_SUBRECTANGLE_DISALBE\n"); +	instr_out(data, hw_offset, 0, "3DSTATE_DEPTH_SUBRECTANGLE_DISABLE\n");  	return 1;      case 0x10:  	instr_out(data, hw_offset, 0, "3DSTATE_SCISSOR_ENABLE\n"); @@ -323,7 +312,8 @@ decode_3d_1c(uint32_t *data, int count, uint32_t hw_offset, int *failures)  	return 1;      } -    instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); +    instr_out(data, hw_offset, 0, "3D UNKNOWN: 3d_1c opcode = 0x%x\n", +	      opcode);      (*failures)++;      return 1;  } @@ -381,7 +371,7 @@ i915_get_instruction_dst(uint32_t *data, int i, char *dstname, int do_mask)  	sprintf(dstname, "oD%s%s",  dstmask, sat);  	break;      case 6: -	if (dst_nr > 2) +	if (dst_nr > 3)  	    fprintf(out, "bad destination reg U%d\n", dst_nr);  	sprintf(dstname, "U%d%s%s", dst_nr, dstmask, sat);  	break; @@ -452,7 +442,7 @@ i915_get_instruction_src_name(uint32_t src_type, uint32_t src_nr, char *name)  	break;      case 6:  	sprintf(name, "U%d", src_nr); -	if (src_nr > 2) +	if (src_nr > 3)  	    fprintf(out, "bad src reg %s\n", name);  	break;      default: @@ -797,10 +787,14 @@ i915_decode_instruction(uint32_t *data, uint32_t hw_offset,  }  static int -decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i830) +decode_3d_1d(uint32_t *data, int count, +	     uint32_t hw_offset, +	     uint32_t devid, +	     int *failures)  { -    unsigned int len, i, c, opcode, word, map, sampler, instr; +    unsigned int len, i, c, idx, word, map, sampler, instr;      char *format; +    uint32_t opcode;      struct {  	uint32_t opcode; @@ -811,7 +805,7 @@ decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i      } opcodes_3d_1d[] = {  	{ 0x8e, 0, 3, 3, "3DSTATE_BUFFER_INFO" },  	{ 0x86, 0, 4, 4, "3DSTATE_CHROMA_KEY" }, -	{ 0x9c, 0, 1, 1, "3DSTATE_CLEAR_PARAMETERS" }, +	{ 0x9c, 0, 7, 7, "3DSTATE_CLEAR_PARAMETERS" },  	{ 0x88, 0, 2, 2, "3DSTATE_CONSTANT_BLEND_COLOR" },  	{ 0x99, 0, 2, 2, "3DSTATE_DEFAULT_DIFFUSE" },  	{ 0x9a, 0, 2, 2, "3DSTATE_DEFAULT_SPECULAR" }, @@ -819,7 +813,6 @@ decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i  	{ 0x97, 0, 2, 2, "3DSTATE_DEPTH_OFFSET_SCALE" },  	{ 0x85, 0, 2, 2, "3DSTATE_DEST_BUFFER_VARIABLES" },  	{ 0x80, 0, 5, 5, "3DSTATE_DRAWING_RECTANGLE" }, -	{ 0x8e, 0, 3, 3, "3DSTATE_BUFFER_INFO" },  	{ 0x9d, 0, 65, 65, "3DSTATE_FILTER_COEFFICIENTS_4X4" },  	{ 0x9e, 0, 4, 4, "3DSTATE_MONO_FILTER" },  	{ 0x89, 0, 4, 4, "3DSTATE_FOG_MODE" }, @@ -831,9 +824,11 @@ decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i  	{ 0x8d, 1, 3, 3, "3DSTATE_W_STATE_I830" },  	{ 0x01, 1, 2, 2, "3DSTATE_COLOR_FACTOR_I830" },  	{ 0x02, 1, 2, 2, "3DSTATE_MAP_COORD_SETBIND_I830" }, -    }; +    }, *opcode_3d_1d; -    switch ((data[0] & 0x00ff0000) >> 16) { +    opcode = (data[0] & 0x00ff0000) >> 16; + +    switch (opcode) {      case 0x07:  	/* This instruction is unusual.  A 0 length means just 1 DWORD instead of  	 * 2.  The 0 length is specified in one place to be unsupported, but @@ -888,26 +883,56 @@ decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i  	instr_out(data, hw_offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_1\n");  	len = (data[0] & 0x0000000f) + 2;  	i = 1; -	for (word = 0; word <= 7; word++) { +	for (word = 0; word <= 8; word++) {  	    if (data[0] & (1 << (4 + word))) {  		if (i >= count)  		    BUFFER_FAIL(count, len, "3DSTATE_LOAD_STATE_IMMEDIATE_1");  		/* save vertex state for decode */ -		if (word == 2) { -		    saved_s2_set = 1; -		    saved_s2 = data[i]; -		} -		if (word == 4) { -		    saved_s4_set = 1; -		    saved_s4 = data[i]; +		if (IS_9XX(devid)) { +		    if (word == 2) { +			saved_s2_set = 1; +			saved_s2 = data[i]; +		    } +		    if (word == 4) { +			saved_s4_set = 1; +			saved_s4 = data[i]; +		    }  		}  		instr_out(data, hw_offset, i++, "S%d\n", word);  	    }  	}  	if (len != i) { -	    fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n"); +	    fprintf(out, "Bad count in 3DSTATE_LOAD_STATE_IMMEDIATE_1\n"); +	    (*failures)++; +	} +	return len; +    case 0x03: +	instr_out(data, hw_offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_2\n"); +	len = (data[0] & 0x0000000f) + 2; +	i = 1; +	for (word = 6; word <= 14; word++) { +	    if (data[0] & (1 << word)) { +		if (i >= count) +		    BUFFER_FAIL(count, len, "3DSTATE_LOAD_STATE_IMMEDIATE_2"); + +		if (word == 6) +		    instr_out(data, hw_offset, i++, "TBCF\n"); +		else if (word >= 7 && word <= 10) { +		    instr_out(data, hw_offset, i++, "TB%dC\n", word - 7); +		    instr_out(data, hw_offset, i++, "TB%dA\n", word - 7); +		} else if (word >= 11 && word <= 14) { +		    instr_out(data, hw_offset, i++, "TM%dS0\n", word - 11); +		    instr_out(data, hw_offset, i++, "TM%dS1\n", word - 11); +		    instr_out(data, hw_offset, i++, "TM%dS2\n", word - 11); +		    instr_out(data, hw_offset, i++, "TM%dS3\n", word - 11); +		    instr_out(data, hw_offset, i++, "TM%dS4\n", word - 11); +		} +	    } +	} +	if (len != i) { +	    fprintf(out, "Bad count in 3DSTATE_LOAD_STATE_IMMEDIATE_2\n");  	    (*failures)++;  	}  	return len; @@ -919,11 +944,28 @@ decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i  	i = 2;  	for (map = 0; map <= 15; map++) {  	    if (data[1] & (1 << map)) { +		int width, height, pitch, dword; +		const char *tiling; +  		if (i + 3 >= count)  		    BUFFER_FAIL(count, len, "3DSTATE_MAP_STATE"); +  		instr_out(data, hw_offset, i++, "map %d MS2\n", map); -		instr_out(data, hw_offset, i++, "map %d MS3\n", map); -		instr_out(data, hw_offset, i++, "map %d MS4\n", map); + +		dword = data[i]; +		width = ((dword >> 10) & ((1 << 11) - 1))+1; +		height = ((dword >> 21) & ((1 << 11) - 1))+1; + +		tiling = "none"; +		if (dword & (1 << 2)) +			tiling = "fenced"; +		else if (dword & (1 << 1)) +			tiling = dword & (1 << 0) ? "Y" : "X"; +		instr_out(data, hw_offset, i++, "map %d MS3 [width=%d, height=%d, tiling=%s]\n", map, width, height, tiling); + +		dword = data[i]; +		pitch = 4*(((dword >> 21) & ((1 << 11) - 1))+1); +		instr_out(data, hw_offset, i++, "map %d MS4 [pitch=%d]\n", map, pitch);  	    }  	}  	if (len != i) { @@ -979,8 +1021,8 @@ decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i  	}  	return len;      case 0x01: -	if (i830) -	    break; +	if (!IS_9XX(devid)) +		break;  	instr_out(data, hw_offset, 0, "3DSTATE_SAMPLER_STATE\n");  	instr_out(data, hw_offset, 1, "mask\n");  	len = (data[0] & 0x0000003f) + 2; @@ -1031,32 +1073,61 @@ decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i  		  format,  		  (data[1] & (1 << 31)) ? "en" : "dis");  	return len; + +    case 0x8e: +	{ +	    const char *name, *tiling; + +	    len = (data[0] & 0x0000000f) + 2; +	    if (len != 3) +		fprintf(out, "Bad count in 3DSTATE_BUFFER_INFO\n"); +	    if (count < 3) +		BUFFER_FAIL(count, len, "3DSTATE_BUFFER_INFO"); + +	    switch((data[1] >> 24) & 0x7) { +	    case 0x3: name = "color"; break; +	    case 0x7: name = "depth"; break; +	    default: name = "unknown"; break; +	    } + +	    tiling = "none"; +	    if (data[1] & (1 << 23)) +		tiling = "fenced"; +	    else if (data[1] & (1 << 22)) +		tiling = data[1] & (1 << 21) ? "Y" : "X"; + +	    instr_out(data, hw_offset, 0, "3DSTATE_BUFFER_INFO\n"); +	    instr_out(data, hw_offset, 1, "%s, tiling = %s, pitch=%d\n", name, tiling, data[1]&0xffff); + +	    instr_out(data, hw_offset, 2, "address\n"); +	    return len; +	}      } -    for (opcode = 0; opcode < sizeof(opcodes_3d_1d) / sizeof(opcodes_3d_1d[0]); -	 opcode++) +    for (idx = 0; idx < ARRAY_SIZE(opcodes_3d_1d); idx++)      { -	if (opcodes_3d_1d[opcode].i830_only && !i830) +	opcode_3d_1d = &opcodes_3d_1d[idx]; +	if (opcode_3d_1d->i830_only && IS_9XX(devid))  	    continue; -	if (((data[0] & 0x00ff0000) >> 16) == opcodes_3d_1d[opcode].opcode) { +	if (((data[0] & 0x00ff0000) >> 16) == opcode_3d_1d->opcode) {  	    len = 1; -	    instr_out(data, hw_offset, 0, "%s\n", opcodes_3d_1d[opcode].name); -	    if (opcodes_3d_1d[opcode].max_len > 1) { +	    instr_out(data, hw_offset, 0, "%s\n", opcode_3d_1d->name); +	    if (opcode_3d_1d->max_len > 1) {  		len = (data[0] & 0x0000ffff) + 2; -		if (len < opcodes_3d_1d[opcode].min_len || -		    len > opcodes_3d_1d[opcode].max_len) +		if (len < opcode_3d_1d->min_len || +		    len > opcode_3d_1d->max_len)  		{  		    fprintf(out, "Bad count in %s\n", -			    opcodes_3d_1d[opcode].name); +			    opcode_3d_1d->name);  		    (*failures)++;  		}  	    }  	    for (i = 1; i < len; i++) {  		if (i >= count) -		    BUFFER_FAIL(count, len,  opcodes_3d_1d[opcode].name); +		    BUFFER_FAIL(count, len,  opcode_3d_1d->name);  		instr_out(data, hw_offset, i, "dword %d\n", i);  	    } @@ -1064,7 +1135,7 @@ decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i  	}      } -    instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); +    instr_out(data, hw_offset, 0, "3D UNKNOWN: 3d_1d opcode = 0x%x\n", opcode);      (*failures)++;      return 1;  } @@ -1074,8 +1145,10 @@ decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset,  		    int *failures)  {      char immediate = (data[0] & (1 << 23)) == 0; -    unsigned int len, i; +    unsigned int len, i, ret;      char *primtype; +    int original_s2 = saved_s2; +    int original_s4 = saved_s4;      switch ((data[0] >> 18) & 0xf) {      case 0x0: primtype = "TRILIST"; break; @@ -1088,7 +1161,7 @@ decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset,      case 0x7: primtype = "RECTLIST"; break;      case 0x8: primtype = "POINTLIST"; break;      case 0x9: primtype = "DIB"; break; -    case 0xa: primtype = "CLEAR_RECT"; break; +    case 0xa: primtype = "CLEAR_RECT"; saved_s4 = 3 << 6; saved_s2 = ~0; break;      default: primtype = "unknown"; break;      } @@ -1192,6 +1265,8 @@ decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset,  		vertex++;  	    }  	} + +	ret = len;      } else {  	/* indirect vertices */  	len = data[0] & 0x0000ffff; /* index count */ @@ -1209,13 +1284,15 @@ decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset,  		    if ((data[i] & 0xffff) == 0xffff) {  			instr_out(data, hw_offset, i,  				  "            indices: (terminator)\n"); -			return i; +			ret = i; +			goto out;  		    } else if ((data[i] >> 16) == 0xffff) {  			instr_out(data, hw_offset, i,  				  "            indices: 0x%04x, "  				  "(terminator)\n",  				  data[i] & 0xffff); -			return i; +			ret = i; +			goto out;  		    } else {  			instr_out(data, hw_offset, i,  				  "            indices: 0x%04x, 0x%04x\n", @@ -1225,7 +1302,8 @@ decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset,  		fprintf(out,  			"3DPRIMITIVE: no terminator found in index buffer\n");  		(*failures)++; -		return count; +		ret = count; +		goto out;  	    } else {  		/* fixed size vertex index buffer */  		for (i = 0; i < len; i += 2) { @@ -1240,7 +1318,8 @@ decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset,  		    }  		}  	    } -	    return (len + 1) / 2 + 1; +	    ret = (len + 1) / 2 + 1; +	    goto out;  	} else {  	    /* sequential vertex access */  	    if (count < 2) @@ -1249,17 +1328,22 @@ decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset,  		      "3DPRIMITIVE sequential indirect %s, %d starting from "  		      "%d\n", primtype, len, data[1] & 0xffff);  	    instr_out(data, hw_offset, 1, "           start\n"); -	    return 2; +	    ret = 2; +	    goto out;  	}      } -    return len; +out: +    saved_s2 = original_s2; +    saved_s4 = original_s4; +    return ret;  }  static int -decode_3d(uint32_t *data, int count, uint32_t hw_offset, int *failures) +decode_3d(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid, int *failures)  { -    unsigned int opcode; +    uint32_t opcode; +    unsigned int idx;      struct {  	uint32_t opcode; @@ -1276,42 +1360,44 @@ decode_3d(uint32_t *data, int count, uint32_t hw_offset, int *failures)  	{ 0x0d, 1, 1, "3DSTATE_MODES_4" },  	{ 0x0c, 1, 1, "3DSTATE_MODES_5" },  	{ 0x07, 1, 1, "3DSTATE_RASTERIZATION_RULES" }, -    }; +    }, *opcode_3d; + +    opcode = (data[0] & 0x1f000000) >> 24; -    switch ((data[0] & 0x1f000000) >> 24) { +    switch (opcode) {      case 0x1f:  	return decode_3d_primitive(data, count, hw_offset, failures);      case 0x1d: -	return decode_3d_1d(data, count, hw_offset, failures, 0); +	return decode_3d_1d(data, count, hw_offset, devid, failures);      case 0x1c:  	return decode_3d_1c(data, count, hw_offset, failures);      } -    for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]); -	 opcode++) { -	if ((data[0] & 0x1f000000) >> 24 == opcodes_3d[opcode].opcode) { +    for (idx = 0; idx < ARRAY_SIZE(opcodes_3d); idx++) { +	opcode_3d = &opcodes_3d[idx]; +	if (opcode == opcode_3d->opcode) {  	    unsigned int len = 1, i; -	    instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name); -	    if (opcodes_3d[opcode].max_len > 1) { +	    instr_out(data, hw_offset, 0, "%s\n", opcode_3d->name); +	    if (opcode_3d->max_len > 1) {  		len = (data[0] & 0xff) + 2; -		if (len < opcodes_3d[opcode].min_len || -		    len > opcodes_3d[opcode].max_len) +		if (len < opcode_3d->min_len || +		    len > opcode_3d->max_len)  		{ -		    fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name); +		    fprintf(out, "Bad count in %s\n", opcode_3d->name);  		}  	    }  	    for (i = 1; i < len; i++) {  		if (i >= count) -		    BUFFER_FAIL(count, len, opcodes_3d[opcode].name); +		    BUFFER_FAIL(count, len, opcode_3d->name);  		instr_out(data, hw_offset, i, "dword %d\n", i);  	    }  	    return len;  	}      } -    instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); +    instr_out(data, hw_offset, 0, "3D UNKNOWN: 3d opcode = 0x%x\n", opcode);      (*failures)++;      return 1;  } @@ -1403,11 +1489,86 @@ get_965_prim_type(uint32_t data)  }  static int -decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, int *failures) +i965_decode_urb_fence(uint32_t *data, uint32_t hw_offset, int len, int count, +		      int *failures)  { -    unsigned int opcode, len; -    int i; -    char *desc1; +	uint32_t vs_fence, clip_fence, gs_fence, sf_fence, vfe_fence, cs_fence; + +	if (len != 3) +	    fprintf(out, "Bad count in URB_FENCE\n"); +	if (count < 3) +	    BUFFER_FAIL(count, len, "URB_FENCE"); + +	vs_fence = data[1] & 0x3ff; +	gs_fence = (data[1] >> 10) & 0x3ff; +	clip_fence = (data[1] >> 20) & 0x3ff; +	sf_fence = data[2] & 0x3ff; +	vfe_fence = (data[2] >> 10) & 0x3ff; +	cs_fence = (data[2] >> 20) & 0x7ff; + +	instr_out(data, hw_offset, 0, "URB_FENCE: %s%s%s%s%s%s\n", +			(data[0] >> 13) & 1 ? "cs " : "", +			(data[0] >> 12) & 1 ? "vfe " : "", +			(data[0] >> 11) & 1 ? "sf " : "", +			(data[0] >> 10) & 1 ? "clip " : "", +			(data[0] >> 9)  & 1 ? "gs " : "", +			(data[0] >> 8)  & 1 ? "vs " : ""); +	instr_out(data, hw_offset, 1, +		  "vs fence: %d, clip_fence: %d, gs_fence: %d\n", +		  vs_fence, clip_fence, gs_fence); +	instr_out(data, hw_offset, 2, +		  "sf fence: %d, vfe_fence: %d, cs_fence: %d\n", +		  sf_fence, vfe_fence, cs_fence); +	if (gs_fence < vs_fence) +	    fprintf(out, "gs fence < vs fence!\n"); +	if (clip_fence < gs_fence) +	    fprintf(out, "clip fence < gs fence!\n"); +	if (sf_fence < clip_fence) +	    fprintf(out, "sf fence < clip fence!\n"); +	if (cs_fence < sf_fence) +	    fprintf(out, "cs fence < sf fence!\n"); + +	return len; +} + +static void +state_base_out(uint32_t *data, uint32_t hw_offset, unsigned int index, +	       char *name) +{ +    if (data[index] & 1) { +	instr_out(data, hw_offset, index, "%s state base address 0x%08x\n", +		  name, data[index] & ~1); +    } else { +	instr_out(data, hw_offset, index, "%s state base not updated\n", +		  name); +    } +} + +static void +state_max_out(uint32_t *data, uint32_t hw_offset, unsigned int index, +	      char *name) +{ +    if (data[index] & 1) { +	if (data[index] == 1) { +	    instr_out(data, hw_offset, index, +		      "%s state upper bound disabled\n", name); +	} else { +	    instr_out(data, hw_offset, index, "%s state upper bound 0x%08x\n", +		      name, data[index] & ~1); +	} +    } else { +	instr_out(data, hw_offset, index, "%s state upper bound not updated\n", +		  name); +    } +} + +static int +decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid, int *failures) +{ +    uint32_t opcode; +    unsigned int idx, len; +    int i, sba_len; +    char *desc1 = NULL;      struct {  	uint32_t opcode; @@ -1436,57 +1597,78 @@ decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, int *failures)  	{ 0x7907, 33, 33, "3DSTATE_POLY_STIPPLE_PATTERN" },  	{ 0x7908, 3, 3, "3DSTATE_LINE_STIPPLE" },  	{ 0x7909, 2, 2, "3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP" }, +	{ 0x7909, 2, 2, "3DSTATE_CLEAR_PARAMS" },  	{ 0x790a, 3, 3, "3DSTATE_AA_LINE_PARAMETERS" }, +	{ 0x790b, 4, 4, "3DSTATE_GS_SVB_INDEX" }, +	{ 0x790d, 3, 3, "3DSTATE_MULTISAMPLE" },  	{ 0x7b00, 6, 6, "3DPRIMITIVE" }, +	{ 0x7802, 4, 4, "3DSTATE_SAMPLER_STATE_POINTERS" }, +	{ 0x7805, 3, 3, "3DSTATE_URB" },  	{ 0x780e, 4, 4, "3DSTATE_CC_STATE_POINTERS" },  	{ 0x7810, 6, 6, "3DSTATE_VS_STATE" }, -	{ 0x7811, 6, 6, "3DSTATE_GS_STATE" }, +	{ 0x7811, 7, 7, "3DSTATE_GS_STATE" }, +	{ 0x7812, 4, 4, "3DSTATE_CLIP_STATE" }, +	{ 0x7813, 20, 20, "3DSTATE_SF_STATE" }, +	{ 0x7814, 9, 9, "3DSTATE_WM_STATE" },  	{ 0x7812, 4, 4, "3DSTATE_CLIP_STATE" },  	{ 0x7815, 5, 5, "3DSTATE_CONSTANT_VS_STATE" },  	{ 0x7816, 5, 5, "3DSTATE_CONSTANT_GS_STATE" }, -    }; +	{ 0x7817, 5, 5, "3DSTATE_CONSTANT_PS_STATE" }, +	{ 0x7818, 2, 2, "3DSTATE_SAMPLE_MASK" }, +   }, *opcode_3d;      len = (data[0] & 0x0000ffff) + 2; -    switch ((data[0] & 0xffff0000) >> 16) { +    opcode = (data[0] & 0xffff0000) >> 16; +    switch (opcode) { +    case 0x6000: +	len = (data[0] & 0x000000ff) + 2; +	return i965_decode_urb_fence(data, hw_offset, len, count, failures); +    case 0x6001: +	instr_out(data, hw_offset, 0, "CS_URB_STATE\n"); +	instr_out(data, hw_offset, 1, "entry_size: %d [%d bytes], n_entries: %d\n", +			(data[1] >> 4) & 0x1f, +			(((data[1] >> 4) & 0x1f) + 1) * 64, +			data[1] & 0x7); +	return len; +    case 0x6002: +	len = (data[0] & 0x000000ff) + 2; +	instr_out(data, hw_offset, 0, "CONSTANT_BUFFER: %s\n", +			(data[0] >> 8) & 1 ? "valid" : "invalid"); +	instr_out(data, hw_offset, 1, "offset: 0x%08x, length: %d bytes\n", +			data[1] & ~0x3f, ((data[1] & 0x3f) + 1) * 64); +	return len;      case 0x6101: -	if (len != 6) +	if (IS_GEN6(devid)) +	    sba_len = 10; +	else if (IS_IRONLAKE(devid)) +	    sba_len = 8; +	else +	    sba_len = 6; +	if (len != sba_len)  	    fprintf(out, "Bad count in STATE_BASE_ADDRESS\n"); -	if (count < 6) +	if (len != sba_len)  	    BUFFER_FAIL(count, len, "STATE_BASE_ADDRESS"); +	i = 0;  	instr_out(data, hw_offset, 0,  		  "STATE_BASE_ADDRESS\n"); +	i++; -	if (data[1] & 1) { -	    instr_out(data, hw_offset, 1, "General state at 0x%08x\n", -		      data[1] & ~1); -	} else -	    instr_out(data, hw_offset, 1, "General state not updated\n"); +	state_base_out(data, hw_offset, i++, "general"); +	state_base_out(data, hw_offset, i++, "surface"); +	if (IS_GEN6(devid)) +	    state_base_out(data, hw_offset, i++, "dynamic"); +	state_base_out(data, hw_offset, i++, "indirect"); +	if (IS_IRONLAKE(devid) || IS_GEN6(devid)) +	    state_base_out(data, hw_offset, i++, "instruction"); -	if (data[2] & 1) { -	    instr_out(data, hw_offset, 2, "Surface state at 0x%08x\n", -		      data[2] & ~1); -	} else -	    instr_out(data, hw_offset, 2, "Surface state not updated\n"); - -	if (data[3] & 1) { -	    instr_out(data, hw_offset, 3, "Indirect state at 0x%08x\n", -		      data[3] & ~1); -	} else -	    instr_out(data, hw_offset, 3, "Indirect state not updated\n"); - -	if (data[4] & 1) { -	    instr_out(data, hw_offset, 4, "General state upper bound 0x%08x\n", -		      data[4] & ~1); -	} else -	    instr_out(data, hw_offset, 4, "General state not updated\n"); - -	if (data[5] & 1) { -	    instr_out(data, hw_offset, 5, "Indirect state upper bound 0x%08x\n", -		      data[5] & ~1); -	} else -	    instr_out(data, hw_offset, 5, "Indirect state not updated\n"); +	state_max_out(data, hw_offset, i++, "general"); +	if (IS_GEN6(devid)) +	    state_max_out(data, hw_offset, i++, "dynamic"); +	state_max_out(data, hw_offset, i++, "indirect"); +	if (IS_IRONLAKE(devid) || IS_GEN6(devid)) +	    state_max_out(data, hw_offset, i++, "instruction");  	return len;      case 0x7800: @@ -1505,18 +1687,33 @@ decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, int *failures)  	instr_out(data, hw_offset, 6, "CC state\n");  	return len;      case 0x7801: -	if (len != 6) +	len = (data[0] & 0x000000ff) + 2; +	if (len != 6 && len != 4)  	    fprintf(out, "Bad count in 3DSTATE_BINDING_TABLE_POINTERS\n"); -	if (count < 6) -	    BUFFER_FAIL(count, len, "3DSTATE_BINDING_TABLE_POINTERS"); +	if (len == 6) { +	    if (count < 6) +		BUFFER_FAIL(count, len, "3DSTATE_BINDING_TABLE_POINTERS"); +	    instr_out(data, hw_offset, 0, +		      "3DSTATE_BINDING_TABLE_POINTERS\n"); +	    instr_out(data, hw_offset, 1, "VS binding table\n"); +	    instr_out(data, hw_offset, 2, "GS binding table\n"); +	    instr_out(data, hw_offset, 3, "Clip binding table\n"); +	    instr_out(data, hw_offset, 4, "SF binding table\n"); +	    instr_out(data, hw_offset, 5, "WM binding table\n"); +	} else { +	    if (count < 4) +		BUFFER_FAIL(count, len, "3DSTATE_BINDING_TABLE_POINTERS"); -	instr_out(data, hw_offset, 0, -		  "3DSTATE_BINDING_TABLE_POINTERS\n"); -	instr_out(data, hw_offset, 1, "VS binding table\n"); -	instr_out(data, hw_offset, 2, "GS binding table\n"); -	instr_out(data, hw_offset, 3, "Clip binding table\n"); -	instr_out(data, hw_offset, 4, "SF binding table\n"); -	instr_out(data, hw_offset, 5, "WM binding table\n"); +	    instr_out(data, hw_offset, 0, +		      "3DSTATE_BINDING_TABLE_POINTERS: VS mod %d, " +		      "GS mod %d, PS mod %d\n", +		      (data[0] & (1 << 8)) != 0, +		      (data[0] & (1 << 9)) != 0, +		      (data[0] & (1 << 10)) != 0); +	    instr_out(data, hw_offset, 1, "VS binding table\n"); +	    instr_out(data, hw_offset, 2, "GS binding table\n"); +	    instr_out(data, hw_offset, 3, "WM binding table\n"); +	}  	return len; @@ -1567,6 +1764,18 @@ decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, int *failures)  	}  	return len; +    case 0x780d: +	len = (data[0] & 0xff) + 2; +	if (len != 4) +	    fprintf(out, "Bad count in 3DSTATE_VIEWPORT_STATE_POINTERS\n"); +	if (count < len) +	    BUFFER_FAIL(count, len, "3DSTATE_VIEWPORT_STATE_POINTERS"); +	instr_out(data, hw_offset, 0, "3DSTATE_VIEWPORT_STATE_POINTERS\n"); +	instr_out(data, hw_offset, 1, "clip\n"); +	instr_out(data, hw_offset, 2, "sf\n"); +	instr_out(data, hw_offset, 3, "cc\n"); +	return len; +      case 0x780a:  	len = (data[0] & 0xff) + 2;  	if (len != 3) @@ -1616,10 +1825,10 @@ decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, int *failures)  		  ((data[3] & 0x0007ffc0) >> 6) + 1,  		  ((data[3] & 0xfff80000) >> 19) + 1);  	instr_out(data, hw_offset, 4, "volume depth\n"); -	if (len == 6) +	if (len >= 6)  	    instr_out(data, hw_offset, 5, "\n"); -	if (len == 7) -	    instr_out(data, hw_offset, 6, "render target view extent\n"); +       if (len >= 7) +           instr_out(data, hw_offset, 6, "render target view extent\n");  	return len; @@ -1638,12 +1847,11 @@ decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, int *failures)  	}  	instr_out(data, hw_offset, 0,  		  "PIPE_CONTROL: %s, %sdepth stall, %sRC write flush, " -		  "%sinst flush, %stexture flush\n", +		  "%sinst flush\n",  		  desc1,  		  data[0] & (1 << 13) ? "" : "no ",  		  data[0] & (1 << 12) ? "" : "no ", -		  data[0] & (1 << 11) ? "" : "no ", -		  data[0] & (1 << 9) ? "" : "no "); +		  data[0] & (1 << 11) ? "" : "no ");  	instr_out(data, hw_offset, 1, "destination address\n");  	instr_out(data, hw_offset, 2, "immediate dword low\n");  	instr_out(data, hw_offset, 3, "immediate dword high\n"); @@ -1668,40 +1876,41 @@ decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, int *failures)  	return len;      } -    for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]); -	 opcode++) { -	if ((data[0] & 0xffff0000) >> 16 == opcodes_3d[opcode].opcode) { +    for (idx = 0; idx < ARRAY_SIZE(opcodes_3d); idx++) { +	opcode_3d = &opcodes_3d[idx]; +	if ((data[0] & 0xffff0000) >> 16 == opcode_3d->opcode) {  	    unsigned int i;  	    len = 1; -	    instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name); -	    if (opcodes_3d[opcode].max_len > 1) { +	    instr_out(data, hw_offset, 0, "%s\n", opcode_3d->name); +	    if (opcode_3d->max_len > 1) {  		len = (data[0] & 0xff) + 2; -		if (len < opcodes_3d[opcode].min_len || -		    len > opcodes_3d[opcode].max_len) +		if (len < opcode_3d->min_len || +		    len > opcode_3d->max_len)  		{ -		    fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name); +		    fprintf(out, "Bad count in %s\n", opcode_3d->name);  		}  	    }  	    for (i = 1; i < len; i++) {  		if (i >= count) -		    BUFFER_FAIL(count, len, opcodes_3d[opcode].name); +		    BUFFER_FAIL(count, len, opcode_3d->name);  		instr_out(data, hw_offset, i, "dword %d\n", i);  	    }  	    return len;  	}      } -    instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); +    instr_out(data, hw_offset, 0, "3D UNKNOWN: 3d_965 opcode = 0x%x\n", opcode);      (*failures)++;      return 1;  }  static int -decode_3d_i830(uint32_t *data, int count, uint32_t hw_offset, int *failures) +decode_3d_i830(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid, int *failures)  { -    unsigned int opcode; +    unsigned int idx; +    uint32_t opcode;      struct {  	uint32_t opcode; @@ -1725,42 +1934,44 @@ decode_3d_i830(uint32_t *data, int count, uint32_t hw_offset, int *failures)  	{ 0x0f, 1, 1, "3DSTATE_MODES_2" },  	{ 0x15, 1, 1, "3DSTATE_FOG_COLOR" },  	{ 0x16, 1, 1, "3DSTATE_MODES_4" }, -    }; +    }, *opcode_3d; -    switch ((data[0] & 0x1f000000) >> 24) { +    opcode = (data[0] & 0x1f000000) >> 24; + +    switch (opcode) {      case 0x1f:  	return decode_3d_primitive(data, count, hw_offset, failures);      case 0x1d: -	return decode_3d_1d(data, count, hw_offset, failures, 1); +	return decode_3d_1d(data, count, hw_offset, devid, failures);      case 0x1c:  	return decode_3d_1c(data, count, hw_offset, failures);      } -    for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]); -	 opcode++) { -	if ((data[0] & 0x1f000000) >> 24 == opcodes_3d[opcode].opcode) { +    for (idx = 0; idx < ARRAY_SIZE(opcodes_3d); idx++) { +	opcode_3d = &opcodes_3d[idx]; +	if ((data[0] & 0x1f000000) >> 24 == opcode_3d->opcode) {  	    unsigned int len = 1, i; -	    instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name); -	    if (opcodes_3d[opcode].max_len > 1) { +	    instr_out(data, hw_offset, 0, "%s\n", opcode_3d->name); +	    if (opcode_3d->max_len > 1) {  		len = (data[0] & 0xff) + 2; -		if (len < opcodes_3d[opcode].min_len || -		    len > opcodes_3d[opcode].max_len) +		if (len < opcode_3d->min_len || +		    len > opcode_3d->max_len)  		{ -		    fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name); +		    fprintf(out, "Bad count in %s\n", opcode_3d->name);  		}  	    }  	    for (i = 1; i < len; i++) {  		if (i >= count) -		    BUFFER_FAIL(count, len, opcodes_3d[opcode].name); +		    BUFFER_FAIL(count, len, opcode_3d->name);  		instr_out(data, hw_offset, i, "dword %d\n", i);  	    }  	    return len;  	}      } -    instr_out(data, hw_offset, 0, "3D UNKNOWN\n"); +    instr_out(data, hw_offset, 0, "3D UNKNOWN: 3d_i830 opcode = 0x%x\n", opcode);      (*failures)++;      return 1;  } @@ -1773,18 +1984,37 @@ decode_3d_i830(uint32_t *data, int count, uint32_t hw_offset, int *failures)   * \param hw_offset hardware address for the buffer   */  int -intel_decode(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid) +intel_decode(uint32_t *data, int count, +	     uint32_t hw_offset, +	     uint32_t devid, +	     uint32_t ignore_end_of_batchbuffer)  { +    int ret;      int index = 0;      int failures = 0; -    out = stderr; +    out = stdout;      while (index < count) {  	switch ((data[index] & 0xe0000000) >> 29) {  	case 0x0: -	    index += decode_mi(data + index, count - index, +	    ret = decode_mi(data + index, count - index,  			       hw_offset + index * 4, &failures); + +	    /* If MI_BATCHBUFFER_END happened, then dump the rest of the +	     * output in case we some day want it in debugging, but don't +	     * decode it since it'll just confuse in the common case. +	     */ +	    if (ret == -1) { +		if (ignore_end_of_batchbuffer) { +		    index++; +		} else { +		    for (index = index + 1; index < count; index++) { +			instr_out(data, hw_offset, index, "\n"); +		    } +		} +	    } else +		index += ret;  	    break;  	case 0x2:  	    index += decode_2d(data + index, count - index, @@ -1793,13 +2023,16 @@ intel_decode(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid)  	case 0x3:  	    if (IS_965(devid)) {  		index += decode_3d_965(data + index, count - index, -				       hw_offset + index * 4, &failures); +				       hw_offset + index * 4, +				       devid, &failures);  	    } else if (IS_9XX(devid)) {  		index += decode_3d(data + index, count - index, -				   hw_offset + index * 4, &failures); +				   hw_offset + index * 4, +				   devid, &failures);  	    } else {  		index += decode_3d_i830(data + index, count - index, -					hw_offset + index * 4, &failures); +					hw_offset + index * 4, +					devid, &failures);  	    }  	    break;  	default: @@ -1820,3 +2053,8 @@ void intel_decode_context_reset(void)      saved_s4_set = 1;  } +void intel_decode_context_set_head_tail(uint32_t head, uint32_t tail) +{ +	head_offset = head; +	tail_offset = tail; +} diff --git a/src/mesa/drivers/dri/intel/intel_decode.h b/src/mesa/drivers/dri/intel/intel_decode.h index c50644a46b..a13b075cef 100644 --- a/src/mesa/drivers/dri/intel/intel_decode.h +++ b/src/mesa/drivers/dri/intel/intel_decode.h @@ -25,5 +25,7 @@   *   */ -int intel_decode(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid); +int intel_decode(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid, +		 uint32_t ignore_end_of_batchbuffer); +void intel_decode_context_set_head_tail(uint32_t head, uint32_t tail);  void intel_decode_context_reset(void); | 
