gallium/radeon: fix (S)DMA read-after-write hazards

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
This commit is contained in:
Marek Olšák
2016-04-26 19:29:55 +02:00
parent f837c37f02
commit a512da36ae
8 changed files with 32 additions and 0 deletions

View File

@@ -77,6 +77,7 @@ void evergreen_dma_copy_buffer(struct r600_context *rctx,
src_offset += csize << shift;
size -= csize;
}
r600_dma_emit_wait_idle(&rctx->b);
}
/* The max number of bytes to copy per packet. */

View File

@@ -3470,6 +3470,7 @@ static void evergreen_dma_copy_tile(struct r600_context *rctx,
addr += cheight * pitch;
y += cheight;
}
r600_dma_emit_wait_idle(&rctx->b);
}
static void evergreen_dma_copy(struct pipe_context *ctx,

View File

@@ -484,4 +484,5 @@ void r600_dma_copy_buffer(struct r600_context *rctx,
src_offset += csize << 2;
size -= csize;
}
r600_dma_emit_wait_idle(&rctx->b);
}

View File

@@ -2941,6 +2941,7 @@ static boolean r600_dma_copy_tile(struct r600_context *rctx,
addr += cheight * pitch;
y += cheight;
}
r600_dma_emit_wait_idle(&rctx->b);
return TRUE;
}

View File

@@ -149,6 +149,30 @@ void r600_need_dma_space(struct r600_common_context *ctx, unsigned num_dw)
}
}
/* This is required to prevent read-after-write hazards. */
void r600_dma_emit_wait_idle(struct r600_common_context *rctx)
{
struct radeon_winsys_cs *cs = rctx->dma.cs;
/* done at the end of DMA calls, so increment this. */
rctx->num_dma_calls++;
r600_need_dma_space(rctx, 1);
if (cs->cdw == 0) /* empty queue */
return;
/* NOP waits for idle on Evergreen and later. */
if (rctx->chip_class >= CIK)
radeon_emit(cs, 0x00000000); /* NOP */
else if (rctx->chip_class >= EVERGREEN)
radeon_emit(cs, 0xf0000000); /* NOP */
else {
/* TODO: R600-R700 should use the FENCE packet.
* CS checker support is required. */
}
}
static void r600_memory_barrier(struct pipe_context *ctx, unsigned flags)
{
}

View File

@@ -598,6 +598,7 @@ struct pipe_resource *r600_resource_create_common(struct pipe_screen *screen,
const struct pipe_resource *templ);
const char *r600_get_llvm_processor_name(enum radeon_family family);
void r600_need_dma_space(struct r600_common_context *ctx, unsigned num_dw);
void r600_dma_emit_wait_idle(struct r600_common_context *rctx);
/* r600_gpu_load.c */
void r600_gpu_load_kill_thread(struct r600_common_screen *rscreen);

View File

@@ -87,6 +87,7 @@ static void cik_sdma_copy_buffer(struct si_context *ctx,
dst_offset + size);
cik_sdma_do_copy_buffer(ctx, dst, src, dst_offset, src_offset, size);
r600_dma_emit_wait_idle(&ctx->b);
}
static void cik_sdma_copy(struct pipe_context *ctx,

View File

@@ -82,6 +82,7 @@ static void si_dma_copy_buffer(struct si_context *ctx,
src_offset += csize << shift;
size -= csize;
}
r600_dma_emit_wait_idle(&ctx->b);
}
static void si_dma_copy_tile(struct si_context *ctx,
@@ -188,6 +189,7 @@ static void si_dma_copy_tile(struct si_context *ctx,
addr += cheight * pitch;
tiled_y += cheight;
}
r600_dma_emit_wait_idle(&ctx->b);
}
static void si_dma_copy(struct pipe_context *ctx,