mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-03-17 23:20:33 +01:00
nvk: Lower descriptors for VK_EXT_descriptor_buffer buffer views
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30580>
This commit is contained in:
parent
8cafd2667f
commit
3b94c5c22a
1 changed files with 194 additions and 2 deletions
|
|
@ -942,6 +942,137 @@ lower_msaa_image_intrin(nir_builder *b, nir_intrinsic_instr *intrin,
|
|||
nir_intrinsic_set_image_dim(intrin, GLSL_SAMPLER_DIM_2D);
|
||||
}
|
||||
|
||||
static bool
|
||||
is_edb_buffer_view(nir_deref_instr *deref,
|
||||
const struct lower_descriptors_ctx *ctx)
|
||||
{
|
||||
if (glsl_get_sampler_dim(deref->type) != GLSL_SAMPLER_DIM_BUF)
|
||||
return false;
|
||||
|
||||
nir_variable *var = nir_deref_instr_get_variable(deref);
|
||||
uint8_t set = var->data.descriptor_set;
|
||||
|
||||
return ctx->set_layouts[set]->flags &
|
||||
VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT;
|
||||
}
|
||||
|
||||
static nir_def *
|
||||
edb_buffer_view_is_null(nir_builder *b, nir_def *desc)
|
||||
{
|
||||
assert(desc->num_components == 4);
|
||||
nir_def *index = nir_channel(b, desc, 0);
|
||||
return nir_ieq_imm(b, index, 0);
|
||||
}
|
||||
|
||||
static nir_def *
|
||||
edb_buffer_view_offset_el(nir_builder *b, nir_def *desc)
|
||||
{
|
||||
assert(desc->num_components == 4);
|
||||
return nir_channel(b, desc, 1);
|
||||
}
|
||||
|
||||
static nir_def *
|
||||
edb_buffer_view_size_el(nir_builder *b, nir_def *desc)
|
||||
{
|
||||
assert(desc->num_components == 4);
|
||||
return nir_channel(b, desc, 2);
|
||||
}
|
||||
|
||||
static nir_def *
|
||||
edb_buffer_view_oob_alpha(nir_builder *b, nir_def *desc)
|
||||
{
|
||||
assert(desc->num_components == 4);
|
||||
return nir_channel(b, desc, 3);
|
||||
}
|
||||
|
||||
static nir_def *
|
||||
edb_buffer_view_coord_is_in_bounds(nir_builder *b, nir_def *desc,
|
||||
nir_def *coord)
|
||||
{
|
||||
assert(desc->num_components == 4);
|
||||
return nir_ult(b, coord, edb_buffer_view_size_el(b, desc));
|
||||
}
|
||||
|
||||
static nir_def *
|
||||
edb_buffer_view_index(nir_builder *b, nir_def *desc, nir_def *in_bounds)
|
||||
{
|
||||
assert(desc->num_components == 4);
|
||||
nir_def *index = nir_channel(b, desc, 0);
|
||||
|
||||
/* Use the NULL descriptor for OOB access */
|
||||
return nir_bcsel(b, in_bounds, index, nir_imm_int(b, 0));
|
||||
}
|
||||
|
||||
static nir_def *
|
||||
adjust_edb_buffer_view_coord(nir_builder *b, nir_def *desc, nir_def *coord)
|
||||
{
|
||||
return nir_iadd(b, coord, edb_buffer_view_offset_el(b, desc));
|
||||
}
|
||||
|
||||
static nir_def *
|
||||
fixup_edb_buffer_view_result(nir_builder *b, nir_def *desc, nir_def *in_bounds,
|
||||
nir_def *res, nir_alu_type dest_type)
|
||||
{
|
||||
if (res->num_components < 4)
|
||||
return res;
|
||||
|
||||
nir_def *is_null = edb_buffer_view_is_null(b, desc);
|
||||
nir_def *oob_alpha = edb_buffer_view_oob_alpha(b, desc);
|
||||
|
||||
nir_def *a = nir_channel(b, res, 3);
|
||||
a = nir_bcsel(b, nir_ior(b, in_bounds, is_null), a, oob_alpha);
|
||||
return nir_vector_insert_imm(b, res, a, 3);
|
||||
}
|
||||
|
||||
static void
|
||||
lower_edb_buffer_image_intrin(nir_builder *b, nir_intrinsic_instr *intrin,
|
||||
const struct lower_descriptors_ctx *ctx)
|
||||
{
|
||||
assert(nir_intrinsic_image_dim(intrin) == GLSL_SAMPLER_DIM_BUF);
|
||||
|
||||
b->cursor = nir_before_instr(&intrin->instr);
|
||||
nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
|
||||
nir_def *desc = load_resource_deref_desc(b, 4, 32, deref, 0, ctx);
|
||||
|
||||
switch (intrin->intrinsic) {
|
||||
case nir_intrinsic_image_deref_load:
|
||||
case nir_intrinsic_image_deref_store:
|
||||
case nir_intrinsic_image_deref_atomic:
|
||||
case nir_intrinsic_image_deref_atomic_swap: {
|
||||
nir_def *pos = intrin->src[1].ssa;
|
||||
nir_def *x = nir_channel(b, pos, 0);
|
||||
|
||||
nir_def *in_bounds = edb_buffer_view_coord_is_in_bounds(b, desc, x);
|
||||
nir_def *index = edb_buffer_view_index(b, desc, in_bounds);
|
||||
|
||||
nir_def *new_x = adjust_edb_buffer_view_coord(b, desc, x);
|
||||
pos = nir_vector_insert_imm(b, pos, new_x, 0);
|
||||
nir_src_rewrite(&intrin->src[1], pos);
|
||||
|
||||
if (intrin->intrinsic == nir_intrinsic_image_deref_load) {
|
||||
b->cursor = nir_after_instr(&intrin->instr);
|
||||
nir_def *res = &intrin->def;
|
||||
res = fixup_edb_buffer_view_result(b, desc, in_bounds, res,
|
||||
nir_intrinsic_dest_type(intrin));
|
||||
nir_def_rewrite_uses_after(&intrin->def, res, res->parent_instr);
|
||||
}
|
||||
|
||||
nir_rewrite_image_intrinsic(intrin, index, true);
|
||||
break;
|
||||
}
|
||||
|
||||
case nir_intrinsic_image_deref_size: {
|
||||
assert(intrin->def.num_components == 1);
|
||||
nir_def *size_el = nir_channel(b, desc, 2);
|
||||
nir_def_rewrite_uses(&intrin->def, size_el);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
unreachable("Unknown image intrinsic");
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
lower_image_intrin(nir_builder *b, nir_intrinsic_instr *intrin,
|
||||
const struct lower_descriptors_ctx *ctx)
|
||||
|
|
@ -950,6 +1081,8 @@ lower_image_intrin(nir_builder *b, nir_intrinsic_instr *intrin,
|
|||
|
||||
if (glsl_get_sampler_dim(deref->type) == GLSL_SAMPLER_DIM_MS) {
|
||||
lower_msaa_image_intrin(b, intrin, ctx);
|
||||
} else if (is_edb_buffer_view(deref, ctx)) {
|
||||
lower_edb_buffer_image_intrin(b, intrin, ctx);
|
||||
} else {
|
||||
b->cursor = nir_before_instr(&intrin->instr);
|
||||
nir_def *desc = load_resource_deref_desc(b, 1, 32, deref, 0, ctx);
|
||||
|
|
@ -1044,12 +1177,64 @@ try_lower_intrin(nir_builder *b, nir_intrinsic_instr *intrin,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
lower_edb_buffer_tex_instr(nir_builder *b, nir_tex_instr *tex,
|
||||
const struct lower_descriptors_ctx *ctx)
|
||||
{
|
||||
assert(tex->sampler_dim == GLSL_SAMPLER_DIM_BUF);
|
||||
|
||||
b->cursor = nir_before_instr(&tex->instr);
|
||||
|
||||
const int texture_src_idx =
|
||||
nir_tex_instr_src_index(tex, nir_tex_src_texture_deref);
|
||||
nir_deref_instr *texture = nir_src_as_deref(tex->src[texture_src_idx].src);
|
||||
|
||||
nir_def *plane_ssa = nir_steal_tex_src(tex, nir_tex_src_plane);
|
||||
ASSERTED const uint32_t plane =
|
||||
plane_ssa ? nir_src_as_uint(nir_src_for_ssa(plane_ssa)) : 0;
|
||||
assert(plane == 0);
|
||||
|
||||
nir_def *desc = load_resource_deref_desc(b, 4, 32, texture, 0, ctx);
|
||||
|
||||
switch (tex->op) {
|
||||
case nir_texop_txf: {
|
||||
const int coord_src_idx = nir_tex_instr_src_index(tex, nir_tex_src_coord);
|
||||
assert(coord_src_idx >= 0);
|
||||
nir_def *coord = tex->src[coord_src_idx].src.ssa;
|
||||
|
||||
nir_def *in_bounds = edb_buffer_view_coord_is_in_bounds(b, desc, coord);
|
||||
|
||||
nir_def *index = edb_buffer_view_index(b, desc, in_bounds);
|
||||
nir_src_rewrite(&tex->src[texture_src_idx].src, index);
|
||||
tex->src[texture_src_idx].src_type = nir_tex_src_texture_handle;
|
||||
|
||||
nir_def *new_coord = adjust_edb_buffer_view_coord(b, desc, coord);
|
||||
nir_src_rewrite(&tex->src[coord_src_idx].src, new_coord);
|
||||
|
||||
b->cursor = nir_after_instr(&tex->instr);
|
||||
nir_def *res = &tex->def;
|
||||
res = fixup_edb_buffer_view_result(b, desc, in_bounds,
|
||||
res, tex->dest_type);
|
||||
nir_def_rewrite_uses_after(&tex->def, res, res->parent_instr);
|
||||
break;
|
||||
}
|
||||
|
||||
case nir_texop_txs: {
|
||||
assert(tex->def.num_components == 1);
|
||||
nir_def *size_el = edb_buffer_view_size_el(b, desc);
|
||||
nir_def_rewrite_uses(&tex->def, size_el);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
unreachable("Invalid buffer texture op");
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
lower_tex(nir_builder *b, nir_tex_instr *tex,
|
||||
const struct lower_descriptors_ctx *ctx)
|
||||
{
|
||||
b->cursor = nir_before_instr(&tex->instr);
|
||||
|
||||
const int texture_src_idx =
|
||||
nir_tex_instr_src_index(tex, nir_tex_src_texture_deref);
|
||||
const int sampler_src_idx =
|
||||
|
|
@ -1064,6 +1249,13 @@ lower_tex(nir_builder *b, nir_tex_instr *tex,
|
|||
nir_src_as_deref(tex->src[sampler_src_idx].src);
|
||||
assert(texture);
|
||||
|
||||
if (is_edb_buffer_view(texture, ctx)) {
|
||||
lower_edb_buffer_tex_instr(b, tex, ctx);
|
||||
return true;
|
||||
}
|
||||
|
||||
b->cursor = nir_before_instr(&tex->instr);
|
||||
|
||||
nir_def *plane_ssa = nir_steal_tex_src(tex, nir_tex_src_plane);
|
||||
const uint32_t plane =
|
||||
plane_ssa ? nir_src_as_uint(nir_src_for_ssa(plane_ssa)) : 0;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue