venus: refactor image memory barrier fix storage and conventions

Prepare to allocate VkExternalMemoryAcquireUnmodifiedEXT structs from
command pool cached storage with the same lifetime as
VkImageMemoryBarrier(2) structs.

Also use common parameter naming and function call signatures for the
both the barrier and barrier2 variants.

Signed-off-by: Ryan Neph <ryanneph@google.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29777>
This commit is contained in:
Ryan Neph 2024-06-26 10:59:49 -07:00 committed by Marge Bot
parent 53f0c12b0c
commit 1656eb4706

View file

@ -74,12 +74,48 @@ struct vn_cmd_fix_image_memory_barrier_result {
bool visibility_op_needed; // set dst access/stage (invalidate)
};
static inline VkImageMemoryBarrier *
vn_cmd_get_image_memory_barriers(struct vn_command_buffer *cmd,
uint32_t count)
struct vn_cmd_cached_storage {
VkDependencyInfo *dep_infos;
union {
VkImageMemoryBarrier *barriers;
VkImageMemoryBarrier2 *barriers2;
};
};
static inline bool
vn_cmd_get_cached_storage(struct vn_command_buffer *cmd,
VkStructureType barrier_type,
uint32_t barrier_count,
uint32_t dep_info_count,
struct vn_cmd_cached_storage *out_storage)
{
return vn_cached_storage_get(&cmd->pool->storage,
count * sizeof(VkImageMemoryBarrier));
size_t dep_infos_size = dep_info_count * sizeof(VkDependencyInfo);
size_t barriers_size;
switch (barrier_type) {
case VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER:
assert(!dep_info_count);
barriers_size = barrier_count * sizeof(VkImageMemoryBarrier);
break;
case VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2:
barriers_size = barrier_count * sizeof(VkImageMemoryBarrier2);
break;
default:
unreachable("invalid barrier_type");
}
size_t total_size = dep_infos_size + barriers_size;
void *data = vn_cached_storage_get(&cmd->pool->storage, total_size);
if (!data)
return false;
memset(out_storage, 0, sizeof(*out_storage));
if (dep_info_count) {
out_storage->dep_infos = data;
data += dep_infos_size;
}
out_storage->barriers = data;
return true;
}
/* About VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, the spec says
@ -224,40 +260,39 @@ vn_cmd_fix_image_memory_barrier_common(const struct vn_image *img,
static void
vn_cmd_fix_image_memory_barrier(const struct vn_command_buffer *cmd,
const VkImageMemoryBarrier *src_barrier,
VkImageMemoryBarrier *out_barrier)
VkImageMemoryBarrier *barrier)
{
const struct vn_image *img = vn_image_from_handle(src_barrier->image);
const struct vn_image *img = vn_image_from_handle(barrier->image);
*out_barrier = *src_barrier;
struct vn_cmd_fix_image_memory_barrier_result result =
vn_cmd_fix_image_memory_barrier_common(
img, cmd->pool->queue_family_index, &out_barrier->oldLayout,
&out_barrier->newLayout, &out_barrier->srcQueueFamilyIndex,
&out_barrier->dstQueueFamilyIndex);
img, cmd->pool->queue_family_index, &barrier->oldLayout,
&barrier->newLayout, &barrier->srcQueueFamilyIndex,
&barrier->dstQueueFamilyIndex);
if (!result.availability_op_needed)
out_barrier->srcAccessMask = 0;
barrier->srcAccessMask = 0;
if (!result.visibility_op_needed)
out_barrier->dstAccessMask = 0;
barrier->dstAccessMask = 0;
}
static void
vn_cmd_fix_image_memory_barrier2(const struct vn_command_buffer *cmd,
VkImageMemoryBarrier2 *b)
VkImageMemoryBarrier2 *barrier)
{
const struct vn_image *img = vn_image_from_handle(b->image);
const struct vn_image *img = vn_image_from_handle(barrier->image);
struct vn_cmd_fix_image_memory_barrier_result result =
vn_cmd_fix_image_memory_barrier_common(
img, cmd->pool->queue_family_index, &b->oldLayout, &b->newLayout,
&b->srcQueueFamilyIndex, &b->dstQueueFamilyIndex);
img, cmd->pool->queue_family_index, &barrier->oldLayout,
&barrier->newLayout, &barrier->srcQueueFamilyIndex,
&barrier->dstQueueFamilyIndex);
if (!result.availability_op_needed) {
b->srcStageMask = 0;
b->srcAccessMask = 0;
barrier->srcStageMask = 0;
barrier->srcAccessMask = 0;
}
if (!result.visibility_op_needed) {
b->dstStageMask = 0;
b->dstAccessMask = 0;
barrier->dstStageMask = 0;
barrier->dstAccessMask = 0;
}
}
@ -274,24 +309,27 @@ vn_cmd_wait_events_fix_image_memory_barriers(
!vn_image_memory_barrier_has_present_src(src_barriers, count))
return src_barriers;
VkImageMemoryBarrier *img_barriers =
vn_cmd_get_image_memory_barriers(cmd, count * 2);
if (!img_barriers) {
struct vn_cmd_cached_storage storage;
if (!vn_cmd_get_cached_storage(cmd, VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
count * 2, /*dep_info_count=*/0,
&storage)) {
cmd->state = VN_COMMAND_BUFFER_STATE_INVALID;
return src_barriers;
}
VkImageMemoryBarrier *img_barriers = storage.barriers;
VkImageMemoryBarrier *transfer_barriers = storage.barriers + count;
/* vkCmdWaitEvents cannot be used for queue family ownership transfers.
* Nothing appears to be said about the submission order of image memory
* barriers in the same array. We take the liberty to move queue family
* ownership transfers to the tail.
*/
VkImageMemoryBarrier *transfer_barriers = img_barriers + count;
uint32_t transfer_count = 0;
uint32_t valid_count = 0;
for (uint32_t i = 0; i < count; i++) {
VkImageMemoryBarrier *img_barrier = &img_barriers[valid_count];
vn_cmd_fix_image_memory_barrier(cmd, &src_barriers[i], img_barrier);
*img_barrier = src_barriers[i];
vn_cmd_fix_image_memory_barrier(cmd, img_barrier);
if (VN_PRESENT_SRC_INTERNAL_LAYOUT == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
valid_count++;
@ -327,19 +365,19 @@ vn_cmd_pipeline_barrier_fix_image_memory_barriers(
!vn_image_memory_barrier_has_present_src(src_barriers, count))
return src_barriers;
VkImageMemoryBarrier *img_barriers =
vn_cmd_get_image_memory_barriers(cmd, count);
if (!img_barriers) {
struct vn_cmd_cached_storage storage;
if (!vn_cmd_get_cached_storage(cmd, VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
count, /*dep_info_count=*/0, &storage)) {
cmd->state = VN_COMMAND_BUFFER_STATE_INVALID;
return src_barriers;
}
for (uint32_t i = 0; i < count; i++) {
vn_cmd_fix_image_memory_barrier(cmd, &src_barriers[i],
&img_barriers[i]);
}
memcpy(storage.barriers, src_barriers,
count * sizeof(VkImageMemoryBarrier));
for (uint32_t i = 0; i < count; i++)
vn_cmd_fix_image_memory_barrier(cmd, &storage.barriers[i]);
return img_barriers;
return storage.barriers;
}
static const VkDependencyInfo *
@ -355,34 +393,32 @@ vn_cmd_fix_dependency_infos(struct vn_command_buffer *cmd,
for (uint32_t i = 0; i < dep_count; i++)
total_barrier_count += dep_infos[i].imageMemoryBarrierCount;
size_t tmp_size = dep_count * sizeof(VkDependencyInfo) +
total_barrier_count * sizeof(VkImageMemoryBarrier2);
void *tmp = vn_cached_storage_get(&cmd->pool->storage, tmp_size);
if (!tmp) {
struct vn_cmd_cached_storage storage;
if (!vn_cmd_get_cached_storage(cmd,
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
total_barrier_count, dep_count, &storage)) {
cmd->state = VN_COMMAND_BUFFER_STATE_INVALID;
return dep_infos;
}
memcpy(storage.dep_infos, dep_infos, dep_count * sizeof(VkDependencyInfo));
VkDependencyInfo *new_dep_infos = tmp;
tmp += dep_count * sizeof(VkDependencyInfo);
memcpy(new_dep_infos, dep_infos, dep_count * sizeof(VkDependencyInfo));
uint32_t barrier_index = 0;
for (uint32_t i = 0; i < dep_count; i++) {
uint32_t barrier_count = dep_infos[i].imageMemoryBarrierCount;
VkImageMemoryBarrier2 *new_barriers = tmp;
tmp += barrier_count * sizeof(VkImageMemoryBarrier2);
VkImageMemoryBarrier2 *new_barriers = &storage.barriers2[barrier_index];
barrier_index += barrier_count;
memcpy(new_barriers, dep_infos[i].pImageMemoryBarriers,
barrier_count * sizeof(VkImageMemoryBarrier2));
new_dep_infos[i].pImageMemoryBarriers = new_barriers;
storage.dep_infos[i].pImageMemoryBarriers = new_barriers;
for (uint32_t j = 0; j < barrier_count; j++) {
vn_cmd_fix_image_memory_barrier2(cmd, &new_barriers[j]);
}
}
return new_dep_infos;
return storage.dep_infos;
}
static void
@ -434,9 +470,9 @@ vn_cmd_transfer_present_src_images(
const struct vn_present_src_attachment *atts,
uint32_t count)
{
VkImageMemoryBarrier *img_barriers =
vn_cmd_get_image_memory_barriers(cmd, count);
if (!img_barriers) {
struct vn_cmd_cached_storage storage;
if (!vn_cmd_get_cached_storage(cmd, VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
count, /*dep_info_count=*/0, &storage)) {
cmd->state = VN_COMMAND_BUFFER_STATE_INVALID;
return;
}
@ -448,16 +484,15 @@ vn_cmd_transfer_present_src_images(
dst_stage_mask |= atts[i].dst_stage_mask;
vn_present_src_attachment_to_image_memory_barrier(
images[i], &atts[i], &img_barriers[i], acquire);
vn_cmd_fix_image_memory_barrier(cmd, &img_barriers[i],
&img_barriers[i]);
images[i], &atts[i], &storage.barriers[i], acquire);
vn_cmd_fix_image_memory_barrier(cmd, &storage.barriers[i]);
}
if (VN_PRESENT_SRC_INTERNAL_LAYOUT == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
return;
vn_cmd_encode_memory_barriers(cmd, src_stage_mask, dst_stage_mask, 0, NULL,
count, img_barriers);
count, storage.barriers);
}
struct vn_cmd_query_record *