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>
This commit is contained in:
parent
674a5ccd3c
commit
aa9d99ff6b
@ -9,6 +9,9 @@ Milestone 85
|
||||
|
||||
* <insert new release notes here>
|
||||
|
||||
* Add VkSharingMode field to GrVkImageInfo.
|
||||
https://review.skia.org/293559
|
||||
|
||||
* Move SkBitmapRegionDecoder into client_utils/android.
|
||||
|
||||
* Remove SkSurface::MakeFromBackendTextureAsRenderTarget.
|
||||
|
@ -149,6 +149,12 @@ struct GrVkYcbcrConversionInfo {
|
||||
VkFormatFeatureFlags fFormatFeatures;
|
||||
};
|
||||
|
||||
/*
|
||||
* When wrapping a GrBackendTexture or GrBackendRendenderTarget, the fCurrentQueueFamily should
|
||||
* either be VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_EXTERNAL, or VK_QUEUE_FAMILY_FOREIGN_EXT. If
|
||||
* fSharingMode is VK_SHARING_MODE_EXCLUSIVE then fCurrentQueueFamily can also be the graphics
|
||||
* queue index passed into Skia.
|
||||
*/
|
||||
struct GrVkImageInfo {
|
||||
VkImage fImage;
|
||||
GrVkAlloc fAlloc;
|
||||
@ -159,6 +165,7 @@ struct GrVkImageInfo {
|
||||
uint32_t fCurrentQueueFamily;
|
||||
GrProtected fProtected;
|
||||
GrVkYcbcrConversionInfo fYcbcrConversionInfo;
|
||||
VkSharingMode fSharingMode;
|
||||
|
||||
GrVkImageInfo()
|
||||
: fImage(VK_NULL_HANDLE)
|
||||
@ -169,7 +176,8 @@ struct GrVkImageInfo {
|
||||
, fLevelCount(0)
|
||||
, fCurrentQueueFamily(VK_QUEUE_FAMILY_IGNORED)
|
||||
, fProtected(GrProtected::kNo)
|
||||
, fYcbcrConversionInfo() {}
|
||||
, fYcbcrConversionInfo()
|
||||
, fSharingMode(VK_SHARING_MODE_EXCLUSIVE) {}
|
||||
|
||||
GrVkImageInfo(VkImage image,
|
||||
GrVkAlloc alloc,
|
||||
@ -179,7 +187,8 @@ struct GrVkImageInfo {
|
||||
uint32_t levelCount,
|
||||
uint32_t currentQueueFamily = VK_QUEUE_FAMILY_IGNORED,
|
||||
GrProtected isProtected = GrProtected::kNo,
|
||||
GrVkYcbcrConversionInfo ycbcrConversionInfo = GrVkYcbcrConversionInfo())
|
||||
GrVkYcbcrConversionInfo ycbcrConversionInfo = GrVkYcbcrConversionInfo(),
|
||||
VkSharingMode sharingMode = VK_SHARING_MODE_EXCLUSIVE)
|
||||
: fImage(image)
|
||||
, fAlloc(alloc)
|
||||
, fImageTiling(imageTiling)
|
||||
@ -188,7 +197,8 @@ struct GrVkImageInfo {
|
||||
, fLevelCount(levelCount)
|
||||
, fCurrentQueueFamily(currentQueueFamily)
|
||||
, fProtected(isProtected)
|
||||
, fYcbcrConversionInfo(ycbcrConversionInfo) {}
|
||||
, fYcbcrConversionInfo(ycbcrConversionInfo)
|
||||
, fSharingMode(sharingMode) {}
|
||||
|
||||
GrVkImageInfo(const GrVkImageInfo& info, VkImageLayout layout, uint32_t familyQueueIndex)
|
||||
: fImage(info.fImage)
|
||||
@ -199,7 +209,8 @@ struct GrVkImageInfo {
|
||||
, fLevelCount(info.fLevelCount)
|
||||
, fCurrentQueueFamily(familyQueueIndex)
|
||||
, fProtected(info.fProtected)
|
||||
, fYcbcrConversionInfo(info.fYcbcrConversionInfo) {}
|
||||
, fYcbcrConversionInfo(info.fYcbcrConversionInfo)
|
||||
, fSharingMode(info.fSharingMode) {}
|
||||
|
||||
#if GR_TEST_UTILS
|
||||
bool operator==(const GrVkImageInfo& that) const {
|
||||
@ -207,7 +218,8 @@ struct GrVkImageInfo {
|
||||
fImageTiling == that.fImageTiling && fImageLayout == that.fImageLayout &&
|
||||
fFormat == that.fFormat && fLevelCount == that.fLevelCount &&
|
||||
fCurrentQueueFamily == that.fCurrentQueueFamily && fProtected == that.fProtected &&
|
||||
fYcbcrConversionInfo == that.fYcbcrConversionInfo;
|
||||
fYcbcrConversionInfo == that.fYcbcrConversionInfo &&
|
||||
fSharingMode == that.fSharingMode;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
@ -486,6 +486,7 @@ static GrBackendTexture make_vk_backend_texture(
|
||||
// "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;
|
||||
|
@ -1198,7 +1198,8 @@ bool GrVkGpu::updateBuffer(GrVkBuffer* buffer, const void* src,
|
||||
|
||||
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 @@ static bool check_image_info(const GrVkCaps& caps,
|
||||
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 @@ sk_sp<GrTexture> GrVkGpu::onWrapBackendTexture(const GrBackendTexture& backendTe
|
||||
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 @@ sk_sp<GrTexture> GrVkGpu::onWrapCompressedBackendTexture(const GrBackendTexture&
|
||||
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 @@ sk_sp<GrTexture> GrVkGpu::onWrapRenderableBackendTexture(const GrBackendTexture&
|
||||
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 @@ sk_sp<GrRenderTarget> GrVkGpu::onWrapBackendRenderTarget(const GrBackendRenderTa
|
||||
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 @@ sk_sp<GrRenderTarget> GrVkGpu::onWrapBackendTextureAsRenderTarget(const GrBacken
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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 @@ void GrVkImage::setImageLayout(const GrVkGpu* gpu, VkImageLayout newLayout,
|
||||
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 @@ bool GrVkImage::InitImageInfo(GrVkGpu* gpu, const ImageDesc& imageDesc, GrVkImag
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -29,22 +29,8 @@ public:
|
||||
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 {
|
||||
|
@ -317,12 +317,14 @@ bool VulkanWindowContext::createSwapchain(int width, int height,
|
||||
fDestroySwapchainKHR(fDevice, swapchainCreateInfo.oldSwapchain, nullptr);
|
||||
}
|
||||
|
||||
this->createBuffers(swapchainCreateInfo.imageFormat, colorType);
|
||||
this->createBuffers(swapchainCreateInfo.imageFormat, colorType,
|
||||
swapchainCreateInfo.imageSharingMode);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void VulkanWindowContext::createBuffers(VkFormat format, SkColorType colorType) {
|
||||
void VulkanWindowContext::createBuffers(VkFormat format, SkColorType colorType,
|
||||
VkSharingMode sharingMode) {
|
||||
fGetSwapchainImagesKHR(fDevice, fSwapchain, &fImageCount, nullptr);
|
||||
SkASSERT(fImageCount);
|
||||
fImages = new VkImage[fImageCount];
|
||||
@ -342,6 +344,7 @@ void VulkanWindowContext::createBuffers(VkFormat format, SkColorType colorType)
|
||||
info.fFormat = format;
|
||||
info.fLevelCount = 1;
|
||||
info.fCurrentQueueFamily = fPresentQueueIndex;
|
||||
info.fSharingMode = sharingMode;
|
||||
|
||||
if (fSampleCount == 1) {
|
||||
GrBackendRenderTarget backendRT(fWidth, fHeight, fSampleCount, info);
|
||||
|
@ -61,7 +61,7 @@ private:
|
||||
|
||||
BackbufferInfo* getAvailableBackbuffer();
|
||||
bool createSwapchain(int width, int height, const DisplayParams& params);
|
||||
void createBuffers(VkFormat format, SkColorType colorType);
|
||||
void createBuffers(VkFormat format, SkColorType colorType, VkSharingMode);
|
||||
void destroyBuffers();
|
||||
|
||||
VkInstance fInstance = VK_NULL_HANDLE;
|
||||
|
Loading…
Reference in New Issue
Block a user