#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);
- }
-
- assert(deref->deref_type == nir_deref_type_var);
- nir_variable *var = deref->var;
-
- *set = var->data.descriptor_set;
- *binding = var->data.binding;
+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;
+
+ *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);
-
- 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;
- }
+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);
+
+ 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);
-
- 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);
-
- 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;
-
- default:
- unreachable("Unhandled texture source");
- }
- }
-
- return true;
+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;
+
+ 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;
+
+ 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");
+ }
+ }
+
+ return true;
}
-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;
- }
+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;
+ }
}
-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);
}