mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-26 12:10:22 +01:00
nvk: Reformat nvk_nir_lower_descriptors
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24326>
This commit is contained in:
parent
4fbe45ca58
commit
fca440dcb2
1 changed files with 143 additions and 128 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue