summaryrefslogtreecommitdiff
path: root/r600_shader.c
diff options
context:
space:
mode:
Diffstat (limited to 'r600_shader.c')
-rw-r--r--r600_shader.c282
1 files changed, 90 insertions, 192 deletions
diff --git a/r600_shader.c b/r600_shader.c
index 7f8794d..fd482c8 100644
--- a/r600_shader.c
+++ b/r600_shader.c
@@ -20,72 +20,71 @@
struct r600_block {
struct list_head list;
u32 idx;
- u32 f_idx;
- u32 ninst;
u32 last;
};
struct r600_inst_name {
+ char safe;
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"},
+ {1, "NOP"},
+ {0, "TEX"},
+ {0, "VTX"},
+ {0, "VTX_TC"},
+ {1, "LOOP_START"},
+ {1, "LOOP_END"},
+ {1, "LOOP_START_DX10"},
+ {1, "LOOP_START_NO_AL"},
+ {1, "LOOP_CONTINUE"},
+ {1, "LOOP_BREAK"},
+ {1, "JUMP"},
+ {1, "PUSH"},
+ {1, "PUSH_ELSE"},
+ {1, "ELSE"},
+ {1, "POP"},
+ {1, "POP_JUMP"},
+ {1, "POP_PUSH"},
+ {1, "POP_PUSH_ELSE"},
+ {1, "CALL"},
+ {1, "CALL_FS"},
+ {1, "RETURN"},
+ {0, "EMIT_VERTEX"},
+ {0, "EMIT_CUT_VERTEX"},
+ {0, "CUT_VERTEX"},
+ {1, "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"},
+ {0, "unknown"},
+ {0, "unknown"},
+ {0, "unknown"},
+ {0, "unknown"},
+ {0, "unknown"},
+ {0, "unknown"},
+ {0, "unknown"},
+ {0, "unknown"},
+ {1, "ALU"},
+ {1, "ALU_PUSH_BEFORE"},
+ {1, "ALU_POP_AFTER"},
+ {1, "ALU_POP2_AFTER"},
+ {0, "unknown"},
+ {1, "ALU_CONTINUE"},
+ {1, "ALU_BREAK"},
+ {1, "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"},
+ {0, "MEM_STREAM0"},
+ {0, "MEM_STREAM1"},
+ {0, "MEM_STREAM2"},
+ {0, "MEM_STREAM3"},
+ {0, "MEM_SCRATCH"},
+ {0, "MEM_REDUCTION"},
+ {0, "MEM_RING"},
+ {1, "EXPORT"},
+ {1, "EXPORT_DONE"},
};
void r600_disassemble_sq_cf_inst(u32 *bytecode, u32 ndwords, u32 idx)
@@ -157,37 +156,6 @@ struct r600_block *r600_block_new(u32 *bytecode, u32 ndwords, u32 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) {
@@ -196,115 +164,6 @@ struct r600_block *r600_block_new(u32 *bytecode, u32 ndwords, u32 idx)
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;
}
@@ -322,3 +181,42 @@ void r600_shader_disassemble(u32 *bytecode, u32 ndwords)
idx += 2;
} while (!blk->last);
}
+
+int r600_shader_build_fs(struct radeon_device *rdev,
+ u32 *bytecode, u32 *ndwords,
+ struct drm_r600_vs_input *inputs,
+ struct drm_r600_vs_shader *vs)
+{
+ u32 idx = 0, i, rid, gpr, j;
+
+ *ndwords = 0;
+ if (!inputs->nelements) {
+ dev_err(rdev->dev, "need at least one input for vertex shader\n");
+ return -EINVAL;
+ }
+ bytecode[idx++] = 0x00000001;
+ bytecode[idx++] = 0x81200000 | S_008DFC_COUNT(inputs->nelements - 1);
+ for (i = 0; i < inputs->nelements; i++) {
+ if (inputs->elements[i].buffer_id >= inputs->nbuffers) {
+ dev_err(rdev->dev, "elements %d referencing invalid buffer %d\n",
+ i, inputs->elements[i].buffer_id);
+ return -EINVAL;
+ }
+ rid = inputs->buffers[inputs->elements[i].buffer_id].resource_id;
+ for (j = 0, gpr = -1; j < vs->ninputs; j++) {
+ if (vs->input_semantic[j] == inputs->elements[i].semantic) {
+ gpr = vs->input_gpr[j];
+ break;
+ }
+ }
+ /* if vs has no corresponding input skip the elements */
+ if (gpr == -1)
+ continue;
+ bytecode[idx++] = (inputs->elements[i].sq_vtx_word0 & 0xFC000000) | S_008DFC_BUFFER_ID(rid);
+ bytecode[idx++] = (inputs->elements[i].sq_vtx_word1 & 0xFFFFFC00) | S_008DFC_DST_GPR(gpr);
+ bytecode[idx++] = inputs->elements[i].sq_vtx_word2;
+ bytecode[idx++] = 0xCAFEDEAD;
+ }
+ *ndwords = idx;
+ return 0;
+}