[Mesa-dev,3/9] radeonsi: use S_BFE/V_BFE for extracting bitfields from parameters

Submitted by Marek Olšák on March 2, 2015, 11:54 a.m.

Details

Message ID 1425297263-25991-3-git-send-email-maraeo@gmail.com
State New
Headers show

Not browsing as part of any series.

Commit Message

Marek Olšák March 2, 2015, 11:54 a.m.
From: Marek Olšák <marek.olsak@amd.com>

And use AND/OR in special cases.

This universal helper will be used a lot (especially by tessellation).
---
 src/gallium/drivers/radeonsi/si_shader.c | 48 +++++++++++++++++++++-----------
 1 file changed, 32 insertions(+), 16 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index f125483..085a350 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -206,6 +206,35 @@  static LLVMValueRef build_bfe(struct gallivm_state *gallivm,
 }
 
 /**
+ * Get the value of a shader input parameter and extract a bitfield.
+ */
+static LLVMValueRef unpack_param(struct si_shader_context *si_shader_ctx,
+				 unsigned param, unsigned rshift,
+				 unsigned bitwidth)
+{
+	struct gallivm_state *gallivm = &si_shader_ctx->radeon_bld.gallivm;
+	LLVMValueRef value = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn,
+					  param);
+
+	if (rshift) {
+		if (rshift + bitwidth < 32)
+			return build_bfe(gallivm, value,
+					 lp_build_const_int32(gallivm, rshift),
+					 lp_build_const_int32(gallivm, bitwidth));
+		else
+			return LLVMBuildLShr(gallivm->builder, value,
+					     lp_build_const_int32(gallivm, rshift), "");
+	} else {
+		if (bitwidth < 32) {
+			unsigned mask = (1 << bitwidth) - 1;
+			return LLVMBuildAnd(gallivm->builder, value,
+					    lp_build_const_int32(gallivm, mask), "");
+		} else
+			return value;
+	}
+}
+
+/**
  * Build an LLVM bytecode indexed load using LLVMBuildGEP + LLVMBuildLoad.
  * It's equivalent to doing a load from &base_ptr[index].
  *
@@ -575,14 +604,8 @@  static void declare_input_fs(
 
 static LLVMValueRef get_sample_id(struct radeon_llvm_context *radeon_bld)
 {
-	struct gallivm_state *gallivm = &radeon_bld->gallivm;
-	LLVMValueRef value = LLVMGetParam(radeon_bld->main_fn,
-					  SI_PARAM_ANCILLARY);
-	value = LLVMBuildLShr(gallivm->builder, value,
-			      lp_build_const_int32(gallivm, 8), "");
-	value = LLVMBuildAnd(gallivm->builder, value,
-			     lp_build_const_int32(gallivm, 0xf), "");
-	return value;
+	return unpack_param(si_shader_context(&radeon_bld->soa.bld_base),
+			    SI_PARAM_ANCILLARY, 8, 4);
 }
 
 /**
@@ -990,16 +1013,9 @@  static void si_llvm_emit_streamout(struct si_shader_context *shader,
 
 	LLVMTypeRef i32 = LLVMInt32TypeInContext(gallivm->context);
 
-	LLVMValueRef so_param =
-		LLVMGetParam(shader->radeon_bld.main_fn,
-			     shader->param_streamout_config);
-
 	/* Get bits [22:16], i.e. (so_param >> 16) & 127; */
 	LLVMValueRef so_vtx_count =
-		LLVMBuildAnd(builder,
-			     LLVMBuildLShr(builder, so_param,
-					   LLVMConstInt(i32, 16, 0), ""),
-			     LLVMConstInt(i32, 127, 0), "");
+		unpack_param(shader, shader->param_streamout_config, 16, 7);
 
 	LLVMValueRef tid = build_intrinsic(builder, "llvm.SI.tid", i32,
 					   NULL, 0, LLVMReadNoneAttribute);

Comments

On Mon, Mar 02, 2015 at 12:54:17PM +0100, Marek Olšák wrote:
> From: Marek Olšák <marek.olsak@amd.com>

