Mesa (master): r600g: track dirty registers better. (v2)

Dave Airlie airlied at kemper.freedesktop.org
Mon Apr 18 17:06:56 PDT 2011


Module: Mesa
Branch: master
Commit: 352543881375349d9b30ec62053acfbf00f3499b
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=352543881375349d9b30ec62053acfbf00f3499b

Author: Dave Airlie <airlied at redhat.com>
Date:   Sun Apr 17 17:35:44 2011 +1000

r600g: track dirty registers better. (v2)

This is a first step to decreasing the CPU usage, by decreasing how much
stuff we pass to the GPU and hence to the kernel CS checker.

This adds a check to see if the values we need to write are actually dirty,
and avoids writing if they are. However certain register need to always
be written so we add a new flag to say which ones should be always written
if used. (Note this could probably be done cleaner with a larger refactoring,
 since I think the CONST_BUFFER_SIZE_PS/VS and CONST_CACHE_PS/VS might
be better off as a special state).

It also moves the need_bo to be a flags on the register now.

With this, a frame of gears goes from emitting 3k dwords to emitting 2k dwords,
and I'm sure it could get a lot smaller.

v2: fix some evergreen dirty bits.

Original patch from: Bas Nieuwenhuizen, I NIHed nearly the same thing
before seeing his patch on the list, oops.

Reviewed-by: Bas Nieuwenhuizen
Signed-off-by: Dave Airlie <airlied at redhat.com>

---

 src/gallium/drivers/r600/r600.h                    |    1 +
 src/gallium/winsys/r600/drm/evergreen_hw_context.c |  136 ++++++++++--------
 src/gallium/winsys/r600/drm/r600_hw_context.c      |  145 ++++++++++++--------
 src/gallium/winsys/r600/drm/r600_priv.h            |   10 +-
 4 files changed, 171 insertions(+), 121 deletions(-)

diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h
index 4256a7e..d605000 100644
--- a/src/gallium/drivers/r600/r600.h
+++ b/src/gallium/drivers/r600/r600.h
@@ -179,6 +179,7 @@ struct r600_block_reloc {
 struct r600_block {
 	struct list_head	list;
 	unsigned		status;
+	unsigned                flags;
 	unsigned		start_offset;
 	unsigned		pm4_ndwords;
 	unsigned		pm4_flush_ndwords;
diff --git a/src/gallium/winsys/r600/drm/evergreen_hw_context.c b/src/gallium/winsys/r600/drm/evergreen_hw_context.c
index d914836..b287ed5 100644
--- a/src/gallium/winsys/r600/drm/evergreen_hw_context.c
+++ b/src/gallium/winsys/r600/drm/evergreen_hw_context.c
@@ -69,29 +69,29 @@ static const struct r600_reg evergreen_context_reg_list[] = {
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_02800C_DB_RENDER_OVERRIDE, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028010_DB_RENDER_OVERRIDE2, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028014_DB_HTILE_DATA_BASE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028014_DB_HTILE_DATA_BASE, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028028_DB_STENCIL_CLEAR, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_02802C_DB_DEPTH_CLEAR, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028030_PA_SC_SCREEN_SCISSOR_TL, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028034_PA_SC_SCREEN_SCISSOR_BR, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028040_DB_Z_INFO, 1, 0, 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028040_DB_Z_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028044_DB_STENCIL_INFO, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028048_DB_Z_READ_BASE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028048_DB_Z_READ_BASE, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_02804C_DB_STENCIL_READ_BASE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_02804C_DB_STENCIL_READ_BASE, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028050_DB_Z_WRITE_BASE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028050_DB_Z_WRITE_BASE, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028054_DB_STENCIL_WRITE_BASE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028054_DB_STENCIL_WRITE_BASE, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028058_DB_DEPTH_SIZE, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_02805C_DB_DEPTH_SLICE, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028140_ALU_CONST_BUFFER_SIZE_PS_0, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028180_ALU_CONST_BUFFER_SIZE_VS_0, 0, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028140_ALU_CONST_BUFFER_SIZE_PS_0, REG_FLAG_DIRTY_ALWAYS, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028180_ALU_CONST_BUFFER_SIZE_VS_0, REG_FLAG_DIRTY_ALWAYS, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028200_PA_SC_WINDOW_OFFSET, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028204_PA_SC_WINDOW_SCISSOR_TL, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028208_PA_SC_WINDOW_SCISSOR_BR, 0, 0, 0},
@@ -258,14 +258,14 @@ static const struct r600_reg evergreen_context_reg_list[] = {
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_02881C_PA_CL_VS_OUT_CNTL, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028820_PA_CL_NANINF_CNTL, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028838_SQ_DYN_GPR_RESOURCE_LIMIT_1, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028840_SQ_PGM_START_PS, 1, S_0085F0_SH_ACTION_ENA(1), 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028840_SQ_PGM_START_PS, REG_FLAG_NEED_BO, S_0085F0_SH_ACTION_ENA(1), 0xFFFFFFFF},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028844_SQ_PGM_RESOURCES_PS, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028848_SQ_PGM_RESOURCES_2_PS, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_02884C_SQ_PGM_EXPORTS_PS, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_02885C_SQ_PGM_START_VS, 1, S_0085F0_SH_ACTION_ENA(1), 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_02885C_SQ_PGM_START_VS, REG_FLAG_NEED_BO, S_0085F0_SH_ACTION_ENA(1), 0xFFFFFFFF},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028860_SQ_PGM_RESOURCES_VS, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028864_SQ_PGM_RESOURCES_2_VS, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_0288A4_SQ_PGM_START_FS, 1, S_0085F0_SH_ACTION_ENA(1), 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_0288A4_SQ_PGM_START_FS, REG_FLAG_NEED_BO, S_0085F0_SH_ACTION_ENA(1), 0xFFFFFFFF},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_0288A8_SQ_PGM_RESOURCES_FS, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_0288EC_SQ_LDS_ALLOC_PS, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028900_SQ_ESGS_RING_ITEMSIZE, 0, 0, 0},
@@ -278,8 +278,8 @@ static const struct r600_reg evergreen_context_reg_list[] = {
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028920_SQ_GS_VERT_ITEMSIZE_1, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028924_SQ_GS_VERT_ITEMSIZE_2, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028928_SQ_GS_VERT_ITEMSIZE_3, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028940_ALU_CONST_CACHE_PS_0, 1, S_0085F0_SH_ACTION_ENA(1), 0xFFFFFFFF},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028980_ALU_CONST_CACHE_VS_0, 1, S_0085F0_SH_ACTION_ENA(1), 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028940_ALU_CONST_CACHE_PS_0, REG_FLAG_NEED_BO, S_0085F0_SH_ACTION_ENA(1), 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028980_ALU_CONST_CACHE_VS_0, REG_FLAG_NEED_BO, S_0085F0_SH_ACTION_ENA(1), 0xFFFFFFFF},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028A00_PA_SU_POINT_SIZE, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028A04_PA_SU_POINT_MINMAX, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028A08_PA_SU_LINE_CNTL, 0, 0, 0},
@@ -324,100 +324,100 @@ static const struct r600_reg evergreen_context_reg_list[] = {
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028C1C_PA_SC_AA_SAMPLE_LOCS_MCTX, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028C3C_PA_SC_AA_MASK, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028C60_CB_COLOR0_BASE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028C60_CB_COLOR0_BASE, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028C64_CB_COLOR0_PITCH, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028C68_CB_COLOR0_SLICE, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028C6C_CB_COLOR0_VIEW, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028C70_CB_COLOR0_INFO, 1, 0, 0xFFFFFFFF},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028C74_CB_COLOR0_ATTRIB, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028C70_CB_COLOR0_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028C74_CB_COLOR0_ATTRIB, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028C78_CB_COLOR0_DIM, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028C9C_CB_COLOR1_BASE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028C9C_CB_COLOR1_BASE, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028CA0_CB_COLOR1_PITCH, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028CA4_CB_COLOR1_SLICE, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028CA8_CB_COLOR1_VIEW, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028CAC_CB_COLOR1_INFO, 1, 0, 0xFFFFFFFF},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028CB0_CB_COLOR1_ATTRIB, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028CAC_CB_COLOR1_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028CB0_CB_COLOR1_ATTRIB, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028CB4_CB_COLOR1_DIM, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028CD8_CB_COLOR2_BASE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028CD8_CB_COLOR2_BASE, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028CDC_CB_COLOR2_PITCH, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028CE0_CB_COLOR2_SLICE, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028CE4_CB_COLOR2_VIEW, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028CE8_CB_COLOR2_INFO, 1, 0, 0xFFFFFFFF},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028CEC_CB_COLOR2_ATTRIB, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028CE8_CB_COLOR2_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028CEC_CB_COLOR2_ATTRIB, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028CF0_CB_COLOR2_DIM, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028D14_CB_COLOR3_BASE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028D14_CB_COLOR3_BASE, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028D18_CB_COLOR3_PITCH, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028D1C_CB_COLOR3_SLICE, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028D20_CB_COLOR3_VIEW, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028D24_CB_COLOR3_INFO, 1, 0, 0xFFFFFFFF},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028D28_CB_COLOR3_ATTRIB, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028D24_CB_COLOR3_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028D28_CB_COLOR3_ATTRIB, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028D2C_CB_COLOR3_DIM, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028D50_CB_COLOR4_BASE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028D50_CB_COLOR4_BASE, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028D54_CB_COLOR4_PITCH, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028D58_CB_COLOR4_SLICE, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028D5C_CB_COLOR4_VIEW, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028D60_CB_COLOR4_INFO, 1, 0, 0xFFFFFFFF},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028D64_CB_COLOR4_ATTRIB, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028D60_CB_COLOR4_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028D64_CB_COLOR4_ATTRIB, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028D68_CB_COLOR4_DIM, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028D8C_CB_COLOR5_BASE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028D8C_CB_COLOR5_BASE, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028D90_CB_COLOR5_PITCH, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028D94_CB_COLOR5_SLICE, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028D98_CB_COLOR5_VIEW, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028D9C_CB_COLOR5_INFO, 1, 0, 0xFFFFFFFF},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028DA0_CB_COLOR5_ATTRIB, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028D9C_CB_COLOR5_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028DA0_CB_COLOR5_ATTRIB, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028DA4_CB_COLOR5_DIM, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028DC8_CB_COLOR6_BASE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028DC8_CB_COLOR6_BASE, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028DCC_CB_COLOR6_PITCH, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028DD0_CB_COLOR6_SLICE, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028DD4_CB_COLOR6_VIEW, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028DD8_CB_COLOR6_INFO, 1, 0, 0xFFFFFFFF},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028DDC_CB_COLOR6_ATTRIB, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028DD8_CB_COLOR6_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028DDC_CB_COLOR6_ATTRIB, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028DE0_CB_COLOR6_DIM, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E04_CB_COLOR7_BASE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E04_CB_COLOR7_BASE, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E08_CB_COLOR7_PITCH, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E0C_CB_COLOR7_SLICE, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E10_CB_COLOR7_VIEW, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E14_CB_COLOR7_INFO, 1, 0, 0xFFFFFFFF},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E18_CB_COLOR7_ATTRIB, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E14_CB_COLOR7_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E18_CB_COLOR7_ATTRIB, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E1C_CB_COLOR7_DIM, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E40_CB_COLOR8_BASE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E40_CB_COLOR8_BASE, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E44_CB_COLOR8_PITCH, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E48_CB_COLOR8_SLICE, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E4C_CB_COLOR8_VIEW, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E50_CB_COLOR8_INFO, 1, 0, 0xFFFFFFFF},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E54_CB_COLOR8_ATTRIB, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E50_CB_COLOR8_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E54_CB_COLOR8_ATTRIB, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E58_CB_COLOR8_DIM, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E5C_CB_COLOR9_BASE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E5C_CB_COLOR9_BASE, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E60_CB_COLOR9_PITCH, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E64_CB_COLOR9_SLICE, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E68_CB_COLOR9_VIEW, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E6C_CB_COLOR9_INFO, 1, 0, 0xFFFFFFFF},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E70_CB_COLOR9_ATTRIB, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E6C_CB_COLOR9_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E70_CB_COLOR9_ATTRIB, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E74_CB_COLOR9_DIM, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E78_CB_COLOR10_BASE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E78_CB_COLOR10_BASE, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E7C_CB_COLOR10_PITCH, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E80_CB_COLOR10_SLICE, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E84_CB_COLOR10_VIEW, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E88_CB_COLOR10_INFO, 1, 0, 0xFFFFFFFF},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E8C_CB_COLOR10_ATTRIB, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E88_CB_COLOR10_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E8C_CB_COLOR10_ATTRIB, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E90_CB_COLOR10_DIM, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E94_CB_COLOR11_BASE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E94_CB_COLOR11_BASE, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E98_CB_COLOR11_PITCH, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028E9C_CB_COLOR11_SLICE, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028EA0_CB_COLOR11_VIEW, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028EA4_CB_COLOR11_INFO, 1, 0, 0xFFFFFFFF},
-	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028EA8_CB_COLOR11_ATTRIB, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028EA4_CB_COLOR11_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028EA8_CB_COLOR11_ATTRIB, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, EVERGREEN_CONTEXT_REG_OFFSET, R_028EAC_CB_COLOR11_DIM, 0, 0, 0},
 };
 
