Skip to content

Commit

Permalink
Fix issue of reseting CAMetalDrawable and MTLTexture of peer swapchai…
Browse files Browse the repository at this point in the history
…n images.

Add MVKPresentableSwapchainImage and MVKPeerSwapchainImage subclasses to
MVKSwapchainImage, with MVKPresentableSwapchainImage instances created inside
swapchain, and MVKPeerSwapchainImage instances created using vkCreateImage().
MVKPeerSwapchainImage retrieve and share CAMetalDrawable from corresponding
MVKPresentableSwapchainImage.
  • Loading branch information
billhollings committed Apr 5, 2020
1 parent aa27fd6 commit 70bf788
Show file tree
Hide file tree
Showing 9 changed files with 183 additions and 94 deletions.
1 change: 1 addition & 0 deletions Docs/Whats_New.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Released 2020/04/05
- Fix issue causing screen captures from swapchain image to deadlock.
- Fix memory estimates for iOS 13+.
- Broaden conditions for host read sync for image memory barriers on macOS.
- Fix issue of reseting `CAMetalDrawable` and `MTLTexture` of peer swapchain images.
- Fix the `make install` build command to overwrite the existing framework in the system
framework library, and update `README.md` to clarify the instructions for using `make install`.
- Update the `README.md` and `MoltenVK_Runtime_UserGuide.md` documents to clarify that
Expand Down
14 changes: 7 additions & 7 deletions MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class MVKResource;
class MVKBuffer;
class MVKBufferView;
class MVKImage;
class MVKSwapchainImage;
class MVKPresentableSwapchainImage;
class MVKImageView;
class MVKSwapchain;
class MVKDeviceMemory;
Expand Down Expand Up @@ -450,12 +450,12 @@ class MVKDevice : public MVKDispatchableVulkanAPIObject {
void destroySwapchain(MVKSwapchain* mvkSwpChn,
const VkAllocationCallbacks* pAllocator);

MVKSwapchainImage* createSwapchainImage(const VkImageCreateInfo* pCreateInfo,
MVKSwapchain* swapchain,
uint32_t swapchainIndex,
const VkAllocationCallbacks* pAllocator);
void destroySwapchainImage(MVKSwapchainImage* mvkImg,
const VkAllocationCallbacks* pAllocator);
MVKPresentableSwapchainImage* createPresentableSwapchainImage(const VkImageCreateInfo* pCreateInfo,
MVKSwapchain* swapchain,
uint32_t swapchainIndex,
const VkAllocationCallbacks* pAllocator);
void destroyPresentableSwapchainImage(MVKPresentableSwapchainImage* mvkImg,
const VkAllocationCallbacks* pAllocator);

MVKFence* createFence(const VkFenceCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator);
Expand Down
16 changes: 8 additions & 8 deletions MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
Original file line number Diff line number Diff line change
Expand Up @@ -2138,7 +2138,7 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope
}
}
if (swapchainInfo) {
return createSwapchainImage(pCreateInfo, (MVKSwapchain*)swapchainInfo->swapchain, uint32_t(-1), pAllocator);
return (MVKImage*)addResource(new MVKPeerSwapchainImage(this, pCreateInfo, (MVKSwapchain*)swapchainInfo->swapchain, uint32_t(-1)));
}
return (MVKImage*)addResource(new MVKImage(this, pCreateInfo));
}
Expand Down Expand Up @@ -2169,15 +2169,15 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope
mvkSwpChn->destroy();
}

