[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