nvk: Reformat nvk_nir_lower_descriptors

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24326>
This commit is contained in:
Faith Ekstrand 2023-01-30 20:11:48 -06:00 committed by Marge Bot
parent 4fbe45ca58
commit fca440dcb2

View file

@ -5,193 +5,208 @@
#include "nir_builder.h"
struct lower_descriptors_ctx {
const struct nvk_pipeline_layout *layout;
bool clamp_desc_array_bounds;
nir_address_format desc_addr_format;
nir_address_format ubo_addr_format;
nir_address_format ssbo_addr_format;
const struct nvk_pipeline_layout *layout;
bool clamp_desc_array_bounds;
nir_address_format desc_addr_format;
nir_address_format ubo_addr_format;
nir_address_format ssbo_addr_format;
};
static bool
lower_load_vulkan_descriptor(nir_builder *b, nir_intrinsic_instr *intrin,
const struct lower_descriptors_ctx *ctx) {
b->cursor = nir_before_instr(&intrin->instr);
const struct lower_descriptors_ctx *ctx)
{
b->cursor = nir_before_instr(&intrin->instr);
nir_ssa_def *index = nir_imm_int(b, 0);
nir_ssa_def *index = nir_imm_int(b, 0);
nir_intrinsic_instr *parent = nir_src_as_intrinsic(intrin->src[0]);
while (parent->intrinsic == nir_intrinsic_vulkan_resource_reindex) {
index = nir_iadd(b, index, nir_ssa_for_src(b, intrin->src[1], 1));
parent = nir_src_as_intrinsic(intrin->src[0]);
}
nir_intrinsic_instr *parent = nir_src_as_intrinsic(intrin->src[0]);
while (parent->intrinsic == nir_intrinsic_vulkan_resource_reindex) {
index = nir_iadd(b, index, nir_ssa_for_src(b, intrin->src[1], 1));
parent = nir_src_as_intrinsic(intrin->src[0]);
}
assert(parent->intrinsic == nir_intrinsic_vulkan_resource_index);
uint32_t set = nir_intrinsic_desc_set(parent);
uint32_t binding = nir_intrinsic_binding(parent);
index = nir_iadd(b, index, nir_ssa_for_src(b, parent->src[0], 1));
assert(parent->intrinsic == nir_intrinsic_vulkan_resource_index);
uint32_t set = nir_intrinsic_desc_set(parent);
uint32_t binding = nir_intrinsic_binding(parent);
index = nir_iadd(b, index, nir_ssa_for_src(b, parent->src[0], 1));
const struct nvk_descriptor_set_binding_layout *binding_layout =
const struct nvk_descriptor_set_binding_layout *binding_layout =
&ctx->layout->set[set].layout->binding[binding];
if (ctx->clamp_desc_array_bounds)
index = nir_umin(b, index, nir_imm_int(b, binding_layout->array_size - 1));
if (ctx->clamp_desc_array_bounds)
index = nir_umin(b, index, nir_imm_int(b, binding_layout->array_size - 1));
const uint32_t desc_ubo_index = set; /* TODO */
const uint32_t desc_ubo_index = set; /* TODO */
assert(binding_layout->stride > 0);
nir_ssa_def *desc_ubo_offset = nir_iadd_imm(
assert(binding_layout->stride > 0);
nir_ssa_def *desc_ubo_offset = nir_iadd_imm(
b, nir_imul_imm(b, index, binding_layout->stride), binding_layout->offset);
unsigned desc_align = (1 << (ffs(binding_layout->stride) - 1));
desc_align = MIN2(desc_align, 16);
unsigned desc_align = (1 << (ffs(binding_layout->stride) - 1));
desc_align = MIN2(desc_align, 16);
nir_ssa_def *desc =
nir_ssa_def *desc =
nir_load_ubo(b, 4, 32, nir_imm_int(b, desc_ubo_index), desc_ubo_offset,
.align_mul = 16, .align_offset = 0, .range = ~0);
nir_ssa_def_rewrite_uses(&intrin->dest.ssa, desc);
nir_ssa_def_rewrite_uses(&intrin->dest.ssa, desc);
return true;
return true;
}
static void get_resource_deref_binding(nir_builder *b, nir_deref_instr *deref,
uint32_t *set, uint32_t *binding,
nir_ssa_def **index) {
if (deref->deref_type == nir_deref_type_array) {
*index = deref->arr.index.ssa;
deref = nir_deref_instr_parent(deref);
} else {
*index = nir_imm_int(b, 0);
}
static void
get_resource_deref_binding(nir_builder *b, nir_deref_instr *deref,
uint32_t *set, uint32_t *binding,
nir_ssa_def **index)
{
if (deref->deref_type == nir_deref_type_array) {
*index = deref->arr.index.ssa;
deref = nir_deref_instr_parent(deref);
} else {
*index = nir_imm_int(b, 0);
}
assert(deref->deref_type == nir_deref_type_var);
nir_variable *var = deref->var;
assert(deref->deref_type == nir_deref_type_var);
nir_variable *var = deref->var;
*set = var->data.descriptor_set;
*binding = var->data.binding;
*set = var->data.descriptor_set;
*binding = var->data.binding;
}
static nir_ssa_def *
load_resource_deref_desc(nir_builder *b, nir_deref_instr *deref,
unsigned desc_offset, unsigned num_components,
unsigned bit_size,
const struct lower_descriptors_ctx *ctx) {
uint32_t set, binding;
nir_ssa_def *index;
get_resource_deref_binding(b, deref, &set, &binding, &index);
const struct lower_descriptors_ctx *ctx)
{
uint32_t set, binding;
nir_ssa_def *index;
get_resource_deref_binding(b, deref, &set, &binding, &index);
const struct nvk_descriptor_set_binding_layout *binding_layout =
const struct nvk_descriptor_set_binding_layout *binding_layout =
&ctx->layout->set[set].layout->binding[binding];
if (ctx->clamp_desc_array_bounds)
index = nir_umin(b, index, nir_imm_int(b, binding_layout->array_size - 1));
if (ctx->clamp_desc_array_bounds)
index = nir_umin(b, index, nir_imm_int(b, binding_layout->array_size - 1));
const uint32_t desc_ubo_index = set; /* TODO */
const uint32_t desc_ubo_index = set; /* TODO */
assert(binding_layout->stride > 0);
nir_ssa_def *desc_ubo_offset =
assert(binding_layout->stride > 0);
nir_ssa_def *desc_ubo_offset =
nir_iadd_imm(b, nir_imul_imm(b, index, binding_layout->stride),
binding_layout->offset + desc_offset);
unsigned desc_align = (1 << (ffs(binding_layout->stride) - 1));
desc_align = MIN2(desc_align, 16);
unsigned desc_align = (1 << (ffs(binding_layout->stride) - 1));
desc_align = MIN2(desc_align, 16);
return nir_load_ubo(b, num_components, bit_size,
nir_imm_int(b, desc_ubo_index), desc_ubo_offset,
.align_mul = desc_align,
.align_offset = (desc_offset % desc_align), .range = ~0);
return nir_load_ubo(b, num_components, bit_size,
nir_imm_int(b, desc_ubo_index), desc_ubo_offset,
.align_mul = desc_align,
.align_offset = (desc_offset % desc_align), .range = ~0);
}
static bool lower_image_intrin(nir_builder *b, nir_intrinsic_instr *intrin,
const struct lower_descriptors_ctx *ctx) {
nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
nir_ssa_def *desc = load_resource_deref_desc(b, deref, 0, 1, 32, ctx);
nir_rewrite_image_intrinsic(intrin, desc, true);
return true;
static bool
lower_image_intrin(nir_builder *b, nir_intrinsic_instr *intrin,
const struct lower_descriptors_ctx *ctx)
{
nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
nir_ssa_def *desc = load_resource_deref_desc(b, deref, 0, 1, 32, ctx);
nir_rewrite_image_intrinsic(intrin, desc, true);
return true;
}
static bool lower_intrin(nir_builder *b, nir_intrinsic_instr *intrin,
const struct lower_descriptors_ctx *ctx) {
switch (intrin->intrinsic) {
case nir_intrinsic_load_vulkan_descriptor:
return lower_load_vulkan_descriptor(b, intrin, ctx);
static bool
lower_intrin(nir_builder *b, nir_intrinsic_instr *intrin,
const struct lower_descriptors_ctx *ctx)
{
switch (intrin->intrinsic) {
case nir_intrinsic_load_vulkan_descriptor:
return lower_load_vulkan_descriptor(b, intrin, ctx);
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:
case nir_intrinsic_image_deref_size:
case nir_intrinsic_image_deref_samples:
case nir_intrinsic_image_deref_load_param_intel:
case nir_intrinsic_image_deref_load_raw_intel:
case nir_intrinsic_image_deref_store_raw_intel:
return lower_image_intrin(b, intrin, ctx);
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:
case nir_intrinsic_image_deref_size:
case nir_intrinsic_image_deref_samples:
case nir_intrinsic_image_deref_load_param_intel:
case nir_intrinsic_image_deref_load_raw_intel:
case nir_intrinsic_image_deref_store_raw_intel:
return lower_image_intrin(b, intrin, ctx);
default:
return false;
}
default:
return false;
}
}
static bool lower_tex(nir_builder *b, nir_tex_instr *tex,
const struct lower_descriptors_ctx *ctx) {
b->cursor = nir_before_instr(&tex->instr);
static bool
lower_tex(nir_builder *b, nir_tex_instr *tex,
const struct lower_descriptors_ctx *ctx)
{
b->cursor = nir_before_instr(&tex->instr);
for (unsigned i = 0; i < tex->num_srcs; i++) {
if (tex->src[i].src_type != nir_tex_src_texture_deref &&
tex->src[i].src_type != nir_tex_src_sampler_deref)
continue;
for (unsigned i = 0; i < tex->num_srcs; i++) {
if (tex->src[i].src_type != nir_tex_src_texture_deref &&
tex->src[i].src_type != nir_tex_src_sampler_deref)
continue;
nir_deref_instr *deref = nir_src_as_deref(tex->src[i].src);
nir_ssa_def *desc = load_resource_deref_desc(b, deref, 0, 1, 32, ctx);
nir_deref_instr *deref = nir_src_as_deref(tex->src[i].src);
nir_ssa_def *desc = load_resource_deref_desc(b, deref, 0, 1, 32, ctx);
switch (tex->src[i].src_type) {
case nir_tex_src_texture_deref:
tex->src[i].src_type = nir_tex_src_texture_handle;
nir_instr_rewrite_src_ssa(&tex->instr, &tex->src[i].src,
nir_iand_imm(b, desc, 0x000fffff));
break;
switch (tex->src[i].src_type) {
case nir_tex_src_texture_deref:
tex->src[i].src_type = nir_tex_src_texture_handle;
nir_instr_rewrite_src_ssa(&tex->instr, &tex->src[i].src,
nir_iand_imm(b, desc, 0x000fffff));
break;
case nir_tex_src_sampler_deref:
tex->src[i].src_type = nir_tex_src_sampler_handle;
nir_instr_rewrite_src_ssa(&tex->instr, &tex->src[i].src,
nir_iand_imm(b, desc, 0xfff00000));
break;
case nir_tex_src_sampler_deref:
tex->src[i].src_type = nir_tex_src_sampler_handle;
nir_instr_rewrite_src_ssa(&tex->instr, &tex->src[i].src,
nir_iand_imm(b, desc, 0xfff00000));
break;
default:
unreachable("Unhandled texture source");
}
}
default:
unreachable("Unhandled texture source");
}
}
return true;
return true;
}
static bool lower_descriptors_instr(nir_builder *b, nir_instr *instr,
void *_data) {
const struct lower_descriptors_ctx *ctx = _data;
static bool
lower_descriptors_instr(nir_builder *b, nir_instr *instr,
void *_data)
{
const struct lower_descriptors_ctx *ctx = _data;
switch (instr->type) {
case nir_instr_type_tex:
return lower_tex(b, nir_instr_as_tex(instr), ctx);
case nir_instr_type_intrinsic:
return lower_intrin(b, nir_instr_as_intrinsic(instr), ctx);
default:
return false;
}
switch (instr->type) {
case nir_instr_type_tex:
return lower_tex(b, nir_instr_as_tex(instr), ctx);
case nir_instr_type_intrinsic:
return lower_intrin(b, nir_instr_as_intrinsic(instr), ctx);
default:
return false;
}
}
bool nvk_nir_lower_descriptors(nir_shader *nir,
const struct nvk_pipeline_layout *layout,
bool robust_buffer_access) {
struct lower_descriptors_ctx ctx = {
bool
nvk_nir_lower_descriptors(nir_shader *nir,
const struct nvk_pipeline_layout *layout,
bool robust_buffer_access)
{
struct lower_descriptors_ctx ctx = {
.layout = layout,
.clamp_desc_array_bounds = robust_buffer_access,
.desc_addr_format = nir_address_format_32bit_index_offset,
.ubo_addr_format = nir_address_format_32bit_index_offset,
.ssbo_addr_format = robust_buffer_access
? nir_address_format_64bit_bounded_global
: nir_address_format_64bit_global_32bit_offset,
};
return nir_shader_instructions_pass(
nir, lower_descriptors_instr,
nir_metadata_block_index | nir_metadata_dominance, (void *)&ctx);
.ssbo_addr_format = robust_buffer_access ?
nir_address_format_64bit_bounded_global :
nir_address_format_64bit_global_32bit_offset,
};
return nir_shader_instructions_pass(nir, lower_descriptors_instr,
nir_metadata_block_index |
nir_metadata_dominance,
(void *)&ctx);
}