diff options
Diffstat (limited to 'r600_shader.c')
-rw-r--r-- | r600_shader.c | 282 |
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; +} |