anv: add descriptor heap binding support

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Acked-by: Alyssa Rosenzweig <alyssa.rosenzweig@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39478>
This commit is contained in:
Lionel Landwerlin 2025-08-14 20:51:16 +03:00 committed by Marge Bot
parent 9231204026
commit cf3b4757cf
4 changed files with 114 additions and 6 deletions

View file

@ -78,7 +78,8 @@ anv_get_buffer_memory_requirements(struct anv_device *device,
if (flags & VK_BUFFER_CREATE_PROTECTED_BIT)
memory_types = device->physical->memory.protected_mem_types;
else if (usage & (VK_BUFFER_USAGE_2_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT |
VK_BUFFER_USAGE_2_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT))
VK_BUFFER_USAGE_2_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT |
VK_BUFFER_USAGE_2_DESCRIPTOR_HEAP_BIT_EXT))
memory_types = device->physical->memory.dynamic_visible_mem_types;
else if (device->physical->instance->enable_buffer_comp)
memory_types = device->physical->memory.default_buffer_mem_types |
@ -238,7 +239,8 @@ VkResult anv_CreateBuffer(
* allocate it on the correct heap.
*/
if (buffer->vk.usage & (VK_BUFFER_USAGE_2_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT |
VK_BUFFER_USAGE_2_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT)) {
VK_BUFFER_USAGE_2_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT |
VK_BUFFER_USAGE_2_DESCRIPTOR_HEAP_BIT_EXT)) {
alloc_flags |= ANV_BO_ALLOC_DYNAMIC_VISIBLE_POOL;
}

View file

