summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2013-09-06 16:43:34 -0400
committerCarl Worth <cworth@cworth.org>2013-10-02 21:47:02 -0700
commit4a8d1c5ef2f9c57a3c2feb829be3534ac43b9077 (patch)
tree3fb60a4aacaf30db2e6ce3084c0ac28197b435c3
parent5af672491a695857d8e535e8684dc083a757bf15 (diff)
radeon/winsys: pad IBs to a multiple of 8 DWs
This aligns the gfx, compute, and dma IBs to 8 DW boundries. This aligns the the IB to the fetch size of the CP for optimal performance. Additionally, r6xx hardware requires at least 4 DW alignment to avoid a hw bug. This also aligns the DMA IBs to 8 DW which is required for the DMA engine. This alignment is already handled in the gallium driver, but that patch can be removed now that it's done in the winsys. Reviewed-by: Marek Olšák <marek.olsak@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> CC: "9.2" <mesa-stable@lists.freedesktop.org> CC: "9.1" <mesa-stable@lists.freedesktop.org> (cherry picked from commit a81beee37e0dd7b75422448420e8e8b0b4b76c1e)
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm_cs.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
index 6a7115ba76b..007d1290114 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
@@ -455,6 +455,36 @@ static void radeon_drm_cs_flush(struct radeon_winsys_cs *rcs, unsigned flags)
struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
struct radeon_cs_context *tmp;
+ switch (cs->base.ring_type) {
+ case RING_DMA:
+ /* pad DMA ring to 8 DWs */
+ if (cs->ws->info.chip_class <= SI) {
+ while (rcs->cdw & 7)
+ OUT_CS(&cs->base, 0xf0000000); /* NOP packet */
+ } else {
+ while (rcs->cdw & 7)
+ OUT_CS(&cs->base, 0x00000000); /* NOP packet */
+ }
+ break;
+ case RING_GFX:
+ /* pad DMA ring to 8 DWs to meet CP fetch alignment requirements
+ * r6xx, requires at least 4 dw alignment to avoid a hw bug.
+ */
+ if (flags & RADEON_FLUSH_COMPUTE) {
+ if (cs->ws->info.chip_class <= SI) {
+ while (rcs->cdw & 7)
+ OUT_CS(&cs->base, 0x80000000); /* type2 nop packet */
+ } else {
+ while (rcs->cdw & 7)
+ OUT_CS(&cs->base, 0xffff1000); /* type3 nop packet */
+ }
+ } else {
+ while (rcs->cdw & 7)
+ OUT_CS(&cs->base, 0x80000000); /* type2 nop packet */
+ }
+ break;
+ }
+
if (rcs->cdw > RADEON_MAX_CMDBUF_DWORDS) {
fprintf(stderr, "radeon: command stream overflowed\n");
}