radeonsi: add PKT3_CONTEXT_REG_RMW
authorMarek Olšák <marek.olsak@amd.com>
Wed, 21 Aug 2019 04:13:17 +0000 (00:13 -0400)
committerMarek Olšák <marek.olsak@amd.com>
Tue, 27 Aug 2019 20:16:08 +0000 (16:16 -0400)
Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
src/amd/common/sid.h
src/gallium/drivers/radeonsi/si_build_pm4.h

index 0b996e5488483bd9755e23e9f1ec32a35212fdd7..387689876d10c6fa76f8e321cc4fd689380d4b5d 100644 (file)
 /* fix CP DMA before uncommenting: */
 /*#define PKT3_EVENT_WRITE_EOS                   0x48*/ /* not on GFX9 */
 #define PKT3_RELEASE_MEM                       0x49 /* GFX9+ [any ring] or GFX8 [compute ring only] */
+#define PKT3_CONTEXT_REG_RMW                   0x51 /* older firmware versions on older chips don't have this */
 #define PKT3_ONE_REG_WRITE                     0x57 /* not on CIK */
 #define PKT3_ACQUIRE_MEM                       0x58 /* new for CIK */
 #define PKT3_REWIND                            0x59 /* VI+ [any ring] or CIK [compute ring only] */
index 4e8890a5f9789871c39c0c5e07f54e9eea39647c..0b0b64ca13ca842f5f9bfe832ddf0d44288691a8 100644 (file)
@@ -116,6 +116,36 @@ static inline void radeon_set_uconfig_reg_idx(struct radeon_cmdbuf *cs,
        radeon_emit(cs, value);
 }
 
+static inline void radeon_set_context_reg_rmw(struct radeon_cmdbuf *cs, unsigned reg,
+                                             unsigned value, unsigned mask)
+{
+       assert(reg >= SI_CONTEXT_REG_OFFSET);
+       assert(cs->current.cdw + 4 <= cs->current.max_dw);
+       radeon_emit(cs, PKT3(PKT3_CONTEXT_REG_RMW, 2, 0));
+       radeon_emit(cs, (reg - SI_CONTEXT_REG_OFFSET) >> 2);
+       radeon_emit(cs, mask);
+       radeon_emit(cs, value);
+}
+
+/* Emit PKT3_CONTEXT_REG_RMW if the register value is different. */
+static inline void radeon_opt_set_context_reg_rmw(struct si_context *sctx, unsigned offset,
+                                                 enum si_tracked_reg reg, unsigned value,
+                                                 unsigned mask)
+{
+       struct radeon_cmdbuf *cs = sctx->gfx_cs;
+
+       assert((value & ~mask) == 0);
+       value &= mask;
+
+       if (((sctx->tracked_regs.reg_saved >> reg) & 0x1) != 0x1 ||
+           sctx->tracked_regs.reg_value[reg] != value) {
+               radeon_set_context_reg_rmw(cs, offset, value, mask);
+
+               sctx->tracked_regs.reg_saved |= 0x1ull << reg;
+               sctx->tracked_regs.reg_value[reg] = value;
+       }
+}
+
 /* Emit PKT3_SET_CONTEXT_REG if the register value is different. */
 static inline void radeon_opt_set_context_reg(struct si_context *sctx, unsigned offset,
                                              enum si_tracked_reg reg, unsigned value)