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:
@@ -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:
|
||||
|
Reference in New Issue
Block a user