Module: Mesa Branch: master Commit: 4a269a8dc0170c75ff22af3910786228727ea41e URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=4a269a8dc0170c75ff22af3910786228727ea41e
Author: Tom Stellard <thomas.stell...@amd.com> Date: Thu Apr 12 22:07:40 2012 -0400 r300/compiler: Clear loop registers in vertex shaders w/o loops The loop registers weren't being cleared, so any shader that was executed after a shader containing loops was at risk of having a loop randomly inserted into it. This fixes over one hundred piglit tests, although these test only failed during full piglit runs and would pass if run individually. The exact number of piglit tests that this patch fixes will vary depending on the version of piglit and the order the tests are run. NOTE: This is a candidate for the stable branches. --- src/gallium/drivers/r300/r300_emit.c | 24 +++++++++++------------- src/gallium/drivers/r300/r300_state.c | 5 ++--- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 3897e99..e4afe78 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -1030,20 +1030,18 @@ void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state) R300_PVS_VF_MAX_VTX_NUM(12) | (r300screen->caps.is_r500 ? R500_TCL_STATE_OPTIMIZATION : 0)); - /* Emit flow control instructions. */ - if (code->num_fc_ops) { - - OUT_CS_REG(R300_VAP_PVS_FLOW_CNTL_OPC, code->fc_ops); - if (r300screen->caps.is_r500) { - OUT_CS_REG_SEQ(R500_VAP_PVS_FLOW_CNTL_ADDRS_LW_0, code->num_fc_ops * 2); - OUT_CS_TABLE(code->fc_op_addrs.r500, code->num_fc_ops * 2); - } else { - OUT_CS_REG_SEQ(R300_VAP_PVS_FLOW_CNTL_ADDRS_0, code->num_fc_ops); - OUT_CS_TABLE(code->fc_op_addrs.r300, code->num_fc_ops); - } - OUT_CS_REG_SEQ(R300_VAP_PVS_FLOW_CNTL_LOOP_INDEX_0, code->num_fc_ops); - OUT_CS_TABLE(code->fc_loop_index, code->num_fc_ops); + /* Emit flow control instructions. Even if there are no fc instructions, + * we still need to write the registers to make sure they are cleared. */ + OUT_CS_REG(R300_VAP_PVS_FLOW_CNTL_OPC, code->fc_ops); + if (r300screen->caps.is_r500) { + OUT_CS_REG_SEQ(R500_VAP_PVS_FLOW_CNTL_ADDRS_LW_0, R300_VS_MAX_FC_OPS * 2); + OUT_CS_TABLE(code->fc_op_addrs.r500, R300_VS_MAX_FC_OPS * 2); + } else { + OUT_CS_REG_SEQ(R300_VAP_PVS_FLOW_CNTL_ADDRS_0, R300_VS_MAX_FC_OPS); + OUT_CS_TABLE(code->fc_op_addrs.r300, R300_VS_MAX_FC_OPS); } + OUT_CS_REG_SEQ(R300_VAP_PVS_FLOW_CNTL_LOOP_INDEX_0, R300_VS_MAX_FC_OPS); + OUT_CS_TABLE(code->fc_loop_index, R300_VS_MAX_FC_OPS); END_CS; } diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 4101523..10625b4 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -1796,9 +1796,8 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader) if (r300->screen->caps.has_tcl) { unsigned fc_op_dwords = r300->screen->caps.is_r500 ? 3 : 2; r300_mark_atom_dirty(r300, &r300->vs_state); - r300->vs_state.size = - vs->code.length + 9 + - (vs->code.num_fc_ops ? vs->code.num_fc_ops * fc_op_dwords + 4 : 0); + r300->vs_state.size = vs->code.length + 9 + + (R300_VS_MAX_FC_OPS * fc_op_dwords + 4); r300_mark_atom_dirty(r300, &r300->vs_constants); r300->vs_constants.size = _______________________________________________ mesa-commit mailing list mesa-commit@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-commit