@@ -427,8 +427,8 @@ static int evergreen_state_resource_init(struct r600_context *ctx, u32 offset)
 	struct r600_reg r600_shader_resource[] = {
 		{PKT3_SET_RESOURCE, EVERGREEN_RESOURCE_OFFSET, R_030000_RESOURCE0_WORD0, 0, 0, 0},
 		{PKT3_SET_RESOURCE, EVERGREEN_RESOURCE_OFFSET, R_030004_RESOURCE0_WORD1, 0, 0, 0},
-		{PKT3_SET_RESOURCE, EVERGREEN_RESOURCE_OFFSET, R_030008_RESOURCE0_WORD2, 1, S_0085F0_TC_ACTION_ENA(1) | S_0085F0_VC_ACTION_ENA(1), 0xFFFFFFFF},
-		{PKT3_SET_RESOURCE, EVERGREEN_RESOURCE_OFFSET, R_03000C_RESOURCE0_WORD3, 1, S_0085F0_TC_ACTION_ENA(1) | S_0085F0_VC_ACTION_ENA(1), 0xFFFFFFFF},
+		{PKT3_SET_RESOURCE, EVERGREEN_RESOURCE_OFFSET, R_030008_RESOURCE0_WORD2, REG_FLAG_NEED_BO, S_0085F0_TC_ACTION_ENA(1) | S_0085F0_VC_ACTION_ENA(1), 0xFFFFFFFF},
+		{PKT3_SET_RESOURCE, EVERGREEN_RESOURCE_OFFSET, R_03000C_RESOURCE0_WORD3, REG_FLAG_NEED_BO, S_0085F0_TC_ACTION_ENA(1) | S_0085F0_VC_ACTION_ENA(1), 0xFFFFFFFF},
 		{PKT3_SET_RESOURCE, EVERGREEN_RESOURCE_OFFSET, R_030010_RESOURCE0_WORD4, 0, 0, 0},
 		{PKT3_SET_RESOURCE, EVERGREEN_RESOURCE_OFFSET, R_030014_RESOURCE0_WORD5, 0, 0, 0},
 		{PKT3_SET_RESOURCE, EVERGREEN_RESOURCE_OFFSET, R_030018_RESOURCE0_WORD6, 0, 0, 0},
@@ -499,7 +499,7 @@ static int evergreen_loop_const_init(struct r600_context *ctx, u32 offset)
 		r600_loop_consts[i].opcode = PKT3_SET_LOOP_CONST;
 		r600_loop_consts[i].offset_base = EVERGREEN_LOOP_CONST_OFFSET;
 		r600_loop_consts[i].offset = EVERGREEN_LOOP_CONST_OFFSET + ((offset + i) * 4);
-		r600_loop_consts[i].need_bo = 0;
+		r600_loop_consts[i].flags = 0;
 		r600_loop_consts[i].flush_flags = 0;
 	}
 	return r600_context_add_block(ctx, r600_loop_consts, nreg);
@@ -664,7 +664,7 @@ static inline void evergreen_context_pipe_state_set_resource(struct r600_context
 		r600_bo_reference(ctx->radeon, &block->reloc[1].bo, state->regs[2].bo);
 		r600_bo_reference(ctx->radeon, &block->reloc[2].bo, state->regs[3].bo);
 	}
-	r600_context_dirty_block(ctx, block);
+	r600_context_dirty_block(ctx, block, R600_BLOCK_STATUS_DIRTY);
 }
 
 void evergreen_context_pipe_state_set_ps_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid)
@@ -693,6 +693,7 @@ static inline void evergreen_context_pipe_state_set_sampler(struct r600_context
 	struct r600_range *range;
 	struct r600_block *block;
 	int i;
+	int dirty;
 
 	range = &ctx->range[CTX_RANGE_ID(ctx, offset)];
 	block = range->blocks[CTX_BLOCK_ID(ctx, offset)];
@@ -701,10 +702,16 @@ static inline void evergreen_context_pipe_state_set_sampler(struct r600_context
 		LIST_DELINIT(&block->list);
 		return;
 	}
-	for (i = 0; i < 3; i++)
-		block->reg[i] = state->regs[i].value;
+	dirty = block->status & R600_BLOCK_STATUS_DIRTY;
+
+	for (i = 0; i < 3; i++) {
+		if (block->reg[i] != state->regs[i].value) {
+			dirty |= R600_BLOCK_STATUS_DIRTY;
+			block->reg[i] = state->regs[i].value;
+		}
+	}
 
-	r600_context_dirty_block(ctx, block);
+	r600_context_dirty_block(ctx, block, dirty);
 }
 
 static inline void evergreen_context_pipe_state_set_sampler_border(struct r600_context *ctx, struct r600_pipe_state *state, unsigned offset, unsigned id)
@@ -713,6 +720,7 @@ static inline void evergreen_context_pipe_state_set_sampler_border(struct r600_c
 	struct r600_range *range;
 	struct r600_block *block;
 	int i;
+	int dirty;
 
 	range = &ctx->range[CTX_RANGE_ID(ctx, fake_offset)];
 	block = range->blocks[CTX_BLOCK_ID(ctx, fake_offset)];
@@ -724,12 +732,20 @@ static inline void evergreen_context_pipe_state_set_sampler_border(struct r600_c
 	if (state->nregs <= 3) {
 		return;
 	}
-	block->reg[0] = id;
+	dirty = block->status & R600_BLOCK_STATUS_DIRTY;
+	if (block->reg[0] != id) {
+		block->reg[0] = id;
+		dirty |= R600_BLOCK_STATUS_DIRTY;
+	}
 
-	for (i = 1; i < 5; i++)
-		block->reg[i] = state->regs[i + 2].value;
+	for (i = 1; i < 5; i++) {
+		if (block->reg[i] != state->regs[i + 2].value) {
+			block->reg[i] = state->regs[i + 2].value;
+			dirty |= R600_BLOCK_STATUS_DIRTY;
+		}
+	}
 
-	r600_context_dirty_block(ctx, block);
+	r600_context_dirty_block(ctx, block, dirty);
 }
 
 void evergreen_context_pipe_state_set_ps_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned id)
diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c b/src/gallium/winsys/r600/drm/r600_hw_context.c
index dd032ad..2d9e403 100644
--- a/src/gallium/winsys/r600/drm/r600_hw_context.c
+++ b/src/gallium/winsys/r600/drm/r600_hw_context.c
@@ -106,16 +106,21 @@ int r600_context_add_block(struct r600_context *ctx, const struct r600_reg *reg,
 		}
 
 		/* initialize block */
+		block->status |= R600_BLOCK_STATUS_DIRTY; /* dirty all blocks at start */
 		block->start_offset = reg[i].offset;
 		block->pm4[block->pm4_ndwords++] = PKT3(reg[i].opcode, n, 0);
 		block->pm4[block->pm4_ndwords++] = (block->start_offset - reg[i].offset_base) >> 2;
 		block->reg = &block->pm4[block->pm4_ndwords];
 		block->pm4_ndwords += n;
 		block->nreg = n;
+		block->flags = 0;
 		LIST_INITHEAD(&block->list);
 
 		for (j = 0; j < n; j++) {
-			if (reg[i+j].need_bo) {
+			if (reg[i+j].flags & REG_FLAG_DIRTY_ALWAYS) {
+				block->flags |= REG_FLAG_DIRTY_ALWAYS;
+			}
+			if (reg[i+j].flags & REG_FLAG_NEED_BO) {
 				block->nbo++;
 				assert(block->nbo < R600_BLOCK_MAX_BO);
 				block->pm4_bo_index[j] = block->nbo;
@@ -191,97 +196,97 @@ static const struct r600_reg r600_context_reg_list[] = {
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028028_DB_STENCIL_CLEAR, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02802C_DB_DEPTH_CLEAR, 0, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028040_CB_COLOR0_BASE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028040_CB_COLOR0_BASE, REG_FLAG_NEED_BO, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280A0_CB_COLOR0_INFO, 1, 0, 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280A0_CB_COLOR0_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028060_CB_COLOR0_SIZE, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028080_CB_COLOR0_VIEW, 0, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280E0_CB_COLOR0_FRAG, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280E0_CB_COLOR0_FRAG, REG_FLAG_NEED_BO, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280C0_CB_COLOR0_TILE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280C0_CB_COLOR0_TILE, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028100_CB_COLOR0_MASK, 0, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028044_CB_COLOR1_BASE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028044_CB_COLOR1_BASE, REG_FLAG_NEED_BO, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280A4_CB_COLOR1_INFO, 1, 0, 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280A4_CB_COLOR1_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028064_CB_COLOR1_SIZE, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028084_CB_COLOR1_VIEW, 0, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280E4_CB_COLOR1_FRAG, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280E4_CB_COLOR1_FRAG, REG_FLAG_NEED_BO, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280C4_CB_COLOR1_TILE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280C4_CB_COLOR1_TILE, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028104_CB_COLOR1_MASK, 0, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028048_CB_COLOR2_BASE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028048_CB_COLOR2_BASE, REG_FLAG_NEED_BO, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280A8_CB_COLOR2_INFO, 1, 0, 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280A8_CB_COLOR2_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028068_CB_COLOR2_SIZE, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028088_CB_COLOR2_VIEW, 0, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280E8_CB_COLOR2_FRAG, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280E8_CB_COLOR2_FRAG, REG_FLAG_NEED_BO, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280C8_CB_COLOR2_TILE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280C8_CB_COLOR2_TILE, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028108_CB_COLOR2_MASK, 0, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02804C_CB_COLOR3_BASE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02804C_CB_COLOR3_BASE, REG_FLAG_NEED_BO, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280AC_CB_COLOR3_INFO, 1, 0, 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280AC_CB_COLOR3_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02806C_CB_COLOR3_SIZE, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02808C_CB_COLOR3_VIEW, 0, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280EC_CB_COLOR3_FRAG, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280EC_CB_COLOR3_FRAG, REG_FLAG_NEED_BO, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280CC_CB_COLOR3_TILE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280CC_CB_COLOR3_TILE, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02810C_CB_COLOR3_MASK, 0, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028050_CB_COLOR4_BASE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028050_CB_COLOR4_BASE, REG_FLAG_NEED_BO, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280B0_CB_COLOR4_INFO, 1, 0, 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280B0_CB_COLOR4_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028070_CB_COLOR4_SIZE, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028090_CB_COLOR4_VIEW, 0, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280F0_CB_COLOR4_FRAG, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280F0_CB_COLOR4_FRAG, REG_FLAG_NEED_BO, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280D0_CB_COLOR4_TILE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280D0_CB_COLOR4_TILE, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028110_CB_COLOR4_MASK, 0, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028054_CB_COLOR5_BASE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028054_CB_COLOR5_BASE, REG_FLAG_NEED_BO, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280B4_CB_COLOR5_INFO, 1, 0, 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280B4_CB_COLOR5_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028074_CB_COLOR5_SIZE, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028094_CB_COLOR5_VIEW, 0, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280F4_CB_COLOR5_FRAG, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280F4_CB_COLOR5_FRAG, REG_FLAG_NEED_BO, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280D4_CB_COLOR5_TILE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280D4_CB_COLOR5_TILE, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028114_CB_COLOR5_MASK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028058_CB_COLOR6_BASE, 1, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280B8_CB_COLOR6_INFO, 1, 0, 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028058_CB_COLOR6_BASE, REG_FLAG_NEED_BO, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280B8_CB_COLOR6_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028078_CB_COLOR6_SIZE, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028098_CB_COLOR6_VIEW, 0, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280F8_CB_COLOR6_FRAG, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280F8_CB_COLOR6_FRAG, REG_FLAG_NEED_BO, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280D8_CB_COLOR6_TILE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280D8_CB_COLOR6_TILE, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028118_CB_COLOR6_MASK, 0, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02805C_CB_COLOR7_BASE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02805C_CB_COLOR7_BASE, REG_FLAG_NEED_BO, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280BC_CB_COLOR7_INFO, 1, 0, 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280BC_CB_COLOR7_INFO, REG_FLAG_NEED_BO, 0, 0xFFFFFFFF},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02807C_CB_COLOR7_SIZE, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02809C_CB_COLOR7_VIEW, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280FC_CB_COLOR7_FRAG, 1, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280DC_CB_COLOR7_TILE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280FC_CB_COLOR7_FRAG, REG_FLAG_NEED_BO, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0280DC_CB_COLOR7_TILE, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02811C_CB_COLOR7_MASK, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028120_CB_CLEAR_RED, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028124_CB_CLEAR_GREEN, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028128_CB_CLEAR_BLUE, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02812C_CB_CLEAR_ALPHA, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028140_ALU_CONST_BUFFER_SIZE_PS_0, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028180_ALU_CONST_BUFFER_SIZE_VS_0, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028940_ALU_CONST_CACHE_PS_0, 1, S_0085F0_SH_ACTION_ENA(1), 0xFFFFFFFF},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028980_ALU_CONST_CACHE_VS_0, 1, S_0085F0_SH_ACTION_ENA(1), 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028140_ALU_CONST_BUFFER_SIZE_PS_0, REG_FLAG_DIRTY_ALWAYS, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028180_ALU_CONST_BUFFER_SIZE_VS_0, REG_FLAG_DIRTY_ALWAYS, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028940_ALU_CONST_CACHE_PS_0, REG_FLAG_NEED_BO, S_0085F0_SH_ACTION_ENA(1), 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028980_ALU_CONST_CACHE_VS_0, REG_FLAG_NEED_BO, S_0085F0_SH_ACTION_ENA(1), 0xFFFFFFFF},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02823C_CB_SHADER_MASK, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028238_CB_TARGET_MASK, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028410_SX_ALPHA_TEST_CONTROL, 0, 0, 0},
@@ -321,11 +326,11 @@ static const struct r600_reg r600_context_reg_list[] = {
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028C48_PA_SC_AA_MASK, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028D2C_DB_SRESULTS_COMPARE_STATE1, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028D44_DB_ALPHA_TO_MASK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02800C_DB_DEPTH_BASE, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_02800C_DB_DEPTH_BASE, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028000_DB_DEPTH_SIZE, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028004_DB_DEPTH_VIEW, 0, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028010_DB_DEPTH_INFO, 1, 0, 0},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028010_DB_DEPTH_INFO, REG_FLAG_NEED_BO, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028D0C_DB_RENDER_CONTROL, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028D10_DB_RENDER_OVERRIDE, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028D24_DB_HTILE_SURFACE, 0, 0, 0},
@@ -449,11 +454,11 @@ static const struct r600_reg r600_context_reg_list[] = {
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028638_SPI_VS_OUT_ID_9, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0286C4_SPI_VS_OUT_CONFIG, 0, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028858_SQ_PGM_START_VS, 1, S_0085F0_SH_ACTION_ENA(1), 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028858_SQ_PGM_START_VS, REG_FLAG_NEED_BO, S_0085F0_SH_ACTION_ENA(1), 0xFFFFFFFF},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028868_SQ_PGM_RESOURCES_VS, 0, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028894_SQ_PGM_START_FS, 1, S_0085F0_SH_ACTION_ENA(1), 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028894_SQ_PGM_START_FS, REG_FLAG_NEED_BO, S_0085F0_SH_ACTION_ENA(1), 0xFFFFFFFF},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0288A4_SQ_PGM_RESOURCES_FS, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0288D0_SQ_PGM_CF_OFFSET_VS, 0, 0, 0},
@@ -494,7 +499,7 @@ static const struct r600_reg r600_context_reg_list[] = {
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0286D0_SPI_PS_IN_CONTROL_1, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_0286D8_SPI_INPUT_Z, 0, 0, 0},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
-	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028840_SQ_PGM_START_PS, 1, S_0085F0_SH_ACTION_ENA(1), 0xFFFFFFFF},
+	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028840_SQ_PGM_START_PS, REG_FLAG_NEED_BO, S_0085F0_SH_ACTION_ENA(1), 0xFFFFFFFF},
 	{0, 0, GROUP_FORCE_NEW_BLOCK, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028850_SQ_PGM_RESOURCES_PS, 0, 0, 0},
 	{PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028854_SQ_PGM_EXPORTS_PS, 0, 0, 0},
