[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