aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/r300_cmdbuf.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/r300_cmdbuf.c')
-rw-r--r--drivers/gpu/drm/radeon/r300_cmdbuf.c117
1 files changed, 97 insertions, 20 deletions
diff --git a/drivers/gpu/drm/radeon/r300_cmdbuf.c b/drivers/gpu/drm/radeon/r300_cmdbuf.c
index 702df45320f7..4b3bd6303daf 100644
--- a/drivers/gpu/drm/radeon/r300_cmdbuf.c
+++ b/drivers/gpu/drm/radeon/r300_cmdbuf.c
@@ -136,6 +136,18 @@ static int r300_emit_cliprects(drm_radeon_private_t *dev_priv,
136 ADVANCE_RING(); 136 ADVANCE_RING();
137 } 137 }
138 138
139 /* flus cache and wait idle clean after cliprect change */
140 BEGIN_RING(2);
141 OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
142 OUT_RING(R300_RB3D_DC_FLUSH);
143 ADVANCE_RING();
144 BEGIN_RING(2);
145 OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
146 OUT_RING(RADEON_WAIT_3D_IDLECLEAN);
147 ADVANCE_RING();
148 /* set flush flag */
149 dev_priv->track_flush |= RADEON_FLUSH_EMITED;
150
139 return 0; 151 return 0;
140} 152}
141 153
@@ -166,13 +178,13 @@ void r300_init_reg_flags(struct drm_device *dev)
166 ADD_RANGE(0x21DC, 1); 178 ADD_RANGE(0x21DC, 1);
167 ADD_RANGE(R300_VAP_UNKNOWN_221C, 1); 179 ADD_RANGE(R300_VAP_UNKNOWN_221C, 1);
168 ADD_RANGE(R300_VAP_CLIP_X_0, 4); 180 ADD_RANGE(R300_VAP_CLIP_X_0, 4);
169 ADD_RANGE(R300_VAP_PVS_WAITIDLE, 1); 181 ADD_RANGE(R300_VAP_PVS_STATE_FLUSH_REG, 1);
170 ADD_RANGE(R300_VAP_UNKNOWN_2288, 1); 182 ADD_RANGE(R300_VAP_UNKNOWN_2288, 1);
171 ADD_RANGE(R300_VAP_OUTPUT_VTX_FMT_0, 2); 183 ADD_RANGE(R300_VAP_OUTPUT_VTX_FMT_0, 2);
172 ADD_RANGE(R300_VAP_PVS_CNTL_1, 3); 184 ADD_RANGE(R300_VAP_PVS_CNTL_1, 3);
173 ADD_RANGE(R300_GB_ENABLE, 1); 185 ADD_RANGE(R300_GB_ENABLE, 1);
174 ADD_RANGE(R300_GB_MSPOS0, 5); 186 ADD_RANGE(R300_GB_MSPOS0, 5);
175 ADD_RANGE(R300_TX_CNTL, 1); 187 ADD_RANGE(R300_TX_INVALTAGS, 1);
176 ADD_RANGE(R300_TX_ENABLE, 1); 188 ADD_RANGE(R300_TX_ENABLE, 1);
177 ADD_RANGE(0x4200, 4); 189 ADD_RANGE(0x4200, 4);
178 ADD_RANGE(0x4214, 1); 190 ADD_RANGE(0x4214, 1);
@@ -388,15 +400,28 @@ static __inline__ int r300_emit_vpu(drm_radeon_private_t *dev_priv,
388 if (sz * 16 > cmdbuf->bufsz) 400 if (sz * 16 > cmdbuf->bufsz)
389 return -EINVAL; 401 return -EINVAL;
390 402
391 BEGIN_RING(5 + sz * 4); 403 /* VAP is very sensitive so we purge cache before we program it
392 /* Wait for VAP to come to senses.. */ 404 * and we also flush its state before & after */
393 /* there is no need to emit it multiple times, (only once before VAP is programmed, 405 BEGIN_RING(6);
394 but this optimization is for later */ 406 OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
395 OUT_RING_REG(R300_VAP_PVS_WAITIDLE, 0); 407 OUT_RING(R300_RB3D_DC_FLUSH);
408 OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
409 OUT_RING(RADEON_WAIT_3D_IDLECLEAN);
410 OUT_RING(CP_PACKET0(R300_VAP_PVS_STATE_FLUSH_REG, 0));
411 OUT_RING(0);
412 ADVANCE_RING();
413 /* set flush flag */
414 dev_priv->track_flush |= RADEON_FLUSH_EMITED;
415
416 BEGIN_RING(3 + sz * 4);
396 OUT_RING_REG(R300_VAP_PVS_UPLOAD_ADDRESS, addr); 417 OUT_RING_REG(R300_VAP_PVS_UPLOAD_ADDRESS, addr);
397 OUT_RING(CP_PACKET0_TABLE(R300_VAP_PVS_UPLOAD_DATA, sz * 4 - 1)); 418 OUT_RING(CP_PACKET0_TABLE(R300_VAP_PVS_UPLOAD_DATA, sz * 4 - 1));
398 OUT_RING_TABLE((int *)cmdbuf->buf, sz * 4); 419 OUT_RING_TABLE((int *)cmdbuf->buf, sz * 4);
420 ADVANCE_RING();
399 421
422 BEGIN_RING(2);
423 OUT_RING(CP_PACKET0(R300_VAP_PVS_STATE_FLUSH_REG, 0));
424 OUT_RING(0);
400 ADVANCE_RING(); 425 ADVANCE_RING();
401 426
402 cmdbuf->buf += sz * 16; 427 cmdbuf->buf += sz * 16;
@@ -424,6 +449,15 @@ static __inline__ int r300_emit_clear(drm_radeon_private_t *dev_priv,
424 OUT_RING_TABLE((int *)cmdbuf->buf, 8); 449 OUT_RING_TABLE((int *)cmdbuf->buf, 8);
425 ADVANCE_RING(); 450 ADVANCE_RING();
426 451
452 BEGIN_RING(4);
453 OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
454 OUT_RING(R300_RB3D_DC_FLUSH);
455 OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
456 OUT_RING(RADEON_WAIT_3D_IDLECLEAN);
457 ADVANCE_RING();
458 /* set flush flag */
459 dev_priv->track_flush |= RADEON_FLUSH_EMITED;
460
427 cmdbuf->buf += 8 * 4; 461 cmdbuf->buf += 8 * 4;
428 cmdbuf->bufsz -= 8 * 4; 462 cmdbuf->bufsz -= 8 * 4;
429 463
@@ -613,11 +647,19 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv,
613 case RADEON_CNTL_BITBLT_MULTI: 647 case RADEON_CNTL_BITBLT_MULTI:
614 return r300_emit_bitblt_multi(dev_priv, cmdbuf); 648 return r300_emit_bitblt_multi(dev_priv, cmdbuf);
615 649
616 case RADEON_CP_INDX_BUFFER: /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */ 650 case RADEON_CP_INDX_BUFFER:
651 /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */
617 return r300_emit_indx_buffer(dev_priv, cmdbuf); 652 return r300_emit_indx_buffer(dev_priv, cmdbuf);
618 case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */ 653 case RADEON_CP_3D_DRAW_IMMD_2:
619 case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */ 654 /* triggers drawing using in-packet vertex data */
620 case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */ 655 case RADEON_CP_3D_DRAW_VBUF_2:
656 /* triggers drawing of vertex buffers setup elsewhere */
657 case RADEON_CP_3D_DRAW_INDX_2:
658 /* triggers drawing using indices to vertex buffer */
659 /* whenever we send vertex we clear flush & purge */
660 dev_priv->track_flush &= ~(RADEON_FLUSH_EMITED |
661 RADEON_PURGE_EMITED);
662 break;
621 case RADEON_WAIT_FOR_IDLE: 663 case RADEON_WAIT_FOR_IDLE:
622 case RADEON_CP_NOP: 664 case RADEON_CP_NOP:
623 /* these packets are safe */ 665 /* these packets are safe */
@@ -713,17 +755,53 @@ static __inline__ int r300_emit_packet3(drm_radeon_private_t *dev_priv,
713 */ 755 */
714static __inline__ void r300_pacify(drm_radeon_private_t *dev_priv) 756static __inline__ void r300_pacify(drm_radeon_private_t *dev_priv)
715{ 757{
758 uint32_t cache_z, cache_3d, cache_2d;
716 RING_LOCALS; 759 RING_LOCALS;
760
761 cache_z = R300_ZC_FLUSH;
762 cache_2d = R300_RB2D_DC_FLUSH;
763 cache_3d = R300_RB3D_DC_FLUSH;
764 if (!(dev_priv->track_flush & RADEON_PURGE_EMITED)) {
765 /* we can purge, primitive where draw since last purge */
766 cache_z |= R300_ZC_FREE;
767 cache_2d |= R300_RB2D_DC_FREE;
768 cache_3d |= R300_RB3D_DC_FREE;
769 }
717 770
718 BEGIN_RING(6); 771 /* flush & purge zbuffer */
719 OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); 772 BEGIN_RING(2);
720 OUT_RING(R300_RB3D_DSTCACHE_UNKNOWN_0A);
721 OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 0)); 773 OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 0));
722 OUT_RING(R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE| 774 OUT_RING(cache_z);
723 R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); 775 ADVANCE_RING();
724 OUT_RING(CP_PACKET3(RADEON_CP_NOP, 0)); 776 /* flush & purge 3d */
725 OUT_RING(0x0); 777 BEGIN_RING(2);
778 OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
779 OUT_RING(cache_3d);
780 ADVANCE_RING();
781 /* flush & purge texture */
782 BEGIN_RING(2);
783 OUT_RING(CP_PACKET0(R300_TX_INVALTAGS, 0));
784 OUT_RING(0);
785 ADVANCE_RING();
786 /* FIXME: is this one really needed ? */
787 BEGIN_RING(2);
788 OUT_RING(CP_PACKET0(R300_RB3D_AARESOLVE_CTL, 0));
789 OUT_RING(0);
790 ADVANCE_RING();
791 BEGIN_RING(2);
792 OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
793 OUT_RING(RADEON_WAIT_3D_IDLECLEAN);
794 ADVANCE_RING();
795 /* flush & purge 2d through E2 as RB2D will trigger lockup */
796 BEGIN_RING(4);
797 OUT_RING(CP_PACKET0(R300_DSTCACHE_CTLSTAT, 0));
798 OUT_RING(cache_2d);
799 OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
800 OUT_RING(RADEON_WAIT_2D_IDLECLEAN |
801 RADEON_WAIT_HOST_IDLECLEAN);
726 ADVANCE_RING(); 802 ADVANCE_RING();
803 /* set flush & purge flags */
804 dev_priv->track_flush |= RADEON_FLUSH_EMITED | RADEON_PURGE_EMITED;
727} 805}
728 806
729/** 807/**
@@ -905,8 +983,7 @@ int r300_do_cp_cmdbuf(struct drm_device *dev,
905 983
906 DRM_DEBUG("\n"); 984 DRM_DEBUG("\n");
907 985
908 /* See the comment above r300_emit_begin3d for why this call must be here, 986 /* pacify */
909 * and what the cleanup gotos are for. */
910 r300_pacify(dev_priv); 987 r300_pacify(dev_priv);
911 988
912 if (cmdbuf->nbox <= R300_SIMULTANEOUS_CLIPRECTS) { 989 if (cmdbuf->nbox <= R300_SIMULTANEOUS_CLIPRECTS) {