summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2012-12-10 09:44:19 -0800
committerEric Anholt <[email protected]>2012-12-14 15:05:10 -0800
commitf74560f3fb516971e6a7b03a2382db2f58699f59 (patch)
tree45c28d454046d7d7dc9ec50f29ca39b47a95ba5a
parent338b5f887d462bbe7ef58a233cd00619e43415f0 (diff)
i965: Scale shader_time to compensate for resets.
Some shaders experience resets more than others, which skews the numbers reported. Attempt to correct for this by linearly scaling according to the number of resets that happen. Note that will not be accurate if invocations of shaders have varying times and longer invocations are more likely to reset. However, this should at least be better than the previous situation.
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.h6
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp10
-rw-r--r--src/mesa/drivers/dri/i965/brw_program.c72
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4.cpp4
4 files changed, 83 insertions, 9 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index dc25cabcf53..eba9eb59016 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -655,8 +655,14 @@ struct brw_tracked_state {
enum shader_time_shader_type {
ST_NONE,
ST_VS,
+ ST_VS_WRITTEN,
+ ST_VS_RESET,
ST_FS8,
+ ST_FS8_WRITTEN,
+ ST_FS8_RESET,
ST_FS16,
+ ST_FS16_WRITTEN,
+ ST_FS16_RESET,
};
/* Flags for brw->state.cache.
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 2f4c6691ee8..f428a83d212 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -505,12 +505,16 @@ fs_visitor::emit_shader_time_end()
{
current_annotation = "shader time end";
- enum shader_time_shader_type type;
+ enum shader_time_shader_type type, written_type, reset_type;
if (dispatch_width == 8) {
type = ST_FS8;
+ written_type = ST_FS8_WRITTEN;
+ reset_type = ST_FS8_RESET;
} else {
assert(dispatch_width == 16);
type = ST_FS16;
+ written_type = ST_FS16_WRITTEN;
+ reset_type = ST_FS16_RESET;
}
fs_reg shader_end_time = get_timestamp();
@@ -537,7 +541,9 @@ fs_visitor::emit_shader_time_end()
emit(ADD(diff, diff, fs_reg(-2u)));
emit_shader_time_write(type, diff);
-
+ emit_shader_time_write(written_type, fs_reg(1u));
+ emit(BRW_OPCODE_ELSE);
+ emit_shader_time_write(reset_type, fs_reg(1u));
emit(BRW_OPCODE_ENDIF);
pop_force_uncompressed();
diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c
index 1859041bc27..035824171e3 100644
--- a/src/mesa/drivers/dri/i965/brw_program.c
+++ b/src/mesa/drivers/dri/i965/brw_program.c
@@ -222,16 +222,73 @@ compare_time(const void *a, const void *b)
}
static void
+get_written_and_reset(struct brw_context *brw, int i,
+ uint64_t *written, uint64_t *reset)
+{
+ enum shader_time_shader_type type = brw->shader_time.types[i];
+ assert(type == ST_VS || type == ST_FS8 || type == ST_FS16);
+
+ /* Find where we recorded written and reset. */
+ int wi, ri;
+
+ for (wi = i; brw->shader_time.types[wi] != type + 1; wi++)
+ ;
+
+ for (ri = i; brw->shader_time.types[ri] != type + 2; ri++)
+ ;
+
+ *written = brw->shader_time.cumulative[wi];
+ *reset = brw->shader_time.cumulative[ri];
+}
+
+static void
brw_report_shader_time(struct brw_context *brw)
{
if (!brw->shader_time.bo || !brw->shader_time.num_entries)
return;
+ uint64_t scaled[brw->shader_time.num_entries];
uint64_t *sorted[brw->shader_time.num_entries];
double total = 0;
for (int i = 0; i < brw->shader_time.num_entries; i++) {
- sorted[i] = &brw->shader_time.cumulative[i];
- total += brw->shader_time.cumulative[i];
+ uint64_t written = 0, reset = 0;
+
+ sorted[i] = &scaled[i];
+
+ switch (brw->shader_time.types[i]) {
+ case ST_VS_WRITTEN:
+ case ST_VS_RESET:
+ case ST_FS8_WRITTEN:
+ case ST_FS8_RESET:
+ case ST_FS16_WRITTEN:
+ case ST_FS16_RESET:
+ /* We'll handle these when along with the time. */
+ scaled[i] = 0;
+ continue;
+
+ case ST_VS:
+ case ST_FS8:
+ case ST_FS16:
+ get_written_and_reset(brw, i, &written, &reset);
+ break;
+
+ default:
+ /* I sometimes want to print things that aren't the 3 shader times.
+ * Just print the sum in that case.
+ */
+ written = 1;
+ reset = 0;
+ break;
+ }
+
+ uint64_t time = brw->shader_time.cumulative[i];
+ if (written) {
+ scaled[i] = time / written * (written + reset);
+ } else {
+ scaled[i] = time;
+ }
+
+ total += scaled[i];
}
if (total == 0) {
@@ -245,7 +302,10 @@ brw_report_shader_time(struct brw_context *brw)
printf("type ID cycles spent %% of total\n");
for (int s = 0; s < brw->shader_time.num_entries; s++) {
/* Work back from the sorted pointers times to a time to print. */
- int i = sorted[s] - brw->shader_time.cumulative;
+ int i = sorted[s] - scaled;
+
+ if (scaled[i] == 0)
+ continue;
int shader_num = -1;
if (brw->shader_time.programs[i]) {
@@ -268,9 +328,9 @@ brw_report_shader_time(struct brw_context *brw)
}
printf("%16lld (%7.2f Gcycles) %4.1f%%\n",
- (long long)brw->shader_time.cumulative[i],
- (double)brw->shader_time.cumulative[i] / 1000000000.0,
- (double)brw->shader_time.cumulative[i] / total * 100.0);
+ (long long)scaled[i],
+ (double)scaled[i] / 1000000000.0,
+ (double)scaled[i] / total * 100.0);
}
}
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp
index 28199dde80e..436ba97e147 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp
@@ -1104,7 +1104,9 @@ vec4_visitor::emit_shader_time_end()
emit(ADD(diff, src_reg(diff), src_reg(-2u)));
emit_shader_time_write(ST_VS, src_reg(diff));
-
+ emit_shader_time_write(ST_VS_WRITTEN, src_reg(1u));
+ emit(BRW_OPCODE_ELSE);
+ emit_shader_time_write(ST_VS_RESET, src_reg(1u));
emit(BRW_OPCODE_ENDIF);
}