[PATCH i-g-t,v2 6/6] lib/intel_compute: Allow the user to provide input and output buffers

Zbigniew Kempczyński zbigniew.kempczynski at intel.com
Wed Feb 26 08:10:39 UTC 2025


On Mon, Feb 24, 2025 at 03:46:14PM +0100, Francois Dugast wrote:
> Allow the user to create and provide the buffers to be used as input
> and as output of the compute kernel. This allows special handling as
> well as read/write from outside the compute library. Support is
> limited to xe2lpg.
> 
> Signed-off-by: Francois Dugast <francois.dugast at intel.com>
> ---
>  lib/intel_compute.c | 32 ++++++++++++++++++++++++--------
>  lib/intel_compute.h |  2 ++
>  2 files changed, 26 insertions(+), 8 deletions(-)
> 
> diff --git a/lib/intel_compute.c b/lib/intel_compute.c
> index 4818c0ff7..cb9561946 100644
> --- a/lib/intel_compute.c
> +++ b/lib/intel_compute.c
> @@ -1665,6 +1665,8 @@ static void xe2lpg_compute_exec(int fd, const unsigned char *kernel,
>  
>  	struct bo_execenv execenv;
>  	float *input_data, *output_data;
> +	uint64_t bind_input_addr = (user && user->input_addr) ? user->input_addr : ADDR_INPUT;
> +	uint64_t bind_output_addr = (user && user->output_addr) ? user->output_addr : ADDR_OUTPUT;
>  
>  	bo_execenv_create(fd, &execenv, eci, user);
>  
> @@ -1675,16 +1677,24 @@ static void xe2lpg_compute_exec(int fd, const unsigned char *kernel,
>  
>  	memcpy(bo_dict[0].data, kernel, size);
>  	create_dynamic_state(bo_dict[1].data, OFFSET_KERNEL);
> -	xehp_create_surface_state(bo_dict[2].data, ADDR_INPUT, ADDR_OUTPUT);
> -	xehp_create_indirect_data(bo_dict[3].data, ADDR_INPUT, ADDR_OUTPUT, SIZE_DATA);
> -	xehp_create_surface_state(bo_dict[7].data, ADDR_INPUT, ADDR_OUTPUT);
> +	xehp_create_surface_state(bo_dict[2].data, bind_input_addr, bind_output_addr);
> +	xehp_create_indirect_data(bo_dict[3].data, bind_input_addr, bind_output_addr, SIZE_DATA);
> +	xehp_create_surface_state(bo_dict[7].data, bind_input_addr, bind_output_addr);
>  
> -	input_data = (float *) bo_dict[4].data;
> -	output_data = (float *) bo_dict[5].data;
> -	srand(time(NULL));
> +	if (user && user->input_addr) {
> +		input_data = (float *) user->input_addr;
> +	} else {
> +		input_data = (float *) bo_dict[4].data;
> +		srand(time(NULL));
>  
> -	for (int i = 0; i < SIZE_DATA; i++)
> -		input_data[i] = rand() / (float)RAND_MAX;
> +		for (int i = 0; i < SIZE_DATA; i++)
> +			input_data[i] = rand() / (float)RAND_MAX;
> +	}
> +
> +	if (user && user->output_addr)
> +		output_data = (float *) user->output_addr;
> +	else
> +		output_data = (float *) bo_dict[5].data;
>  
>  	xe2lpg_compute_exec_compute(bo_dict[8].data,
>  				  ADDR_GENERAL_STATE_BASE,
> @@ -1802,6 +1812,12 @@ static bool __run_intel_compute_kernel(int fd,
>  		return false;
>  	}
>  
> +	if (user && (user->input_addr || user->output_addr) &&
> +	    intel_compute_batches[batch].compute_exec != xe2lpg_compute_exec) {
> +		igt_debug("GPU version 0x%x does not support user input/output buffers\n", ip_ver);
> +		return false;
> +	}
> +
>  	/* If the user provides a kernel, use it */
>  	if (user && user->kernel) {
>  		kernel = user->kernel;
> diff --git a/lib/intel_compute.h b/lib/intel_compute.h
> index dc0fe2ec2..edc17b894 100644
> --- a/lib/intel_compute.h
> +++ b/lib/intel_compute.h
> @@ -55,6 +55,8 @@ struct user_execenv {
>  	unsigned int kernel_size;
>  	/** @skip_results_check: do not verify correctness of the results if true */
>  	bool skip_results_check;
> +	uint64_t input_addr;
> +	uint64_t output_addr;

I like this change, but you should introduce this in all pipelines,
otherwise user passing different address won't see any effect.

--
Zbigniew

>  };
>  
>  extern const struct intel_compute_kernels intel_compute_square_kernels[];
> -- 
> 2.43.0
> 


More information about the igt-dev mailing list