summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2010-02-13 19:02:35 +0100
committerJerome Glisse <jglisse@redhat.com>2010-02-13 19:02:35 +0100
commitbbad7babb8640f4779d1ff355b098b36c790729f (patch)
treef4b012022f94a6830cb5c9d183b280318c81802a
parent6c2097cd142555bcfd77837d9d5865cc7b2bdd72 (diff)
r600 shader disassembler
-rw-r--r--Makefile2
-rw-r--r--r600_shader.c324
-rw-r--r--r600d.h250
-rw-r--r--test.c29
4 files changed, 592 insertions, 13 deletions
diff --git a/Makefile b/Makefile
index 3c20326..80bc022 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
OBJECTS = radeon.o mode.o test.o r700_atom.o radeon_device.o radeon_atom.o\
- r600_atom.o
+ r600_atom.o r600_shader.o
CFLAGS = -g3 -O0 -std=gnu99 -I/usr/include/drm
LDFLAGS = -ldrm -ldrm_radeon
DEPS = radeon.h
diff --git a/r600_shader.c b/r600_shader.c
new file mode 100644
index 0000000..7f8794d
--- /dev/null
+++ b/r600_shader.c
@@ -0,0 +1,324 @@
+/*
+ * Copyright © 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include "radeon_device.h"
+#include "r600d.h"
+
+struct r600_block {
+ struct list_head list;
+ u32 idx;
+ u32 f_idx;
+ u32 ninst;
+ u32 last;
+};
+
+struct r600_inst_name {
+ char name[64];
+};
+
+static struct r600_inst_name sq_cf_inst_name[] = {
+ {"NOP"},
+ {"TEX"},
+ {"VTX"},
+ {"VTX_TC"},
+ {"LOOP_START"},
+ {"LOOP_END"},
+ {"LOOP_START_DX10"},
+ {"LOOP_START_NO_AL"},
+ {"LOOP_CONTINUE"},
+ {"LOOP_BREAK"},
+ {"JUMP"},
+ {"PUSH"},
+ {"PUSH_ELSE"},
+ {"ELSE"},
+ {"POP"},
+ {"POP_JUMP"},
+ {"POP_PUSH"},
+ {"POP_PUSH_ELSE"},
+ {"CALL"},
+ {"CALL_FS"},
+ {"RETURN"},
+ {"EMIT_VERTEX"},
+ {"EMIT_CUT_VERTEX"},
+ {"CUT_VERTEX"},
+ {"KILL"},
+};
+
+static struct r600_inst_name sq_cf_alu_inst_name[] = {
+ {"unknown"},
+ {"unknown"},
+ {"unknown"},
+ {"unknown"},
+ {"unknown"},
+ {"unknown"},
+ {"unknown"},
+ {"unknown"},
+ {"ALU"},
+ {"ALU_PUSH_BEFORE"},
+ {"ALU_POP_AFTER"},
+ {"ALU_POP2_AFTER"},
+ {"unknown"},
+ {"ALU_CONTINUE"},
+ {"ALU_BREAK"},
+ {"ALU_ELSE_AFTER"},
+};
+
+static struct r600_inst_name sq_cf_alloc_export_inst_name[] = {
+ {"MEM_STREAM0"},
+ {"MEM_STREAM1"},
+ {"MEM_STREAM2"},
+ {"MEM_STREAM3"},
+ {"MEM_SCRATCH"},
+ {"MEM_REDUCTION"},
+ {"MEM_RING"},
+ {"EXPORT"},
+ {"EXPORT_DONE"},
+};
+
+void r600_disassemble_sq_cf_inst(u32 *bytecode, u32 ndwords, u32 idx)
+{
+ printf("0x%08X 0x%08X CF_INST: %s\n", bytecode[idx+0], bytecode[idx+1],
+ sq_cf_inst_name[G_008DFC_CF_INST(bytecode[idx+1])].name);
+ printf(" word0: addr (in dw) %d\n", G_008DFC_ADDR(bytecode[idx+0]) << 1);
+ printf(" word1: pop count %d\n", G_008DFC_POP_COUNT(bytecode[idx+1]));
+ printf(" word1: cf const %d\n", G_008DFC_CF_CONST(bytecode[idx+1]));
+ printf(" word1: cond %d\n", G_008DFC_COND(bytecode[idx+1]));
+ printf(" word1: count %d\n", G_008DFC_COUNT(bytecode[idx+1]));
+ printf(" word1: call count %d\n", G_008DFC_CALL_COUNT(bytecode[idx+1]));
+ printf(" word1: end of program %d\n", G_008DFC_END_OF_PROGRAM(bytecode[idx+1]));
+ printf(" word1: valid pixel mode %d\n", G_008DFC_VALID_PIXEL_MODE(bytecode[idx+1]));
+ printf(" word1: inst 0x%02X (%s)\n", G_008DFC_CF_INST(bytecode[idx+1]),
+ sq_cf_inst_name[G_008DFC_CF_INST(bytecode[idx+1])].name);
+ printf(" word1: whole quad mode %d\n", G_008DFC_WHOLE_QUAD_MODE(bytecode[idx+1]));
+ printf(" word1: barrier %d\n", G_008DFC_BARRIER(bytecode[idx+1]));
+}
+
+void r600_disassemble_sq_cf_alu_inst(u32 *bytecode, u32 ndwords, u32 idx)
+{
+ printf("0x%08X 0x%08X CF_ALU_INST: %s\n", bytecode[idx+0], bytecode[idx+1],
+ sq_cf_alu_inst_name[G_008DFC_CF_ALU_INST(bytecode[idx+1])].name);
+ printf(" word0: addr (in dw) %d\n", G_008DFC_ALU_ADDR(bytecode[idx+0]) << 1);
+ printf(" word0: kcache bank0 %d\n", G_008DFC_KCACHE_BANK0(bytecode[idx+0]));
+ printf(" word0: kcache bank1 %d\n", G_008DFC_KCACHE_BANK1(bytecode[idx+0]));
+ printf(" word0: kcache mode0 %d\n", G_008DFC_KCACHE_MODE0(bytecode[idx+0]));
+ printf(" word1: kcache mode1 %d\n", G_008DFC_KCACHE_MODE1(bytecode[idx+1]));
+ printf(" word1: kcache addr0 %d\n", G_008DFC_KCACHE_ADDR0(bytecode[idx+1]));
+ printf(" word1: kcache addr1 %d\n", G_008DFC_KCACHE_ADDR1(bytecode[idx+1]));
+ printf(" word1: count %d\n", G_008DFC_ALU_COUNT(bytecode[idx+1]));
+ printf(" word1: use waterfall %d\n", G_008DFC_USES_WATERFALL(bytecode[idx+1]));
+ printf(" word1: inst 0x%02X (%s)\n", G_008DFC_CF_ALU_INST(bytecode[idx+1]),
+ sq_cf_alu_inst_name[G_008DFC_CF_ALU_INST(bytecode[idx+1])].name);
+ printf(" word1: whole quad mode %d\n", G_008DFC_WHOLE_QUAD_MODE(bytecode[idx+1]));
+ printf(" word1: barrier %d\n", G_008DFC_BARRIER(bytecode[idx+1]));
+}
+
+void r600_disassemble_sq_cf_alloc_export_inst(u32 *bytecode, u32 ndwords, u32 idx)
+{
+ printf("0x%08X 0x%08X CF_ALLOC_EXPORT: %s\n", bytecode[idx+0], bytecode[idx+1],
+ sq_cf_alloc_export_inst_name[G_008DFC_CF_INST(bytecode[idx+1])-0x20].name);
+ printf(" word0: array base %d\n", G_008DFC_ARRAY_BASE(bytecode[idx+0]));
+ printf(" word0: type %d\n", G_008DFC_TYPE(bytecode[idx+0]));
+ printf(" word0: rw gpr %d\n", G_008DFC_RW_GPR(bytecode[idx+0]));
+ printf(" word0: rw rel %d\n", G_008DFC_RW_REL(bytecode[idx+0]));
+ printf(" word0: index gpr %d\n", G_008DFC_INDEX_GPR(bytecode[idx+0]));
+ printf(" word0: elem size %d\n", G_008DFC_ELEM_SIZE(bytecode[idx+0]));
+ printf(" word1: burst count %d\n", G_008DFC_BURST_COUNT(bytecode[idx+1]));
+ printf(" word1: end of program %d\n", G_008DFC_END_OF_PROGRAM(bytecode[idx+1]));
+ printf(" word1: valid pixel mode %d\n", G_008DFC_VALID_PIXEL_MODE(bytecode[idx+1]));
+ printf(" word1: inst 0x%02X (%s)\n", G_008DFC_CF_INST(bytecode[idx+1]),
+ sq_cf_alloc_export_inst_name[G_008DFC_CF_INST(bytecode[idx+1])-0x20].name);
+ printf(" word1: whole quad mode %d\n", G_008DFC_WHOLE_QUAD_MODE(bytecode[idx+1]));
+ printf(" word1: barrier %d\n", G_008DFC_BARRIER(bytecode[idx+1]));
+}
+
+struct r600_block *r600_block_new(u32 *bytecode, u32 ndwords, u32 idx)
+{
+ struct r600_block *blk;
+ u32 inst;
+
+ blk = malloc(sizeof(struct r600_block));
+ if (blk == NULL)
+ return NULL;
+ INIT_LIST_HEAD(&blk->list);
+ blk->idx = idx;
+ blk->last = 0;
+ inst = (bytecode[idx+1] >> 23) & 0x7F;
+ if ((inst & 0x78) >= 0x40) {
+ blk->f_idx = G_008DFC_ALU_ADDR(bytecode[idx+0]) << 1;
+ blk->ninst = G_008DFC_ALU_COUNT(bytecode[idx+1]);
+#if 0
+ /* SQ_CF_ALU */
+ switch (G_008DFC_CF_ALU_INST(bytecode[idx+1])) {
+ case V_008DFC_SQ_CF_INST_ALU:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_ALU\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_ALU_PUSH_BEFORE:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_ALU_PUSH_BEFORE\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_ALU_POP_AFTER:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_ALU_POP_AFTER\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_ALU_POP2_AFTER:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_ALU_POP2_AFTER\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_ALU_CONTINUE:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_ALU_CONTINUE\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_ALU_BREAK:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_ALU_BREAK\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_ALU_ELSE_AFTER:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_ALU_ELSE_AFTER\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ default:
+ printf("Block[%d %d %d] unknown cf alu instruction 0x%02X\n", blk->idx, blk->f_idx, blk->ninst, G_008DFC_CF_ALU_INST(bytecode[idx+1]));
+ break;
+ }
+#endif
+ r600_disassemble_sq_cf_alu_inst(bytecode, ndwords, idx);
+ } else {
+ if (G_008DFC_CF_INST(bytecode[idx+1]) < 0x20) {
+ r600_disassemble_sq_cf_inst(bytecode, ndwords, idx);
+ } else {
+ r600_disassemble_sq_cf_alloc_export_inst(bytecode, ndwords, idx);
+ blk->last = G_008DFC_END_OF_PROGRAM(bytecode[idx+1]);
+ }
+#if 0
+ switch (G_008DFC_CF_INST(bytecode[idx+1])) {
+ case V_008DFC_SQ_CF_INST_NOP:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_NOP\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_TEX:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_TEX\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_VTX:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_VTX\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_VTX_TC:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_VTX_TC\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_LOOP_START:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_LOOP_START\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_LOOP_END:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_LOOP_END\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_LOOP_START_DX10:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_LOOP_START_DX10\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_LOOP_START_NO_AL:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_LOOP_START_NO_AL\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_LOOP_CONTINUE:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_LOOP_CONTINUE\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_LOOP_BREAK:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_LOOP_BREAK\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_JUMP:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_JUMP\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_PUSH:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_PUSH\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_PUSH_ELSE:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_PUSH_ELSE\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_ELSE:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_ELSE\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_POP:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_POP\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_POP_JUMP:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_POP_JUMP\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_POP_PUSH:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_POP_PUSH\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_POP_PUSH_ELSE:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_POP_PUSH_ELSE\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_CALL:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_CALL\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_CALL_FS:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_CALL_FS\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_RETURN:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_RETURN\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_EMIT_VERTEX:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_EMIT_VERTEX\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_EMIT_CUT_VERTEX:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_EMIT_CUT_VERTEX\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_CUT_VERTEX:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_CUT_VERTEX\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_KILL:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_KILL\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_MEM_STREAM0:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_MEM_STREAM0\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_MEM_STREAM1:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_MEM_STREAM1\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_MEM_STREAM2:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_MEM_STREAM2\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_MEM_STREAM3:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_MEM_STREAM3\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_MEM_SCRATCH:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_MEM_SCRATCH\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_MEM_REDUCTION:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_MEM_REDUCTION\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_MEM_RING:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_MEM_RING\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_EXPORT:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_EXPORT\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ case V_008DFC_SQ_CF_INST_EXPORT_DONE:
+ printf("Block[%d %d %d] V_008DFC_SQ_CF_INST_EXPORT_DONE\n", blk->idx, blk->f_idx, blk->ninst);
+ break;
+ default:
+ printf("Block[%d %d %d] unknown cf instruction 0x%02X\n", blk->idx, blk->f_idx, blk->ninst, G_008DFC_CF_INST(bytecode[idx+1]));
+ break;
+ }
+#endif
+ }
+ return blk;
+}
+
+void r600_shader_disassemble(u32 *bytecode, u32 ndwords)
+{
+ struct r600_block *blk = NULL;
+ u32 idx = 0;
+
+ do {
+ free(blk);
+ blk = r600_block_new(bytecode, ndwords, idx);
+ if (blk == NULL)
+ return;
+ idx += 2;
+ } while (!blk->last);
+}
diff --git a/r600d.h b/r600d.h
index cd0c9bf..ae51a2c 100644
--- a/r600d.h
+++ b/r600d.h
@@ -326,5 +326,255 @@
#define S_028A40_CUT_MODE(x) (((x) & 0x3) << 3)
#define G_028A40_CUT_MODE(x) (((x) >> 3) & 0x3)
#define C_028A40_CUT_MODE 0xFFFFFFE7
+#define R_008DFC_SQ_CF_WORD0 0x008DFC
+#define S_008DFC_ADDR(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_008DFC_ADDR(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_008DFC_ADDR 0x00000000
+#define R_008DFC_SQ_CF_WORD1 0x008DFC
+#define S_008DFC_POP_COUNT(x) (((x) & 0x7) << 0)
+#define G_008DFC_POP_COUNT(x) (((x) >> 0) & 0x7)
+#define C_008DFC_POP_COUNT 0xFFFFFFF8
+#define S_008DFC_CF_CONST(x) (((x) & 0x1F) << 3)
+#define G_008DFC_CF_CONST(x) (((x) >> 3) & 0x1F)
+#define C_008DFC_CF_CONST 0xFFFFFF07
+#define S_008DFC_COND(x) (((x) & 0x3) << 8)
+#define G_008DFC_COND(x) (((x) >> 8) & 0x3)
+#define C_008DFC_COND 0xFFFFFCFF
+#define S_008DFC_COUNT(x) (((x) & 0x7) << 10)
+#define G_008DFC_COUNT(x) (((x) >> 10) & 0x7)
+#define C_008DFC_COUNT 0xFFFFE3FF
+#define S_008DFC_CALL_COUNT(x) (((x) & 0x3F) << 13)
+#define G_008DFC_CALL_COUNT(x) (((x) >> 13) & 0x3F)
+#define C_008DFC_CALL_COUNT 0xFFF81FFF
+#define S_008DFC_END_OF_PROGRAM(x) (((x) & 0x1) << 21)
+#define G_008DFC_END_OF_PROGRAM(x) (((x) >> 21) & 0x1)
+#define C_008DFC_END_OF_PROGRAM 0xFFDFFFFF
+#define S_008DFC_VALID_PIXEL_MODE(x) (((x) & 0x1) << 22)
+#define G_008DFC_VALID_PIXEL_MODE(x) (((x) >> 22) & 0x1)
+#define C_008DFC_VALID_PIXEL_MODE 0xFFBFFFFF
+#define S_008DFC_CF_INST(x) (((x) & 0x7F) << 23)
+#define G_008DFC_CF_INST(x) (((x) >> 23) & 0x7F)
+#define C_008DFC_CF_INST 0xC07FFFFF
+#define V_008DFC_SQ_CF_INST_NOP 0x00000000
+#define V_008DFC_SQ_CF_INST_TEX 0x00000001
+#define V_008DFC_SQ_CF_INST_VTX 0x00000002
+#define V_008DFC_SQ_CF_INST_VTX_TC 0x00000003
+#define V_008DFC_SQ_CF_INST_LOOP_START 0x00000004
+#define V_008DFC_SQ_CF_INST_LOOP_END 0x00000005
+#define V_008DFC_SQ_CF_INST_LOOP_START_DX10 0x00000006
+#define V_008DFC_SQ_CF_INST_LOOP_START_NO_AL 0x00000007
+#define V_008DFC_SQ_CF_INST_LOOP_CONTINUE 0x00000008
+#define V_008DFC_SQ_CF_INST_LOOP_BREAK 0x00000009
+#define V_008DFC_SQ_CF_INST_JUMP 0x0000000A
+#define V_008DFC_SQ_CF_INST_PUSH 0x0000000B
+#define V_008DFC_SQ_CF_INST_PUSH_ELSE 0x0000000C
+#define V_008DFC_SQ_CF_INST_ELSE 0x0000000D
+#define V_008DFC_SQ_CF_INST_POP 0x0000000E
+#define V_008DFC_SQ_CF_INST_POP_JUMP 0x0000000F
+#define V_008DFC_SQ_CF_INST_POP_PUSH 0x00000010
+#define V_008DFC_SQ_CF_INST_POP_PUSH_ELSE 0x00000011
+#define V_008DFC_SQ_CF_INST_CALL 0x00000012
+#define V_008DFC_SQ_CF_INST_CALL_FS 0x00000013
+#define V_008DFC_SQ_CF_INST_RETURN 0x00000014
+#define V_008DFC_SQ_CF_INST_EMIT_VERTEX 0x00000015
+#define V_008DFC_SQ_CF_INST_EMIT_CUT_VERTEX 0x00000016
+#define V_008DFC_SQ_CF_INST_CUT_VERTEX 0x00000017
+#define V_008DFC_SQ_CF_INST_KILL 0x00000018
+#define S_008DFC_WHOLE_QUAD_MODE(x) (((x) & 0x1) << 30)
+#define G_008DFC_WHOLE_QUAD_MODE(x) (((x) >> 30) & 0x1)
+#define C_008DFC_WHOLE_QUAD_MODE 0xBFFFFFFF
+#define S_008DFC_BARRIER(x) (((x) & 0x1) << 31)
+#define G_008DFC_BARRIER(x) (((x) >> 31) & 0x1)
+#define C_008DFC_BARRIER 0x7FFFFFFF
+#define R_008DFC_SQ_CF_ALU_WORD0 0x008DFC
+#define S_008DFC_ALU_ADDR(x) (((x) & 0x3FFFFF) << 0)
+#define G_008DFC_ALU_ADDR(x) (((x) >> 0) & 0x3FFFFF)
+#define C_008DFC_ALU_ADDR 0xFFC00000
+#define S_008DFC_KCACHE_BANK0(x) (((x) & 0xF) << 22)
+#define G_008DFC_KCACHE_BANK0(x) (((x) >> 22) & 0xF)
+#define C_008DFC_KCACHE_BANK0 0xFC3FFFFF
+#define S_008DFC_KCACHE_BANK1(x) (((x) & 0xF) << 26)
+#define G_008DFC_KCACHE_BANK1(x) (((x) >> 26) & 0xF)
+#define C_008DFC_KCACHE_BANK1 0xC3FFFFFF
+#define S_008DFC_KCACHE_MODE0(x) (((x) & 0x3) << 30)
+#define G_008DFC_KCACHE_MODE0(x) (((x) >> 30) & 0x3)
+#define C_008DFC_KCACHE_MODE0 0x3FFFFFFF
+#define R_008DFC_SQ_CF_ALU_WORD1 0x008DFC
+#define S_008DFC_KCACHE_MODE1(x) (((x) & 0x3) << 0)
+#define G_008DFC_KCACHE_MODE1(x) (((x) >> 0) & 0x3)
+#define C_008DFC_KCACHE_MODE1 0xFFFFFFFC
+#define S_008DFC_KCACHE_ADDR0(x) (((x) & 0xFF) << 2)
+#define G_008DFC_KCACHE_ADDR0(x) (((x) >> 2) & 0xFF)
+#define C_008DFC_KCACHE_ADDR0 0xFFFFFC03
+#define S_008DFC_KCACHE_ADDR1(x) (((x) & 0xFF) << 10)
+#define G_008DFC_KCACHE_ADDR1(x) (((x) >> 10) & 0xFF)
+#define C_008DFC_KCACHE_ADDR1 0xFFFC03FF
+#define S_008DFC_ALU_COUNT(x) (((x) & 0x7F) << 18)
+#define G_008DFC_ALU_COUNT(x) (((x) >> 18) & 0x7F)
+#define C_008DFC_ALU_COUNT 0xFE03FFFF
+#define S_008DFC_USES_WATERFALL(x) (((x) & 0x1) << 25)
+#define G_008DFC_USES_WATERFALL(x) (((x) >> 25) & 0x1)
+#define C_008DFC_USES_WATERFALL 0xFDFFFFFF
+#define S_008DFC_CF_ALU_INST(x) (((x) & 0xF) << 26)
+#define G_008DFC_CF_ALU_INST(x) (((x) >> 26) & 0xF)
+#define C_008DFC_CF_ALU_INST 0xC3FFFFFF
+#define V_008DFC_SQ_CF_INST_ALU 0x00000008
+#define V_008DFC_SQ_CF_INST_ALU_PUSH_BEFORE 0x00000009
+#define V_008DFC_SQ_CF_INST_ALU_POP_AFTER 0x0000000A
+#define V_008DFC_SQ_CF_INST_ALU_POP2_AFTER 0x0000000B
+#define V_008DFC_SQ_CF_INST_ALU_CONTINUE 0x0000000D
+#define V_008DFC_SQ_CF_INST_ALU_BREAK 0x0000000E
+#define V_008DFC_SQ_CF_INST_ALU_ELSE_AFTER 0x0000000F
+#define S_008DFC_WHOLE_QUAD_MODE(x) (((x) & 0x1) << 30)
+#define G_008DFC_WHOLE_QUAD_MODE(x) (((x) >> 30) & 0x1)
+#define C_008DFC_WHOLE_QUAD_MODE 0xBFFFFFFF
+#define S_008DFC_BARRIER(x) (((x) & 0x1) << 31)
+#define G_008DFC_BARRIER(x) (((x) >> 31) & 0x1)
+#define C_008DFC_BARRIER 0x7FFFFFFF
+#define R_008DFC_SQ_CF_ALLOC_EXPORT_WORD0 0x008DFC
+#define S_008DFC_ARRAY_BASE(x) (((x) & 0x1FFF) << 0)
+#define G_008DFC_ARRAY_BASE(x) (((x) >> 0) & 0x1FFF)
+#define C_008DFC_ARRAY_BASE 0xFFFFE000
+#define S_008DFC_TYPE(x) (((x) & 0x3) << 13)
+#define G_008DFC_TYPE(x) (((x) >> 13) & 0x3)
+#define C_008DFC_TYPE 0xFFFF9FFF
+#define S_008DFC_RW_GPR(x) (((x) & 0x7F) << 15)
+#define G_008DFC_RW_GPR(x) (((x) >> 15) & 0x7F)
+#define C_008DFC_RW_GPR 0xFFC07FFF
+#define S_008DFC_RW_REL(x) (((x) & 0x1) << 22)
+#define G_008DFC_RW_REL(x) (((x) >> 22) & 0x1)
+#define C_008DFC_RW_REL 0xFFBFFFFF
+#define S_008DFC_INDEX_GPR(x) (((x) & 0x7F) << 23)
+#define G_008DFC_INDEX_GPR(x) (((x) >> 23) & 0x7F)
+#define C_008DFC_INDEX_GPR 0xC07FFFFF
+#define S_008DFC_ELEM_SIZE(x) (((x) & 0x3) << 30)
+#define G_008DFC_ELEM_SIZE(x) (((x) >> 30) & 0x3)
+#define C_008DFC_ELEM_SIZE 0x3FFFFFFF
+#define R_008DFC_SQ_CF_ALLOC_EXPORT_WORD1 0x008DFC
+#define S_008DFC_BURST_COUNT(x) (((x) & 0xF) << 17)
+#define G_008DFC_BURST_COUNT(x) (((x) >> 17) & 0xF)
+#define C_008DFC_BURST_COUNT 0xFFE1FFFF
+#define S_008DFC_END_OF_PROGRAM(x) (((x) & 0x1) << 21)
+#define G_008DFC_END_OF_PROGRAM(x) (((x) >> 21) & 0x1)
+#define C_008DFC_END_OF_PROGRAM 0xFFDFFFFF
+#define S_008DFC_VALID_PIXEL_MODE(x) (((x) & 0x1) << 22)
+#define G_008DFC_VALID_PIXEL_MODE(x) (((x) >> 22) & 0x1)
+#define C_008DFC_VALID_PIXEL_MODE 0xFFBFFFFF
+#define S_008DFC_CF_INST(x) (((x) & 0x7F) << 23)
+#define G_008DFC_CF_INST(x) (((x) >> 23) & 0x7F)
+#define C_008DFC_CF_INST 0xC07FFFFF
+#define V_008DFC_SQ_CF_INST_MEM_STREAM0 0x00000020
+#define V_008DFC_SQ_CF_INST_MEM_STREAM1 0x00000021
+#define V_008DFC_SQ_CF_INST_MEM_STREAM2 0x00000022
+#define V_008DFC_SQ_CF_INST_MEM_STREAM3 0x00000023
+#define V_008DFC_SQ_CF_INST_MEM_SCRATCH 0x00000024
+#define V_008DFC_SQ_CF_INST_MEM_REDUCTION 0x00000025
+#define V_008DFC_SQ_CF_INST_MEM_RING 0x00000026
+#define V_008DFC_SQ_CF_INST_EXPORT 0x00000027
+#define V_008DFC_SQ_CF_INST_EXPORT_DONE 0x00000028
+#define S_008DFC_WHOLE_QUAD_MODE(x) (((x) & 0x1) << 30)
+#define G_008DFC_WHOLE_QUAD_MODE(x) (((x) >> 30) & 0x1)
+#define C_008DFC_WHOLE_QUAD_MODE 0xBFFFFFFF
+#define S_008DFC_BARRIER(x) (((x) & 0x1) << 31)
+#define G_008DFC_BARRIER(x) (((x) >> 31) & 0x1)
+#define C_008DFC_BARRIER 0x7FFFFFFF
+#define R_008DFC_SQ_CF_ALLOC_EXPORT_WORD1_BUF 0x008DFC
+#define S_008DFC_ARRAY_SIZE(x) (((x) & 0xFFF) << 0)
+#define G_008DFC_ARRAY_SIZE(x) (((x) >> 0) & 0xFFF)
+#define C_008DFC_ARRAY_SIZE 0xFFFFF000
+#define S_008DFC_COMP_MASK(x) (((x) & 0xF) << 12)
+#define G_008DFC_COMP_MASK(x) (((x) >> 12) & 0xF)
+#define C_008DFC_COMP_MASK 0xFFFF0FFF
+#define R_008DFC_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ 0x008DFC
+#define S_008DFC_SEL_X(x) (((x) & 0x7) << 0)
+#define G_008DFC_SEL_X(x) (((x) >> 0) & 0x7)
+#define C_008DFC_SEL_X 0xFFFFFFF8
+#define S_008DFC_SEL_Y(x) (((x) & 0x7) << 3)
+#define G_008DFC_SEL_Y(x) (((x) >> 3) & 0x7)
+#define C_008DFC_SEL_Y 0xFFFFFFC7
+#define S_008DFC_SEL_Z(x) (((x) & 0x7) << 6)
+#define G_008DFC_SEL_Z(x) (((x) >> 6) & 0x7)
+#define C_008DFC_SEL_Z 0xFFFFFE3F
+#define S_008DFC_SEL_W(x) (((x) & 0x7) << 9)
+#define G_008DFC_SEL_W(x) (((x) >> 9) & 0x7)
+#define C_008DFC_SEL_W 0xFFFFF1FF
+#define R_008DFC_SQ_ALU_WORD0 0x008DFC
+#define S_008DFC_SRC0_SEL(x) (((x) & 0x1FF) << 0)
+#define G_008DFC_SRC0_SEL(x) (((x) >> 0) & 0x1FF)
+#define C_008DFC_SRC0_SEL 0xFFFFFE00
+#define S_008DFC_SRC0_REL(x) (((x) & 0x1) << 9)
+#define G_008DFC_SRC0_REL(x) (((x) >> 9) & 0x1)
+#define C_008DFC_SRC0_REL 0xFFFFFDFF
+#define S_008DFC_SRC0_CHAN(x) (((x) & 0x3) << 10)
+#define G_008DFC_SRC0_CHAN(x) (((x) >> 10) & 0x3)
+#define C_008DFC_SRC0_CHAN 0xFFFFF3FF
+#define S_008DFC_SRC0_NEG(x) (((x) & 0x1) << 12)
+#define G_008DFC_SRC0_NEG(x) (((x) >> 12) & 0x1)
+#define C_008DFC_SRC0_NEG 0xFFFFEFFF
+#define S_008DFC_SRC1_SEL(x) (((x) & 0x1FF) << 13)
+#define G_008DFC_SRC1_SEL(x) (((x) >> 13) & 0x1FF)
+#define C_008DFC_SRC1_SEL 0xFFC01FFF
+#define S_008DFC_SRC1_REL(x) (((x) & 0x1) << 22)
+#define G_008DFC_SRC1_REL(x) (((x) >> 22) & 0x1)
+#define C_008DFC_SRC1_REL 0xFFBFFFFF
+#define S_008DFC_SRC1_CHAN(x) (((x) & 0x3) << 23)
+#define G_008DFC_SRC1_CHAN(x) (((x) >> 23) & 0x3)
+#define C_008DFC_SRC1_CHAN 0xFE7FFFFF
+#define S_008DFC_SRC1_NEG(x) (((x) & 0x1) << 25)
+#define G_008DFC_SRC1_NEG(x) (((x) >> 25) & 0x1)
+#define C_008DFC_SRC1_NEG 0xFDFFFFFF
+#define S_008DFC_INDEX_MODE(x) (((x) & 0x7) << 26)
+#define G_008DFC_INDEX_MODE(x) (((x) >> 26) & 0x7)
+#define C_008DFC_INDEX_MODE 0xE3FFFFFF
+#define S_008DFC_PRED_SEL(x) (((x) & 0x3) << 29)
+#define G_008DFC_PRED_SEL(x) (((x) >> 29) & 0x3)
+#define C_008DFC_PRED_SEL 0x9FFFFFFF
+#define S_008DFC_LAST(x) (((x) & 0x1) << 31)
+#define G_008DFC_LAST(x) (((x) >> 31) & 0x1)
+#define C_008DFC_LAST 0x7FFFFFFF
+#define R_008DFC_SQ_ALU_WORD1 0x008DFC
+#define S_008DFC_ENCODING(x) (((x) & 0x7) << 15)
+#define G_008DFC_ENCODING(x) (((x) >> 15) & 0x7)
+#define C_008DFC_ENCODING 0xFFFC7FFF
+#define S_008DFC_BANK_SWIZZLE(x) (((x) & 0x7) << 18)
+#define G_008DFC_BANK_SWIZZLE(x) (((x) >> 18) & 0x7)
+#define C_008DFC_BANK_SWIZZLE 0xFFE3FFFF
+#define S_008DFC_DST_GPR(x) (((x) & 0x7F) << 21)
+#define G_008DFC_DST_GPR(x) (((x) >> 21) & 0x7F)
+#define C_008DFC_DST_GPR 0xF01FFFFF
+#define S_008DFC_DST_REL(x) (((x) & 0x1) << 28)
+#define G_008DFC_DST_REL(x) (((x) >> 28) & 0x1)
+#define C_008DFC_DST_REL 0xEFFFFFFF
+#define S_008DFC_DST_CHAN(x) (((x) & 0x3) << 29)
+#define G_008DFC_DST_CHAN(x) (((x) >> 29) & 0x3)
+#define C_008DFC_DST_CHAN 0x9FFFFFFF
+#define S_008DFC_CLAMP(x) (((x) & 0x1) << 31)
+#define G_008DFC_CLAMP(x) (((x) >> 31) & 0x1)
+#define C_008DFC_CLAMP 0x7FFFFFFF
+#define R_008DFC_SQ_ALU_WORD1_OP2 0x008DFC
+#define S_008DFC_SRC0_ABS(x) (((x) & 0x1) << 0)
+#define G_008DFC_SRC0_ABS(x) (((x) >> 0) & 0x1)
+#define C_008DFC_SRC0_ABS 0xFFFFFFFE
+#define S_008DFC_SRC1_ABS(x) (((x) & 0x1) << 1)
+#define G_008DFC_SRC1_ABS(x) (((x) >> 1) & 0x1)
+#define C_008DFC_SRC1_ABS 0xFFFFFFFD
+#define S_008DFC_UPDATE_EXECUTE_MASK(x) (((x) & 0x1) << 2)
+#define G_008DFC_UPDATE_EXECUTE_MASK(x) (((x) >> 2) & 0x1)
+#define C_008DFC_UPDATE_EXECUTE_MASK 0xFFFFFFFB
+#define S_008DFC_UPDATE_PRED(x) (((x) & 0x1) << 3)
+#define G_008DFC_UPDATE_PRED(x) (((x) >> 3) & 0x1)
+#define C_008DFC_UPDATE_PRED 0xFFFFFFF7
+#define S_008DFC_WRITE_MASK(x) (((x) & 0x1) << 4)
+#define G_008DFC_WRITE_MASK(x) (((x) >> 4) & 0x1)
+#define C_008DFC_WRITE_MASK 0xFFFFFFEF
+#define S_008DFC_FOG_MERGE(x) (((x) & 0x1) << 5)
+#define G_008DFC_FOG_MERGE(x) (((x) >> 5) & 0x1)
+#define C_008DFC_FOG_MERGE 0xFFFFFFDF
+#define S_008DFC_OMOD(x) (((x) & 0x3) << 6)
+#define G_008DFC_OMOD(x) (((x) >> 6) & 0x3)
+#define C_008DFC_OMOD 0xFFFFFF3F
+#define S_008DFC_ALU_INST(x) (((x) & 0x3FF) << 8)
+#define G_008DFC_ALU_INST(x) (((x) >> 8) & 0x3FF)
+#define C_008DFC_ALU_INST 0xFFFC00FF
#endif
diff --git a/test.c b/test.c
index 3b12ee5..1da3ffb 100644
--- a/test.c
+++ b/test.c
@@ -52,18 +52,21 @@ static u32 vsconstants[16] = {
};
static u32 vsshaders[64] = {
- 0x0000001C, 0x81000400, 0x00000005, 0x80000000, 0x00000007,
- 0xA04C0000, 0xC001A03C, 0x94000688, 0xC0024000, 0x94200688,
- 0x900000F8, 0x00A80C90, 0x00000000, 0x00000000, 0x00200001,
- 0x006C2810, 0x00A00401, 0x206C2800, 0x01200801, 0x406C2800,
- 0x81A00C01, 0x606C2800, 0x00202001, 0x006C2800, 0x00A02401,
- 0x206C2810, 0x01202801, 0x406C2800, 0x81A02C01, 0x606C2800,
- 0x00204001, 0x006C2800, 0x00A04401, 0x206C2800, 0x01204801,
- 0x406C2810, 0x81A04C01, 0x606C2800, 0x00206001, 0x006C2800,
- 0x00A06401, 0x206C2800, 0x01206801, 0x406C2800, 0x81A06C01,
- 0x606C2810, 0x00000002, 0x00940C90, 0x00000402, 0x20940C90,
- 0x00000802, 0x40940C90, 0x80000C02, 0x60940C90, 0x00000000,
- 0x00000000, 0x7C000000, 0x1C351001, 0x00080000, 0x0BEADEAF,
+ 0x0000001C, 0x81000400, 0x00000005, 0x80000000,
+ 0x00000007, 0xA04C0000, 0xC001A03C, 0x94000688,
+ 0xC0024000, 0x94200688, 0x900000F8, 0x00A80C90,
+ 0x00000000, 0x00000000, 0x00200001, 0x006C2810,
+ 0x00A00401, 0x206C2800, 0x01200801, 0x406C2800,
+ 0x81A00C01, 0x606C2800, 0x00202001, 0x006C2800,
+ 0x00A02401, 0x206C2810, 0x01202801, 0x406C2800,
+ 0x81A02C01, 0x606C2800, 0x00204001, 0x006C2800,
+ 0x00A04401, 0x206C2800, 0x01204801, 0x406C2810,
+ 0x81A04C01, 0x606C2800, 0x00206001, 0x006C2800,
+ 0x00A06401, 0x206C2800, 0x01206801, 0x406C2800,
+ 0x81A06C01, 0x606C2810, 0x00000002, 0x00940C90,
+ 0x00000402, 0x20940C90, 0x00000802, 0x40940C90,
+ 0x80000C02, 0x60940C90, 0x00000000, 0x00000000,
+ 0x7C000000, 0x1C351001, 0x00080000, 0x0BEADEAF,
0x7C000300, 0x18ED1002, 0x00080000, 0x0BEADEAF,
};
@@ -75,6 +78,7 @@ static u32 psshaders[20] = {
0x80000C00, 0x60340C90, 0x00000000, 0x00000000,
};
+void r600_shader_disassemble(u32 *bytecode, u32 ndwords);
int r600_tri_flat(struct radeon *radeon)
{
struct radeon_device *rdev;
@@ -95,6 +99,7 @@ int r600_tri_flat(struct radeon *radeon)
struct drm_radeon_atom atom;
int r;
+ r600_shader_disassemble(vsshaders, 64);
r = radeon_device_init(&rdev, radeon);
if (r)
return r;