venus: factor image memory barrier fixes to common implementation
Signed-off-by: Ryan Neph <ryanneph@google.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29777>
This commit is contained in:
@@ -69,6 +69,11 @@ vn_dependency_info_has_present_src(uint32_t dep_count,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct vn_cmd_fix_image_memory_barrier_result {
|
||||||
|
bool availability_op_needed; // set src access/stage (flush)
|
||||||
|
bool visibility_op_needed; // set dst access/stage (invalidate)
|
||||||
|
};
|
||||||
|
|
||||||
static inline VkImageMemoryBarrier *
|
static inline VkImageMemoryBarrier *
|
||||||
vn_cmd_get_image_memory_barriers(struct vn_command_buffer *cmd,
|
vn_cmd_get_image_memory_barriers(struct vn_command_buffer *cmd,
|
||||||
uint32_t count)
|
uint32_t count)
|
||||||
@@ -139,6 +144,84 @@ vn_cmd_get_image_memory_barriers(struct vn_command_buffer *cmd,
|
|||||||
* I likely also violate some VUs or miss some cases below. They are
|
* I likely also violate some VUs or miss some cases below. They are
|
||||||
* hopefully fixable and are left as TODOs.
|
* hopefully fixable and are left as TODOs.
|
||||||
*/
|
*/
|
||||||
|
static struct vn_cmd_fix_image_memory_barrier_result
|
||||||
|
vn_cmd_fix_image_memory_barrier_common(const struct vn_image *img,
|
||||||
|
uint32_t cmd_pool_qfi,
|
||||||
|
VkImageLayout *old_layout,
|
||||||
|
VkImageLayout *new_layout,
|
||||||
|
uint32_t *src_qfi,
|
||||||
|
uint32_t *dst_qfi)
|
||||||
|
{
|
||||||
|
struct vn_cmd_fix_image_memory_barrier_result result = {
|
||||||
|
.availability_op_needed = true,
|
||||||
|
.visibility_op_needed = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (VN_PRESENT_SRC_INTERNAL_LAYOUT == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
/* no fix needed */
|
||||||
|
if (*old_layout != VK_IMAGE_LAYOUT_PRESENT_SRC_KHR &&
|
||||||
|
*new_layout != VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
assert(img->wsi.is_wsi);
|
||||||
|
|
||||||
|
/* prime blit src or no layout transition */
|
||||||
|
if (img->wsi.is_prime_blit_src || *old_layout == *new_layout) {
|
||||||
|
if (*old_layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
|
||||||
|
*old_layout = VN_PRESENT_SRC_INTERNAL_LAYOUT;
|
||||||
|
if (*new_layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
|
||||||
|
*new_layout = VN_PRESENT_SRC_INTERNAL_LAYOUT;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*old_layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
|
||||||
|
*old_layout = VN_PRESENT_SRC_INTERNAL_LAYOUT;
|
||||||
|
|
||||||
|
result.availability_op_needed = false;
|
||||||
|
|
||||||
|
if (img->sharing_mode == VK_SHARING_MODE_CONCURRENT) {
|
||||||
|
*src_qfi = VK_QUEUE_FAMILY_FOREIGN_EXT;
|
||||||
|
*dst_qfi = VK_QUEUE_FAMILY_IGNORED;
|
||||||
|
} else if (*dst_qfi == *src_qfi || *dst_qfi == cmd_pool_qfi) {
|
||||||
|
*src_qfi = VK_QUEUE_FAMILY_FOREIGN_EXT;
|
||||||
|
*dst_qfi = cmd_pool_qfi;
|
||||||
|
} else {
|
||||||
|
/* The barrier also defines a queue family ownership transfer, and
|
||||||
|
* this is the one that gets submitted to the source queue family to
|
||||||
|
* release the ownership. Skip both the transfer and the transition.
|
||||||
|
*/
|
||||||
|
*src_qfi = VK_QUEUE_FAMILY_IGNORED;
|
||||||
|
*dst_qfi = VK_QUEUE_FAMILY_IGNORED;
|
||||||
|
*new_layout = *old_layout;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*new_layout = VN_PRESENT_SRC_INTERNAL_LAYOUT;
|
||||||
|
|
||||||
|
result.visibility_op_needed = false;
|
||||||
|
|
||||||
|
if (img->sharing_mode == VK_SHARING_MODE_CONCURRENT) {
|
||||||
|
*src_qfi = VK_QUEUE_FAMILY_IGNORED;
|
||||||
|
*dst_qfi = VK_QUEUE_FAMILY_FOREIGN_EXT;
|
||||||
|
} else if (*src_qfi == *dst_qfi || *src_qfi == cmd_pool_qfi) {
|
||||||
|
*src_qfi = cmd_pool_qfi;
|
||||||
|
*dst_qfi = VK_QUEUE_FAMILY_FOREIGN_EXT;
|
||||||
|
} else {
|
||||||
|
/* The barrier also defines a queue family ownership transfer, and
|
||||||
|
* this is the one that gets submitted to the destination queue
|
||||||
|
* family to acquire the ownership. Skip both the transfer and the
|
||||||
|
* transition.
|
||||||
|
*/
|
||||||
|
*src_qfi = VK_QUEUE_FAMILY_IGNORED;
|
||||||
|
*dst_qfi = VK_QUEUE_FAMILY_IGNORED;
|
||||||
|
*old_layout = *new_layout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vn_cmd_fix_image_memory_barrier(const struct vn_command_buffer *cmd,
|
vn_cmd_fix_image_memory_barrier(const struct vn_command_buffer *cmd,
|
||||||
const VkImageMemoryBarrier *src_barrier,
|
const VkImageMemoryBarrier *src_barrier,
|
||||||
@@ -147,147 +230,34 @@ vn_cmd_fix_image_memory_barrier(const struct vn_command_buffer *cmd,
|
|||||||
const struct vn_image *img = vn_image_from_handle(src_barrier->image);
|
const struct vn_image *img = vn_image_from_handle(src_barrier->image);
|
||||||
|
|
||||||
*out_barrier = *src_barrier;
|
*out_barrier = *src_barrier;
|
||||||
|
struct vn_cmd_fix_image_memory_barrier_result result =
|
||||||
/* no fix needed */
|
vn_cmd_fix_image_memory_barrier_common(
|
||||||
if (out_barrier->oldLayout != VK_IMAGE_LAYOUT_PRESENT_SRC_KHR &&
|
img, cmd->pool->queue_family_index, &out_barrier->oldLayout,
|
||||||
out_barrier->newLayout != VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
|
&out_barrier->newLayout, &out_barrier->srcQueueFamilyIndex,
|
||||||
return;
|
&out_barrier->dstQueueFamilyIndex);
|
||||||
|
if (!result.availability_op_needed)
|
||||||
assert(img->wsi.is_wsi);
|
|
||||||
|
|
||||||
if (VN_PRESENT_SRC_INTERNAL_LAYOUT == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* prime blit src or no layout transition */
|
|
||||||
if (img->wsi.is_prime_blit_src ||
|
|
||||||
out_barrier->oldLayout == out_barrier->newLayout) {
|
|
||||||
if (out_barrier->oldLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
|
|
||||||
out_barrier->oldLayout = VN_PRESENT_SRC_INTERNAL_LAYOUT;
|
|
||||||
if (out_barrier->newLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
|
|
||||||
out_barrier->newLayout = VN_PRESENT_SRC_INTERNAL_LAYOUT;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (out_barrier->oldLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
|
|
||||||
out_barrier->oldLayout = VN_PRESENT_SRC_INTERNAL_LAYOUT;
|
|
||||||
|
|
||||||
/* no availability operation needed */
|
|
||||||
out_barrier->srcAccessMask = 0;
|
out_barrier->srcAccessMask = 0;
|
||||||
|
if (!result.visibility_op_needed)
|
||||||
const uint32_t dst_qfi = out_barrier->dstQueueFamilyIndex;
|
|
||||||
if (img->sharing_mode == VK_SHARING_MODE_CONCURRENT) {
|
|
||||||
out_barrier->srcQueueFamilyIndex = VK_QUEUE_FAMILY_FOREIGN_EXT;
|
|
||||||
out_barrier->dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
|
||||||
} else if (dst_qfi == out_barrier->srcQueueFamilyIndex ||
|
|
||||||
dst_qfi == cmd->pool->queue_family_index) {
|
|
||||||
out_barrier->srcQueueFamilyIndex = VK_QUEUE_FAMILY_FOREIGN_EXT;
|
|
||||||
out_barrier->dstQueueFamilyIndex = cmd->pool->queue_family_index;
|
|
||||||
} else {
|
|
||||||
/* The barrier also defines a queue family ownership transfer, and
|
|
||||||
* this is the one that gets submitted to the source queue family to
|
|
||||||
* release the ownership. Skip both the transfer and the transition.
|
|
||||||
*/
|
|
||||||
out_barrier->srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
|
||||||
out_barrier->dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
|
||||||
out_barrier->newLayout = out_barrier->oldLayout;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
out_barrier->newLayout = VN_PRESENT_SRC_INTERNAL_LAYOUT;
|
|
||||||
|
|
||||||
/* no visibility operation needed */
|
|
||||||
out_barrier->dstAccessMask = 0;
|
out_barrier->dstAccessMask = 0;
|
||||||
|
|
||||||
const uint32_t src_qfi = out_barrier->srcQueueFamilyIndex;
|
|
||||||
if (img->sharing_mode == VK_SHARING_MODE_CONCURRENT) {
|
|
||||||
out_barrier->srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
|
||||||
out_barrier->dstQueueFamilyIndex = VK_QUEUE_FAMILY_FOREIGN_EXT;
|
|
||||||
} else if (src_qfi == out_barrier->dstQueueFamilyIndex ||
|
|
||||||
src_qfi == cmd->pool->queue_family_index) {
|
|
||||||
out_barrier->srcQueueFamilyIndex = cmd->pool->queue_family_index;
|
|
||||||
out_barrier->dstQueueFamilyIndex = VK_QUEUE_FAMILY_FOREIGN_EXT;
|
|
||||||
} else {
|
|
||||||
/* The barrier also defines a queue family ownership transfer, and
|
|
||||||
* this is the one that gets submitted to the destination queue
|
|
||||||
* family to acquire the ownership. Skip both the transfer and the
|
|
||||||
* transition.
|
|
||||||
*/
|
|
||||||
out_barrier->srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
|
||||||
out_barrier->dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
|
||||||
out_barrier->oldLayout = out_barrier->newLayout;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** See vn_cmd_fix_image_memory_barrier(). */
|
|
||||||
static void
|
static void
|
||||||
vn_cmd_fix_image_memory_barrier2(const struct vn_command_buffer *cmd,
|
vn_cmd_fix_image_memory_barrier2(const struct vn_command_buffer *cmd,
|
||||||
VkImageMemoryBarrier2 *b)
|
VkImageMemoryBarrier2 *b)
|
||||||
{
|
{
|
||||||
if (VN_PRESENT_SRC_INTERNAL_LAYOUT == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (b->oldLayout != VK_IMAGE_LAYOUT_PRESENT_SRC_KHR &&
|
|
||||||
b->newLayout != VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const struct vn_image *img = vn_image_from_handle(b->image);
|
const struct vn_image *img = vn_image_from_handle(b->image);
|
||||||
assert(img->wsi.is_wsi);
|
|
||||||
|
|
||||||
if (img->wsi.is_prime_blit_src || b->oldLayout == b->newLayout) {
|
struct vn_cmd_fix_image_memory_barrier_result result =
|
||||||
if (b->oldLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
|
vn_cmd_fix_image_memory_barrier_common(
|
||||||
b->oldLayout = VN_PRESENT_SRC_INTERNAL_LAYOUT;
|
img, cmd->pool->queue_family_index, &b->oldLayout, &b->newLayout,
|
||||||
if (b->newLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
|
&b->srcQueueFamilyIndex, &b->dstQueueFamilyIndex);
|
||||||
b->newLayout = VN_PRESENT_SRC_INTERNAL_LAYOUT;
|
if (!result.availability_op_needed) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b->oldLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
|
|
||||||
b->oldLayout = VN_PRESENT_SRC_INTERNAL_LAYOUT;
|
|
||||||
|
|
||||||
/* no availability operation needed */
|
|
||||||
b->srcStageMask = 0;
|
b->srcStageMask = 0;
|
||||||
b->srcAccessMask = 0;
|
b->srcAccessMask = 0;
|
||||||
|
|
||||||
if (img->sharing_mode == VK_SHARING_MODE_CONCURRENT) {
|
|
||||||
b->srcQueueFamilyIndex = VK_QUEUE_FAMILY_FOREIGN_EXT;
|
|
||||||
b->dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
|
||||||
} else if (b->dstQueueFamilyIndex == b->srcQueueFamilyIndex ||
|
|
||||||
b->dstQueueFamilyIndex == cmd->pool->queue_family_index) {
|
|
||||||
b->srcQueueFamilyIndex = VK_QUEUE_FAMILY_FOREIGN_EXT;
|
|
||||||
b->dstQueueFamilyIndex = cmd->pool->queue_family_index;
|
|
||||||
} else {
|
|
||||||
/* The barrier also defines a queue family ownership transfer, and
|
|
||||||
* this is the one that gets submitted to the source queue family to
|
|
||||||
* release the ownership. Skip both the transfer and the transition.
|
|
||||||
*/
|
|
||||||
b->srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
|
||||||
b->dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
|
||||||
b->newLayout = b->oldLayout;
|
|
||||||
}
|
}
|
||||||
} else {
|
if (!result.visibility_op_needed) {
|
||||||
b->newLayout = VN_PRESENT_SRC_INTERNAL_LAYOUT;
|
|
||||||
|
|
||||||
/* no visibility operation needed */
|
|
||||||
b->dstStageMask = 0;
|
b->dstStageMask = 0;
|
||||||
b->dstAccessMask = 0;
|
b->dstAccessMask = 0;
|
||||||
|
|
||||||
if (img->sharing_mode == VK_SHARING_MODE_CONCURRENT) {
|
|
||||||
b->srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
|
||||||
b->dstQueueFamilyIndex = VK_QUEUE_FAMILY_FOREIGN_EXT;
|
|
||||||
} else if (b->srcQueueFamilyIndex == b->dstQueueFamilyIndex ||
|
|
||||||
b->srcQueueFamilyIndex == cmd->pool->queue_family_index) {
|
|
||||||
b->srcQueueFamilyIndex = cmd->pool->queue_family_index;
|
|
||||||
b->dstQueueFamilyIndex = VK_QUEUE_FAMILY_FOREIGN_EXT;
|
|
||||||
} else {
|
|
||||||
/* The barrier also defines a queue family ownership transfer, and
|
|
||||||
* this is the one that gets submitted to the destination queue
|
|
||||||
* family to acquire the ownership. Skip both the transfer and the
|
|
||||||
* transition.
|
|
||||||
*/
|
|
||||||
b->srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
|
||||||
b->dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
|
||||||
b->oldLayout = b->newLayout;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user