kk: Support nullDescriptor

Add handling for null images and vertex inputs.

Reviewed-by: Aitor Camacho <aitor@lunarg.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41313>
This commit is contained in:
squidbus 2026-05-01 04:22:52 -07:00 committed by Marge Bot
parent 0c9dfa90f9
commit cccf953545
5 changed files with 117 additions and 1 deletions

View file

@ -552,7 +552,7 @@ kk_CmdBindVertexBuffers2(VkCommandBuffer commandBuffer, uint32_t firstBinding,
const struct kk_addr_range addr_range =
kk_buffer_addr_range(buffer, pOffsets[i], size);
cmd->state.gfx.vb.addr_range[idx] = addr_range;
cmd->state.gfx.vb.handles[idx] = buffer->mtl_handle;
cmd->state.gfx.vb.handles[idx] = buffer ? buffer->mtl_handle : NULL;
cmd->state.gfx.dirty |= KK_DIRTY_VB;
}
}

View file

@ -0,0 +1,107 @@
/*
* Copyright © 2025 Imagination Technologies Ltd.
* Copyright (C) 2020-2021 Collabora, Ltd.
* Copyright © 2020 Valve Corporation
* Copyright 2026 LunarG, Inc.
* Copyright 2026 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "kk_shader.h"
#include "compiler/nir/nir.h"
#include "compiler/nir/nir_builder.h"
static nir_def*
tex_handle_to_resource_id(nir_builder *b, nir_def* handle)
{
/* Work backwards from the handle to the descriptor address it was loaded
* from, and load the plain resource ID */
const nir_instr *instr = nir_def_instr_const(handle);
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
return nir_load_global_constant(b, 1, 64, intr->src[0].ssa);
}
static nir_def*
get_is_null(nir_builder *b, nir_instr *instr, nir_def **def)
{
*def = NULL;
nir_def *handle = NULL;
if (instr->type == nir_instr_type_intrinsic) {
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
switch (intr->intrinsic) {
case nir_intrinsic_bindless_image_load:
case nir_intrinsic_bindless_image_sparse_load:
case nir_intrinsic_bindless_image_store:
case nir_intrinsic_bindless_image_atomic:
case nir_intrinsic_bindless_image_atomic_swap:
case nir_intrinsic_bindless_image_size:
case nir_intrinsic_bindless_image_samples:
case nir_intrinsic_bindless_image_levels:
if (nir_intrinsic_infos[intr->intrinsic].has_dest)
*def = &intr->def;
handle = intr->src[0].ssa;
break;
default:
break;
}
} else if (instr->type == nir_instr_type_tex) {
nir_tex_instr *tex = nir_instr_as_tex(instr);
*def = &tex->def;
handle = nir_get_tex_src(tex, nir_tex_src_texture_handle);
}
if (!handle)
return NULL;
nir_def* resource_id = tex_handle_to_resource_id(b, handle);
return nir_ieq_imm(b, resource_id, 0);
}
static bool
lower(nir_builder *b, nir_instr *instr, UNUSED void *data)
{
b->cursor = nir_before_instr(instr);
nir_def *def;
nir_def *is_null = get_is_null(b, instr, &def);
if (!is_null)
return false;
nir_def *zero = NULL;
nir_if *nif = nir_push_if(b, nir_inot(b, is_null));
nir_instr_remove(instr);
nir_builder_instr_insert(b, instr);
if (def) {
nir_push_else(b, nif);
zero = nir_imm_zero(b, def->num_components, def->bit_size);
}
nir_pop_if(b, nif);
if (def) {
nir_def *phi = nir_if_phi(b, def, zero);
/* We can't use nir_def_rewrite_uses_after on phis, so use the global
* version and fixup the phi manually
*/
nir_def_rewrite_uses(def, phi);
nir_instr *phi_instr = nir_def_instr(phi);
nir_phi_instr *phi_as_phi = nir_instr_as_phi(phi_instr);
nir_phi_src *phi_src =
nir_phi_get_src_from_block(phi_as_phi, instr->block);
nir_src_rewrite(&phi_src->src, def);
}
return true;
}
bool kk_nir_lower_null_images(nir_shader *shader)
{
return nir_shader_instructions_pass(shader, lower,
nir_metadata_none, NULL);
}

View file

@ -182,6 +182,9 @@ kk_hash_graphics_state(struct vk_physical_device *device,
sizeof(state->mv->view_mask));
}
_mesa_blake3_update(&blake3_ctx, &enabled_features->nullDescriptor,
sizeof(enabled_features->nullDescriptor));
_mesa_blake3_final(&blake3_ctx, blake3_out);
}
@ -585,6 +588,9 @@ kk_lower_nir(struct kk_device *dev, nir_shader *nir,
set_layouts);
NIR_PASS(_, nir, kk_nir_lower_textures);
if (dev->vk.enabled_features.nullDescriptor)
NIR_PASS(_, nir, kk_nir_lower_null_images);
NIR_PASS(_, nir, nir_lower_global_vars_to_local);
}

View file

@ -108,6 +108,8 @@ kk_nir_lower_descriptors(nir_shader *nir,
uint32_t set_layout_count,
struct vk_descriptor_set_layout *const *set_layouts);
bool kk_nir_lower_null_images(nir_shader *nir);
bool kk_nir_lower_textures(nir_shader *nir);
bool kk_nir_lower_vs_multiview(nir_shader *nir, uint32_t view_mask);

View file

@ -80,6 +80,7 @@ kk_files = files(
'kk_instance.c',
'kk_nir_lower_descriptors.c',
'kk_nir_lower_multiview.c',
'kk_nir_lower_null_images.c',
'kk_nir_lower_textures.c',
'kk_nir_lower_vbo.h',
'kk_nir_lower_vbo.c',