@@ -515,8 +520,8 @@ static int r600_state_resource_init(struct r600_context *ctx, u32 offset)
 	struct r600_reg r600_shader_resource[] = {
 		{PKT3_SET_RESOURCE, R600_RESOURCE_OFFSET, R_038000_RESOURCE0_WORD0, 0, 0, 0},
 		{PKT3_SET_RESOURCE, R600_RESOURCE_OFFSET, R_038004_RESOURCE0_WORD1, 0, 0, 0},
-		{PKT3_SET_RESOURCE, R600_RESOURCE_OFFSET, R_038008_RESOURCE0_WORD2, 1, S_0085F0_TC_ACTION_ENA(1) | S_0085F0_VC_ACTION_ENA(1), 0xFFFFFFFF},
-		{PKT3_SET_RESOURCE, R600_RESOURCE_OFFSET, R_03800C_RESOURCE0_WORD3, 1, S_0085F0_TC_ACTION_ENA(1) | S_0085F0_VC_ACTION_ENA(1), 0xFFFFFFFF},
+		{PKT3_SET_RESOURCE, R600_RESOURCE_OFFSET, R_038008_RESOURCE0_WORD2, REG_FLAG_NEED_BO, S_0085F0_TC_ACTION_ENA(1) | S_0085F0_VC_ACTION_ENA(1), 0xFFFFFFFF},
+		{PKT3_SET_RESOURCE, R600_RESOURCE_OFFSET, R_03800C_RESOURCE0_WORD3, REG_FLAG_NEED_BO, S_0085F0_TC_ACTION_ENA(1) | S_0085F0_VC_ACTION_ENA(1), 0xFFFFFFFF},
 		{PKT3_SET_RESOURCE, R600_RESOURCE_OFFSET, R_038010_RESOURCE0_WORD4, 0, 0, 0},
 		{PKT3_SET_RESOURCE, R600_RESOURCE_OFFSET, R_038014_RESOURCE0_WORD5, 0, 0, 0},
 		{PKT3_SET_RESOURCE, R600_RESOURCE_OFFSET, R_038018_RESOURCE0_WORD6, 0, 0, 0},
@@ -572,7 +577,7 @@ static int r600_loop_const_init(struct r600_context *ctx, u32 offset)
 		r600_loop_consts[i].opcode = PKT3_SET_LOOP_CONST;
 		r600_loop_consts[i].offset_base = R600_LOOP_CONST_OFFSET;
 		r600_loop_consts[i].offset = R600_LOOP_CONST_OFFSET + ((offset + i) * 4);
-		r600_loop_consts[i].need_bo = 0;
+		r600_loop_consts[i].flags = 0;
 		r600_loop_consts[i].flush_flags = 0;
 		r600_loop_consts[i].flush_mask = 0;
 	}
