mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-06 08:50:09 +01:00
ir3: Split out bindless tex/samp encoding
It will be used with prefetching, which is an intrinsic. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29873>
This commit is contained in:
parent
ccf88d940b
commit
fa8758fc81
1 changed files with 102 additions and 88 deletions
|
|
@ -1647,6 +1647,105 @@ emit_intrinsic_image_size_tex(struct ir3_context *ctx,
|
|||
}
|
||||
}
|
||||
|
||||
static struct tex_src_info
|
||||
get_bindless_samp_src(struct ir3_context *ctx, nir_src *tex,
|
||||
nir_src *samp)
|
||||
{
|
||||
struct ir3_block *b = ctx->block;
|
||||
struct tex_src_info info = {0};
|
||||
|
||||
info.flags |= IR3_INSTR_B;
|
||||
|
||||
/* Gather information required to determine which encoding to
|
||||
* choose as well as for prefetch.
|
||||
*/
|
||||
nir_intrinsic_instr *bindless_tex = NULL;
|
||||
bool tex_const;
|
||||
if (tex) {
|
||||
ctx->so->bindless_tex = true;
|
||||
bindless_tex = ir3_bindless_resource(*tex);
|
||||
assert(bindless_tex);
|
||||
info.tex_base = nir_intrinsic_desc_set(bindless_tex);
|
||||
tex_const = nir_src_is_const(bindless_tex->src[0]);
|
||||
if (tex_const)
|
||||
info.tex_idx = nir_src_as_uint(bindless_tex->src[0]);
|
||||
} else {
|
||||
/* To simplify some of the logic below, assume the index is
|
||||
* constant 0 when it's not enabled.
|
||||
*/
|
||||
tex_const = true;
|
||||
info.tex_idx = 0;
|
||||
}
|
||||
nir_intrinsic_instr *bindless_samp = NULL;
|
||||
bool samp_const;
|
||||
if (samp) {
|
||||
ctx->so->bindless_samp = true;
|
||||
bindless_samp = ir3_bindless_resource(*samp);
|
||||
assert(bindless_samp);
|
||||
info.samp_base = nir_intrinsic_desc_set(bindless_samp);
|
||||
samp_const = nir_src_is_const(bindless_samp->src[0]);
|
||||
if (samp_const)
|
||||
info.samp_idx = nir_src_as_uint(bindless_samp->src[0]);
|
||||
} else {
|
||||
samp_const = true;
|
||||
info.samp_idx = 0;
|
||||
}
|
||||
|
||||
/* Choose encoding. */
|
||||
if (tex_const && samp_const && info.tex_idx < 256 &&
|
||||
info.samp_idx < 256) {
|
||||
if (info.tex_idx < 16 && info.samp_idx < 16 &&
|
||||
(!bindless_tex || !bindless_samp ||
|
||||
info.tex_base == info.samp_base)) {
|
||||
/* Everything fits within the instruction */
|
||||
info.base = info.tex_base;
|
||||
} else {
|
||||
info.base = info.tex_base;
|
||||
if (ctx->compiler->gen <= 6) {
|
||||
info.a1_val = info.tex_idx << 3 | info.samp_base;
|
||||
} else {
|
||||
info.a1_val = info.samp_idx << 3 | info.samp_base;
|
||||
}
|
||||
|
||||
info.flags |= IR3_INSTR_A1EN;
|
||||
}
|
||||
info.samp_tex = NULL;
|
||||
} else {
|
||||
info.flags |= IR3_INSTR_S2EN;
|
||||
/* In the indirect case, we only use a1.x to store the sampler
|
||||
* base if it differs from the texture base.
|
||||
*/
|
||||
if (!bindless_tex || !bindless_samp ||
|
||||
info.tex_base == info.samp_base) {
|
||||
info.base = info.tex_base;
|
||||
} else {
|
||||
info.base = info.tex_base;
|
||||
info.a1_val = info.samp_base;
|
||||
info.flags |= IR3_INSTR_A1EN;
|
||||
}
|
||||
|
||||
/* Note: the indirect source is now a vec2 instead of hvec2, and
|
||||
* for some reason the texture and sampler are swapped.
|
||||
*/
|
||||
struct ir3_instruction *texture, *sampler;
|
||||
|
||||
if (bindless_tex) {
|
||||
texture = ir3_get_src(ctx, tex)[0];
|
||||
} else {
|
||||
texture = create_immed(b, 0);
|
||||
}
|
||||
|
||||
if (bindless_samp) {
|
||||
sampler = ir3_get_src(ctx, samp)[0];
|
||||
} else {
|
||||
sampler = create_immed(b, 0);
|
||||
}
|
||||
info.samp_tex = ir3_collect(b, texture, sampler);
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
/* src[] = { buffer_index, offset }. No const_index */
|
||||
static void
|
||||
emit_intrinsic_load_ssbo(struct ir3_context *ctx,
|
||||
|
|
@ -3057,97 +3156,12 @@ get_tex_samp_tex_src(struct ir3_context *ctx, nir_tex_instr *tex)
|
|||
|
||||
if (texture_idx >= 0 || sampler_idx >= 0) {
|
||||
/* Bindless case */
|
||||
info.flags |= IR3_INSTR_B;
|
||||
info = get_bindless_samp_src(ctx,
|
||||
texture_idx >= 0 ? &tex->src[texture_idx].src : NULL,
|
||||
sampler_idx >= 0 ? &tex->src[sampler_idx].src : NULL);
|
||||
|
||||
if (tex->texture_non_uniform || tex->sampler_non_uniform)
|
||||
info.flags |= IR3_INSTR_NONUNIF;
|
||||
|
||||
/* Gather information required to determine which encoding to
|
||||
* choose as well as for prefetch.
|
||||
*/
|
||||
nir_intrinsic_instr *bindless_tex = NULL;
|
||||
bool tex_const;
|
||||
if (texture_idx >= 0) {
|
||||
ctx->so->bindless_tex = true;
|
||||
bindless_tex = ir3_bindless_resource(tex->src[texture_idx].src);
|
||||
assert(bindless_tex);
|
||||
info.tex_base = nir_intrinsic_desc_set(bindless_tex);
|
||||
tex_const = nir_src_is_const(bindless_tex->src[0]);
|
||||
if (tex_const)
|
||||
info.tex_idx = nir_src_as_uint(bindless_tex->src[0]);
|
||||
} else {
|
||||
/* To simplify some of the logic below, assume the index is
|
||||
* constant 0 when it's not enabled.
|
||||
*/
|
||||
tex_const = true;
|
||||
info.tex_idx = 0;
|
||||
}
|
||||
nir_intrinsic_instr *bindless_samp = NULL;
|
||||
bool samp_const;
|
||||
if (sampler_idx >= 0) {
|
||||
ctx->so->bindless_samp = true;
|
||||
bindless_samp = ir3_bindless_resource(tex->src[sampler_idx].src);
|
||||
assert(bindless_samp);
|
||||
info.samp_base = nir_intrinsic_desc_set(bindless_samp);
|
||||
samp_const = nir_src_is_const(bindless_samp->src[0]);
|
||||
if (samp_const)
|
||||
info.samp_idx = nir_src_as_uint(bindless_samp->src[0]);
|
||||
} else {
|
||||
samp_const = true;
|
||||
info.samp_idx = 0;
|
||||
}
|
||||
|
||||
/* Choose encoding. */
|
||||
if (tex_const && samp_const && info.tex_idx < 256 &&
|
||||
info.samp_idx < 256) {
|
||||
if (info.tex_idx < 16 && info.samp_idx < 16 &&
|
||||
(!bindless_tex || !bindless_samp ||
|
||||
info.tex_base == info.samp_base)) {
|
||||
/* Everything fits within the instruction */
|
||||
info.base = info.tex_base;
|
||||
} else {
|
||||
info.base = info.tex_base;
|
||||
if (ctx->compiler->gen <= 6) {
|
||||
info.a1_val = info.tex_idx << 3 | info.samp_base;
|
||||
} else {
|
||||
info.a1_val = info.samp_idx << 3 | info.samp_base;
|
||||
}
|
||||
|
||||
info.flags |= IR3_INSTR_A1EN;
|
||||
}
|
||||
info.samp_tex = NULL;
|
||||
} else {
|
||||
info.flags |= IR3_INSTR_S2EN;
|
||||
/* In the indirect case, we only use a1.x to store the sampler
|
||||
* base if it differs from the texture base.
|
||||
*/
|
||||
if (!bindless_tex || !bindless_samp ||
|
||||
info.tex_base == info.samp_base) {
|
||||
info.base = info.tex_base;
|
||||
} else {
|
||||
info.base = info.tex_base;
|
||||
info.a1_val = info.samp_base;
|
||||
info.flags |= IR3_INSTR_A1EN;
|
||||
}
|
||||
|
||||
/* Note: the indirect source is now a vec2 instead of hvec2, and
|
||||
* for some reason the texture and sampler are swapped.
|
||||
*/
|
||||
struct ir3_instruction *texture, *sampler;
|
||||
|
||||
if (bindless_tex) {
|
||||
texture = ir3_get_src(ctx, &tex->src[texture_idx].src)[0];
|
||||
} else {
|
||||
texture = create_immed(b, 0);
|
||||
}
|
||||
|
||||
if (bindless_samp) {
|
||||
sampler = ir3_get_src(ctx, &tex->src[sampler_idx].src)[0];
|
||||
} else {
|
||||
sampler = create_immed(b, 0);
|
||||
}
|
||||
info.samp_tex = ir3_collect(b, texture, sampler);
|
||||
}
|
||||
} else {
|
||||
info.flags |= IR3_INSTR_S2EN;
|
||||
texture_idx = nir_tex_instr_src_index(tex, nir_tex_src_texture_offset);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue