From 4cb6a8d2dee5f1ef56f26090441fa9d1758ecce5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Fri, 11 Sep 2020 19:59:32 -0400 Subject: [PATCH] gallivm: add support for lowered IO in vertex shaders for Selection/Feedback/RasterPos in st/mesa. Reviewed-by: Dave Airlie Part-of: --- src/gallium/auxiliary/gallivm/lp_bld_nir.c | 73 ++++++++++++++++++++ src/gallium/auxiliary/nir/nir_to_tgsi_info.c | 29 +++++++- 2 files changed, 101 insertions(+), 1 deletion(-) diff --git a/src/gallium/auxiliary/gallivm/lp_bld_nir.c b/src/gallium/auxiliary/gallivm/lp_bld_nir.c index b5ee9744e4f..93879969fd0 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_nir.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_nir.c @@ -978,6 +978,57 @@ out: *indir_out = offset; } +static void +visit_load_input(struct lp_build_nir_context *bld_base, + nir_intrinsic_instr *instr, + LLVMValueRef result[NIR_MAX_VEC_COMPONENTS]) +{ + nir_variable var = {0}; + var.data.location = nir_intrinsic_io_semantics(instr).location; + var.data.driver_location = nir_intrinsic_base(instr); + var.data.location_frac = nir_intrinsic_component(instr); + + unsigned nc = nir_dest_num_components(instr->dest); + unsigned bit_size = nir_dest_bit_size(instr->dest); + + nir_src offset = *nir_get_io_offset_src(instr); + bool indirect = !nir_src_is_const(offset); + if (!indirect) + assert(nir_src_as_uint(offset) == 0); + LLVMValueRef indir_index = indirect ? get_src(bld_base, offset) : NULL; + + bld_base->load_var(bld_base, nir_var_shader_in, nc, bit_size, &var, 0, NULL, 0, indir_index, result); +} + +static void +visit_store_output(struct lp_build_nir_context *bld_base, + nir_intrinsic_instr *instr) +{ + nir_variable var = {0}; + var.data.location = nir_intrinsic_io_semantics(instr).location; + var.data.driver_location = nir_intrinsic_base(instr); + var.data.location_frac = nir_intrinsic_component(instr); + + unsigned mask = nir_intrinsic_write_mask(instr); + + unsigned bit_size = nir_src_bit_size(instr->src[0]); + LLVMValueRef src = get_src(bld_base, instr->src[0]); + + nir_src offset = *nir_get_io_offset_src(instr); + bool indirect = !nir_src_is_const(offset); + if (!indirect) + assert(nir_src_as_uint(offset) == 0); + LLVMValueRef indir_index = indirect ? get_src(bld_base, offset) : NULL; + + if (mask == 0x1 && LLVMGetTypeKind(LLVMTypeOf(src)) == LLVMArrayTypeKind) { + src = LLVMBuildExtractValue(bld_base->base.gallivm->builder, + src, 0, ""); + } + + bld_base->store_var(bld_base, nir_var_shader_out, util_last_bit(mask), + bit_size, &var, mask, NULL, 0, indir_index, src); +} + static void visit_load_var(struct lp_build_nir_context *bld_base, nir_intrinsic_instr *instr, LLVMValueRef result[NIR_MAX_VEC_COMPONENTS]) @@ -1428,6 +1479,12 @@ static void visit_intrinsic(struct lp_build_nir_context *bld_base, { LLVMValueRef result[NIR_MAX_VEC_COMPONENTS] = {0}; switch (instr->intrinsic) { + case nir_intrinsic_load_input: + visit_load_input(bld_base, instr, result); + break; + case nir_intrinsic_store_output: + visit_store_output(bld_base, instr); + break; case nir_intrinsic_load_deref: visit_load_var(bld_base, instr, result); break; @@ -2020,6 +2077,22 @@ bool lp_build_nir_llvm( nir_foreach_shader_out_variable(variable, nir) handle_shader_output_decl(bld_base, nir, variable); + if (nir->info.io_lowered) { + uint64_t outputs_written = nir->info.outputs_written; + + while (outputs_written) { + unsigned location = u_bit_scan64(&outputs_written); + nir_variable var = {0}; + + var.type = glsl_vec4_type(); + var.data.mode = nir_var_shader_out; + var.data.location = location; + var.data.driver_location = util_bitcount64(nir->info.outputs_written & + BITFIELD64_MASK(location)); + bld_base->emit_var_decl(bld_base, &var); + } + } + bld_base->regs = _mesa_hash_table_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal); bld_base->vars = _mesa_hash_table_create(NULL, _mesa_hash_pointer, diff --git a/src/gallium/auxiliary/nir/nir_to_tgsi_info.c b/src/gallium/auxiliary/nir/nir_to_tgsi_info.c index 299523f4b6a..20052bae9d2 100644 --- a/src/gallium/auxiliary/nir/nir_to_tgsi_info.c +++ b/src/gallium/auxiliary/nir/nir_to_tgsi_info.c @@ -573,7 +573,13 @@ void nir_tgsi_scan_shader(const struct nir_shader *nir, } info->num_inputs = nir->num_inputs; - info->file_max[TGSI_FILE_INPUT] = nir->num_inputs - 1; + if (nir->info.io_lowered) { + info->num_inputs = util_bitcount64(nir->info.inputs_read); + if (nir->info.inputs_read_indirectly) + info->indirect_files |= 1 << TGSI_FILE_INPUT; + } + + info->file_max[TGSI_FILE_INPUT] = info->num_inputs - 1; i = 0; uint64_t processed_outputs = 0; @@ -749,6 +755,27 @@ void nir_tgsi_scan_shader(const struct nir_shader *nir, } } + if (nir->info.io_lowered) { + uint64_t outputs_written = nir->info.outputs_written; + + while (outputs_written) { + unsigned location = u_bit_scan64(&outputs_written); + unsigned i = util_bitcount64(nir->info.outputs_written & + BITFIELD64_MASK(location)); + unsigned semantic_name, semantic_index; + + tgsi_get_gl_varying_semantic(location, need_texcoord, + &semantic_name, &semantic_index); + + info->output_semantic_name[i] = semantic_name; + info->output_semantic_index[i] = semantic_index; + info->output_usagemask[i] = 0xf; + } + num_outputs = util_bitcount64(nir->info.outputs_written); + if (nir->info.outputs_accessed_indirectly) + info->indirect_files |= 1 << TGSI_FILE_OUTPUT; + } + uint32_t sampler_mask = 0, image_mask = 0; nir_foreach_uniform_variable(var, nir) { uint32_t sampler_count = glsl_type_get_sampler_count(var->type);