radeon/winsys: introduce radeon_winsys_cs_chunk
authorNicolai Hähnle <nicolai.haehnle@amd.com>
Fri, 6 May 2016 22:14:29 +0000 (17:14 -0500)
committerNicolai Hähnle <nicolai.haehnle@amd.com>
Wed, 1 Jun 2016 20:52:20 +0000 (22:52 +0200)
We will chain multiple chunks together and will keep pointers to the older
chunks to support IB dumping.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
src/gallium/drivers/r300/r300_cs.h
src/gallium/drivers/r600/r600_hw_context.c
src/gallium/drivers/r600/r600_pipe.h
src/gallium/drivers/radeon/r600_cs.h
src/gallium/drivers/radeon/r600_pipe_common.c
src/gallium/drivers/radeon/radeon_vce.h
src/gallium/drivers/radeon/radeon_vce_40_2_2.c
src/gallium/drivers/radeon/radeon_winsys.h
src/gallium/drivers/radeonsi/si_hw_context.c
src/gallium/winsys/amdgpu/drm/amdgpu_cs.c
src/gallium/winsys/radeon/drm/radeon_drm_cs.c

index 7ae83a8920b8183f7f87fcafca146496c993c97d..727b9e22475bdc93d5e1742122177128cb87abb4 100644 (file)
@@ -46,7 +46,7 @@
 #ifdef DEBUG
 
 #define BEGIN_CS(size) do { \
-    assert(size <= (cs_copy->max_dw - cs_copy->cdw)); \
+    assert(size <= (cs_copy->current.max_dw - cs_copy->current.cdw)); \
     cs_count = size; \
 } while (0)
 
@@ -72,7 +72,7 @@
  */
 
 #define OUT_CS(value) do { \
-    cs_copy->buf[cs_copy->cdw++] = (value); \
+    cs_copy->current.buf[cs_copy->current.cdw++] = (value); \
     CS_USED_DW(1); \
 } while (0)
 
@@ -96,8 +96,8 @@
     OUT_CS(CP_PACKET3(op, count))
 
 #define OUT_CS_TABLE(values, count) do { \
-    memcpy(cs_copy->buf + cs_copy->cdw, (values), (count) * 4); \
-    cs_copy->cdw += (count); \
+    memcpy(cs_copy->current.buf + cs_copy->current.cdw, (values), (count) * 4); \
+    cs_copy->current.cdw += (count); \
     CS_USED_DW(count); \
 } while (0)
 
 
 #define WRITE_CS_TABLE(values, count) do { \
     assert(cs_count == 0); \
-    memcpy(cs_copy->buf + cs_copy->cdw, (values), (count) * 4); \
-    cs_copy->cdw += (count); \
+    memcpy(cs_copy->current.buf + cs_copy->current.cdw, (values), (count) * 4); \
+    cs_copy->current.cdw += (count); \
 } while (0)
 
 #endif /* R300_CS_H */
index ccfa8f5c306f0c11398855c894c57ce86340c9e0..430ffb345507d012809c276c2ffd365ffda8e753 100644 (file)
@@ -357,7 +357,8 @@ void r600_begin_new_cs(struct r600_context *ctx)
        ctx->last_primitive_type = -1;
        ctx->last_start_instance = -1;
 
-       ctx->b.initial_gfx_cs_size = ctx->b.gfx.cs->cdw;
+       assert(!ctx->b.gfx.cs->prev_dw);
+       ctx->b.initial_gfx_cs_size = ctx->b.gfx.cs->current.cdw;
 }
 
 /* The max number of bytes to copy per packet. */
