summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2010-08-26 14:42:06 -0700
committerEric Anholt <eric@anholt.net>2010-08-26 14:55:44 -0700
commit363d0f6774b4c6b825f5b903284da1cd51a91986 (patch)
tree9214a43a590fbd63ae7ea68808eda53a13b1c721
parent7268bd82f60b1c9642a48dcfff6d77b2897222cd (diff)
i965: Add GLSL IR-level source annotation and comments to new FS debug.
This should make debugging way easier, as now we have context for reading large programs.
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp88
1 files changed, 83 insertions, 5 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index f856ee79fa6..640f797e9e6 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -292,7 +292,7 @@ public:
{
void *node;
- node = talloc_size(ctx, size);
+ node = talloc_zero_size(ctx, size);
assert(node != NULL);
return node;
@@ -345,6 +345,13 @@ public:
bool saturate;
bool predicated;
int conditional_mod; /**< BRW_CONDITIONAL_* */
+
+ /** @{
+ * Annotation for the generated IR. One of the two can be set.
+ */
+ ir_instruction *ir;
+ const char *annotation;
+ /** @} */
};
class fs_visitor : public ir_visitor
@@ -369,6 +376,10 @@ public:
this->frag_data = NULL;
this->frag_depth = NULL;
this->first_non_payload_grf = 0;
+
+ this->current_annotation = NULL;
+ this->annotation_string = NULL;
+ this->annotation_ir = NULL;
}
~fs_visitor()
{
@@ -424,6 +435,13 @@ public:
ir_variable *frag_color, *frag_data, *frag_depth;
int first_non_payload_grf;
+ /** @{ debug annotation info */
+ const char *current_annotation;
+ ir_instruction *base_ir;
+ const char **annotation_string;
+ ir_instruction **annotation_ir;
+ /** @} */
+
bool fail;
/* Result of last visit() method. */
@@ -912,6 +930,7 @@ fs_visitor::visit(ir_function *ir)
foreach_iter(exec_list_iterator, iter, sig->body) {
ir_instruction *ir = (ir_instruction *)iter.get();
+ this->base_ir = ir;
ir->accept(this);
}
@@ -931,6 +950,9 @@ fs_visitor::emit(fs_inst inst)
fs_inst *list_inst = new(mem_ctx) fs_inst;
*list_inst = inst;
+ list_inst->annotation = this->current_annotation;
+ list_inst->ir = this->base_ir;
+
this->instructions.push_tail(list_inst);
return list_inst;
@@ -984,7 +1006,7 @@ fs_visitor::emit_interpolation()
*/
fs_reg src_reg = reg_undef;
- /* Compute the pixel centers. */
+ this->current_annotation = "compute pixel centers";
this->pixel_x = fs_reg(this, glsl_type::uint_type);
this->pixel_y = fs_reg(this, glsl_type::uint_type);
emit(fs_inst(BRW_OPCODE_ADD,
@@ -996,7 +1018,7 @@ fs_visitor::emit_interpolation()
fs_reg(stride(suboffset(g1_uw, 5), 2, 4, 0)),
fs_reg(brw_imm_v(0x11001100))));
- /* Compute the offsets from vertex 0 to the pixel centers */
+ this->current_annotation = "compute pixel deltas from v0";
this->delta_x = fs_reg(this, glsl_type::float_type);
this->delta_y = fs_reg(this, glsl_type::float_type);
emit(fs_inst(BRW_OPCODE_ADD,
@@ -1008,6 +1030,7 @@ fs_visitor::emit_interpolation()
this->pixel_y,
fs_reg(brw_vec1_grf(1, 1))));
+ this->current_annotation = "compute pos.w and 1/pos.w";
/* Compute wpos. Unlike many other varying inputs, we usually need it
* to produce 1/w, and the varying variable wouldn't show up.
*/
@@ -1042,8 +1065,14 @@ fs_visitor::emit_interpolation()
if (var->location == 0)
continue;
+ this->current_annotation = talloc_asprintf(this->mem_ctx,
+ "interpolate %s "
+ "(FRAG_ATTRIB[%d])",
+ var->name,
+ var->location);
emit_pinterp(var->location);
}
+ this->current_annotation = NULL;
}
void
@@ -1075,6 +1104,8 @@ fs_visitor::emit_pinterp(int location)
void
fs_visitor::emit_fb_writes()
{
+ this->current_annotation = "FB write";
+
assert(this->frag_color || !"FINISHME: MRT");
fs_reg color = *(variable_storage(this->frag_color));
@@ -1088,6 +1119,8 @@ fs_visitor::emit_fb_writes()
emit(fs_inst(FS_OPCODE_FB_WRITE,
fs_reg(0),
fs_reg(0)));
+
+ this->current_annotation = NULL;
}
void
@@ -1306,6 +1339,9 @@ static struct brw_reg brw_reg_from_fs_reg(fs_reg *reg)
void
fs_visitor::generate_code()
{
+ unsigned int annotation_len = 0;
+ int last_native_inst = 0;
+
foreach_iter(exec_list_iterator, iter, this->instructions) {
fs_inst *inst = (fs_inst *)iter.get();
struct brw_reg src[3], dst;
@@ -1347,6 +1383,27 @@ fs_visitor::generate_code()
default:
assert(!"not reached");
}
+
+ if (annotation_len < p->nr_insn) {
+ annotation_len *= 2;
+ if (annotation_len < 16)
+ annotation_len = 16;
+
+ this->annotation_string = talloc_realloc(this->mem_ctx,
+ annotation_string,
+ const char *,
+ annotation_len);
+ this->annotation_ir = talloc_realloc(this->mem_ctx,
+ annotation_ir,
+ ir_instruction *,
+ annotation_len);
+ }
+
+ for (unsigned int i = last_native_inst; i < p->nr_insn; i++) {
+ this->annotation_string[i] = inst->annotation;
+ this->annotation_ir[i] = inst->ir;
+ }
+ last_native_inst = p->nr_insn;
}
}
@@ -1400,7 +1457,11 @@ brw_wm_fs_emit(struct brw_context *brw, struct brw_wm_compile *c)
/* Generate FS IR for main(). (the visitor only descends into
* functions called "main").
*/
- visit_exec_list(shader->ir, &v);
+ foreach_iter(exec_list_iterator, iter, *shader->ir) {
+ ir_instruction *ir = (ir_instruction *)iter.get();
+ v.base_ir = ir;
+ ir->accept(&v);
+ }
if (v.fail)
return GL_FALSE;
@@ -1413,9 +1474,26 @@ brw_wm_fs_emit(struct brw_context *brw, struct brw_wm_compile *c)
v.generate_code();
if (INTEL_DEBUG & DEBUG_WM) {
+ const char *last_annotation_string = NULL;
+ ir_instruction *last_annotation_ir = NULL;
+
printf("Native code for fragment shader %d:\n", prog->Name);
- for (unsigned int i = 0; i < p->nr_insn; i++)
+ for (unsigned int i = 0; i < p->nr_insn; i++) {
+ if (last_annotation_ir != v.annotation_ir[i]) {
+ last_annotation_ir = v.annotation_ir[i];
+ if (last_annotation_ir) {
+ printf(" ");
+ last_annotation_ir->print();
+ printf("\n");
+ }
+ }
+ if (last_annotation_string != v.annotation_string[i]) {
+ last_annotation_string = v.annotation_string[i];
+ if (last_annotation_string)
+ printf(" %s\n", last_annotation_string);
+ }
brw_disasm(stdout, &p->store[i], intel->gen);
+ }
printf("\n");
}