MVKSwapchainImage* MVKDevice::createSwapchainImage(const VkImageCreateInfo* pCreateInfo,
MVKSwapchain* swapchain,
uint32_t swapchainIndex,
const VkAllocationCallbacks* pAllocator) {
return (MVKSwapchainImage*)addResource(new MVKSwapchainImage(this, pCreateInfo, swapchain, swapchainIndex));
MVKPresentableSwapchainImage* MVKDevice::createPresentableSwapchainImage(const VkImageCreateInfo* pCreateInfo,
MVKSwapchain* swapchain,
uint32_t swapchainIndex,
const VkAllocationCallbacks* pAllocator) {
return (MVKPresentableSwapchainImage*)addResource(new MVKPresentableSwapchainImage(this, pCreateInfo, swapchain, swapchainIndex));
}

void MVKDevice::destroySwapchainImage(MVKSwapchainImage* mvkImg,
const VkAllocationCallbacks* pAllocator) {
void MVKDevice::destroyPresentableSwapchainImage(MVKPresentableSwapchainImage* mvkImg,
const VkAllocationCallbacks* pAllocator) {
removeResource(mvkImg);
mvkImg->destroy();
}
Expand Down
89 changes: 69 additions & 20 deletions MoltenVK/MoltenVK/GPUObjects/MVKImage.h
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,41 @@ class MVKImage : public MVKResource {
#pragma mark -
#pragma mark MVKSwapchainImage

/** Abstract class of Vulkan image used as a rendering destination within a swapchain. */
class MVKSwapchainImage : public MVKImage {

public:

/** Binds this resource to the specified offset within the specified memory allocation. */
VkResult bindDeviceMemory(MVKDeviceMemory* mvkMem, VkDeviceSize memOffset) override;

#pragma mark Metal

/** Returns the Metal texture used by the CAMetalDrawable underlying this image. */
id<MTLTexture> getMTLTexture() override;


#pragma mark Construction

/** Constructs an instance for the specified device and swapchain. */
MVKSwapchainImage(MVKDevice* device,
const VkImageCreateInfo* pCreateInfo,
MVKSwapchain* swapchain,
uint32_t swapchainIndex);

protected:
friend class MVKPeerSwapchainImage;

virtual id<CAMetalDrawable> getCAMetalDrawable() = 0;

MVKSwapchain* _swapchain;
uint32_t _swapchainIndex;
};


#pragma mark -
#pragma mark MVKPresentableSwapchainImage

/** Indicates the relative availability of each image in the swapchain. */
typedef struct MVKSwapchainImageAvailability {
uint64_t acquisitionID; /**< When this image was last made available, relative to the other images in the swapchain. Smaller value is earlier. */
Expand All @@ -286,23 +321,13 @@ typedef struct MVKSwapchainImageAvailability {
typedef std::pair<MVKSemaphore*, MVKFence*> MVKSwapchainSignaler;


/** Represents a Vulkan image used as a rendering destination within a swapchain. */
class MVKSwapchainImage : public MVKImage {
/** Represents a Vulkan swapchain image that can be submitted to the presentation engine. */
class MVKPresentableSwapchainImage : public MVKSwapchainImage {

public:

/** Binds this resource to the specified offset within the specified memory allocation. */
VkResult bindDeviceMemory(MVKDeviceMemory* mvkMem, VkDeviceSize memOffset) override;

/** Binds this resource according to the specified bind information. */
VkResult bindDeviceMemory2(const void* pBindInfo) override;


#pragma mark Metal

/** Returns the Metal texture used by the CAMetalDrawable underlying this image. */
id<MTLTexture> getMTLTexture() override;

/**
* Presents the contained drawable to the OS, releases the Metal drawable and its
* texture back to the Metal layer's pool, and makes the image memory available for new use.
Expand All @@ -317,17 +342,17 @@ class MVKSwapchainImage : public MVKImage {
#pragma mark Construction

/** Constructs an instance for the specified device and swapchain. */
MVKSwapchainImage(MVKDevice* device,
const VkImageCreateInfo* pCreateInfo,
MVKSwapchain* swapchain,
uint32_t swapchainIndex);
MVKPresentableSwapchainImage(MVKDevice* device,
const VkImageCreateInfo* pCreateInfo,
MVKSwapchain* swapchain,
uint32_t swapchainIndex);

~MVKSwapchainImage() override;
~MVKPresentableSwapchainImage() override;

protected:
friend MVKSwapchain;

id<CAMetalDrawable> getCAMetalDrawable();
id<CAMetalDrawable> getCAMetalDrawable() override;
void releaseMetalDrawable();
MVKSwapchainImageAvailability getAvailability();
void makeAvailable();
Expand All @@ -338,8 +363,6 @@ class MVKSwapchainImage : public MVKImage {
static void unmarkAsTracked(MVKSwapchainSignaler& signaler);
void renderWatermark(id<MTLCommandBuffer> mtlCmdBuff);

MVKSwapchain* _swapchain;
uint32_t _swapchainIndex;
id<CAMetalDrawable> _mtlDrawable;
MVKSwapchainImageAvailability _availability;
MVKVectorInline<MVKSwapchainSignaler, 1> _availabilitySignalers;
Expand All @@ -348,6 +371,32 @@ class MVKSwapchainImage : public MVKImage {
};


#pragma mark -
#pragma mark MVKPeerSwapchainImage

/** Represents a Vulkan swapchain image that can be associated as a peer to a swapchain image. */
class MVKPeerSwapchainImage : public MVKSwapchainImage {

public:

/** Binds this resource according to the specified bind information. */
VkResult bindDeviceMemory2(const void* pBindInfo) override;


#pragma mark Construction

/** Constructs an instance for the specified device and swapchain. */
MVKPeerSwapchainImage(MVKDevice* device,
const VkImageCreateInfo* pCreateInfo,
MVKSwapchain* swapchain,
uint32_t swapchainIndex);

protected:
id<CAMetalDrawable> getCAMetalDrawable() override;

};


#pragma mark -
#pragma mark MVKImageView

Expand Down
Loading

0 comments on commit 70bf788

Please sign in to comment.