Add support for vk image sharing mode and handle queues xfers correctly.
Change-Id: I9dbe6020d67cc452c9cbbdeace68f1d01275b419
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/293559
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Jim Van Verth <jvanverth@google.com>
diff --git a/src/gpu/GrAHardwareBufferUtils.cpp b/src/gpu/GrAHardwareBufferUtils.cpp
index b701daf..badb8ee 100644
--- a/src/gpu/GrAHardwareBufferUtils.cpp
+++ b/src/gpu/GrAHardwareBufferUtils.cpp
@@ -486,6 +486,7 @@
// "foreign" device we can leave them as external.
imageInfo.fCurrentQueueFamily = VK_QUEUE_FAMILY_EXTERNAL;
imageInfo.fYcbcrConversionInfo = *ycbcrConversion;
+ imageInfo.fSharingMode = imageCreateInfo.sharingMode;
*deleteProc = delete_vk_image;
*updateProc = update_vk_image;
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 97d819f..c8ee2c7 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -1198,7 +1198,8 @@
static bool check_image_info(const GrVkCaps& caps,
const GrVkImageInfo& info,
- bool needsAllocation) {
+ bool needsAllocation,
+ uint32_t graphicsQueueIndex) {
if (VK_NULL_HANDLE == info.fImage) {
return false;
}
@@ -1211,6 +1212,18 @@
return false;
}
+ if (info.fCurrentQueueFamily != VK_QUEUE_FAMILY_IGNORED &&
+ info.fCurrentQueueFamily != VK_QUEUE_FAMILY_EXTERNAL &&
+ info.fCurrentQueueFamily != VK_QUEUE_FAMILY_FOREIGN_EXT) {
+ if (info.fSharingMode == VK_SHARING_MODE_EXCLUSIVE) {
+ if (info.fCurrentQueueFamily != graphicsQueueIndex) {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
if (info.fYcbcrConversionInfo.isValid()) {
if (!caps.supportsYcbcrConversion()) {
return false;
@@ -1256,7 +1269,8 @@
return nullptr;
}
- if (!check_image_info(this->vkCaps(), imageInfo, kAdopt_GrWrapOwnership == ownership)) {
+ if (!check_image_info(this->vkCaps(), imageInfo, kAdopt_GrWrapOwnership == ownership,
+ this->queueIndex())) {
return nullptr;
}
@@ -1282,7 +1296,8 @@
return nullptr;
}
- if (!check_image_info(this->vkCaps(), imageInfo, kAdopt_GrWrapOwnership == ownership)) {
+ if (!check_image_info(this->vkCaps(), imageInfo, kAdopt_GrWrapOwnership == ownership,
+ this->queueIndex())) {
return nullptr;
}
@@ -1309,7 +1324,8 @@
return nullptr;
}
- if (!check_image_info(this->vkCaps(), imageInfo, kAdopt_GrWrapOwnership == ownership)) {
+ if (!check_image_info(this->vkCaps(), imageInfo, kAdopt_GrWrapOwnership == ownership,
+ this->queueIndex())) {
return nullptr;
}
@@ -1349,7 +1365,7 @@
return nullptr;
}
- if (!check_image_info(this->vkCaps(), info, false)) {
+ if (!check_image_info(this->vkCaps(), info, false, this->queueIndex())) {
return nullptr;
}
@@ -1382,7 +1398,7 @@
if (!tex.getVkImageInfo(&imageInfo)) {
return nullptr;
}
- if (!check_image_info(this->vkCaps(), imageInfo, false)) {
+ if (!check_image_info(this->vkCaps(), imageInfo, false, this->queueIndex())) {
return nullptr;
}
diff --git a/src/gpu/vk/GrVkImage.cpp b/src/gpu/vk/GrVkImage.cpp
index 9b50ca7..1270743 100644
--- a/src/gpu/vk/GrVkImage.cpp
+++ b/src/gpu/vk/GrVkImage.cpp
@@ -13,6 +13,43 @@
#define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
+GrVkImage::GrVkImage(const GrVkGpu* gpu,
+ const GrVkImageInfo& info,
+ sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
+ GrBackendObjectOwnership ownership,
+ bool forSecondaryCB)
+ : fInfo(info)
+ , fInitialQueueFamily(info.fCurrentQueueFamily)
+ , fMutableState(std::move(mutableState))
+ , fIsBorrowed(GrBackendObjectOwnership::kBorrowed == ownership) {
+ SkASSERT(fMutableState->getImageLayout() == fInfo.fImageLayout);
+ SkASSERT(fMutableState->getQueueFamilyIndex() == fInfo.fCurrentQueueFamily);
+#ifdef SK_DEBUG
+ // We can't transfer from the non graphics queue to the graphics queue since we can't
+ // release the image from the original queue without having that queue. This limits us in terms
+ // of the types of queue indices we can handle.
+ if (info.fCurrentQueueFamily != VK_QUEUE_FAMILY_IGNORED &&
+ info.fCurrentQueueFamily != VK_QUEUE_FAMILY_EXTERNAL &&
+ info.fCurrentQueueFamily != VK_QUEUE_FAMILY_FOREIGN_EXT) {
+ if (info.fSharingMode == VK_SHARING_MODE_EXCLUSIVE) {
+ if (info.fCurrentQueueFamily != gpu->queueIndex()) {
+ SkASSERT(false);
+ }
+ } else {
+ SkASSERT(false);
+ }
+ }
+#endif
+ if (forSecondaryCB) {
+ fResource = nullptr;
+ } else if (fIsBorrowed) {
+ fResource = new BorrowedResource(gpu, info.fImage, info.fAlloc, info.fImageTiling);
+ } else {
+ SkASSERT(VK_NULL_HANDLE != info.fAlloc.fMemory);
+ fResource = new Resource(gpu, info.fImage, info.fAlloc, info.fImageTiling);
+ }
+}
+
VkPipelineStageFlags GrVkImage::LayoutToPipelineSrcStageFlags(const VkImageLayout layout) {
if (VK_IMAGE_LAYOUT_GENERAL == layout) {
return VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
@@ -116,15 +153,22 @@
uint32_t srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
uint32_t dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
if (this->currentQueueFamilyIndex() != VK_QUEUE_FAMILY_IGNORED &&
- gpu->queueIndex() != this->currentQueueFamilyIndex()) {
+ this->currentQueueFamilyIndex() != gpu->queueIndex()) {
// The image still is owned by its original queue family and we need to transfer it into
// ours.
SkASSERT(!releaseFamilyQueue);
SkASSERT(this->currentQueueFamilyIndex() == fInitialQueueFamily);
-
+ // We only support transferring from external or foreign queues here and not arbitrary
+ // ones.
+ SkASSERT(this->currentQueueFamilyIndex() == VK_QUEUE_FAMILY_EXTERNAL ||
+ this->currentQueueFamilyIndex() == VK_QUEUE_FAMILY_FOREIGN_EXT);
srcQueueFamilyIndex = this->currentQueueFamilyIndex();
- dstQueueFamilyIndex = gpu->queueIndex();
- this->setQueueFamilyIndex(gpu->queueIndex());
+ if (fInfo.fSharingMode == VK_SHARING_MODE_EXCLUSIVE) {
+ dstQueueFamilyIndex = gpu->queueIndex();
+ } else {
+ dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ }
+ this->setQueueFamilyIndex(dstQueueFamilyIndex);
} else if (releaseFamilyQueue) {
// We are releasing the image so we must transfer the image back to its original queue
// family.
@@ -217,6 +261,7 @@
info->fCurrentQueueFamily = VK_QUEUE_FAMILY_IGNORED;
info->fProtected =
(createflags & VK_IMAGE_CREATE_PROTECTED_BIT) ? GrProtected::kYes : GrProtected::kNo;
+ info->fSharingMode = VK_SHARING_MODE_EXCLUSIVE;
return true;
}
diff --git a/src/gpu/vk/GrVkImage.h b/src/gpu/vk/GrVkImage.h
index 4ff3e7e..d7657dc 100644
--- a/src/gpu/vk/GrVkImage.h
+++ b/src/gpu/vk/GrVkImage.h
@@ -29,22 +29,8 @@
const GrVkImageInfo& info,
sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
GrBackendObjectOwnership ownership,
- bool forSecondaryCB = false)
- : fInfo(info)
- , fInitialQueueFamily(info.fCurrentQueueFamily)
- , fMutableState(std::move(mutableState))
- , fIsBorrowed(GrBackendObjectOwnership::kBorrowed == ownership) {
- SkASSERT(fMutableState->getImageLayout() == fInfo.fImageLayout);
- SkASSERT(fMutableState->getQueueFamilyIndex() == fInfo.fCurrentQueueFamily);
- if (forSecondaryCB) {
- fResource = nullptr;
- } else if (fIsBorrowed) {
- fResource = new BorrowedResource(gpu, info.fImage, info.fAlloc, info.fImageTiling);
- } else {
- SkASSERT(VK_NULL_HANDLE != info.fAlloc.fMemory);
- fResource = new Resource(gpu, info.fImage, info.fAlloc, info.fImageTiling);
- }
- }
+ bool forSecondaryCB = false);
+
virtual ~GrVkImage();
VkImage image() const {