[Mesa-dev] [PATCH] [RFC] r600g: rework handling of the constants

Tom Stellard tom at stellard.net
Thu Dec 20 07:41:32 PST 2012


On Thu, Dec 20, 2012 at 04:47:51PM +0400, Vadim Girlin wrote:
> Pack kc_bank, const_index and chan into the load.const operand, unpack
> them in r600_alu_from_byte_stream and use to override sel, kc_bank and chan
> for the constants.
> 
> Expected operand value is (((512 + (kc_bank << 12) + const_index) << 2) + chan).
> ---
>  src/gallium/drivers/r600/r600_llvm.c   |  6 +++++-
>  src/gallium/drivers/r600/r600_shader.c | 33 ++++++++++++++++++++++++++-------
>  2 files changed, 31 insertions(+), 8 deletions(-)
> 
> diff --git a/src/gallium/drivers/r600/r600_llvm.c b/src/gallium/drivers/r600/r600_llvm.c
> index 17d362c..110ba64 100644
> --- a/src/gallium/drivers/r600/r600_llvm.c
> +++ b/src/gallium/drivers/r600/r600_llvm.c
> @@ -25,8 +25,12 @@ static LLVMValueRef llvm_fetch_const(
>  	enum tgsi_opcode_type type,
>  	unsigned swizzle)
>  {
> +	/* load.const's operand currently goes through the compiler unmodified,
> +	 * encoding expected by the bytestream reader is
> +	 * ((512 + (4096 * kc_bank) + const_index)*4 + chan)
> +	 */
>  	LLVMValueRef idx = lp_build_const_int32(bld_base->base.gallivm,
> -			radeon_llvm_reg_index_soa(reg->Register.Index, swizzle));
> +			radeon_llvm_reg_index_soa(reg->Register.Index + 512, swizzle));
>  	LLVMValueRef cval = build_intrinsic(bld_base->base.gallivm->builder,
>  		"llvm.AMDGPU.load.const", bld_base->base.elem_type,
>  		&idx, 1, LLVMReadNoneAttribute);

While we are changing this, I think we should replace the load.const intrinsic
with a load from the constant address space.  You can pass the encoded value as
the pointer.  We do something very similar with USER_SGPRs in radeonsi, so you can
look at use_sgpr() in radeonsi_shader.c and also SITargetLowering::LowerLOAD() in
SIISelLowering.cpp as an example of how to do this.

> diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
> index bcd43f1..5b97088 100644
> --- a/src/gallium/drivers/r600/r600_shader.c
> +++ b/src/gallium/drivers/r600/r600_shader.c
> @@ -299,15 +299,21 @@ static unsigned r600_src_from_byte_stream(unsigned char * bytes,
>  static unsigned r600_alu_from_byte_stream(struct r600_shader_ctx *ctx,
>  				unsigned char * bytes, unsigned bytes_read)
>  {
> -	unsigned src_idx;
> +	unsigned src_idx, src_num;
>  	struct r600_bytecode_alu alu;
> -	unsigned src_const_reg[3];
> +	unsigned src_use_sel[3];
> +	unsigned src_sel[3] = {};
>  	uint32_t word0, word1;
>  
> +	src_num = bytes[bytes_read++];
> +
>  	memset(&alu, 0, sizeof(alu));
> -	for(src_idx = 0; src_idx < 3; src_idx++) {
> +	for(src_idx = 0; src_idx < src_num; src_idx++) {
>  		unsigned i;
> -		src_const_reg[src_idx] = bytes[bytes_read++];
> +		src_use_sel[src_idx] = bytes[bytes_read++];
> +		for (i = 0; i < 4; i++) {
> +			src_sel[src_idx] |= bytes[bytes_read++] << (i * 8);
> +		}
>  		for (i = 0; i < 4; i++) {
>  			alu.src[src_idx].value |= bytes[bytes_read++] << (i * 8);
>  		}
> @@ -327,9 +333,22 @@ static unsigned r600_alu_from_byte_stream(struct r600_shader_ctx *ctx,
>  		break;
>  	}
>  
> -	for(src_idx = 0; src_idx < 3; src_idx++) {
> -		if (src_const_reg[src_idx])
> -			alu.src[src_idx].sel += 512;
> +	for(src_idx = 0; src_idx < src_num; src_idx++) {
> +		if (src_use_sel[src_idx]) {
> +			unsigned sel = src_sel[src_idx];
> +
> +			alu.src[src_idx].chan = sel & 3;
> +			sel >>= 2;
> +
> +			if (sel>=512) { /* constant */
> +				sel -= 512;
> +				alu.src[src_idx].kc_bank = sel >> 12;
> +				alu.src[src_idx].sel = (sel & 4095) + 512;
> +			}
> +			else {
> +				alu.src[src_idx].sel = sel;
> +			}
> +		}
>  	}

As I mentioned in the other patch, it seems like a lot of this logic could
be moved into the LLVM backend.


-Tom
>  
>  #if HAVE_LLVM < 0x0302
> -- 
> 1.8.0.2
> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list