ac/nir: remove dead shader IO code

RADV/LLVM and RadeonSI now lower IO.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6931>
This commit is contained in:
Samuel Pitoiset
2020-09-30 09:26:18 +02:00
parent 456f63e0ba
commit e3296e05ae

View File

@@ -65,21 +65,6 @@ static LLVMValueRef get_sampler_desc(struct ac_nir_context *ctx, nir_deref_instr
enum ac_descriptor_type desc_type, const nir_instr *instr,
LLVMValueRef index, bool image, bool write);
static void build_store_values_extended(struct ac_llvm_context *ac, LLVMValueRef *values,
unsigned value_count, unsigned value_stride,
LLVMValueRef vec)
{
LLVMBuilderRef builder = ac->builder;
unsigned i;
for (i = 0; i < value_count; i++) {
LLVMValueRef ptr = values[i * value_stride];
LLVMValueRef index = LLVMConstInt(ac->i32, i, false);
LLVMValueRef value = LLVMBuildExtractElement(builder, vec, index, "");
LLVMBuildStore(builder, value, ptr);
}
}
static LLVMTypeRef get_def_type(struct ac_nir_context *ctx, const nir_ssa_def *def)
{
LLVMTypeRef type = LLVMIntTypeInContext(ctx->ac.context, def->bit_size);
@@ -1586,15 +1571,6 @@ static LLVMValueRef visit_get_ssbo_size(struct ac_nir_context *ctx,
return get_buffer_size(ctx, ctx->abi->load_ssbo(ctx->abi, index, false), false);
}
static uint32_t widen_mask(uint32_t mask, unsigned multiplier)
{
uint32_t new_mask = 0;
for (unsigned i = 0; i < 32 && (1u << i) <= mask; ++i)
if (mask & (1u << i))
new_mask |= ((1u << multiplier) - 1u) << (i * multiplier);
return new_mask;
}
static LLVMValueRef extract_vector_range(struct ac_llvm_context *ctx, LLVMValueRef src,
unsigned start, unsigned count)
{
@@ -2126,308 +2102,12 @@ static LLVMValueRef visit_load_ubo_buffer(struct ac_nir_context *ctx, nir_intrin
return exit_waterfall(ctx, &wctx, ret);
}
static void get_deref_offset(struct ac_nir_context *ctx, nir_deref_instr *instr, bool vs_in,
unsigned *vertex_index_out, LLVMValueRef *vertex_index_ref,
unsigned *const_out, LLVMValueRef *indir_out)
{
nir_variable *var = nir_deref_instr_get_variable(instr);
nir_deref_path path;
unsigned idx_lvl = 1;
nir_deref_path_init(&path, instr, NULL);
if (vertex_index_out != NULL || vertex_index_ref != NULL) {
if (vertex_index_ref) {
*vertex_index_ref = get_src(ctx, path.path[idx_lvl]->arr.index);
if (vertex_index_out)
*vertex_index_out = 0;
} else {
*vertex_index_out = nir_src_as_uint(path.path[idx_lvl]->arr.index);
}
++idx_lvl;
}
uint32_t const_offset = 0;
LLVMValueRef offset = NULL;
if (var->data.compact) {
assert(instr->deref_type == nir_deref_type_array);
const_offset = nir_src_as_uint(instr->arr.index);
goto out;
}
for (; path.path[idx_lvl]; ++idx_lvl) {
const struct glsl_type *parent_type = path.path[idx_lvl - 1]->type;
if (path.path[idx_lvl]->deref_type == nir_deref_type_struct) {
unsigned index = path.path[idx_lvl]->strct.index;
for (unsigned i = 0; i < index; i++) {
const struct glsl_type *ft = glsl_get_struct_field(parent_type, i);
const_offset += glsl_count_attribute_slots(ft, vs_in);
}
} else if (path.path[idx_lvl]->deref_type == nir_deref_type_array) {
unsigned size = glsl_count_attribute_slots(path.path[idx_lvl]->type, vs_in);
if (nir_src_is_const(path.path[idx_lvl]->arr.index)) {
const_offset += size * nir_src_as_uint(path.path[idx_lvl]->arr.index);
} else {
LLVMValueRef array_off =
LLVMBuildMul(ctx->ac.builder, LLVMConstInt(ctx->ac.i32, size, 0),
get_src(ctx, path.path[idx_lvl]->arr.index), "");
if (offset)
offset = LLVMBuildAdd(ctx->ac.builder, offset, array_off, "");
else
offset = array_off;
}
} else
unreachable("Uhandled deref type in get_deref_instr_offset");
}
out:
nir_deref_path_finish(&path);
if (const_offset && offset)
offset =
LLVMBuildAdd(ctx->ac.builder, offset, LLVMConstInt(ctx->ac.i32, const_offset, 0), "");
*const_out = const_offset;
*indir_out = offset;
}
static LLVMValueRef load_tess_varyings(struct ac_nir_context *ctx, nir_intrinsic_instr *instr,
bool load_inputs)
{
LLVMValueRef result;
LLVMValueRef vertex_index = NULL;
LLVMValueRef indir_index = NULL;
unsigned const_index = 0;
nir_variable *var =
nir_deref_instr_get_variable(nir_instr_as_deref(instr->src[0].ssa->parent_instr));
unsigned location = var->data.location;
unsigned driver_location = var->data.driver_location;
const bool is_patch = var->data.patch || var->data.location == VARYING_SLOT_TESS_LEVEL_INNER ||
var->data.location == VARYING_SLOT_TESS_LEVEL_OUTER;
const bool is_compact = var->data.compact;
get_deref_offset(ctx, nir_instr_as_deref(instr->src[0].ssa->parent_instr), false, NULL,
is_patch ? NULL : &vertex_index, &const_index, &indir_index);
LLVMTypeRef dest_type = get_def_type(ctx, &instr->dest.ssa);
LLVMTypeRef src_component_type;
if (LLVMGetTypeKind(dest_type) == LLVMVectorTypeKind)
src_component_type = LLVMGetElementType(dest_type);
else
src_component_type = dest_type;
result =
ctx->abi->load_tess_varyings(ctx->abi, src_component_type, vertex_index, indir_index,
const_index, location, driver_location, var->data.location_frac,
instr->num_components, is_patch, is_compact, load_inputs);
if (instr->dest.ssa.bit_size == 16) {
result = ac_to_integer(&ctx->ac, result);
result = LLVMBuildTrunc(ctx->ac.builder, result, dest_type, "");
}
return LLVMBuildBitCast(ctx->ac.builder, result, dest_type, "");
}
static unsigned type_scalar_size_bytes(const struct glsl_type *type)
{
assert(glsl_type_is_vector_or_scalar(type) || glsl_type_is_matrix(type));
return glsl_type_is_boolean(type) ? 4 : glsl_get_bit_size(type) / 8;
}
static LLVMValueRef visit_load_var(struct ac_nir_context *ctx, nir_intrinsic_instr *instr)
{
nir_deref_instr *deref = nir_instr_as_deref(instr->src[0].ssa->parent_instr);
nir_variable *var = nir_deref_instr_get_variable(deref);
LLVMValueRef values[8];
int idx = 0;
int ve = instr->dest.ssa.num_components;
unsigned comp = 0;
LLVMValueRef indir_index;
LLVMValueRef ret;
unsigned const_index;
unsigned stride = 4;
int mode = deref->mode;
if (var) {
bool vs_in = ctx->stage == MESA_SHADER_VERTEX && var->data.mode == nir_var_shader_in;
idx = var->data.driver_location;
comp = var->data.location_frac;
mode = var->data.mode;
get_deref_offset(ctx, deref, vs_in, NULL, NULL, &const_index, &indir_index);
if (var->data.compact) {
stride = 1;
const_index += comp;
comp = 0;
}
}
if (instr->dest.ssa.bit_size == 64 &&
(deref->mode == nir_var_shader_in || deref->mode == nir_var_shader_out))
ve *= 2;
switch (mode) {
case nir_var_shader_in:
/* TODO: remove this after RADV switches to lowered IO */
if (ctx->stage == MESA_SHADER_TESS_CTRL || ctx->stage == MESA_SHADER_TESS_EVAL) {
return load_tess_varyings(ctx, instr, true);
}
if (ctx->stage == MESA_SHADER_GEOMETRY) {
LLVMTypeRef type = LLVMIntTypeInContext(ctx->ac.context, instr->dest.ssa.bit_size);
LLVMValueRef indir_index;
unsigned const_index, vertex_index;
get_deref_offset(ctx, deref, false, &vertex_index, NULL, &const_index, &indir_index);
assert(indir_index == NULL);
return ctx->abi->load_inputs(ctx->abi, var->data.location, var->data.driver_location,
var->data.location_frac, instr->num_components, vertex_index,
const_index, type);
}
for (unsigned chan = comp; chan < ve + comp; chan++) {
if (indir_index) {
unsigned count =
glsl_count_attribute_slots(var->type, ctx->stage == MESA_SHADER_VERTEX);
count -= chan / 4;
LLVMValueRef tmp_vec = ac_build_gather_values_extended(
&ctx->ac, ctx->abi->inputs + idx + chan, count, stride, false, true);
values[chan] = LLVMBuildExtractElement(ctx->ac.builder, tmp_vec, indir_index, "");
} else
values[chan] = ctx->abi->inputs[idx + chan + const_index * stride];
}
break;
case nir_var_shader_out:
/* TODO: remove this after RADV switches to lowered IO */
if (ctx->stage == MESA_SHADER_TESS_CTRL) {
return load_tess_varyings(ctx, instr, false);
}
if (ctx->stage == MESA_SHADER_FRAGMENT && var->data.fb_fetch_output && ctx->abi->emit_fbfetch)
return ctx->abi->emit_fbfetch(ctx->abi);
for (unsigned chan = comp; chan < ve + comp; chan++) {
if (indir_index) {
unsigned count = glsl_count_attribute_slots(var->type, false);
count -= chan / 4;
LLVMValueRef tmp_vec = ac_build_gather_values_extended(
&ctx->ac, ctx->abi->outputs + idx + chan, count, stride, true, true);
values[chan] = LLVMBuildExtractElement(ctx->ac.builder, tmp_vec, indir_index, "");
} else {
values[chan] = LLVMBuildLoad(ctx->ac.builder,
ctx->abi->outputs[idx + chan + const_index * stride], "");
}
}
break;
default:
unreachable("unhandle variable mode");
}
ret = ac_build_varying_gather_values(&ctx->ac, values, ve, comp);
return LLVMBuildBitCast(ctx->ac.builder, ret, get_def_type(ctx, &instr->dest.ssa), "");
}
static void visit_store_var(struct ac_nir_context *ctx, nir_intrinsic_instr *instr)
{
if (ctx->ac.postponed_kill) {
LLVMValueRef cond = LLVMBuildLoad(ctx->ac.builder, ctx->ac.postponed_kill, "");
ac_build_ifcc(&ctx->ac, cond, 7002);
}
nir_deref_instr *deref = nir_instr_as_deref(instr->src[0].ssa->parent_instr);
nir_variable *var = nir_deref_instr_get_variable(deref);
LLVMValueRef temp_ptr, value;
int idx = 0;
unsigned comp = 0;
LLVMValueRef src = ac_to_float(&ctx->ac, get_src(ctx, instr->src[1]));
int writemask = instr->const_index[0];
LLVMValueRef indir_index;
unsigned const_index;
if (var) {
get_deref_offset(ctx, deref, false, NULL, NULL, &const_index, &indir_index);
idx = var->data.driver_location;
comp = var->data.location_frac;
if (var->data.compact) {
const_index += comp;
comp = 0;
}
}
if (ac_get_elem_bits(&ctx->ac, LLVMTypeOf(src)) == 64 &&
deref->mode == nir_var_shader_out) {
src = LLVMBuildBitCast(ctx->ac.builder, src,
LLVMVectorType(ctx->ac.f32, ac_get_llvm_num_components(src) * 2), "");
writemask = widen_mask(writemask, 2);
}
writemask = writemask << comp;
switch (deref->mode) {
case nir_var_shader_out:
/* TODO: remove this after RADV switches to lowered IO */
if (ctx->stage == MESA_SHADER_TESS_CTRL) {
LLVMValueRef vertex_index = NULL;
LLVMValueRef indir_index = NULL;
unsigned const_index = 0;
const bool is_patch = var->data.patch ||
var->data.location == VARYING_SLOT_TESS_LEVEL_INNER ||
var->data.location == VARYING_SLOT_TESS_LEVEL_OUTER;
get_deref_offset(ctx, deref, false, NULL, is_patch ? NULL : &vertex_index, &const_index,
&indir_index);
ctx->abi->store_tcs_outputs(ctx->abi, var, vertex_index, indir_index, const_index, src,
writemask, var->data.location_frac, var->data.driver_location);
break;
}
for (unsigned chan = 0; chan < 8; chan++) {
int stride = 4;
if (!(writemask & (1 << chan)))
continue;
value = ac_llvm_extract_elem(&ctx->ac, src, chan - comp);
if (var->data.compact)
stride = 1;
if (indir_index) {
unsigned count = glsl_count_attribute_slots(var->type, false);
count -= chan / 4;
LLVMValueRef tmp_vec = ac_build_gather_values_extended(
&ctx->ac, ctx->abi->outputs + idx + chan, count, stride, true, true);
tmp_vec = LLVMBuildInsertElement(ctx->ac.builder, tmp_vec, value, indir_index, "");
build_store_values_extended(&ctx->ac, ctx->abi->outputs + idx + chan, count, stride,
tmp_vec);
} else {
temp_ptr = ctx->abi->outputs[idx + chan + const_index * stride];
LLVMBuildStore(ctx->ac.builder, value, temp_ptr);
}
}
break;
default:
abort();
break;
}
if (ctx->ac.postponed_kill)
ac_build_endif(&ctx->ac, 7002);
}
static void visit_store_output(struct ac_nir_context *ctx, nir_intrinsic_instr *instr)
{
if (ctx->ac.postponed_kill) {
@@ -3720,12 +3400,6 @@ static void visit_intrinsic(struct ac_nir_context *ctx, nir_intrinsic_instr *ins
case nir_intrinsic_get_ssbo_size:
result = visit_get_ssbo_size(ctx, instr);
break;
case nir_intrinsic_load_deref:
result = visit_load_var(ctx, instr);
break;
case nir_intrinsic_store_deref:
visit_store_var(ctx, instr);
break;
case nir_intrinsic_load_input:
case nir_intrinsic_load_input_vertex:
case nir_intrinsic_load_per_vertex_input: