r600g: fix lockups with streamout on r7xx
authorMarek Olšák <maraeo@gmail.com>
Thu, 14 Jun 2012 20:32:51 +0000 (22:32 +0200)
committerMarek Olšák <maraeo@gmail.com>
Fri, 15 Jun 2012 20:43:00 +0000 (22:43 +0200)
This requires the latest streamout kernel patches.

Streamout is disabled by default on r7xx, so this patch is safe for regular
users.

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
src/gallium/drivers/r600/r600_hw_context.c
src/gallium/drivers/r600/r600d.h

index 1b1c6f4af6501b8d73942e35ad23609a18f05c23..9303d09167c7e6498f271bb0073bfe8ef42361f6 100644 (file)
@@ -1331,6 +1331,7 @@ void r600_context_streamout_begin(struct r600_context *ctx)
                           12 + /* flush_vgt_streamout */
                           6 + /* set_streamout_enable */
                           util_bitcount(buffer_en) * 7 + /* SET_CONTEXT_REG */
+                          (ctx->chip_class == R700 ? util_bitcount(buffer_en) * 5 : 0) + /* STRMOUT_BASE_UPDATE */
                           util_bitcount(buffer_en & ctx->streamout_append_bitmask) * 8 + /* STRMOUT_BUFFER_UPDATE */
                           util_bitcount(buffer_en & ~ctx->streamout_append_bitmask) * 6 + /* STRMOUT_BUFFER_UPDATE */
                           (ctx->family > CHIP_R600 && ctx->family < CHIP_RV770 ? 2 : 0) + /* SURFACE_BASE_UPDATE */
@@ -1366,6 +1367,19 @@ void r600_context_streamout_begin(struct r600_context *ctx)
                                r600_context_bo_reloc(ctx, r600_resource(t[i]->b.buffer),
                                                      RADEON_USAGE_WRITE);
 
+                       /* R7xx requires this packet after updating BUFFER_BASE.
+                        * Without this, R7xx locks up. */
+                       if (ctx->chip_class == R700) {
+                               cs->buf[cs->cdw++] = PKT3(PKT3_STRMOUT_BASE_UPDATE, 1, 0);
+                               cs->buf[cs->cdw++] = i;
+                               cs->buf[cs->cdw++] = va >> 8;
+
+                               cs->buf[cs->cdw++] = PKT3(PKT3_NOP, 0, 0);
+                               cs->buf[cs->cdw++] =
+                                       r600_context_bo_reloc(ctx, r600_resource(t[i]->b.buffer),
+                                                             RADEON_USAGE_WRITE);
+                       }
+
                        if (ctx->streamout_append_bitmask & (1 << i)) {
                                va = r600_resource_va(&ctx->screen->screen,
                                                      (void*)t[i]->filled_size);
index 933d99e1a4bba5d3efe35acd3606e9f42b1e3efa..ab36d73b14f46760927a9b3d3756eb59c90eed28 100644 (file)
 #define PKT3_SET_RESOURCE                      0x6D
 #define PKT3_SET_SAMPLER                       0x6E
 #define PKT3_SET_CTL_CONST                     0x6F
+#define PKT3_STRMOUT_BASE_UPDATE              0x72
 #define PKT3_SURFACE_BASE_UPDATE               0x73
 #define                SURFACE_BASE_UPDATE_DEPTH      (1 << 0)
 #define                SURFACE_BASE_UPDATE_COLOR(x)   (2 << (x))