Reviewed-by: Tom Stellard <thomas.stellard@amd.com>
> 
> And use AND/OR in special cases.
> 
> This universal helper will be used a lot (especially by tessellation).
> ---
>  src/gallium/drivers/radeonsi/si_shader.c | 48 +++++++++++++++++++++-----------
>  1 file changed, 32 insertions(+), 16 deletions(-)
> 
> diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
> index f125483..085a350 100644
> --- a/src/gallium/drivers/radeonsi/si_shader.c
> +++ b/src/gallium/drivers/radeonsi/si_shader.c
> @@ -206,6 +206,35 @@ static LLVMValueRef build_bfe(struct gallivm_state *gallivm,
>  }
>  
>  /**
> + * Get the value of a shader input parameter and extract a bitfield.
> + */
> +static LLVMValueRef unpack_param(struct si_shader_context *si_shader_ctx,
> +				 unsigned param, unsigned rshift,
> +				 unsigned bitwidth)
> +{
> +	struct gallivm_state *gallivm = &si_shader_ctx->radeon_bld.gallivm;
> +	LLVMValueRef value = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn,
> +					  param);
> +
> +	if (rshift) {
> +		if (rshift + bitwidth < 32)
> +			return build_bfe(gallivm, value,
> +					 lp_build_const_int32(gallivm, rshift),
> +					 lp_build_const_int32(gallivm, bitwidth));
> +		else
> +			return LLVMBuildLShr(gallivm->builder, value,
> +					     lp_build_const_int32(gallivm, rshift), "");
> +	} else {
> +		if (bitwidth < 32) {
> +			unsigned mask = (1 << bitwidth) - 1;
> +			return LLVMBuildAnd(gallivm->builder, value,
> +					    lp_build_const_int32(gallivm, mask), "");
> +		} else
> +			return value;
> +	}
> +}
> +
> +/**
>   * Build an LLVM bytecode indexed load using LLVMBuildGEP + LLVMBuildLoad.
>   * It's equivalent to doing a load from &base_ptr[index].
>   *
> @@ -575,14 +604,8 @@ static void declare_input_fs(
>  
>  static LLVMValueRef get_sample_id(struct radeon_llvm_context *radeon_bld)
>  {
> -	struct gallivm_state *gallivm = &radeon_bld->gallivm;
> -	LLVMValueRef value = LLVMGetParam(radeon_bld->main_fn,
> -					  SI_PARAM_ANCILLARY);
> -	value = LLVMBuildLShr(gallivm->builder, value,
> -			      lp_build_const_int32(gallivm, 8), "");
> -	value = LLVMBuildAnd(gallivm->builder, value,
> -			     lp_build_const_int32(gallivm, 0xf), "");
> -	return value;
> +	return unpack_param(si_shader_context(&radeon_bld->soa.bld_base),
> +			    SI_PARAM_ANCILLARY, 8, 4);
>  }
>  
>  /**
> @@ -990,16 +1013,9 @@ static void si_llvm_emit_streamout(struct si_shader_context *shader,
>  
>  	LLVMTypeRef i32 = LLVMInt32TypeInContext(gallivm->context);
>  
> -	LLVMValueRef so_param =
> -		LLVMGetParam(shader->radeon_bld.main_fn,
> -			     shader->param_streamout_config);
> -
>  	/* Get bits [22:16], i.e. (so_param >> 16) & 127; */
>  	LLVMValueRef so_vtx_count =
> -		LLVMBuildAnd(builder,
> -			     LLVMBuildLShr(builder, so_param,
> -					   LLVMConstInt(i32, 16, 0), ""),
> -			     LLVMConstInt(i32, 127, 0), "");
> +		unpack_param(shader, shader->param_streamout_config, 16, 7);
>  
>  	LLVMValueRef tid = build_intrinsic(builder, "llvm.SI.tid", i32,
>  					   NULL, 0, LLVMReadNoneAttribute);
> -- 
> 2.1.0
> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev