anv: shrink image opaque data

Noticed renderdoc complaining about our size :

RDOC 692028: [18:08:18]          vk_core.cpp(2272) - Warning -
VkPhysicalDeviceDescriptorBufferPropertiesEXT.imageCaptureReplayDescriptorDataSizeis too large at 32
(must be <= 16), can't support capture of VK_EXT_descriptor_buffer

Since we only need 2 pointers (main + private), we can shrink this to
16bytes. The 1/2 planes have a relative offset from the base.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Acked-by: Ivan Briano <ivan.briano@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38625>
This commit is contained in:
Lionel Landwerlin 2025-11-24 18:29:49 +02:00 committed by Marge Bot
parent 6aabc3d5d2
commit b1e74a1bb1
5 changed files with 47 additions and 90 deletions

View file

@ -2088,12 +2088,9 @@ anv_descriptor_set_write_image_view(struct anv_device *device,
device->physical, device->physical,
anv_image_view_storage_surface_state(image_view)->state), anv_image_view_storage_surface_state(image_view)->state),
.image_depth = image_view->vk.storage.z_slice_count, .image_depth = image_view->vk.storage.z_slice_count,
.image_address = (anv_image_is_sparse(image_view->image) ? .image_address = anv_address_physical(
image_view->image->bindings[ image_view->image->bindings[
ANV_IMAGE_MEMORY_BINDING_MAIN].sparse_data.address : ANV_IMAGE_MEMORY_BINDING_MAIN].address),
anv_address_physical(
image_view->image->bindings[
ANV_IMAGE_MEMORY_BINDING_MAIN].address)),
.tile_mode = image_view->image->planes[0].primary_surface.isl.tiling == ISL_TILING_LINEAR ? 0 : 0xffffffff, .tile_mode = image_view->image->planes[0].primary_surface.isl.tiling == ISL_TILING_LINEAR ? 0 : 0xffffffff,
.row_pitch_B = image_view->image->planes[0].primary_surface.isl.row_pitch_B, .row_pitch_B = image_view->image->planes[0].primary_surface.isl.row_pitch_B,
.qpitch = image_view->image->planes[0].primary_surface.isl.array_pitch_el_rows, .qpitch = image_view->image->planes[0].primary_surface.isl.array_pitch_el_rows,

View file

@ -1682,15 +1682,7 @@ anv_image_finish_sparse_bindings(struct anv_image *image)
assert(anv_image_is_sparse(image)); assert(anv_image_is_sparse(image));
for (int i = 0; i < ANV_IMAGE_MEMORY_BINDING_END; i++) { anv_free_sparse_bindings(device, &image->sparse_data);
struct anv_image_binding *b = &image->bindings[i];
if (b->sparse_data.size != 0) {
assert(b->memory_range.size == b->sparse_data.size);
assert(b->address.offset == b->sparse_data.address);
anv_free_sparse_bindings(device, &b->sparse_data);
}
}
} }
static VkResult MUST_CHECK static VkResult MUST_CHECK
@ -1699,7 +1691,6 @@ anv_image_init_sparse_bindings(struct anv_image *image,
{ {
struct anv_device *device = struct anv_device *device =
container_of(image->vk.base.device, struct anv_device, vk); container_of(image->vk.base.device, struct anv_device, vk);
VkResult result;
assert(anv_image_is_sparse(image)); assert(anv_image_is_sparse(image));
@ -1715,51 +1706,35 @@ anv_image_init_sparse_bindings(struct anv_image *image,
explicit_addresses = opaque_info->opaqueCaptureDescriptorData; explicit_addresses = opaque_info->opaqueCaptureDescriptorData;
} }
uint64_t total_size = 0;
for (int i = 0; i < ANV_IMAGE_MEMORY_BINDING_END; i++) { for (int i = 0; i < ANV_IMAGE_MEMORY_BINDING_END; i++) {
struct anv_image_binding *b = &image->bindings[i]; struct anv_image_binding *b = &image->bindings[i];
if (b->memory_range.size == 0)
continue;
if (b->memory_range.size != 0) { assert(b->memory_range.alignment == ANV_SPARSE_BLOCK_SIZE);
assert(b->sparse_data.size == 0); assert(b->memory_range.size % ANV_SPARSE_BLOCK_SIZE == 0);
uint64_t explicit_address = 0; total_size = MAX2(total_size,
if (explicit_addresses) { b->memory_range.offset + b->memory_range.size);
switch (i) { }
case ANV_IMAGE_MEMORY_BINDING_MAIN:
explicit_address = explicit_addresses->planes[0];
break;
case ANV_IMAGE_MEMORY_BINDING_PLANE_0:
case ANV_IMAGE_MEMORY_BINDING_PLANE_1:
case ANV_IMAGE_MEMORY_BINDING_PLANE_2:
explicit_address = explicit_addresses->planes[i - ANV_IMAGE_MEMORY_BINDING_PLANE_0];
break;
case ANV_IMAGE_MEMORY_BINDING_PRIVATE:
explicit_address = explicit_addresses->private_binding;
break;
default:
UNREACHABLE("invalid binding");
}
}
/* From the spec, Custom Sparse Image Block Shapes section: struct anv_address base_address;
* "... the size in bytes of the custom sparse image block shape VkResult result = anv_init_sparse_bindings(
* will be reported in VkMemoryRequirements::alignment." device, total_size, &image->sparse_data, alloc_flags,
* explicit_addresses != NULL ? explicit_addresses->main_binding : 0,
* ISL should have set this for us, so just assert it here. &base_address);
*/
assert(b->memory_range.alignment == ANV_SPARSE_BLOCK_SIZE);
assert(b->memory_range.size % ANV_SPARSE_BLOCK_SIZE == 0);
result = anv_init_sparse_bindings(device, if (result == VK_SUCCESS) {
b->memory_range.size, for (int i = 0; i < ANV_IMAGE_MEMORY_BINDING_END; i++) {
&b->sparse_data, struct anv_image_binding *b = &image->bindings[i];
alloc_flags, if (b->memory_range.size == 0)
explicit_address, continue;
&b->address);
if (result != VK_SUCCESS) { b->address = anv_address_add(base_address, b->memory_range.offset);
anv_image_finish_sparse_bindings(image);
return result;
}
} }
} else {
anv_image_finish_sparse_bindings(image);
} }
return VK_SUCCESS; return VK_SUCCESS;
@ -2353,28 +2328,11 @@ anv_GetImageOpaqueCaptureDescriptorDataEXT(VkDevice device,
struct anv_image_opaque_capture_data *bound_addresses = pData; struct anv_image_opaque_capture_data *bound_addresses = pData;
memset(bound_addresses, 0, sizeof(*bound_addresses)); memset(bound_addresses, 0, sizeof(*bound_addresses));
for (int i = 0; i < ANV_IMAGE_MEMORY_BINDING_END; i++) {
struct anv_image_binding *b = &image->bindings[i];
if (b->memory_range.size != 0) { bound_addresses->main_binding =
uint64_t addr = anv_address_physical(b->address); anv_address_physical(image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN].address);
switch (i) { bound_addresses->private_binding =
case ANV_IMAGE_MEMORY_BINDING_MAIN: anv_address_physical(image->bindings[ANV_IMAGE_MEMORY_BINDING_PRIVATE].address);
bound_addresses->planes[0] = addr;
break;
case ANV_IMAGE_MEMORY_BINDING_PLANE_0:
case ANV_IMAGE_MEMORY_BINDING_PLANE_1:
case ANV_IMAGE_MEMORY_BINDING_PLANE_2:
bound_addresses->planes[i - ANV_IMAGE_MEMORY_BINDING_PLANE_0] = addr;
break;
case ANV_IMAGE_MEMORY_BINDING_PRIVATE:
bound_addresses->private_binding = addr;
break;
default:
UNREACHABLE("invalid binding");
}
}
}
return VK_SUCCESS; return VK_SUCCESS;
} }

View file

@ -5611,7 +5611,6 @@ struct anv_image {
struct anv_image_binding { struct anv_image_binding {
struct anv_image_memory_range memory_range; struct anv_image_memory_range memory_range;
struct anv_address address; struct anv_address address;
struct anv_sparse_binding_data sparse_data;
void *host_map; void *host_map;
uint64_t map_delta; uint64_t map_delta;
uint64_t map_size; uint64_t map_size;
@ -5660,6 +5659,8 @@ struct anv_image {
} aux_tt; } aux_tt;
} planes[3]; } planes[3];
struct anv_sparse_binding_data sparse_data;
/* Array pitch of video coding private surfaces */ /* Array pitch of video coding private surfaces */
uint32_t vid_dmv_top_surface_pitch_B; uint32_t vid_dmv_top_surface_pitch_B;
uint32_t av1_cdf_table_pitch_B; uint32_t av1_cdf_table_pitch_B;
@ -5674,7 +5675,7 @@ struct anv_image {
}; };
struct anv_image_opaque_capture_data { struct anv_image_opaque_capture_data {
uint64_t planes[3]; uint64_t main_binding;
uint64_t private_binding; uint64_t private_binding;
}; };

View file

@ -474,17 +474,17 @@ anv_rmv_log_image_create(struct anv_device *device,
vk_rmv_emit_token(&device->vk.memory_trace_data, VK_RMV_TOKEN_TYPE_RESOURCE_CREATE, &token); vk_rmv_emit_token(&device->vk.memory_trace_data, VK_RMV_TOKEN_TYPE_RESOURCE_CREATE, &token);
if (image->vk.create_flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) { if (image->vk.create_flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) {
for (uint32_t b = 0; b < ARRAY_SIZE(image->bindings); b++) { for (uint32_t b = 0; b < ARRAY_SIZE(image->bindings); b++) {
if (image->bindings[b].sparse_data.size != 0) { if (image->bindings[b].memory_range.size != 0) {
anv_rmv_log_vma_locked(device, anv_rmv_log_vma_locked(device,
image->bindings[b].sparse_data.address, anv_address_physical(image->bindings[b].address),
image->bindings[b].sparse_data.size, image->bindings[b].memory_range.size,
false /* internal */, true /* TODO: vram */, false /* internal */, true /* TODO: vram */,
true /* in_invisible_vram */); true /* in_invisible_vram */);
log_resource_bind_locked(device, log_resource_bind_locked(device,
resource_id_locked(device, image), resource_id_locked(device, image),
NULL, NULL,
image->bindings[b].sparse_data.address, anv_address_physical(image->bindings[b].address),
image->bindings[b].sparse_data.size); image->bindings[b].memory_range.size);
} }
} }
} }
@ -498,9 +498,9 @@ anv_rmv_log_image_destroy(struct anv_device *device,
simple_mtx_lock(&device->vk.memory_trace_data.token_mtx); simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
if (image->vk.create_flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) { if (image->vk.create_flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) {
for (uint32_t b = 0; b < ARRAY_SIZE(image->bindings); b++) { for (uint32_t b = 0; b < ARRAY_SIZE(image->bindings); b++) {
if (image->bindings[b].sparse_data.size != 0) { if (image->bindings[b].memory_range.size != 0) {
struct vk_rmv_virtual_free_token token = { struct vk_rmv_virtual_free_token token = {
.address = image->bindings[b].sparse_data.address, .address = anv_address_physical(image->bindings[b].address),
}; };
vk_rmv_emit_token(&device->vk.memory_trace_data, VK_RMV_TOKEN_TYPE_VIRTUAL_FREE, &token); vk_rmv_emit_token(&device->vk.memory_trace_data, VK_RMV_TOKEN_TYPE_VIRTUAL_FREE, &token);

View file

@ -1349,11 +1349,12 @@ out_debug:
static struct anv_vm_bind static struct anv_vm_bind
vk_bind_to_anv_vm_bind(struct anv_sparse_binding_data *sparse, vk_bind_to_anv_vm_bind(struct anv_sparse_binding_data *sparse,
uint64_t binding_offset,
const struct VkSparseMemoryBind *vk_bind) const struct VkSparseMemoryBind *vk_bind)
{ {
struct anv_vm_bind anv_bind = { struct anv_vm_bind anv_bind = {
.bo = NULL, .bo = NULL,
.address = sparse->address + vk_bind->resourceOffset, .address = sparse->address + binding_offset + vk_bind->resourceOffset,
.bo_offset = 0, .bo_offset = 0,
.size = vk_bind->size, .size = vk_bind->size,
.op = ANV_VM_BIND, .op = ANV_VM_BIND,
@ -1378,7 +1379,7 @@ anv_sparse_bind_resource_memory(struct anv_device *device,
const VkSparseMemoryBind *vk_bind, const VkSparseMemoryBind *vk_bind,
struct anv_sparse_submission *submit) struct anv_sparse_submission *submit)
{ {
struct anv_vm_bind bind = vk_bind_to_anv_vm_bind(sparse, vk_bind); struct anv_vm_bind bind = vk_bind_to_anv_vm_bind(sparse, 0, vk_bind);
uint64_t rem = vk_bind->size % ANV_SPARSE_BLOCK_SIZE; uint64_t rem = vk_bind->size % ANV_SPARSE_BLOCK_SIZE;
if (rem != 0) { if (rem != 0) {
@ -1425,7 +1426,7 @@ anv_sparse_bind_image_opaque(struct anv_device *device,
sparse_debug("\n"); sparse_debug("\n");
} }
return anv_sparse_bind_resource_memory(device, &b->sparse_data, return anv_sparse_bind_resource_memory(device, &image->sparse_data,
b->memory_range.size, b->memory_range.size,
vk_bind, submit); vk_bind, submit);
} }
@ -1446,7 +1447,7 @@ anv_sparse_bind_image_memory(struct anv_queue *queue,
struct anv_image_binding *img_binding = image->disjoint ? struct anv_image_binding *img_binding = image->disjoint ?
&image->bindings[anv_image_aspect_to_binding(image, aspect)] : &image->bindings[anv_image_aspect_to_binding(image, aspect)] :
&image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN]; &image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN];
struct anv_sparse_binding_data *sparse_data = &img_binding->sparse_data; struct anv_sparse_binding_data *sparse_data = &image->sparse_data;
const uint32_t plane = anv_image_aspect_to_plane(image, aspect); const uint32_t plane = anv_image_aspect_to_plane(image, aspect);
struct isl_surf *surf = &image->planes[plane].primary_surface.isl; struct isl_surf *surf = &image->planes[plane].primary_surface.isl;
@ -1547,8 +1548,8 @@ anv_sparse_bind_image_memory(struct anv_queue *queue,
assert(opaque_bind.resourceOffset % ANV_SPARSE_BLOCK_SIZE == 0); assert(opaque_bind.resourceOffset % ANV_SPARSE_BLOCK_SIZE == 0);
assert(opaque_bind.size % ANV_SPARSE_BLOCK_SIZE == 0); assert(opaque_bind.size % ANV_SPARSE_BLOCK_SIZE == 0);
struct anv_vm_bind anv_bind = vk_bind_to_anv_vm_bind(sparse_data, struct anv_vm_bind anv_bind = vk_bind_to_anv_vm_bind(
&opaque_bind); sparse_data, img_binding->memory_range.offset, &opaque_bind);
VkResult result = anv_sparse_submission_add(device, submit, VkResult result = anv_sparse_submission_add(device, submit,
&anv_bind); &anv_bind);
if (result != VK_SUCCESS) if (result != VK_SUCCESS)