From 338b5f887d462bbe7ef58a233cd00619e43415f0 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 10 Dec 2012 09:21:34 -0800 Subject: [PATCH] i965: Adjust the split between shader_time_end() and shader_time_write(). I'm about to emit other kinds of writes besides time deltas, and it turns out with the frequency of resets, we couldn't really use the old time delta write() function more than once in a shader. --- src/mesa/drivers/dri/i965/brw_fs.cpp | 57 ++++++++++++++------------ src/mesa/drivers/dri/i965/brw_fs.h | 2 +- src/mesa/drivers/dri/i965/brw_vec4.cpp | 53 ++++++++++++------------ src/mesa/drivers/dri/i965/brw_vec4.h | 2 +- 4 files changed, 59 insertions(+), 55 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index ac0bb56ad7d..2f4c6691ee8 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -513,12 +513,39 @@ fs_visitor::emit_shader_time_end() type = ST_FS16; } - emit_shader_time_write(type, shader_start_time, get_timestamp()); + fs_reg shader_end_time = get_timestamp(); + + /* Check that there weren't any timestamp reset events (assuming these + * were the only two timestamp reads that happened). + */ + fs_reg reset = shader_end_time; + reset.smear = 2; + fs_inst *test = emit(AND(reg_null_d, reset, fs_reg(1u))); + test->conditional_mod = BRW_CONDITIONAL_Z; + emit(IF(BRW_PREDICATE_NORMAL)); + + push_force_uncompressed(); + fs_reg start = shader_start_time; + start.negate = true; + fs_reg diff = fs_reg(this, glsl_type::uint_type); + emit(ADD(diff, start, shader_end_time)); + + /* If there were no instructions between the two timestamp gets, the diff + * is 2 cycles. Remove that overhead, so I can forget about that when + * trying to determine the time taken for single instructions. + */ + emit(ADD(diff, diff, fs_reg(-2u))); + + emit_shader_time_write(type, diff); + + emit(BRW_OPCODE_ENDIF); + + pop_force_uncompressed(); } void fs_visitor::emit_shader_time_write(enum shader_time_shader_type type, - fs_reg start, fs_reg end) + fs_reg value) { /* Choose an index in the buffer and set up tracking information for our * printouts. @@ -532,26 +559,6 @@ fs_visitor::emit_shader_time_write(enum shader_time_shader_type type, prog); } - /* Check that there weren't any timestamp reset events (assuming these - * were the only two timestamp reads that happened). - */ - fs_reg reset = end; - reset.smear = 2; - fs_inst *test = emit(AND(reg_null_d, reset, fs_reg(1u))); - test->conditional_mod = BRW_CONDITIONAL_Z; - emit(IF(BRW_PREDICATE_NORMAL)); - - push_force_uncompressed(); - start.negate = true; - fs_reg diff = fs_reg(this, glsl_type::uint_type); - emit(ADD(diff, start, end)); - - /* If there were no instructions between the two timestamp gets, the diff - * is 2 cycles. Remove that overhead, so I can forget about that when - * trying to determine the time taken for single instructions. - */ - emit(ADD(diff, diff, fs_reg(-2u))); - int base_mrf = 6; fs_reg offset_mrf = fs_reg(MRF, base_mrf); @@ -560,15 +567,11 @@ fs_visitor::emit_shader_time_write(enum shader_time_shader_type type, fs_reg time_mrf = fs_reg(MRF, base_mrf + 1); time_mrf.type = BRW_REGISTER_TYPE_UD; - emit(MOV(time_mrf, diff)); + emit(MOV(time_mrf, value)); fs_inst *inst = emit(fs_inst(SHADER_OPCODE_SHADER_TIME_ADD)); inst->base_mrf = base_mrf; inst->mlen = 2; - - pop_force_uncompressed(); - - emit(BRW_OPCODE_ENDIF); } void diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index d4ddb478fd2..6caf7c337ea 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -392,7 +392,7 @@ public: void emit_shader_time_begin(); void emit_shader_time_end(); void emit_shader_time_write(enum shader_time_shader_type type, - fs_reg start, fs_reg end); + fs_reg value); bool try_rewrite_rhs_to_dst(ir_assignment *ir, fs_reg dst, diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp index dc9d9d5d1a5..28199dde80e 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp @@ -1081,12 +1081,36 @@ vec4_visitor::emit_shader_time_end() current_annotation = "shader time end"; src_reg shader_end_time = get_timestamp(); - emit_shader_time_write(ST_VS, shader_start_time, shader_end_time); + + /* Check that there weren't any timestamp reset events (assuming these + * were the only two timestamp reads that happened). + */ + src_reg reset_end = shader_end_time; + reset_end.swizzle = BRW_SWIZZLE_ZZZZ; + vec4_instruction *test = emit(AND(dst_null_d(), reset_end, src_reg(1u))); + test->conditional_mod = BRW_CONDITIONAL_Z; + + emit(IF(BRW_PREDICATE_NORMAL)); + + /* Take the current timestamp and get the delta. */ + shader_start_time.negate = true; + dst_reg diff = dst_reg(this, glsl_type::uint_type); + emit(ADD(diff, shader_start_time, shader_end_time)); + + /* If there were no instructions between the two timestamp gets, the diff + * is 2 cycles. Remove that overhead, so I can forget about that when + * trying to determine the time taken for single instructions. + */ + emit(ADD(diff, src_reg(diff), src_reg(-2u))); + + emit_shader_time_write(ST_VS, src_reg(diff)); + + emit(BRW_OPCODE_ENDIF); } void vec4_visitor::emit_shader_time_write(enum shader_time_shader_type type, - src_reg start, src_reg end) + src_reg value) { /* Choose an index in the buffer and set up tracking information for our * printouts. @@ -1100,27 +1124,6 @@ vec4_visitor::emit_shader_time_write(enum shader_time_shader_type type, prog); } - /* Check that there weren't any timestamp reset events (assuming these - * were the only two timestamp reads that happened). - */ - src_reg reset_end = end; - reset_end.swizzle = BRW_SWIZZLE_ZZZZ; - vec4_instruction *test = emit(AND(dst_null_d(), reset_end, src_reg(1u))); - test->conditional_mod = BRW_CONDITIONAL_Z; - - emit(IF(BRW_PREDICATE_NORMAL)); - - /* Take the current timestamp and get the delta. */ - start.negate = true; - dst_reg diff = dst_reg(this, glsl_type::uint_type); - emit(ADD(diff, start, end)); - - /* If there were no instructions between the two timestamp gets, the diff - * is 2 cycles. Remove that overhead, so I can forget about that when - * trying to determine the time taken for single instructions. - */ - emit(ADD(diff, src_reg(diff), src_reg(-2u))); - int base_mrf = 6; dst_reg offset_mrf = dst_reg(MRF, base_mrf); @@ -1129,14 +1132,12 @@ vec4_visitor::emit_shader_time_write(enum shader_time_shader_type type, dst_reg time_mrf = dst_reg(MRF, base_mrf + 1); time_mrf.type = BRW_REGISTER_TYPE_UD; - emit(MOV(time_mrf, src_reg(diff))); + emit(MOV(time_mrf, src_reg(value))); vec4_instruction *inst; inst = emit(SHADER_OPCODE_SHADER_TIME_ADD); inst->base_mrf = base_mrf; inst->mlen = 2; - - emit(BRW_OPCODE_ENDIF); } bool diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h index 91d9545559c..92d7bfd4cb3 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4.h +++ b/src/mesa/drivers/dri/i965/brw_vec4.h @@ -439,7 +439,7 @@ public: void emit_shader_time_begin(); void emit_shader_time_end(); void emit_shader_time_write(enum shader_time_shader_type type, - src_reg start, src_reg end); + src_reg value); src_reg get_scratch_offset(vec4_instruction *inst, src_reg *reladdr, int reg_offset);