[Mesa-dev] [PATCH 15/15] radeonsi: enable gs support for nir backend

Timothy Arceri tarceri at itsqueeze.com
Wed Nov 22 10:36:08 UTC 2017



On 22/11/17 21:30, Timothy Arceri wrote:
> ---
>   src/gallium/drivers/radeonsi/si_pipe.c       |  3 ++-
>   src/gallium/drivers/radeonsi/si_shader_nir.c | 10 ++++++++--
>   src/mesa/state_tracker/st_glsl_to_nir.cpp    | 12 ++++++++++++
>   3 files changed, 22 insertions(+), 3 deletions(-)
> 
> diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c
> index b3d8ae508b..dffdab5d41 100644
> --- a/src/gallium/drivers/radeonsi/si_pipe.c
> +++ b/src/gallium/drivers/radeonsi/si_pipe.c
> @@ -542,21 +542,21 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
>   	case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
>   	case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
>   	case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
>   	case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
>   	case PIPE_CAP_MAX_VERTEX_STREAMS:
>   	case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
>   		return 4;
>   
>   	case PIPE_CAP_GLSL_FEATURE_LEVEL:
>   		if (sscreen->b.debug_flags & DBG(NIR))
> -			return 140; /* no geometry and tessellation shaders yet */
> +			return 150; /* no tessellation shaders yet */
>   		if (si_have_tgsi_compute(sscreen))
>   			return 450;
>   		return 420;
>   
>   	case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
>   		return MIN2(sscreen->b.info.max_alloc_size, INT_MAX);
>   
>   	case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
>   	case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
>   	case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
> @@ -746,20 +746,21 @@ static int si_get_shader_param(struct pipe_screen* pscreen,
>   		return SI_NUM_SAMPLERS;
>   	case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
>   		return SI_NUM_SHADER_BUFFERS;
>   	case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
>   		return SI_NUM_IMAGES;
>   	case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
>   		return 32;
>   	case PIPE_SHADER_CAP_PREFERRED_IR:
>   		if (sscreen->b.debug_flags & DBG(NIR) &&
>   		    (shader == PIPE_SHADER_VERTEX ||
> +		     shader == PIPE_SHADER_GEOMETRY ||
>   		     shader == PIPE_SHADER_FRAGMENT))
>   			return PIPE_SHADER_IR_NIR;
>   		return PIPE_SHADER_IR_TGSI;
>   	case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:
>   		return 4;
>   
>   	/* Supported boolean features. */
>   	case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
>   	case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
>   	case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
> diff --git a/src/gallium/drivers/radeonsi/si_shader_nir.c b/src/gallium/drivers/radeonsi/si_shader_nir.c
> index 54f79ba0c3..9396403bf0 100644
> --- a/src/gallium/drivers/radeonsi/si_shader_nir.c
> +++ b/src/gallium/drivers/radeonsi/si_shader_nir.c
> @@ -123,20 +123,21 @@ static void scan_instruction(struct tgsi_shader_info *info,
>   	}
>   }
>   
>   void si_nir_scan_shader(const struct nir_shader *nir,
>   			struct tgsi_shader_info *info)
>   {
>   	nir_function *func;
>   	unsigned i;
>   
>   	assert(nir->info.stage == MESA_SHADER_VERTEX ||
> +	       nir->info.stage == MESA_SHADER_GEOMETRY ||
>   	       nir->info.stage == MESA_SHADER_FRAGMENT);
>   
>   	info->processor = pipe_shader_type_from_mesa(nir->info.stage);
>   	info->num_tokens = 2; /* indicate that the shader is non-empty */
>   	info->num_instructions = 2;
>   
>   	if (nir->info.stage == MESA_SHADER_GEOMETRY) {
>   		info->properties[TGSI_PROPERTY_GS_INPUT_PRIM] = nir->info.gs.input_primitive;
>   		info->properties[TGSI_PROPERTY_GS_OUTPUT_PRIM] = nir->info.gs.output_primitive;
>   		info->properties[TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES] = nir->info.gs.vertices_out;
> @@ -144,29 +145,30 @@ void si_nir_scan_shader(const struct nir_shader *nir,
>   	}
>   
>   	i = 0;
>   	uint64_t processed_inputs = 0;
>   	unsigned num_inputs = 0;
>   	nir_foreach_variable(variable, &nir->inputs) {
>   		unsigned semantic_name, semantic_index;
>   		unsigned attrib_count = glsl_count_attribute_slots(variable->type,
>   								   nir->info.stage == MESA_SHADER_VERTEX);
>   
> -		assert(attrib_count == 1 && "not implemented");
> -
>   		/* Vertex shader inputs don't have semantics. The state
>   		 * tracker has already mapped them to attributes via
>   		 * variable->data.driver_location.
>   		 */
>   		if (nir->info.stage == MESA_SHADER_VERTEX)
>   			continue;
>   
> +		assert(nir->info.stage != MESA_SHADER_FRAGMENT ||
> +		       (attrib_count == 1 && "not implemented"));
> +
>   		/* Fragment shader position is a system value. */
>   		if (nir->info.stage == MESA_SHADER_FRAGMENT &&
>   		    variable->data.location == VARYING_SLOT_POS) {
>   			if (variable->data.pixel_center_integer)
>   				info->properties[TGSI_PROPERTY_FS_COORD_PIXEL_CENTER] =
>   					TGSI_FS_COORD_PIXEL_CENTER_INTEGER;
>   
>   			num_inputs++;
>   			continue;
>   		}
> @@ -552,20 +554,23 @@ si_nir_load_sampler_desc(struct ac_shader_abi *abi,
>   	index = LLVMBuildAdd(ctx->gallivm.builder, index,
>   			     LLVMConstInt(ctx->i32, SI_NUM_IMAGES / 2, 0), "");
>   
>   	return si_load_sampler_desc(ctx, list, index, desc_type);
>   }
>   
>   bool si_nir_build_llvm(struct si_shader_context *ctx, struct nir_shader *nir)
>   {
>   	struct tgsi_shader_info *info = &ctx->shader->selector->info;
>   
> +	//TODO: remove this as and add geo support per nicolais feedback?

Whoops. That comment is bogus and everything inside the if bellow should 
be indented, I've fixed this locally.

> +	if (nir->info.stage == MESA_SHADER_VERTEX ||
> +	    nir->info.stage == MESA_SHADER_FRAGMENT) {
>   	uint64_t processed_outputs = 0;
>   	nir_foreach_variable(variable, &nir->inputs) {
>   		unsigned attrib_count = glsl_count_attribute_slots(variable->type,
>   								   nir->info.stage == MESA_SHADER_VERTEX);
>   		unsigned input_idx = variable->data.driver_location;
>   
>   		assert(attrib_count == 1);
>   
>   		LLVMValueRef data[4];
>   		unsigned loc = variable->data.location;
> @@ -580,20 +585,21 @@ bool si_nir_build_llvm(struct si_shader_context *ctx, struct nir_shader *nir)
>   			declare_nir_input_vs(ctx, variable, data);
>   		else if (nir->info.stage == MESA_SHADER_FRAGMENT)
>   			declare_nir_input_fs(ctx, variable, input_idx / 4, data);
>   
>   		for (unsigned chan = 0; chan < 4; chan++) {
>   			ctx->inputs[input_idx + chan] =
>   				LLVMBuildBitCast(ctx->ac.builder, data[chan], ctx->ac.i32, "");
>   		}
>   		processed_outputs |= ((uint64_t)1 << loc);
>   	}
> +	}
>   
>   	ctx->abi.inputs = &ctx->inputs[0];
>   	ctx->abi.load_sampler_desc = si_nir_load_sampler_desc;
>   	ctx->abi.clamp_shadow_reference = true;
>   
>   	ctx->num_samplers = util_last_bit(info->samplers_declared);
>   	ctx->num_images = util_last_bit(info->images_declared);
>   
>   	ac_nir_translate(&ctx->ac, &ctx->abi, nir, NULL);
>   
> diff --git a/src/mesa/state_tracker/st_glsl_to_nir.cpp b/src/mesa/state_tracker/st_glsl_to_nir.cpp
> index d1cd2ec3ab..1610022334 100644
> --- a/src/mesa/state_tracker/st_glsl_to_nir.cpp
> +++ b/src/mesa/state_tracker/st_glsl_to_nir.cpp
> @@ -644,20 +644,32 @@ st_finalize_nir(struct st_context *st, struct gl_program *prog,
>      NIR_PASS_V(nir, nir_split_var_copies);
>      NIR_PASS_V(nir, nir_lower_var_copies);
>      NIR_PASS_V(nir, nir_lower_io_arrays_to_elements_no_indirects);
>   
>      if (nir->info.stage == MESA_SHADER_VERTEX) {
>         /* Needs special handling so drvloc matches the vbo state: */
>         st_nir_assign_vs_in_locations(prog, nir);
>         /* Re-lower global vars, to deal with any dead VS inputs. */
>         NIR_PASS_V(nir, nir_lower_global_vars_to_local);
>   
> +      sort_varyings(&nir->outputs);
> +      st_nir_assign_var_locations(&nir->outputs,
> +                                  &nir->num_outputs,
> +                                  nir->info.stage);
> +      st_nir_fixup_varying_slots(st, &nir->outputs);
> +   } else if (nir->info.stage == MESA_SHADER_GEOMETRY) {
> +      sort_varyings(&nir->inputs);
> +      st_nir_assign_var_locations(&nir->inputs,
> +                                  &nir->num_inputs,
> +                                  nir->info.stage);
> +      st_nir_fixup_varying_slots(st, &nir->inputs);
> +
>         sort_varyings(&nir->outputs);
>         st_nir_assign_var_locations(&nir->outputs,
>                                     &nir->num_outputs,
>                                     nir->info.stage);
>         st_nir_fixup_varying_slots(st, &nir->outputs);
>      } else if (nir->info.stage == MESA_SHADER_FRAGMENT) {
>         sort_varyings(&nir->inputs);
>         st_nir_assign_var_locations(&nir->inputs,
>                                     &nir->num_inputs,
>                                     nir->info.stage);
> 


More information about the mesa-dev mailing list