pan/bi: Emit TEXC with builder

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8135>
This commit is contained in:
Alyssa Rosenzweig 2020-12-16 13:02:03 -05:00 committed by Marge Bot
parent e477de829f
commit 70d6c5675d
1 changed files with 165 additions and 0 deletions

View File

@ -3160,6 +3160,171 @@ enum bifrost_tex_dreg {
BIFROST_TEX_DREG_COUNT,
};
static void
bi_emit_texc(bi_builder *b, nir_tex_instr *instr)
{
/* TODO: support more with other encodings */
assert(instr->sampler_index < 16);
/* TODO: support more ops */
switch (instr->op) {
case nir_texop_tex:
case nir_texop_txl:
case nir_texop_txb:
case nir_texop_txf:
case nir_texop_txf_ms:
break;
default:
unreachable("Unsupported texture op");
}
struct bifrost_texture_operation desc = {
.sampler_index_or_mode = instr->sampler_index,
.index = instr->texture_index,
.immediate_indices = 1, /* TODO */
.op = bi_tex_op(instr->op),
.offset_or_bias_disable = false, /* TODO */
.shadow_or_clamp_disable = instr->is_shadow,
.array = instr->is_array,
.dimension = bifrost_tex_format(instr->sampler_dim),
.format = bi_texture_format(instr->dest_type | nir_dest_bit_size(instr->dest), BI_CLAMP_NONE), /* TODO */
.mask = 0xF,
};
switch (desc.op) {
case BIFROST_TEX_OP_TEX:
desc.lod_or_fetch = BIFROST_LOD_MODE_COMPUTE;
break;
case BIFROST_TEX_OP_FETCH:
/* TODO: gathers */
desc.lod_or_fetch = BIFROST_TEXTURE_FETCH_TEXEL;
break;
default:
unreachable("texture op unsupported");
}
/* 32-bit indices to be allocated as consecutive staging registers */
bi_index dregs[BIFROST_TEX_DREG_COUNT] = { };
bi_index cx = bi_null(), cy = bi_null();
for (unsigned i = 0; i < instr->num_srcs; ++i) {
bi_index index = bi_src_index(&instr->src[i].src);
unsigned sz = nir_src_bit_size(instr->src[i].src);
ASSERTED nir_alu_type base = nir_tex_instr_src_type(instr, i);
nir_alu_type T = base | sz;
switch (instr->src[i].src_type) {
case nir_tex_src_coord:
if (instr->sampler_dim == GLSL_SAMPLER_DIM_CUBE) {
cx = bi_emit_texc_cube_coord(b, index, &cy);
} else {
unsigned components = nir_src_num_components(instr->src[i].src);
/* Copy XY (for 2D+) or XX (for 1D) */
cx = index;
cy = bi_word(index, MIN2(1, components - 1));
assert(components >= 1 && components <= 3);
if (components < 3) {
/* nothing to do */
} else if (desc.array) {
/* 2D array */
dregs[BIFROST_TEX_DREG_ARRAY] =
bi_emit_texc_array_index(b,
bi_word(index, 2), T);
} else {
/* 3D */
dregs[BIFROST_TEX_DREG_Z_COORD] =
bi_word(index, 2);
}
}
break;
case nir_tex_src_lod:
if (desc.op == BIFROST_TEX_OP_TEX &&
nir_src_is_const(instr->src[i].src) &&
nir_src_as_uint(instr->src[i].src) == 0) {
desc.lod_or_fetch = BIFROST_LOD_MODE_ZERO;
} else if (desc.op == BIFROST_TEX_OP_TEX) {
assert(base == nir_type_float);
assert(sz == 16 || sz == 32);
dregs[BIFROST_TEX_DREG_LOD] =
bi_emit_texc_lod_88(b, index, sz == 16);
desc.lod_or_fetch = BIFROST_LOD_MODE_EXPLICIT;
} else {
assert(desc.op == BIFROST_TEX_OP_FETCH);
assert(base == nir_type_uint || base == nir_type_int);
assert(sz == 16 || sz == 32);
dregs[BIFROST_TEX_DREG_LOD] =
bi_emit_texc_lod_cube(b, index);
}
break;
case nir_tex_src_bias:
/* Upper 16-bits interpreted as a clamp, leave zero */
assert(desc.op == BIFROST_TEX_OP_TEX);
assert(base == nir_type_float);
assert(sz == 16 || sz == 32);
dregs[BIFROST_TEX_DREG_LOD] =
bi_emit_texc_lod_88(b, index, sz == 16);
desc.lod_or_fetch = BIFROST_LOD_MODE_BIAS;
break;
case nir_tex_src_ms_index:
case nir_tex_src_offset:
if (desc.offset_or_bias_disable)
break;
dregs[BIFROST_TEX_DREG_OFFSETMS] =
bi_emit_texc_offset_ms_index(b, instr);
if (!bi_is_equiv(dregs[BIFROST_TEX_DREG_OFFSETMS], bi_zero()))
desc.offset_or_bias_disable = true;
break;
case nir_tex_src_comparator:
dregs[BIFROST_TEX_DREG_SHADOW] = index;
break;
default:
unreachable("Unhandled src type in texc emit");
}
}
if (desc.op == BIFROST_TEX_OP_FETCH && bi_is_null(dregs[BIFROST_TEX_DREG_LOD])) {
dregs[BIFROST_TEX_DREG_LOD] =
bi_emit_texc_lod_cube(b, bi_zero());
}
/* Allocate staging registers contiguously by compacting the array.
* Index is not SSA (tied operands) */
bi_index idx = bi_temp_reg(b->shader);
unsigned sr_count = 0;
for (unsigned i = 0; i < ARRAY_SIZE(dregs); ++i) {
if (!bi_is_null(dregs[i]))
dregs[sr_count++] = dregs[i];
}
if (sr_count)
bi_make_vec_to(b, idx, dregs, NULL, sr_count, 32);
else
bi_mov_i32_to(b, idx, bi_zero()); /* XXX: shouldn't be necessary */
uint32_t desc_u = 0;
memcpy(&desc_u, &desc, sizeof(desc_u));
bi_texc_to(b, idx, idx, cx, cy, bi_imm_u32(desc_u), sr_count);
/* Explicit copy to facilitate tied operands */
bi_index srcs[4] = { idx, idx, idx, idx };
unsigned channels[4] = { 0, 1, 2, 3 };
bi_make_vec_to(b, bi_dest_index(&instr->dest), srcs, channels, 4, 32);
}
static void
emit_texc(bi_context *ctx, nir_tex_instr *instr)
{