[Mesa-dev] [PATCH 1/2] gallium/radeon: set EVENT_WRITE_EOP.INT_SEL = wait for write confirmation
Nicolai Hähnle
nhaehnle at gmail.com
Mon Aug 28 10:39:15 UTC 2017
On 25.08.2017 02:57, Marek Olšák wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> Ported from Vulkan.
> Not sure what this is good for.. maybe write confirmation from L2 flushes?
I think so, yes.
Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>
> ---
> src/amd/common/r600d_common.h | 3 +++
> src/gallium/drivers/radeon/r600_pipe_common.c | 12 +++++++++---
> 2 files changed, 12 insertions(+), 3 deletions(-)
>
> diff --git a/src/amd/common/r600d_common.h b/src/amd/common/r600d_common.h
> index 5775746..76c5c4f 100644
> --- a/src/amd/common/r600d_common.h
> +++ b/src/amd/common/r600d_common.h
> @@ -60,20 +60,23 @@
> #define COPY_DATA_MEM 1
> #define COPY_DATA_PERF 4
> #define COPY_DATA_IMM 5
> #define COPY_DATA_TIMESTAMP 9
> #define COPY_DATA_DST_SEL(x) (((unsigned)(x) & 0xf) << 8)
> #define COPY_DATA_MEM_ASYNC 5
> #define COPY_DATA_COUNT_SEL (1 << 16)
> #define COPY_DATA_WR_CONFIRM (1 << 20)
> #define PKT3_EVENT_WRITE 0x46
> #define PKT3_EVENT_WRITE_EOP 0x47
> +#define EOP_INT_SEL(x) ((x) << 24)
> +#define EOP_INT_SEL_NONE 0
> +#define EOP_INT_SEL_SEND_DATA_AFTER_WR_CONFIRM 3
> #define EOP_DATA_SEL(x) ((x) << 29)
> #define EOP_DATA_SEL_DISCARD 0
> #define EOP_DATA_SEL_VALUE_32BIT 1
> #define EOP_DATA_SEL_VALUE_64BIT 2
> #define EOP_DATA_SEL_TIMESTAMP 3
> #define PKT3_RELEASE_MEM 0x49 /* GFX9+ */
> #define PKT3_SET_CONFIG_REG 0x68
> #define PKT3_SET_CONTEXT_REG 0x69
> #define PKT3_STRMOUT_BASE_UPDATE 0x72 /* r700 only */
> #define PKT3_SURFACE_BASE_UPDATE 0x73 /* r600 only */
> diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c
> index 7226fc2..7c12565 100644
> --- a/src/gallium/drivers/radeon/r600_pipe_common.c
> +++ b/src/gallium/drivers/radeon/r600_pipe_common.c
> @@ -102,20 +102,26 @@ void radeon_shader_binary_clean(struct ac_shader_binary *b)
> void r600_gfx_write_event_eop(struct r600_common_context *ctx,
> unsigned event, unsigned event_flags,
> unsigned data_sel,
> struct r600_resource *buf, uint64_t va,
> uint32_t new_fence, unsigned query_type)
> {
> struct radeon_winsys_cs *cs = ctx->gfx.cs;
> unsigned op = EVENT_TYPE(event) |
> EVENT_INDEX(5) |
> event_flags;
> + unsigned sel = EOP_DATA_SEL(data_sel);
> +
> + /* Wait for write confirmation before writing data, but don't send
> + * an interrupt. */
> + if (ctx->chip_class >= SI && data_sel != EOP_DATA_SEL_DISCARD)
> + sel |= EOP_INT_SEL(EOP_INT_SEL_SEND_DATA_AFTER_WR_CONFIRM);
>
> if (ctx->chip_class >= GFX9) {
> /* A ZPASS_DONE or PIXEL_STAT_DUMP_EVENT (of the DB occlusion
> * counters) must immediately precede every timestamp event to
> * prevent a GPU hang on GFX9.
> *
> * Occlusion queries don't need to do it here, because they
> * always do ZPASS_DONE before the timestamp.
> */
> if (ctx->chip_class == GFX9 &&
> @@ -129,51 +135,51 @@ void r600_gfx_write_event_eop(struct r600_common_context *ctx,
> radeon_emit(cs, EVENT_TYPE(EVENT_TYPE_ZPASS_DONE) | EVENT_INDEX(1));
> radeon_emit(cs, scratch->gpu_address);
> radeon_emit(cs, scratch->gpu_address >> 32);
>
> radeon_add_to_buffer_list(ctx, &ctx->gfx, scratch,
> RADEON_USAGE_WRITE, RADEON_PRIO_QUERY);
> }
>
> radeon_emit(cs, PKT3(PKT3_RELEASE_MEM, 6, 0));
> radeon_emit(cs, op);
> - radeon_emit(cs, EOP_DATA_SEL(data_sel));
> + radeon_emit(cs, sel);
> radeon_emit(cs, va); /* address lo */
> radeon_emit(cs, va >> 32); /* address hi */
> radeon_emit(cs, new_fence); /* immediate data lo */
> radeon_emit(cs, 0); /* immediate data hi */
> radeon_emit(cs, 0); /* unused */
> } else {
> if (ctx->chip_class == CIK ||
> ctx->chip_class == VI) {
> struct r600_resource *scratch = ctx->eop_bug_scratch;
> uint64_t va = scratch->gpu_address;
>
> /* Two EOP events are required to make all engines go idle
> * (and optional cache flushes executed) before the timestamp
> * is written.
> */
> radeon_emit(cs, PKT3(PKT3_EVENT_WRITE_EOP, 4, 0));
> radeon_emit(cs, op);
> radeon_emit(cs, va);
> - radeon_emit(cs, ((va >> 32) & 0xffff) | EOP_DATA_SEL(data_sel));
> + radeon_emit(cs, ((va >> 32) & 0xffff) | sel);
> radeon_emit(cs, 0); /* immediate data */
> radeon_emit(cs, 0); /* unused */
>
> radeon_add_to_buffer_list(ctx, &ctx->gfx, scratch,
> RADEON_USAGE_WRITE, RADEON_PRIO_QUERY);
> }
>
> radeon_emit(cs, PKT3(PKT3_EVENT_WRITE_EOP, 4, 0));
> radeon_emit(cs, op);
> radeon_emit(cs, va);
> - radeon_emit(cs, ((va >> 32) & 0xffff) | EOP_DATA_SEL(data_sel));
> + radeon_emit(cs, ((va >> 32) & 0xffff) | sel);
> radeon_emit(cs, new_fence); /* immediate data */
> radeon_emit(cs, 0); /* unused */
> }
>
> if (buf)
> r600_emit_reloc(ctx, &ctx->gfx, buf, RADEON_USAGE_WRITE,
> RADEON_PRIO_QUERY);
> }
>
> unsigned r600_gfx_write_fence_dwords(struct r600_common_screen *screen)
>
--
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.
More information about the mesa-dev
mailing list