@@ -836,22 +841,36 @@ void r600_context_pipe_state_set(struct r600_context *ctx, struct r600_pipe_stat
 {
 	struct r600_range *range;
 	struct r600_block *block;
-
+	unsigned new_val;
+	int dirty;
 	for (int i = 0; i < state->nregs; i++) {
 		unsigned id;
 
 		range = &ctx->range[CTX_RANGE_ID(ctx, state->regs[i].offset)];
 		block = range->blocks[CTX_BLOCK_ID(ctx, state->regs[i].offset)];
 		id = (state->regs[i].offset - block->start_offset) >> 2;
-		block->reg[id] &= ~state->regs[i].mask;
-		block->reg[id] |= state->regs[i].value;
+
+		dirty = block->status & R600_BLOCK_STATUS_DIRTY;
+
+		new_val = block->reg[id];
+		new_val &= ~state->regs[i].mask;
+		new_val |= state->regs[i].value;
+		if (new_val != block->reg[id]) {
+			block->reg[id] = new_val;
+			dirty |= R600_BLOCK_STATUS_DIRTY;
+		}
+		if (block->flags & REG_FLAG_DIRTY_ALWAYS)
+			dirty |= R600_BLOCK_STATUS_DIRTY;
 		if (block->pm4_bo_index[id]) {
 			/* find relocation */
 			id = block->pm4_bo_index[id];
 			r600_bo_reference(ctx->radeon, &block->reloc[id].bo, state->regs[i].bo);
 			state->regs[i].bo->fence = ctx->radeon->fence;
+			/* always force dirty for relocs for now */
+			dirty |= R600_BLOCK_STATUS_DIRTY;
 		}
-		r600_context_dirty_block(ctx, block);
+
+		r600_context_dirty_block(ctx, block, dirty);
 	}
 }
 
@@ -890,7 +909,7 @@ static inline void r600_context_pipe_state_set_resource(struct r600_context *ctx
 		state->regs[2].bo->fence = ctx->radeon->fence;
 		state->regs[3].bo->fence = ctx->radeon->fence;
 	}
-	r600_context_dirty_block(ctx, block);
+	r600_context_dirty_block(ctx, block, R600_BLOCK_STATUS_DIRTY);
 }
 
 void r600_context_pipe_state_set_ps_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid)
@@ -919,6 +938,7 @@ static inline void r600_context_pipe_state_set_sampler(struct r600_context *ctx,
 	struct r600_range *range;
 	struct r600_block *block;
 	int i;
+	int dirty;
 
 	range = &ctx->range[CTX_RANGE_ID(ctx, offset)];
 	block = range->blocks[CTX_BLOCK_ID(ctx, offset)];
@@ -927,11 +947,15 @@ static inline void r600_context_pipe_state_set_sampler(struct r600_context *ctx,
 		LIST_DELINIT(&block->list);
 		return;
 	}
+	dirty = block->status & R600_BLOCK_STATUS_DIRTY;
+	for (i = 0; i < 3; i++) {
+		if (block->reg[i] != state->regs[i].value) {
+			block->reg[i] = state->regs[i].value;
+			dirty |= R600_BLOCK_STATUS_DIRTY;
+		}
+	}
 
-	for (i = 0; i < 3; i++)
-		block->reg[i] = state->regs[i].value;
-
-	r600_context_dirty_block(ctx, block);
+	r600_context_dirty_block(ctx, block, dirty);
 }
 
 static inline void r600_context_pipe_state_set_sampler_border(struct r600_context *ctx, struct r600_pipe_state *state, unsigned offset)
@@ -939,6 +963,7 @@ static inline void r600_context_pipe_state_set_sampler_border(struct r600_contex
 	struct r600_range *range;
 	struct r600_block *block;
 	int i;
+	int dirty;
 
 	range = &ctx->range[CTX_RANGE_ID(ctx, offset)];
 	block = range->blocks[CTX_BLOCK_ID(ctx, offset)];
@@ -950,11 +975,15 @@ static inline void r600_context_pipe_state_set_sampler_border(struct r600_contex
 	if (state->nregs <= 3) {
 		return;
 	}
+	dirty = block->status & R600_BLOCK_STATUS_DIRTY;
+	for (i = 0; i < 4; i++) {
+		if (block->reg[i] != state->regs[i + 3].value) {
+			block->reg[i] = state->regs[i + 3].value;
+			dirty |= R600_BLOCK_STATUS_DIRTY;
+		}
+	}
 
-	for (i = 0; i < 4; i++)
-		block->reg[i] = state->regs[i + 3].value;
-
-	r600_context_dirty_block(ctx, block);
+	r600_context_dirty_block(ctx, block, dirty);
 }
 
 void r600_context_pipe_state_set_ps_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned id)
diff --git a/src/gallium/winsys/r600/drm/r600_priv.h b/src/gallium/winsys/r600/drm/r600_priv.h
index 0e9dba7..534df11 100644
--- a/src/gallium/winsys/r600/drm/r600_priv.h
+++ b/src/gallium/winsys/r600/drm/r600_priv.h
@@ -59,11 +59,14 @@ struct radeon {
 	pipe_mutex bo_handles_mutex;
 };
 
+#define REG_FLAG_NEED_BO 1
+#define REG_FLAG_DIRTY_ALWAYS 2
+
 struct r600_reg {
 	unsigned			opcode;
 	unsigned			offset_base;
 	unsigned			offset;
-	unsigned			need_bo;
+	unsigned			flags;
 	unsigned			flush_flags;
 	unsigned			flush_mask;
 };
@@ -194,9 +197,10 @@ static void inline r600_context_reg(struct r600_context *ctx,
 	}
 }
 
-static inline void r600_context_dirty_block(struct r600_context *ctx, struct r600_block *block)
+static inline void r600_context_dirty_block(struct r600_context *ctx, struct r600_block *block,
+					    int dirty)
 {
-	if (!(block->status & R600_BLOCK_STATUS_DIRTY)) {
+	if ((dirty != (block->status & R600_BLOCK_STATUS_DIRTY)) || !(block->status & R600_BLOCK_STATUS_ENABLED)) {
 		block->status |= R600_BLOCK_STATUS_ENABLED;
 		block->status |= R600_BLOCK_STATUS_DIRTY;
 		ctx->pm4_dirty_cdwords += block->pm4_ndwords + block->pm4_flush_ndwords;



More information about the mesa-commit mailing list