-#define BRW_NEW_URB_FENCE (1 << BRW_STATE_URB_FENCE)
-#define BRW_NEW_FRAGMENT_PROGRAM (1 << BRW_STATE_FRAGMENT_PROGRAM)
-#define BRW_NEW_GEOMETRY_PROGRAM (1 << BRW_STATE_GEOMETRY_PROGRAM)
-#define BRW_NEW_VERTEX_PROGRAM (1 << BRW_STATE_VERTEX_PROGRAM)
-#define BRW_NEW_CURBE_OFFSETS (1 << BRW_STATE_CURBE_OFFSETS)
-#define BRW_NEW_REDUCED_PRIMITIVE (1 << BRW_STATE_REDUCED_PRIMITIVE)
-#define BRW_NEW_PRIMITIVE (1 << BRW_STATE_PRIMITIVE)
-#define BRW_NEW_CONTEXT (1 << BRW_STATE_CONTEXT)
-#define BRW_NEW_PSP (1 << BRW_STATE_PSP)
-#define BRW_NEW_SURFACES (1 << BRW_STATE_SURFACES)
-#define BRW_NEW_VS_BINDING_TABLE (1 << BRW_STATE_VS_BINDING_TABLE)
-#define BRW_NEW_GS_BINDING_TABLE (1 << BRW_STATE_GS_BINDING_TABLE)
-#define BRW_NEW_PS_BINDING_TABLE (1 << BRW_STATE_PS_BINDING_TABLE)
-#define BRW_NEW_INDICES (1 << BRW_STATE_INDICES)
-#define BRW_NEW_VERTICES (1 << BRW_STATE_VERTICES)
+/**
+ * BRW_NEW_*_PROG_DATA and BRW_NEW_*_PROGRAM are similar, but distinct.
+ *
+ * BRW_NEW_*_PROGRAM relates to the gl_shader_program/gl_program structures.
+ * When the currently bound shader program differs from the previous draw
+ * call, these will be flagged. They cover brw->{stage}_program and
+ * ctx->{Stage}Program->_Current.
+ *
+ * BRW_NEW_*_PROG_DATA is flagged when the effective shaders change, from a
+ * driver perspective. Even if the same shader is bound at the API level,
+ * we may need to switch between multiple versions of that shader to handle
+ * changes in non-orthagonal state.
+ *
+ * Additionally, multiple shader programs may have identical vertex shaders
+ * (for example), or compile down to the same code in the backend. We combine
+ * those into a single program cache entry.
+ *
+ * BRW_NEW_*_PROG_DATA occurs when switching program cache entries, which
+ * covers the brw_*_prog_data structures, and brw->*.prog_offset.
+ */
+#define BRW_NEW_FS_PROG_DATA (1ull << BRW_CACHE_FS_PROG)
+/* XXX: The BRW_NEW_BLORP_BLIT_PROG_DATA dirty bit is unused (as BLORP doesn't
+ * use the normal state upload paths), but the cache is still used. To avoid
+ * polluting the brw_state_cache code with special cases, we retain the dirty
+ * bit for now. It should eventually be removed.
+ */
+#define BRW_NEW_BLORP_BLIT_PROG_DATA (1ull << BRW_CACHE_BLORP_BLIT_PROG)
+#define BRW_NEW_SF_PROG_DATA (1ull << BRW_CACHE_SF_PROG)
+#define BRW_NEW_VS_PROG_DATA (1ull << BRW_CACHE_VS_PROG)
+#define BRW_NEW_FF_GS_PROG_DATA (1ull << BRW_CACHE_FF_GS_PROG)
+#define BRW_NEW_GS_PROG_DATA (1ull << BRW_CACHE_GS_PROG)
+#define BRW_NEW_CLIP_PROG_DATA (1ull << BRW_CACHE_CLIP_PROG)
+#define BRW_NEW_URB_FENCE (1ull << BRW_STATE_URB_FENCE)
+#define BRW_NEW_FRAGMENT_PROGRAM (1ull << BRW_STATE_FRAGMENT_PROGRAM)
+#define BRW_NEW_GEOMETRY_PROGRAM (1ull << BRW_STATE_GEOMETRY_PROGRAM)
+#define BRW_NEW_VERTEX_PROGRAM (1ull << BRW_STATE_VERTEX_PROGRAM)
+#define BRW_NEW_CURBE_OFFSETS (1ull << BRW_STATE_CURBE_OFFSETS)
+#define BRW_NEW_REDUCED_PRIMITIVE (1ull << BRW_STATE_REDUCED_PRIMITIVE)
+#define BRW_NEW_PRIMITIVE (1ull << BRW_STATE_PRIMITIVE)
+#define BRW_NEW_CONTEXT (1ull << BRW_STATE_CONTEXT)
+#define BRW_NEW_PSP (1ull << BRW_STATE_PSP)
+#define BRW_NEW_SURFACES (1ull << BRW_STATE_SURFACES)
+#define BRW_NEW_VS_BINDING_TABLE (1ull << BRW_STATE_VS_BINDING_TABLE)
+#define BRW_NEW_GS_BINDING_TABLE (1ull << BRW_STATE_GS_BINDING_TABLE)
+#define BRW_NEW_PS_BINDING_TABLE (1ull << BRW_STATE_PS_BINDING_TABLE)
+#define BRW_NEW_INDICES (1ull << BRW_STATE_INDICES)
+#define BRW_NEW_VERTICES (1ull << BRW_STATE_VERTICES)