From: Dave Airlie Date: Fri, 19 Jun 2020 07:05:39 +0000 (+1000) Subject: gallivm/nir: add indirect swizzle output loading support X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1d4a560ba263ebeaf104dd1131f427c3c95510c3;p=mesa.git gallivm/nir: add indirect swizzle output loading support Fixes: dEQP-VK.clipping.user_defined.clip_distance.* Reviewed-by: Roland Scheidegger Part-of: --- diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index aabece0ce13..58636316dfb 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -3075,6 +3075,7 @@ draw_tcs_llvm_emit_fetch_input(const struct lp_build_tcs_iface *tes_iface, LLVMValueRef vertex_index, boolean is_aindex_indirect, LLVMValueRef attrib_index, + boolean is_sindex_indirect, LLVMValueRef swizzle_index) { const struct draw_tcs_llvm_iface *tcs = draw_tcs_llvm_iface(tes_iface); @@ -3084,7 +3085,7 @@ draw_tcs_llvm_emit_fetch_input(const struct lp_build_tcs_iface *tes_iface, LLVMValueRef res; struct lp_type type = bld->type; - if (is_vindex_indirect || is_aindex_indirect) { + if (is_vindex_indirect || is_aindex_indirect || is_sindex_indirect) { int i; res = bld->zero; @@ -3092,6 +3093,7 @@ draw_tcs_llvm_emit_fetch_input(const struct lp_build_tcs_iface *tes_iface, LLVMValueRef idx = lp_build_const_int32(gallivm, i); LLVMValueRef vert_chan_index = vertex_index; LLVMValueRef attr_chan_index = attrib_index; + LLVMValueRef swiz_chan_index = swizzle_index; LLVMValueRef channel_vec; if (is_vindex_indirect) { @@ -3102,10 +3104,14 @@ draw_tcs_llvm_emit_fetch_input(const struct lp_build_tcs_iface *tes_iface, attr_chan_index = LLVMBuildExtractElement(builder, attrib_index, idx, ""); } + if (is_sindex_indirect) { + swiz_chan_index = LLVMBuildExtractElement(builder, + swizzle_index, idx, ""); + } indices[0] = vert_chan_index; indices[1] = attr_chan_index; - indices[2] = swizzle_index; + indices[2] = swiz_chan_index; channel_vec = LLVMBuildGEP(builder, tcs->input, indices, 3, ""); channel_vec = LLVMBuildLoad(builder, channel_vec, ""); @@ -3131,6 +3137,7 @@ draw_tcs_llvm_emit_fetch_output(const struct lp_build_tcs_iface *tes_iface, LLVMValueRef vertex_index, boolean is_aindex_indirect, LLVMValueRef attrib_index, + boolean is_sindex_indirect, LLVMValueRef swizzle_index, uint32_t name) { @@ -3141,7 +3148,7 @@ draw_tcs_llvm_emit_fetch_output(const struct lp_build_tcs_iface *tes_iface, LLVMValueRef res; struct lp_type type = bld->type; - if (is_vindex_indirect || is_aindex_indirect) { + if (is_vindex_indirect || is_aindex_indirect || is_sindex_indirect) { int i; res = bld->zero; @@ -3149,6 +3156,7 @@ draw_tcs_llvm_emit_fetch_output(const struct lp_build_tcs_iface *tes_iface, LLVMValueRef idx = lp_build_const_int32(gallivm, i); LLVMValueRef vert_chan_index = vertex_index; LLVMValueRef attr_chan_index = attrib_index; + LLVMValueRef swiz_chan_index = swizzle_index; LLVMValueRef channel_vec; if (is_vindex_indirect) { @@ -3159,10 +3167,14 @@ draw_tcs_llvm_emit_fetch_output(const struct lp_build_tcs_iface *tes_iface, attr_chan_index = LLVMBuildExtractElement(builder, attrib_index, idx, ""); } + if (is_sindex_indirect) { + swiz_chan_index = LLVMBuildExtractElement(builder, + swizzle_index, idx, ""); + } indices[0] = vert_chan_index; indices[1] = attr_chan_index; - indices[2] = swizzle_index; + indices[2] = swiz_chan_index; channel_vec = LLVMBuildGEP(builder, tcs->output, indices, 3, ""); channel_vec = LLVMBuildLoad(builder, channel_vec, ""); @@ -3734,6 +3746,7 @@ draw_tes_llvm_fetch_vertex_input(const struct lp_build_tes_iface *tes_iface, LLVMValueRef vertex_index, boolean is_aindex_indirect, LLVMValueRef attrib_index, + boolean is_sindex_indirect, LLVMValueRef swizzle_index) { const struct draw_tes_llvm_iface *tes = draw_tes_llvm_iface(tes_iface); @@ -3743,7 +3756,7 @@ draw_tes_llvm_fetch_vertex_input(const struct lp_build_tes_iface *tes_iface, LLVMValueRef res; struct lp_type type = bld->type; - if (is_vindex_indirect || is_aindex_indirect) { + if (is_vindex_indirect || is_aindex_indirect || is_sindex_indirect) { int i; res = bld->zero; @@ -3752,6 +3765,7 @@ draw_tes_llvm_fetch_vertex_input(const struct lp_build_tes_iface *tes_iface, LLVMValueRef idx = lp_build_const_int32(gallivm, i); LLVMValueRef vert_chan_index = vertex_index; LLVMValueRef attr_chan_index = attrib_index; + LLVMValueRef swiz_chan_index = swizzle_index; LLVMValueRef channel_vec; if (is_vindex_indirect) { @@ -3762,10 +3776,14 @@ draw_tes_llvm_fetch_vertex_input(const struct lp_build_tes_iface *tes_iface, attr_chan_index = LLVMBuildExtractElement(builder, attrib_index, idx, ""); } + if (is_sindex_indirect) { + swiz_chan_index = LLVMBuildExtractElement(builder, + swizzle_index, idx, ""); + } indices[0] = vert_chan_index; indices[1] = attr_chan_index; - indices[2] = swizzle_index; + indices[2] = swiz_chan_index; channel_vec = LLVMBuildGEP(builder, tes->input, indices, 3, ""); channel_vec = LLVMBuildLoad(builder, channel_vec, ""); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c index ad6df764f6f..b83acd0b58f 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c @@ -307,15 +307,27 @@ static void emit_load_var(struct lp_build_nir_context *bld_base, struct lp_build_nir_soa_context *bld = (struct lp_build_nir_soa_context *)bld_base; struct gallivm_state *gallivm = bld_base->base.gallivm; int dmul = bit_size == 64 ? 2 : 1; + unsigned location = var->data.driver_location; + unsigned location_frac = var->data.location_frac; + + if (!var->data.compact && !indir_index) + location += const_index; + else if (var->data.compact) { + location += const_index / 4; + location_frac += const_index % 4; + const_index = 0; + } switch (deref_mode) { case nir_var_shader_in: for (unsigned i = 0; i < num_components; i++) { - int idx = (i * dmul) + var->data.location_frac; + int idx = (i * dmul) + location_frac; + if (bld->gs_iface) { LLVMValueRef vertex_index_val = lp_build_const_int32(gallivm, vertex_index); - LLVMValueRef attrib_index_val = lp_build_const_int32(gallivm, const_index + var->data.driver_location); + LLVMValueRef attrib_index_val = lp_build_const_int32(gallivm, location); LLVMValueRef swizzle_index_val = lp_build_const_int32(gallivm, idx); LLVMValueRef result2; + result[i] = bld->gs_iface->fetch_input(bld->gs_iface, &bld_base->base, false, vertex_index_val, 0, attrib_index_val, swizzle_index_val); if (bit_size == 64) { @@ -330,10 +342,15 @@ static void emit_load_var(struct lp_build_nir_context *bld_base, LLVMValueRef swizzle_index_val = lp_build_const_int32(gallivm, idx); LLVMValueRef result2; - if (indir_index) - attrib_index_val = lp_build_add(&bld_base->uint_bld, indir_index, lp_build_const_int_vec(gallivm, bld_base->uint_bld.type, var->data.driver_location)); - else - attrib_index_val = lp_build_const_int32(gallivm, const_index + var->data.driver_location); + if (indir_index) { + if (var->data.compact) { + swizzle_index_val = lp_build_add(&bld_base->uint_bld, indir_index, lp_build_const_int_vec(gallivm, bld_base->uint_bld.type, idx)); + attrib_index_val = lp_build_const_int32(gallivm, location); + } else + attrib_index_val = lp_build_add(&bld_base->uint_bld, indir_index, lp_build_const_int_vec(gallivm, bld_base->uint_bld.type, var->data.driver_location)); + } else + attrib_index_val = lp_build_const_int32(gallivm, location); + if (var->data.patch) { result[i] = bld->tes_iface->fetch_patch_input(bld->tes_iface, &bld_base->base, indir_index ? true : false, attrib_index_val, swizzle_index_val); @@ -348,13 +365,14 @@ static void emit_load_var(struct lp_build_nir_context *bld_base, result[i] = bld->tes_iface->fetch_vertex_input(bld->tes_iface, &bld_base->base, indir_vertex_index ? true : false, indir_vertex_index ? indir_vertex_index : vertex_index_val, - indir_index ? true : false, attrib_index_val, swizzle_index_val); + (indir_index && !var->data.compact) ? true : false, attrib_index_val, + (indir_index && var->data.compact) ? true : false, swizzle_index_val); if (bit_size == 64) { LLVMValueRef swizzle_index_val = lp_build_const_int32(gallivm, idx + 1); result2 = bld->tes_iface->fetch_vertex_input(bld->tes_iface, &bld_base->base, indir_vertex_index ? true : false, indir_vertex_index ? indir_vertex_index : vertex_index_val, - indir_index ? true : false, attrib_index_val, swizzle_index_val); + indir_index ? true : false, attrib_index_val, false, swizzle_index_val); result[i] = emit_fetch_64bit(bld_base, result[i], result2); } } @@ -363,18 +381,24 @@ static void emit_load_var(struct lp_build_nir_context *bld_base, LLVMValueRef attrib_index_val; LLVMValueRef swizzle_index_val = lp_build_const_int32(gallivm, idx); - if (indir_index) - attrib_index_val = lp_build_add(&bld_base->uint_bld, indir_index, lp_build_const_int_vec(gallivm, bld_base->uint_bld.type, var->data.driver_location)); - else - attrib_index_val = lp_build_const_int32(gallivm, const_index + var->data.driver_location); + if (indir_index) { + if (var->data.compact) { + swizzle_index_val = lp_build_add(&bld_base->uint_bld, indir_index, lp_build_const_int_vec(gallivm, bld_base->uint_bld.type, idx)); + attrib_index_val = lp_build_const_int32(gallivm, location); + } else + attrib_index_val = lp_build_add(&bld_base->uint_bld, indir_index, lp_build_const_int_vec(gallivm, bld_base->uint_bld.type, var->data.driver_location)); + } else + attrib_index_val = lp_build_const_int32(gallivm, location); result[i] = bld->tcs_iface->emit_fetch_input(bld->tcs_iface, &bld_base->base, indir_vertex_index ? true : false, indir_vertex_index ? indir_vertex_index : vertex_index_val, - indir_index ? true : false, attrib_index_val, swizzle_index_val); + (indir_index && !var->data.compact) ? true : false, attrib_index_val, + (indir_index && var->data.compact) ? true : false, swizzle_index_val); if (bit_size == 64) { LLVMValueRef swizzle_index_val = lp_build_const_int32(gallivm, idx + 1); LLVMValueRef result2 = bld->tcs_iface->emit_fetch_input(bld->tcs_iface, &bld_base->base, indir_vertex_index ? true : false, indir_vertex_index ? indir_vertex_index : vertex_index_val, - indir_index ? true : false, attrib_index_val, swizzle_index_val); + indir_index ? true : false, attrib_index_val, + false, swizzle_index_val); result[i] = emit_fetch_64bit(bld_base, result[i], result2); } } else { @@ -398,12 +422,12 @@ static void emit_load_var(struct lp_build_nir_context *bld_base, } else { if (bld->indirects & nir_var_shader_in) { LLVMValueRef lindex = lp_build_const_int32(gallivm, - var->data.driver_location * 4 + idx); + location * 4 + idx); LLVMValueRef input_ptr = lp_build_pointer_get(gallivm->builder, bld->inputs_array, lindex); if (bit_size == 64) { LLVMValueRef lindex2 = lp_build_const_int32(gallivm, - var->data.driver_location * 4 + (idx + 1)); + location * 4 + (idx + 1)); LLVMValueRef input_ptr2 = lp_build_pointer_get(gallivm->builder, bld->inputs_array, lindex2); result[i] = emit_fetch_64bit(bld_base, input_ptr, input_ptr2); @@ -413,11 +437,11 @@ static void emit_load_var(struct lp_build_nir_context *bld_base, } else { if (bit_size == 64) { LLVMValueRef tmp[2]; - tmp[0] = bld->inputs[var->data.driver_location + const_index][idx]; - tmp[1] = bld->inputs[var->data.driver_location + const_index][idx + 1]; + tmp[0] = bld->inputs[location][idx]; + tmp[1] = bld->inputs[location][idx + 1]; result[i] = emit_fetch_64bit(bld_base, tmp[0], tmp[1]); } else { - result[i] = bld->inputs[var->data.driver_location + const_index][idx]; + result[i] = bld->inputs[location][idx]; } } } @@ -430,7 +454,7 @@ static void emit_load_var(struct lp_build_nir_context *bld_base, return; } for (unsigned i = 0; i < num_components; i++) { - int idx = (i * dmul) + var->data.location_frac; + int idx = (i * dmul) + location_frac; if (bld->tcs_iface) { LLVMValueRef vertex_index_val = lp_build_const_int32(gallivm, vertex_index); LLVMValueRef attrib_index_val; @@ -439,16 +463,18 @@ static void emit_load_var(struct lp_build_nir_context *bld_base, if (indir_index) attrib_index_val = lp_build_add(&bld_base->uint_bld, indir_index, lp_build_const_int_vec(gallivm, bld_base->uint_bld.type, var->data.driver_location)); else - attrib_index_val = lp_build_const_int32(gallivm, const_index + var->data.driver_location); + attrib_index_val = lp_build_const_int32(gallivm, location); result[i] = bld->tcs_iface->emit_fetch_output(bld->tcs_iface, &bld_base->base, - indir_vertex_index ? true : false, indir_vertex_index ? indir_vertex_index : vertex_index_val, - indir_index ? true : false, attrib_index_val, swizzle_index_val, 0); + indir_vertex_index ? true : false, indir_vertex_index ? indir_vertex_index : vertex_index_val, + (indir_index && !var->data.compact) ? true : false, attrib_index_val, + (indir_index && var->data.compact) ? true : false, swizzle_index_val, 0); if (bit_size == 64) { LLVMValueRef swizzle_index_val = lp_build_const_int32(gallivm, idx + 1); LLVMValueRef result2 = bld->tcs_iface->emit_fetch_output(bld->tcs_iface, &bld_base->base, indir_vertex_index ? true : false, indir_vertex_index ? indir_vertex_index : vertex_index_val, - indir_index ? true : false, attrib_index_val, swizzle_index_val, 0); + indir_index ? true : false, attrib_index_val, + false, swizzle_index_val, 0); result[i] = emit_fetch_64bit(bld_base, result[i], result2); } } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h index 12bf55b3f40..d5a01f82c16 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h @@ -470,6 +470,7 @@ struct lp_build_tcs_iface LLVMValueRef vertex_index, boolean is_aindex_indirect, LLVMValueRef attrib_index, + boolean is_sindex_indirect, LLVMValueRef swizzle_index); LLVMValueRef (*emit_fetch_output)(const struct lp_build_tcs_iface *tcs_iface, @@ -478,6 +479,7 @@ struct lp_build_tcs_iface LLVMValueRef vertex_index, boolean is_aindex_indirect, LLVMValueRef attrib_index, + boolean is_sindex_indirect, LLVMValueRef swizzle_index, uint32_t name); }; @@ -490,6 +492,7 @@ struct lp_build_tes_iface LLVMValueRef vertex_index, boolean is_aindex_indirect, LLVMValueRef attrib_index, + boolean is_sindex_indirect, LLVMValueRef swizzle_index); LLVMValueRef (*fetch_patch_input)(const struct lp_build_tes_iface *tes_iface, diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index 5104a572c4d..cbaebca4881 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -1255,6 +1255,7 @@ emit_fetch_tcs_input( vertex_index, reg->Register.Indirect, attrib_index, + FALSE, swizzle_index, bld_base->info->output_semantic_name[reg->Register.Index]); } else { @@ -1263,6 +1264,7 @@ emit_fetch_tcs_input( vertex_index, reg->Register.Indirect, attrib_index, + FALSE, swizzle_index); } @@ -1277,6 +1279,7 @@ emit_fetch_tcs_input( vertex_index, reg->Register.Indirect, attrib_index, + FALSE, swizzle_index, bld_base->info->output_semantic_name[reg->Register.Index]); } else { @@ -1285,6 +1288,7 @@ emit_fetch_tcs_input( vertex_index, reg->Register.Indirect, attrib_index, + FALSE, swizzle_index); } assert(res2); @@ -1358,6 +1362,7 @@ emit_fetch_tes_input( vertex_index, reg->Register.Indirect, attrib_index, + FALSE, swizzle_index); } @@ -1377,6 +1382,7 @@ emit_fetch_tes_input( vertex_index, reg->Register.Indirect, attrib_index, + FALSE, swizzle_index); } assert(res2); diff --git a/src/gallium/drivers/swr/swr_shader.cpp b/src/gallium/drivers/swr/swr_shader.cpp index e5f0074033a..cd1a136d0c9 100644 --- a/src/gallium/drivers/swr/swr_shader.cpp +++ b/src/gallium/drivers/swr/swr_shader.cpp @@ -551,6 +551,7 @@ swr_tcs_llvm_fetch_input(const struct lp_build_tcs_iface *tcs_iface, LLVMValueRef vertex_index, boolean is_aindex_indirect, LLVMValueRef attrib_index, + boolean is_sindex_indirect, LLVMValueRef swizzle_index) { swr_tcs_llvm_iface *iface = (swr_tcs_llvm_iface*)tcs_iface; @@ -571,6 +572,7 @@ swr_tcs_llvm_fetch_output(const struct lp_build_tcs_iface *tcs_iface, LLVMValueRef vertex_index, boolean is_aindex_indirect, LLVMValueRef attrib_index, + boolean is_sindex_indirect, LLVMValueRef swizzle_index, uint32_t name) { @@ -649,6 +651,7 @@ swr_tes_llvm_fetch_vtx_input(const struct lp_build_tes_iface *tes_iface, LLVMValueRef vertex_index, boolean is_aindex_indirect, LLVMValueRef attrib_index, + boolean is_sindex_indirect, LLVMValueRef swizzle_index) { swr_tes_llvm_iface *iface = (swr_tes_llvm_iface*)tes_iface;