[Mesa-dev] [PATCH 2/2] ac/radeonsi: add support for tex instr without a derefence

Nicolai Hähnle nhaehnle at gmail.com
Thu Nov 2 16:21:46 UTC 2017


Both patches:

Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>


On 01.11.2017 02:43, Timothy Arceri wrote:
> These are produced by nir_lower_bitmap(), adding the missing derefence
> would cause other issues that need to be hacked around such as
> skipping sampler lowering and uniform location assignment, so this
> change seems the correct way to go.
> 
> Fixes 194 piglit crashes on radeonsi using NIR.
> ---
>   src/amd/common/ac_nir_to_llvm.c              | 80 ++++++++++++++++------------
>   src/gallium/drivers/radeonsi/si_shader_nir.c |  5 ++
>   2 files changed, 51 insertions(+), 34 deletions(-)
> 
> diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c
> index a736d34d12..2ec30517e0 100644
> --- a/src/amd/common/ac_nir_to_llvm.c
> +++ b/src/amd/common/ac_nir_to_llvm.c
> @@ -173,20 +173,21 @@ struct nir_to_llvm_context {
>   static inline struct nir_to_llvm_context *
>   nir_to_llvm_context_from_abi(struct ac_shader_abi *abi)
>   {
>   	struct nir_to_llvm_context *ctx = NULL;
>   	return container_of(abi, ctx, abi);
>   }
>   
>   static LLVMValueRef get_sampler_desc(struct ac_nir_context *ctx,
>   				     const nir_deref_var *deref,
>   				     enum ac_descriptor_type desc_type,
> +				     const nir_tex_instr *instr,
>   				     bool image, bool write);
>   
>   static unsigned radeon_llvm_reg_index_soa(unsigned index, unsigned chan)
>   {
>   	return (index * 4) + chan;
>   }
>   
>   static unsigned shader_io_get_unique_index(gl_varying_slot slot)
>   {
>   	/* handle patch indices separate */
> @@ -3385,21 +3386,21 @@ static LLVMValueRef get_image_coords(struct ac_nir_context *ctx,
>   					LLVMBuildAdd(ctx->ac.builder, fmask_load_address[chan],
>   						LLVMBuildFPToUI(ctx->ac.builder, ctx->abi->frag_pos[chan],
>   								ctx->ac.i32, ""), "");
>   			fmask_load_address[2] = ac_to_integer(&ctx->ac, ctx->abi->inputs[radeon_llvm_reg_index_soa(VARYING_SLOT_LAYER, 0)]);
>   		}
>   		sample_index = adjust_sample_index_using_fmask(&ctx->ac,
>   							       fmask_load_address[0],
>   							       fmask_load_address[1],
>   							       fmask_load_address[2],
>   							       sample_index,
> -							       get_sampler_desc(ctx, instr->variables[0], AC_DESC_FMASK, true, false));
> +							       get_sampler_desc(ctx, instr->variables[0], AC_DESC_FMASK, NULL, true, false));
>   	}
>   	if (count == 1 && !gfx9_1d) {
>   		if (instr->src[0].ssa->num_components)
>   			res = LLVMBuildExtractElement(ctx->ac.builder, src0, masks[0], "");
>   		else
>   			res = src0;
>   	} else {
>   		int chan;
>   		if (is_ms)
>   			count--;
> @@ -3444,42 +3445,42 @@ static LLVMValueRef visit_image_load(struct ac_nir_context *ctx,
>   	LLVMValueRef res;
>   	char intrinsic_name[64];
>   	const nir_variable *var = instr->variables[0]->var;
>   	const struct glsl_type *type = var->type;
>   
>   	if(instr->variables[0]->deref.child)
>   		type = instr->variables[0]->deref.child->type;
>   
>   	type = glsl_without_array(type);
>   	if (glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_BUF) {
> -		params[0] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_BUFFER, true, false);
> +		params[0] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_BUFFER, NULL, true, false);
>   		params[1] = LLVMBuildExtractElement(ctx->ac.builder, get_src(ctx, instr->src[0]),
>   						    ctx->ac.i32_0, ""); /* vindex */
>   		params[2] = ctx->ac.i32_0; /* voffset */
>   		params[3] = ctx->ac.i1false;  /* glc */
>   		params[4] = ctx->ac.i1false;  /* slc */
>   		res = ac_build_intrinsic(&ctx->ac, "llvm.amdgcn.buffer.load.format.v4f32", ctx->ac.v4f32,
>   					 params, 5, 0);
>   
>   		res = trim_vector(&ctx->ac, res, instr->dest.ssa.num_components);
>   		res = ac_to_integer(&ctx->ac, res);
>   	} else {
>   		bool is_da = glsl_sampler_type_is_array(type) ||
>   			     glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_CUBE ||
>   			     glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_SUBPASS ||
>   			     glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_SUBPASS_MS;
>   		LLVMValueRef da = is_da ? ctx->ac.i1true : ctx->ac.i1false;
>   		LLVMValueRef glc = ctx->ac.i1false;
>   		LLVMValueRef slc = ctx->ac.i1false;
>   
>   		params[0] = get_image_coords(ctx, instr);
> -		params[1] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_IMAGE, true, false);
> +		params[1] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_IMAGE, NULL, true, false);
>   		params[2] = LLVMConstInt(ctx->ac.i32, 15, false); /* dmask */
>   		if (HAVE_LLVM <= 0x0309) {
>   			params[3] = ctx->ac.i1false;  /* r128 */
>   			params[4] = da;
>   			params[5] = glc;
>   			params[6] = slc;
>   		} else {
>   			LLVMValueRef lwe = ctx->ac.i1false;
>   			params[3] = glc;
>   			params[4] = slc;
> @@ -3506,37 +3507,37 @@ static void visit_image_store(struct ac_nir_context *ctx,
>   	char intrinsic_name[64];
>   	const nir_variable *var = instr->variables[0]->var;
>   	const struct glsl_type *type = glsl_without_array(var->type);
>   	LLVMValueRef glc = ctx->ac.i1false;
>   	bool force_glc = ctx->ac.chip_class == SI;
>   	if (force_glc)
>   		glc = ctx->ac.i1true;
>   
>   	if (glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_BUF) {
>   		params[0] = ac_to_float(&ctx->ac, get_src(ctx, instr->src[2])); /* data */
> -		params[1] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_BUFFER, true, true);
> +		params[1] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_BUFFER, NULL, true, true);
>   		params[2] = LLVMBuildExtractElement(ctx->ac.builder, get_src(ctx, instr->src[0]),
>   						    ctx->ac.i32_0, ""); /* vindex */
>   		params[3] = ctx->ac.i32_0; /* voffset */
>   		params[4] = glc;  /* glc */
>   		params[5] = ctx->ac.i1false;  /* slc */
>   		ac_build_intrinsic(&ctx->ac, "llvm.amdgcn.buffer.store.format.v4f32", ctx->ac.voidt,
>   				   params, 6, 0);
>   	} else {
>   		bool is_da = glsl_sampler_type_is_array(type) ||
>   			     glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_CUBE;
>   		LLVMValueRef da = is_da ? ctx->ac.i1true : ctx->ac.i1false;
>   		LLVMValueRef slc = ctx->ac.i1false;
>   
>   		params[0] = ac_to_float(&ctx->ac, get_src(ctx, instr->src[2]));
>   		params[1] = get_image_coords(ctx, instr); /* coords */
> -		params[2] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_IMAGE, true, true);
> +		params[2] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_IMAGE, NULL, true, true);
>   		params[3] = LLVMConstInt(ctx->ac.i32, 15, false); /* dmask */
>   		if (HAVE_LLVM <= 0x0309) {
>   			params[4] = ctx->ac.i1false;  /* r128 */
>   			params[5] = da;
>   			params[6] = glc;
>   			params[7] = slc;
>   		} else {
>   			LLVMValueRef lwe = ctx->ac.i1false;
>   			params[4] = glc;
>   			params[5] = slc;
> @@ -3598,37 +3599,37 @@ static LLVMValueRef visit_image_atomic(struct ac_nir_context *ctx,
>   	default:
>   		abort();
>   	}
>   
>   	if (instr->intrinsic == nir_intrinsic_image_atomic_comp_swap)
>   		params[param_count++] = get_src(ctx, instr->src[3]);
>   	params[param_count++] = get_src(ctx, instr->src[2]);
>   
>   	if (glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_BUF) {
>   		params[param_count++] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_BUFFER,
> -							 true, true);
> +							 NULL, true, true);
>   		params[param_count++] = LLVMBuildExtractElement(ctx->ac.builder, get_src(ctx, instr->src[0]),
>   								ctx->ac.i32_0, ""); /* vindex */
>   		params[param_count++] = ctx->ac.i32_0; /* voffset */
>   		params[param_count++] = ctx->ac.i1false;  /* slc */
>   
>   		length = snprintf(intrinsic_name, sizeof(intrinsic_name),
>   				  "llvm.amdgcn.buffer.atomic.%s", atomic_name);
>   	} else {
>   		char coords_type[8];
>   
>   		bool da = glsl_sampler_type_is_array(type) ||
>   		          glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_CUBE;
>   
>   		LLVMValueRef coords = params[param_count++] = get_image_coords(ctx, instr);
>   		params[param_count++] = get_sampler_desc(ctx, instr->variables[0], AC_DESC_IMAGE,
> -							 true, true);
> +							 NULL, true, true);
>   		params[param_count++] = ctx->ac.i1false; /* r128 */
>   		params[param_count++] = da ? ctx->ac.i1true : ctx->ac.i1false;      /* da */
>   		params[param_count++] = ctx->ac.i1false;  /* slc */
>   
>   		build_int_type_name(LLVMTypeOf(coords),
>   				    coords_type, sizeof(coords_type));
>   
>   		length = snprintf(intrinsic_name, sizeof(intrinsic_name),
>   				  "llvm.amdgcn.image.atomic.%s.%s", atomic_name, coords_type);
>   	}
> @@ -3644,27 +3645,27 @@ static LLVMValueRef visit_image_size(struct ac_nir_context *ctx,
>   	const nir_variable *var = instr->variables[0]->var;
>   	const struct glsl_type *type = instr->variables[0]->var->type;
>   	bool da = glsl_sampler_type_is_array(var->type) ||
>   	          glsl_get_sampler_dim(var->type) == GLSL_SAMPLER_DIM_CUBE;
>   	if(instr->variables[0]->deref.child)
>   		type = instr->variables[0]->deref.child->type;
>   
>   	if (glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_BUF)
>   		return get_buffer_size(ctx,
>   			get_sampler_desc(ctx, instr->variables[0],
> -					 AC_DESC_BUFFER, true, false), true);
> +					 AC_DESC_BUFFER, NULL, true, false), true);
>   
>   	struct ac_image_args args = { 0 };
>   
>   	args.da = da;
>   	args.dmask = 0xf;
> -	args.resource = get_sampler_desc(ctx, instr->variables[0], AC_DESC_IMAGE, true, false);
> +	args.resource = get_sampler_desc(ctx, instr->variables[0], AC_DESC_IMAGE, NULL, true, false);
>   	args.opcode = ac_image_get_resinfo;
>   	args.addr = ctx->ac.i32_0;
>   
>   	res = ac_build_image_opcode(&ctx->ac, &args);
>   
>   	LLVMValueRef two = LLVMConstInt(ctx->ac.i32, 2, false);
>   
>   	if (glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_CUBE &&
>   	    glsl_sampler_type_is_array(type)) {
>   		LLVMValueRef six = LLVMConstInt(ctx->ac.i32, 6, false);
> @@ -4318,55 +4319,66 @@ static LLVMValueRef radv_get_sampler_desc(struct ac_shader_abi *abi,
>   
>   	list = ac_build_gep0(&ctx->ac, list, LLVMConstInt(ctx->i32, offset, 0));
>   	list = LLVMBuildPointerCast(builder, list, const_array(type, 0), "");
>   
>   	return ac_build_load_to_sgpr(&ctx->ac, list, index);
>   }
>   
>   static LLVMValueRef get_sampler_desc(struct ac_nir_context *ctx,
>   				     const nir_deref_var *deref,
>   				     enum ac_descriptor_type desc_type,
> +				     const nir_tex_instr *tex_instr,
>   				     bool image, bool write)
>   {
>   	LLVMValueRef index = NULL;
>   	unsigned constant_index = 0;
> -	const nir_deref *tail = &deref->deref;
> +	unsigned descriptor_set;
> +	unsigned base_index;
>   
> -	while (tail->child) {
> -		const nir_deref_array *child = nir_deref_as_array(tail->child);
> -		unsigned array_size = glsl_get_aoa_size(tail->child->type);
> +	if (!deref) {
> +		assert(tex_instr && !image);
> +		descriptor_set = 0;
> +		base_index = tex_instr->sampler_index;
> +	} else {
> +		const nir_deref *tail = &deref->deref;
> +		while (tail->child) {
> +			const nir_deref_array *child = nir_deref_as_array(tail->child);
> +			unsigned array_size = glsl_get_aoa_size(tail->child->type);
>   
> -		if (!array_size)
> -			array_size = 1;
> +			if (!array_size)
> +				array_size = 1;
>   
> -		assert(child->deref_array_type != nir_deref_array_type_wildcard);
> +			assert(child->deref_array_type != nir_deref_array_type_wildcard);
>   
> -		if (child->deref_array_type == nir_deref_array_type_indirect) {
> -			LLVMValueRef indirect = get_src(ctx, child->indirect);
> +			if (child->deref_array_type == nir_deref_array_type_indirect) {
> +				LLVMValueRef indirect = get_src(ctx, child->indirect);
>   
> -			indirect = LLVMBuildMul(ctx->ac.builder, indirect,
> -				LLVMConstInt(ctx->ac.i32, array_size, false), "");
> +				indirect = LLVMBuildMul(ctx->ac.builder, indirect,
> +					LLVMConstInt(ctx->ac.i32, array_size, false), "");
>   
> -			if (!index)
> -				index = indirect;
> -			else
> -				index = LLVMBuildAdd(ctx->ac.builder, index, indirect, "");
> -		}
> +				if (!index)
> +					index = indirect;
> +				else
> +					index = LLVMBuildAdd(ctx->ac.builder, index, indirect, "");
> +			}
>   
> -		constant_index += child->base_offset * array_size;
> +			constant_index += child->base_offset * array_size;
>   
> -		tail = &child->deref;
> +			tail = &child->deref;
> +		}
> +		descriptor_set = deref->var->data.descriptor_set;
> +		base_index = deref->var->data.binding;
>   	}
>   
>   	return ctx->abi->load_sampler_desc(ctx->abi,
> -					  deref->var->data.descriptor_set,
> -					  deref->var->data.binding,
> +					  descriptor_set,
> +					  base_index,
>   					  constant_index, index,
>   					  desc_type, image, write);
>   }
>   
>   static void set_tex_fetch_args(struct ac_llvm_context *ctx,
>   			       struct ac_image_args *args,
>   			       const nir_tex_instr *instr,
>   			       nir_texop op,
>   			       LLVMValueRef res_ptr, LLVMValueRef samp_ptr,
>   			       LLVMValueRef *param, unsigned count,
> @@ -4427,34 +4439,34 @@ static LLVMValueRef sici_fix_sampler_aniso(struct ac_nir_context *ctx,
>   	return LLVMBuildInsertElement(builder, samp, samp0,
>   	                              LLVMConstInt(ctx->ac.i32, 0, 0), "");
>   }
>   
>   static void tex_fetch_ptrs(struct ac_nir_context *ctx,
>   			   nir_tex_instr *instr,
>   			   LLVMValueRef *res_ptr, LLVMValueRef *samp_ptr,
>   			   LLVMValueRef *fmask_ptr)
>   {
>   	if (instr->sampler_dim  == GLSL_SAMPLER_DIM_BUF)
> -		*res_ptr = get_sampler_desc(ctx, instr->texture, AC_DESC_BUFFER, false, false);
> +		*res_ptr = get_sampler_desc(ctx, instr->texture, AC_DESC_BUFFER, instr, false, false);
>   	else
> -		*res_ptr = get_sampler_desc(ctx, instr->texture, AC_DESC_IMAGE, false, false);
> +		*res_ptr = get_sampler_desc(ctx, instr->texture, AC_DESC_IMAGE, instr, false, false);
>   	if (samp_ptr) {
>   		if (instr->sampler)
> -			*samp_ptr = get_sampler_desc(ctx, instr->sampler, AC_DESC_SAMPLER, false, false);
> +			*samp_ptr = get_sampler_desc(ctx, instr->sampler, AC_DESC_SAMPLER, instr, false, false);
>   		else
> -			*samp_ptr = get_sampler_desc(ctx, instr->texture, AC_DESC_SAMPLER, false, false);
> +			*samp_ptr = get_sampler_desc(ctx, instr->texture, AC_DESC_SAMPLER, instr, false, false);
>   		if (instr->sampler_dim < GLSL_SAMPLER_DIM_RECT)
>   			*samp_ptr = sici_fix_sampler_aniso(ctx, *res_ptr, *samp_ptr);
>   	}
>   	if (fmask_ptr && !instr->sampler && (instr->op == nir_texop_txf_ms ||
>   					     instr->op == nir_texop_samples_identical))
> -		*fmask_ptr = get_sampler_desc(ctx, instr->texture, AC_DESC_FMASK, false, false);
> +		*fmask_ptr = get_sampler_desc(ctx, instr->texture, AC_DESC_FMASK, instr, false, false);
>   }
>   
>   static LLVMValueRef apply_round_slice(struct ac_llvm_context *ctx,
>   				      LLVMValueRef coord)
>   {
>   	coord = ac_to_float(ctx, coord);
>   	coord = ac_build_intrinsic(ctx, "llvm.rint.f32", ctx->f32, &coord, 1, 0);
>   	coord = ac_to_integer(ctx, coord);
>   	return coord;
>   }
> diff --git a/src/gallium/drivers/radeonsi/si_shader_nir.c b/src/gallium/drivers/radeonsi/si_shader_nir.c
> index 7a88227381..32f6d86647 100644
> --- a/src/gallium/drivers/radeonsi/si_shader_nir.c
> +++ b/src/gallium/drivers/radeonsi/si_shader_nir.c
> @@ -52,20 +52,25 @@ static void scan_instruction(struct tgsi_shader_info *info,
>   		case nir_op_fddx_coarse:
>   		case nir_op_fddy_coarse:
>   			info->uses_derivatives = true;
>   			break;
>   		default:
>   			break;
>   		}
>   	} else if (instr->type == nir_instr_type_tex) {
>   		nir_tex_instr *tex = nir_instr_as_tex(instr);
>   
> +		if (!tex->texture) {
> +			info->samplers_declared |=
> +				u_bit_consecutive(tex->sampler_index, 1);
> +		}
> +
>   		switch (tex->op) {
>   		case nir_texop_tex:
>   		case nir_texop_txb:
>   		case nir_texop_lod:
>   			info->uses_derivatives = true;
>   			break;
>   		default:
>   			break;
>   		}
>   	} else if (instr->type == nir_instr_type_intrinsic) {
> 


-- 
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.


More information about the mesa-dev mailing list