@ -892,6 +892,79 @@ void anv_CmdBindDescriptorBufferEmbeddedSamplers2EXT(
/* no-op */
}
void anv_CmdBindSamplerHeapEXT(
VkCommandBuffer commandBuffer,
const VkBindHeapInfoEXT* pBindInfo)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
struct anv_cmd_state *state = &cmd_buffer->state;
if (state->descriptor_buffers.samplers_address != pBindInfo->heapRange.address)
state->descriptor_buffers.samplers_address = pBindInfo->heapRange.address;
}
void anv_CmdBindResourceHeapEXT(
VkCommandBuffer commandBuffer,
const VkBindHeapInfoEXT* pBindInfo)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
struct anv_cmd_state *state = &cmd_buffer->state;
if (state->descriptor_buffers.surfaces_address != pBindInfo->heapRange.address) {
state->descriptor_buffers.surfaces_address = pBindInfo->heapRange.address;
state->descriptor_buffers.dirty = true;
}
anv_cmd_buffer_maybe_dirty_descriptor_mode(cmd_buffer,
ANV_CMD_DESCRIPTOR_BUFFER_MODE_HEAP);
}
void anv_CmdPushDataEXT(
VkCommandBuffer commandBuffer,
const VkPushDataInfoEXT* pPushDataInfo)
{
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
if (anv_cmd_buffer_is_render_queue(cmd_buffer)) {
struct anv_cmd_pipeline_state *pipe_state =
&cmd_buffer->state.gfx.base;
memcpy(pipe_state->push_constants.client_data + pPushDataInfo->offset,
pPushDataInfo->data.address, pPushDataInfo->data.size);
pipe_state->push_constants_data_dirty = true;
pipe_state->push_constants_client_size = MAX2(
pipe_state->push_constants_client_size,
pPushDataInfo->offset + pPushDataInfo->data.size);
cmd_buffer->state.push_constants_dirty |= ANV_GRAPHICS_STAGE_BITS;
}
if (anv_cmd_buffer_is_render_or_compute_queue(cmd_buffer)) {
struct anv_cmd_pipeline_state *cs_state =
&cmd_buffer->state.compute.base;
memcpy(cs_state->push_constants.client_data + pPushDataInfo->offset,
pPushDataInfo->data.address, pPushDataInfo->data.size);
cs_state->push_constants_data_dirty = true;
cs_state->push_constants_client_size = MAX2(
cs_state->push_constants_client_size,
pPushDataInfo->offset + pPushDataInfo->data.size);
cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_COMPUTE_BIT;
if (ANV_SUPPORT_RT && cmd_buffer->device->vk.enabled_features.rayTracingPipeline) {
struct anv_cmd_pipeline_state *rt_state =
&cmd_buffer->state.rt.base;
memcpy(rt_state->push_constants.client_data + pPushDataInfo->offset,
pPushDataInfo->data.address, pPushDataInfo->data.size);
rt_state->push_constants_data_dirty = true;
rt_state->push_constants_client_size = MAX2(
rt_state->push_constants_client_size,
pPushDataInfo->offset + pPushDataInfo->data.size);
cmd_buffer->state.push_constants_dirty |= ANV_RT_STAGE_BITS;
}
}
}
void anv_CmdBindVertexBuffers2(
VkCommandBuffer commandBuffer,
uint32_t firstBinding,

View file

@ -4794,6 +4794,7 @@ enum anv_cmd_descriptor_buffer_mode {
ANV_CMD_DESCRIPTOR_BUFFER_MODE_UNKNOWN,
ANV_CMD_DESCRIPTOR_BUFFER_MODE_LEGACY,
ANV_CMD_DESCRIPTOR_BUFFER_MODE_BUFFER,
ANV_CMD_DESCRIPTOR_BUFFER_MODE_HEAP,
};
enum anv_color_aux_op_class {

View file

@ -112,6 +112,8 @@ fill_state_base_addr(struct anv_cmd_buffer *cmd_buffer,
if (cmd_buffer->state.pending_db_mode ==
ANV_CMD_DESCRIPTOR_BUFFER_MODE_UNKNOWN) {
cmd_buffer->state.pending_db_mode =
cmd_buffer->device->vk.enabled_extensions.EXT_descriptor_heap ?
ANV_CMD_DESCRIPTOR_BUFFER_MODE_HEAP :
cmd_buffer->device->vk.enabled_extensions.EXT_descriptor_buffer ?
ANV_CMD_DESCRIPTOR_BUFFER_MODE_BUFFER :
ANV_CMD_DESCRIPTOR_BUFFER_MODE_LEGACY;
@ -189,7 +191,8 @@ fill_state_base_addr(struct anv_cmd_buffer *cmd_buffer,
sba->DynamicStateBaseAddressModifyEnable = true;
sba->DynamicStateBufferSizeModifyEnable = true;
if (cmd_buffer->state.pending_db_mode == ANV_CMD_DESCRIPTOR_BUFFER_MODE_BUFFER) {
if (cmd_buffer->state.pending_db_mode == ANV_CMD_DESCRIPTOR_BUFFER_MODE_BUFFER ||
cmd_buffer->state.pending_db_mode == ANV_CMD_DESCRIPTOR_BUFFER_MODE_HEAP) {
#if GFX_VERx10 >= 125
sba->BindlessSurfaceStateBaseAddress = (struct anv_address) {
.offset = device->physical->va.dynamic_visible_pool.addr,
@ -3387,11 +3390,22 @@ genX(flush_descriptor_buffers)(struct anv_cmd_buffer *cmd_buffer,
assert(cmd_buffer->state.current_db_mode !=
ANV_CMD_DESCRIPTOR_BUFFER_MODE_UNKNOWN);
if (cmd_buffer->state.current_db_mode == ANV_CMD_DESCRIPTOR_BUFFER_MODE_BUFFER &&
struct anv_push_constants *push_constants =
&pipe_state->push_constants;
if (cmd_buffer->state.current_db_mode == ANV_CMD_DESCRIPTOR_BUFFER_MODE_HEAP) {
/* TODO handle non 4k aligned offsets */
push_constants->desc_surface_offsets[0] =
cmd_buffer->state.descriptor_buffers.surfaces_address -
cmd_buffer->device->physical->va.dynamic_visible_pool.addr;
push_constants->desc_surface_offsets[1] =
cmd_buffer->state.descriptor_buffers.samplers_address -
cmd_buffer->device->physical->va.dynamic_state_pool.addr;
cmd_buffer->state.push_constants_dirty |=
(cmd_buffer->state.descriptor_buffers.offsets_dirty & active_stages);
pipe_state->push_constants_data_dirty = true;
} else if (cmd_buffer->state.current_db_mode == ANV_CMD_DESCRIPTOR_BUFFER_MODE_BUFFER &&
(cmd_buffer->state.descriptor_buffers.dirty ||
(active_stages & cmd_buffer->state.descriptor_buffers.offsets_dirty) != 0)) {
struct anv_push_constants *push_constants =
&pipe_state->push_constants;
for (uint32_t i = 0; i < ARRAY_SIZE(push_constants->desc_surface_offsets); i++) {
update_descriptor_set_surface_state(cmd_buffer, pipe_state, i);
@ -3946,6 +3960,20 @@ genX(BeginCommandBuffer)(
cmd_buffer->state.gfx.n_occlusion_queries = 1;
cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_OCCLUSION_QUERY_ACTIVE;
}
const VkCommandBufferInheritanceDescriptorHeapInfoEXT *heap_info =
vk_find_struct_const(pBeginInfo->pInheritanceInfo->pNext,
COMMAND_BUFFER_INHERITANCE_DESCRIPTOR_HEAP_INFO_EXT);
if (heap_info) {
if (heap_info->pSamplerHeapBindInfo) {
anv_CmdBindSamplerHeapEXT(commandBuffer,
heap_info->pSamplerHeapBindInfo);
}
if (heap_info->pResourceHeapBindInfo) {
anv_CmdBindResourceHeapEXT(commandBuffer,
heap_info->pResourceHeapBindInfo);
}
}
}
return VK_SUCCESS;
@ -4623,6 +4651,7 @@ anv_pipe_invalidate_bits_for_access_flags(struct anv_cmd_buffer *cmd_buffer,
}
break;
case VK_ACCESS_2_DESCRIPTOR_BUFFER_READ_BIT_EXT:
case VK_ACCESS_2_RESOURCE_HEAP_READ_BIT_EXT:
/* Invalidate the state cache (when HW reads RENDER_SURFACE_STATE &
* SAMPLER_STATE) and the constant cache (when shaders read the
* descriptor buffers)
@ -4630,6 +4659,9 @@ anv_pipe_invalidate_bits_for_access_flags(struct anv_cmd_buffer *cmd_buffer,
pipe_bits |= ANV_PIPE_STATE_CACHE_INVALIDATE_BIT |
ANV_PIPE_CONSTANT_CACHE_INVALIDATE_BIT;
break;
case VK_ACCESS_2_SAMPLER_HEAP_READ_BIT_EXT:
pipe_bits |= ANV_PIPE_STATE_CACHE_INVALIDATE_BIT;
break;
default:
break; /* Nothing to do */
}