index cdb8e8211b95c13063062f969c8a223c97ac1dcd..76178c225099f7787bf4bc2da0e2afcc672ba86a 100644 (file)
@@ -518,9 +518,9 @@ struct r600_context {
 static inline void r600_emit_command_buffer(struct radeon_winsys_cs *cs,
                                            struct r600_command_buffer *cb)
 {
-       assert(cs->cdw + cb->num_dw <= cs->max_dw);
-       memcpy(cs->buf + cs->cdw, cb->buf, 4 * cb->num_dw);
-       cs->cdw += cb->num_dw;
+       assert(cs->current.cdw + cb->num_dw <= cs->current.max_dw);
+       memcpy(cs->current.buf + cs->current.cdw, cb->buf, 4 * cb->num_dw);
+       cs->current.cdw += cb->num_dw;
 }
 
 static inline void r600_set_atom_dirty(struct r600_context *rctx,
@@ -874,13 +874,13 @@ static inline void radeon_compute_set_context_reg_seq(struct radeon_winsys_cs *c
 {
        radeon_set_context_reg_seq(cs, reg, num);
        /* Set the compute bit on the packet header */
-       cs->buf[cs->cdw - 2] |= RADEON_CP_PACKET3_COMPUTE_MODE;
+       cs->current.buf[cs->current.cdw - 2] |= RADEON_CP_PACKET3_COMPUTE_MODE;
 }
 
 static inline void radeon_set_ctl_const_seq(struct radeon_winsys_cs *cs, unsigned reg, unsigned num)
 {
        assert(reg >= R600_CTL_CONST_OFFSET);
-       assert(cs->cdw+2+num <= cs->max_dw);
+       assert(cs->current.cdw + 2 + num <= cs->current.max_dw);
        radeon_emit(cs, PKT3(PKT3_SET_CTL_CONST, num, 0));
        radeon_emit(cs, (reg - R600_CTL_CONST_OFFSET) >> 2);
 }
index ff5b055448acc16820bedeb547fc9f7216b429a3..157d56c14c6fd70e1817d99e7be6f4dc3c1a6325 100644 (file)
@@ -72,7 +72,7 @@ static inline void r600_emit_reloc(struct r600_common_context *rctx,
 static inline void radeon_set_config_reg_seq(struct radeon_winsys_cs *cs, unsigned reg, unsigned num)
 {
        assert(reg < R600_CONTEXT_REG_OFFSET);
-       assert(cs->cdw+2+num <= cs->max_dw);
+       assert(cs->current.cdw + 2 + num <= cs->current.max_dw);
        radeon_emit(cs, PKT3(PKT3_SET_CONFIG_REG, num, 0));
        radeon_emit(cs, (reg - R600_CONFIG_REG_OFFSET) >> 2);
 }
@@ -86,7 +86,7 @@ static inline void radeon_set_config_reg(struct radeon_winsys_cs *cs, unsigned r
 static inline void radeon_set_context_reg_seq(struct radeon_winsys_cs *cs, unsigned reg, unsigned num)
 {
        assert(reg >= R600_CONTEXT_REG_OFFSET);
-       assert(cs->cdw+2+num <= cs->max_dw);
+       assert(cs->current.cdw + 2 + num <= cs->current.max_dw);
        radeon_emit(cs, PKT3(PKT3_SET_CONTEXT_REG, num, 0));
        radeon_emit(cs, (reg - R600_CONTEXT_REG_OFFSET) >> 2);
 }
@@ -100,7 +100,7 @@ static inline void radeon_set_context_reg(struct radeon_winsys_cs *cs, unsigned
 static inline void radeon_set_sh_reg_seq(struct radeon_winsys_cs *cs, unsigned reg, unsigned num)
 {
        assert(reg >= SI_SH_REG_OFFSET && reg < SI_SH_REG_END);
-       assert(cs->cdw+2+num <= cs->max_dw);
+       assert(cs->current.cdw + 2 + num <= cs->current.max_dw);
        radeon_emit(cs, PKT3(PKT3_SET_SH_REG, num, 0));
        radeon_emit(cs, (reg - SI_SH_REG_OFFSET) >> 2);
 }
@@ -114,7 +114,7 @@ static inline void radeon_set_sh_reg(struct radeon_winsys_cs *cs, unsigned reg,
 static inline void radeon_set_uconfig_reg_seq(struct radeon_winsys_cs *cs, unsigned reg, unsigned num)
 {
        assert(reg >= CIK_UCONFIG_REG_OFFSET && reg < CIK_UCONFIG_REG_END);
-       assert(cs->cdw+2+num <= cs->max_dw);
+       assert(cs->current.cdw + 2 + num <= cs->current.max_dw);
        radeon_emit(cs, PKT3(PKT3_SET_UCONFIG_REG, num, 0));
        radeon_emit(cs, (reg - CIK_UCONFIG_REG_OFFSET) >> 2);
 }
index fa766977aa02fd435d7acb63184806f8509449b8..7ace34b8772496a0330831444bd8043984fee165 100644 (file)
@@ -171,7 +171,7 @@ void r600_need_dma_space(struct r600_common_context *ctx, unsigned num_dw,
        if (!ctx->ws->cs_check_space(ctx->dma.cs, num_dw) ||
            !ctx->ws->cs_memory_below_limit(ctx->dma.cs, vram, gtt)) {
                ctx->dma.flush(ctx, RADEON_FLUSH_ASYNC, NULL);
-               assert((num_dw + ctx->dma.cs->cdw) <= ctx->dma.cs->max_dw);
+               assert((num_dw + ctx->dma.cs->current.cdw) <= ctx->dma.cs->current.max_dw);
        }
 
        /* If GPUVM is not supported, the CS checker needs 2 entries
index 8290e94fda75890525d1f560dec27c3d8920ae0b..e438148701debea17fcf8be4a5c81319dd90c934 100644 (file)
 
 #include "util/list.h"
 
-#define RVCE_CS(value) (enc->cs->buf[enc->cs->cdw++] = (value))
-#define RVCE_BEGIN(cmd) { uint32_t *begin = &enc->cs->buf[enc->cs->cdw++]; RVCE_CS(cmd)
+#define RVCE_CS(value) (enc->cs->current.buf[enc->cs->current.cdw++] = (value))
+#define RVCE_BEGIN(cmd) { \
+       uint32_t *begin = &enc->cs->current.buf[enc->cs->current.cdw++]; \
+       RVCE_CS(cmd)
 #define RVCE_READ(buf, domain, off) rvce_add_buffer(enc, (buf), RADEON_USAGE_READ, (domain), (off))
 #define RVCE_WRITE(buf, domain, off) rvce_add_buffer(enc, (buf), RADEON_USAGE_WRITE, (domain), (off))
 #define RVCE_READWRITE(buf, domain, off) rvce_add_buffer(enc, (buf), RADEON_USAGE_READWRITE, (domain), (off))
-#define RVCE_END() *begin = (&enc->cs->buf[enc->cs->cdw] - begin) * 4; }
+#define RVCE_END() *begin = (&enc->cs->current.buf[enc->cs->current.cdw] - begin) * 4; }
 
 #define RVCE_MAX_BITSTREAM_OUTPUT_ROW_SIZE (4096 * 16 * 2.5)
 #define RVCE_MAX_AUX_BUFFER_NUM 4
index 18bb28bcc88f9bf1cf2f257ccc21e65cbbbed88b..2906ad0687f8be3bf0ed0134377e53b481a8d1d9 100644 (file)
@@ -59,11 +59,11 @@ static void task_info(struct rvce_encoder *enc, uint32_t op,
        RVCE_BEGIN(0x00000002); // task info
        if (op == 0x3) {
                if (enc->task_info_idx) {
-                       uint32_t offs = enc->cs->cdw - enc->task_info_idx + 3;
+                       uint32_t offs = enc->cs->current.cdw - enc->task_info_idx + 3;
                        // Update offsetOfNextTaskInfo
-                       enc->cs->buf[enc->task_info_idx] = offs;
+                       enc->cs->current.buf[enc->task_info_idx] = offs;
                }
-               enc->task_info_idx = enc->cs->cdw;
+               enc->task_info_idx = enc->cs->current.cdw;
        }
        RVCE_CS(0xffffffff); // offsetOfNextTaskInfo
        RVCE_CS(op); // taskOperation
index e8e429abc11bcbcf090d18f3cbc467aec6c46eeb..806ea6378c3791d29c892219ad9415441a3873ae 100644 (file)
@@ -225,10 +225,18 @@ enum radeon_bo_priority {
 struct winsys_handle;
 struct radeon_winsys_ctx;
 
+struct radeon_winsys_cs_chunk {
+    unsigned cdw;  /* Number of used dwords. */
+    unsigned max_dw; /* Maximum number of dwords. */
+    uint32_t *buf; /* The base pointer of the chunk. */
+};
+
 struct radeon_winsys_cs {
-    unsigned                    cdw;  /* Number of used dwords. */
-    unsigned                    max_dw; /* Maximum number of dwords. */
-    uint32_t                    *buf; /* The command buffer. */
+    struct radeon_winsys_cs_chunk current;
+    struct radeon_winsys_cs_chunk *prev;
+    unsigned                      num_prev; /* Number of previous chunks. */
+    unsigned                      max_prev; /* Space in array pointed to by prev. */
+    unsigned                      prev_dw; /* Total number of dwords in previous chunks. */
 };
 
 struct radeon_info {
@@ -786,19 +794,19 @@ struct radeon_winsys {
 
 static inline bool radeon_emitted(struct radeon_winsys_cs *cs, unsigned num_dw)
 {
-    return cs && cs->cdw > num_dw;
+    return cs && (cs->prev_dw + cs->current.cdw > num_dw);
 }
 
 static inline void radeon_emit(struct radeon_winsys_cs *cs, uint32_t value)
 {
-    cs->buf[cs->cdw++] = value;
+    cs->current.buf[cs->current.cdw++] = value;
 }
 
 static inline void radeon_emit_array(struct radeon_winsys_cs *cs,
                                     const uint32_t *values, unsigned count)
 {
-    memcpy(cs->buf+cs->cdw, values, count * 4);
-    cs->cdw += count;
+    memcpy(cs->current.buf + cs->current.cdw, values, count * 4);
+    cs->current.cdw += count;
 }
 
 #endif
index c25b264ec5c4f13703667e4174de9056d32dd267..fa6a2cbef0b604988620977b3a9a4b2a0af94864 100644 (file)
@@ -130,13 +130,19 @@ void si_context_gfx_flush(void *context, unsigned flags,
                si_trace_emit(ctx);
 
        if (ctx->is_debug) {
+               uint32_t *buf;
                unsigned i;
 
                /* Save the IB for debug contexts. */
                free(ctx->last_ib);
-               ctx->last_ib_dw_size = cs->cdw;
-               ctx->last_ib = malloc(cs->cdw * 4);
-               memcpy(ctx->last_ib, cs->buf, cs->cdw * 4);
+               ctx->last_ib_dw_size = cs->prev_dw + cs->current.cdw;
+               ctx->last_ib = malloc(ctx->last_ib_dw_size * 4);
+               buf = ctx->last_ib;
+               for (i = 0; i < cs->num_prev; ++i) {
+                       memcpy(buf, cs->prev[i].buf, cs->prev[i].cdw * 4);
+                       buf += cs->prev[i].cdw;
+               }
+               memcpy(buf, cs->current.buf, cs->current.cdw * 4);
                r600_resource_reference(&ctx->last_trace_buf, ctx->trace_buf);
                r600_resource_reference(&ctx->trace_buf, NULL);
 
@@ -232,7 +238,8 @@ void si_begin_new_cs(struct si_context *ctx)
 
        r600_postflush_resume_features(&ctx->b);
 
-       ctx->b.initial_gfx_cs_size = ctx->b.gfx.cs->cdw;
+       assert(!ctx->b.gfx.cs->prev_dw);
+       ctx->b.initial_gfx_cs_size = ctx->b.gfx.cs->current.cdw;
 
        /* Invalidate various draw states so that they are emitted before
         * the first draw call. */
index 781960c96000631096a02a7412fbd119637bd6cc..a7274c47f58b5f6c5bf43f1853576b721931f445 100644 (file)
@@ -440,8 +440,10 @@ static bool amdgpu_get_new_ib(struct radeon_winsys *ws, struct amdgpu_cs *cs,
                   4 * MIN2(util_next_power_of_two(ib->max_ib_size),
                            amdgpu_ib_max_submit_dwords(ib_type)));
 
-   ib->base.cdw = 0;
-   ib->base.buf = NULL;
+   ib->base.prev_dw = 0;
+   ib->base.num_prev = 0;
+   ib->base.current.cdw = 0;
+   ib->base.current.buf = NULL;
 
    /* Allocate a new buffer for IBs if the current buffer is all used. */
    if (!ib->big_ib_buffer ||
@@ -455,10 +457,10 @@ static bool amdgpu_get_new_ib(struct radeon_winsys *ws, struct amdgpu_cs *cs,
    amdgpu_cs_add_buffer(&cs->main.base, ib->big_ib_buffer,
                         RADEON_USAGE_READ, 0, RADEON_PRIO_IB1);
 
-   ib->base.buf = (uint32_t*)(ib->ib_mapped + ib->used_ib_space);
+   ib->base.current.buf = (uint32_t*)(ib->ib_mapped + ib->used_ib_space);
 
    ib_size = ib->big_ib_buffer->size - ib->used_ib_space;
-   ib->base.max_dw = ib_size / 4;
+   ib->base.current.max_dw = ib_size / 4;
    return true;
 }
 
@@ -653,7 +655,7 @@ amdgpu_cs_add_const_preamble_ib(struct radeon_winsys_cs *rcs)
    return &cs->const_preamble_ib.base;
 }
 
-#define OUT_CS(cs, value) (cs)->buf[(cs)->cdw++] = (value)
+#define OUT_CS(cs, value) (cs)->current.buf[(cs)->current.cdw++] = (value)
 
 static int amdgpu_cs_lookup_buffer(struct radeon_winsys_cs *rcs,
                                struct pb_buffer *buf)
@@ -672,16 +674,16 @@ static bool amdgpu_cs_check_space(struct radeon_winsys_cs *rcs, unsigned dw)
 {
    struct amdgpu_ib *ib = amdgpu_ib(rcs);
    struct amdgpu_cs *cs = amdgpu_cs_from_ib(ib);
-   unsigned requested_size = rcs->cdw + dw;
+   unsigned requested_size = rcs->prev_dw + rcs->current.cdw + dw;
 
-   assert(rcs->cdw <= rcs->max_dw);
+   assert(rcs->current.cdw <= rcs->current.max_dw);
 
    if (requested_size > amdgpu_ib_max_submit_dwords(ib->ib_type))
       return false;
 
    ib->max_ib_size = MAX2(ib->max_ib_size, requested_size);
 
-   return rcs->max_dw - rcs->cdw >= dw;
+   return rcs->current.max_dw - rcs->current.cdw >= dw;
 }
 
 static boolean amdgpu_cs_memory_below_limit(struct radeon_winsys_cs *rcs, uint64_t vram, uint64_t gtt)
@@ -879,57 +881,60 @@ static void amdgpu_cs_flush(struct radeon_winsys_cs *rcs,
    switch (cs->ring_type) {
    case RING_DMA:
       /* pad DMA ring to 8 DWs */
-      while (rcs->cdw & 7)
+      while (rcs->current.cdw & 7)
          OUT_CS(rcs, 0x00000000); /* NOP packet */
       break;
    case RING_GFX:
       /* pad GFX ring to 8 DWs to meet CP fetch alignment requirements */
-      while (rcs->cdw & 7)
+      while (rcs->current.cdw & 7)
          OUT_CS(rcs, 0xffff1000); /* type3 nop packet */
 
       /* Also pad the const IB. */
       if (cs->const_ib.ib_mapped)
-         while (!cs->const_ib.base.cdw || (cs->const_ib.base.cdw & 7))
+         while (!cs->const_ib.base.current.cdw || (cs->const_ib.base.current.cdw & 7))
             OUT_CS(&cs->const_ib.base, 0xffff1000); /* type3 nop packet */
 
       if (cs->const_preamble_ib.ib_mapped)
-         while (!cs->const_preamble_ib.base.cdw || (cs->const_preamble_ib.base.cdw & 7))
+         while (!cs->const_preamble_ib.base.current.cdw || (cs->const_preamble_ib.base.current.cdw & 7))
             OUT_CS(&cs->const_preamble_ib.base, 0xffff1000);
       break;
    case RING_UVD:
-      while (rcs->cdw & 15)
+      while (rcs->current.cdw & 15)
          OUT_CS(rcs, 0x80000000); /* type2 nop packet */
       break;
    default:
       break;
    }
 
-   if (rcs->cdw > rcs->max_dw) {
+   if (rcs->current.cdw > rcs->current.max_dw) {
       fprintf(stderr, "amdgpu: command stream overflowed\n");
    }
 
    /* If the CS is not empty or overflowed.... */
-   if (cs->main.base.cdw && cs->main.base.cdw <= cs->main.base.max_dw &&
+   if (radeon_emitted(&cs->main.base, 0) &&
+       cs->main.base.current.cdw <= cs->main.base.current.max_dw &&
        !debug_get_option_noop()) {
       struct amdgpu_cs_context *cur = cs->csc;
       unsigned i, num_buffers = cur->num_buffers;
 
       /* Set IB sizes. */
-      cur->ib[IB_MAIN].size = cs->main.base.cdw;
-      cs->main.used_ib_space += cs->main.base.cdw * 4;
-      cs->main.max_ib_size = MAX2(cs->main.max_ib_size, cs->main.base.cdw);
+      cur->ib[IB_MAIN].size = cs->main.base.current.cdw;
+      cs->main.used_ib_space += cs->main.base.current.cdw * 4;
+      cs->main.max_ib_size = MAX2(cs->main.max_ib_size, cs->main.base.prev_dw + cs->main.base.current.cdw);
 
       if (cs->const_ib.ib_mapped) {
-         cur->ib[IB_CONST].size = cs->const_ib.base.cdw;
-         cs->const_ib.used_ib_space += cs->const_ib.base.cdw * 4;
-         cs->const_ib.max_ib_size = MAX2(cs->const_ib.max_ib_size, cs->const_ib.base.cdw);
+         cur->ib[IB_CONST].size = cs->const_ib.base.current.cdw;
+         cs->const_ib.used_ib_space += cs->const_ib.base.current.cdw * 4;
+         cs->const_ib.max_ib_size =
+            MAX2(cs->const_ib.max_ib_size, cs->main.base.prev_dw + cs->const_ib.base.current.cdw);
       }
 
       if (cs->const_preamble_ib.ib_mapped) {
-         cur->ib[IB_CONST_PREAMBLE].size = cs->const_preamble_ib.base.cdw;
-         cs->const_preamble_ib.used_ib_space += cs->const_preamble_ib.base.cdw * 4;
+         cur->ib[IB_CONST_PREAMBLE].size = cs->const_preamble_ib.base.current.cdw;
+         cs->const_preamble_ib.used_ib_space += cs->const_preamble_ib.base.current.cdw * 4;
          cs->const_preamble_ib.max_ib_size =
-            MAX2(cs->const_preamble_ib.max_ib_size, cs->const_preamble_ib.base.cdw);
+            MAX2(cs->const_preamble_ib.max_ib_size,
+                 cs->const_preamble_ib.base.prev_dw + cs->const_preamble_ib.base.current.cdw);
       }
 
       /* Create a fence. */
index a6ca37744dc4b927f6be9ec7eaf18fdddd985968..e9ab53dac85e194af86a0c50ce3b116a041cc283 100644 (file)
@@ -196,15 +196,15 @@ radeon_drm_cs_create(struct radeon_winsys_ctx *ctx,
     /* Set the first command buffer as current. */
     cs->csc = &cs->csc1;
     cs->cst = &cs->csc2;
-    cs->base.buf = cs->csc->buf;
-    cs->base.max_dw = ARRAY_SIZE(cs->csc->buf);
+    cs->base.current.buf = cs->csc->buf;
+    cs->base.current.max_dw = ARRAY_SIZE(cs->csc->buf);
     cs->ring_type = ring_type;
 
     p_atomic_inc(&ws->num_cs);
     return &cs->base;
 }
 
-#define OUT_CS(cs, value) (cs)->buf[(cs)->cdw++] = (value)
+#define OUT_CS(cs, value) (cs)->current.buf[(cs)->current.cdw++] = (value)
 
 static inline void update_reloc(struct drm_radeon_cs_reloc *reloc,
                                 enum radeon_bo_domain rd,
@@ -374,8 +374,8 @@ static boolean radeon_drm_cs_validate(struct radeon_winsys_cs *rcs)
         } else {
             radeon_cs_context_cleanup(cs->csc);
 
-            assert(cs->base.cdw == 0);
-            if (cs->base.cdw != 0) {
+            assert(cs->base.current.cdw == 0);
+            if (cs->base.current.cdw != 0) {
                 fprintf(stderr, "radeon: Unexpected error in %s.\n", __func__);
             }
         }
@@ -385,8 +385,8 @@ static boolean radeon_drm_cs_validate(struct radeon_winsys_cs *rcs)
 
 static bool radeon_drm_cs_check_space(struct radeon_winsys_cs *rcs, unsigned dw)
 {
-   assert(rcs->cdw <= rcs->max_dw);
-   return rcs->max_dw - rcs->cdw >= dw;
+   assert(rcs->current.cdw <= rcs->current.max_dw);
+   return rcs->current.max_dw - rcs->current.cdw >= dw;
 }
 
 static boolean radeon_drm_cs_memory_below_limit(struct radeon_winsys_cs *rcs, uint64_t vram, uint64_t gtt)
@@ -483,10 +483,10 @@ static void radeon_drm_cs_flush(struct radeon_winsys_cs *rcs,
     case RING_DMA:
         /* pad DMA ring to 8 DWs */
         if (cs->ws->info.chip_class <= SI) {
-            while (rcs->cdw & 7)
+            while (rcs->current.cdw & 7)
                 OUT_CS(&cs->base, 0xf0000000); /* NOP packet */
         } else {
-            while (rcs->cdw & 7)
+            while (rcs->current.cdw & 7)
                 OUT_CS(&cs->base, 0x00000000); /* NOP packet */
         }
         break;
@@ -495,22 +495,22 @@ static void radeon_drm_cs_flush(struct radeon_winsys_cs *rcs,
          * r6xx, requires at least 4 dw alignment to avoid a hw bug.
          */
         if (cs->ws->info.gfx_ib_pad_with_type2) {
-            while (rcs->cdw & 7)
+            while (rcs->current.cdw & 7)
                 OUT_CS(&cs->base, 0x80000000); /* type2 nop packet */
         } else {
-            while (rcs->cdw & 7)
+            while (rcs->current.cdw & 7)
                 OUT_CS(&cs->base, 0xffff1000); /* type3 nop packet */
         }
         break;
     case RING_UVD:
-        while (rcs->cdw & 15)
+        while (rcs->current.cdw & 15)
             OUT_CS(&cs->base, 0x80000000); /* type2 nop packet */
         break;
     default:
         break;
     }
 
-    if (rcs->cdw > rcs->max_dw) {
+    if (rcs->current.cdw > rcs->current.max_dw) {
        fprintf(stderr, "radeon: command stream overflowed\n");
     }
 
@@ -527,12 +527,12 @@ static void radeon_drm_cs_flush(struct radeon_winsys_cs *rcs,
     cs->cst = tmp;
 
     /* If the CS is not empty or overflowed, emit it in a separate thread. */
-    if (cs->base.cdw && cs->base.cdw <= cs->base.max_dw && !debug_get_option_noop()) {
+    if (cs->base.current.cdw && cs->base.current.cdw <= cs->base.current.max_dw && !debug_get_option_noop()) {
         unsigned i, crelocs;
 
         crelocs = cs->cst->crelocs;
 
-        cs->cst->chunks[0].length_dw = cs->base.cdw;
+        cs->cst->chunks[0].length_dw = cs->base.current.cdw;
 
         for (i = 0; i < crelocs; i++) {
             /* Update the number of active asynchronous CS ioctls for the buffer. */
@@ -599,8 +599,8 @@ static void radeon_drm_cs_flush(struct radeon_winsys_cs *rcs,
     }
 
     /* Prepare a new CS. */
-    cs->base.buf = cs->csc->buf;
-    cs->base.cdw = 0;
+    cs->base.current.buf = cs->csc->buf;
+    cs->base.current.cdw = 0;
 
     cs->ws->num_cs_flushes++;
 }