Reorganize code in MVKImage.h/mm to move MVKSwapchainImage closer to MVKImage.

This commit is contained in:
Bill Hollings 2020-03-30 19:35:01 -04:00
parent d256991a7a
commit d5c62cc55a
2 changed files with 144 additions and 146 deletions

View File

@ -271,6 +271,60 @@ protected:
};
#pragma mark -
#pragma mark MVKSwapchainImage
/** Represents a 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;
/** Binds this resource according to the specified bind information. */
VkResult bindDeviceMemory2(const void* pBindInfo) override;
#pragma mark Metal
/**
* 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.
*
* If mtlCmdBuff is not nil, the contained drawable is scheduled for presentation using
* the presentDrawable: method of the command buffer. If mtlCmdBuff is nil, the contained
* drawable is presented immediately using the present method of the drawable.
*/
void presentCAMetalDrawable(id<MTLCommandBuffer> mtlCmdBuff);
#pragma mark Construction
/** Constructs an instance for the specified device and swapchain. */
MVKSwapchainImage(MVKDevice* device,
const VkImageCreateInfo* pCreateInfo,
MVKSwapchain* swapchain,
uint32_t swapchainIndex);
/** Constructs an instance for the specified device and swapchain, without binding to a particular swapchain image index. */
MVKSwapchainImage(MVKDevice* device,
const VkImageCreateInfo* pCreateInfo,
MVKSwapchain* swapchain);
~MVKSwapchainImage() override;
protected:
id<MTLTexture> newMTLTexture() override;
id<CAMetalDrawable> getCAMetalDrawable();
void resetMetalSurface();
void renderWatermark(id<MTLCommandBuffer> mtlCmdBuff);
MVKSwapchain* _swapchain;
uint32_t _swapchainIndex;
};
#pragma mark -
#pragma mark MVKImageView
@ -401,58 +455,3 @@ protected:
SPIRV_CROSS_NAMESPACE::MSLConstexprSampler _constExprSampler;
bool _requiresConstExprSampler;
};
#pragma mark -
#pragma mark MVKSwapchainImage
/** Represents a 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;
/** Binds this resource according to the specified bind information. */
VkResult bindDeviceMemory2(const void* pBindInfo) override;
#pragma mark Metal
/**
* 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.
*
* If mtlCmdBuff is not nil, the contained drawable is scheduled for presentation using
* the presentDrawable: method of the command buffer. If mtlCmdBuff is nil, the contained
* drawable is presented immediately using the present method of the drawable.
*/
void presentCAMetalDrawable(id<MTLCommandBuffer> mtlCmdBuff);
#pragma mark Construction
/** Constructs an instance for the specified device and swapchain. */
MVKSwapchainImage(MVKDevice* device,
const VkImageCreateInfo* pCreateInfo,
MVKSwapchain* swapchain,
uint32_t swapchainIndex);
/** Constructs an instance for the specified device and swapchain, without binding to a particular swapchain image index. */
MVKSwapchainImage(MVKDevice* device,
const VkImageCreateInfo* pCreateInfo,
MVKSwapchain* swapchain);
~MVKSwapchainImage() override;
protected:
id<MTLTexture> newMTLTexture() override;
id<CAMetalDrawable> getCAMetalDrawable();
void resetMetalSurface();
void renderWatermark(id<MTLCommandBuffer> mtlCmdBuff);
MVKSwapchain* _swapchain;
uint32_t _swapchainIndex;
};

View File

@ -791,6 +791,96 @@ MVKImage::~MVKImage() {
}
#pragma mark -
#pragma mark MVKSwapchainImage
VkResult MVKSwapchainImage::bindDeviceMemory(MVKDeviceMemory*, VkDeviceSize) {
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
}
VkResult MVKSwapchainImage::bindDeviceMemory2(const void* pBindInfo) {
const auto* imageInfo = (const VkBindImageMemoryInfo*)pBindInfo;
const VkBindImageMemorySwapchainInfoKHR* swapchainInfo = nullptr;
for (const auto* next = (const VkBaseInStructure*)imageInfo->pNext; next; next = next->pNext) {
switch (next->sType) {
case VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR:
swapchainInfo = (const VkBindImageMemorySwapchainInfoKHR*)next;
break;
default:
break;
}
if (swapchainInfo) { break; }
}
if (!swapchainInfo) {
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
}
_swapchainIndex = swapchainInfo->imageIndex;
return VK_SUCCESS;
}
#pragma mark Metal
// Creates and returns a retained Metal texture suitable for use in this instance.
// This implementation retrieves a MTLTexture from the CAMetalDrawable.
id<MTLTexture> MVKSwapchainImage::newMTLTexture() {
return [[getCAMetalDrawable() texture] retain];
}
id<CAMetalDrawable> MVKSwapchainImage::getCAMetalDrawable() {
id<CAMetalDrawable> mtlDrawable = _swapchain->getCAMetalDrawable(_swapchainIndex);
MVKAssert(mtlDrawable, "Could not acquire an available CAMetalDrawable from the CAMetalLayer in MVKSwapchain image: %p.", this);
return mtlDrawable;
}
// Present the drawable and make myself available only once the command buffer has completed.
void MVKSwapchainImage::presentCAMetalDrawable(id<MTLCommandBuffer> mtlCmdBuff) {
_swapchain->willPresentSurface(getMTLTexture(), mtlCmdBuff);
NSString* scName = _swapchain->getDebugName();
if (scName) { mvkPushDebugGroup(mtlCmdBuff, scName); }
[mtlCmdBuff presentDrawable: getCAMetalDrawable()];
if (scName) { mvkPopDebugGroup(mtlCmdBuff); }
resetMetalSurface();
_swapchain->signalPresentationSemaphore(_swapchainIndex, mtlCmdBuff);
retain(); // Ensure this image is not destroyed while awaiting MTLCommandBuffer completion
[mtlCmdBuff addCompletedHandler: ^(id<MTLCommandBuffer> mcb) {
_swapchain->makeAvailable(_swapchainIndex);
release();
}];
}
// Resets the MTLTexture and CAMetalDrawable underlying this image.
void MVKSwapchainImage::resetMetalSurface() {
resetMTLTexture(); // Release texture first so drawable will be last to release it
_swapchain->resetCAMetalDrawable(_swapchainIndex);
}
#pragma mark Construction
MVKSwapchainImage::MVKSwapchainImage(MVKDevice* device,
const VkImageCreateInfo* pCreateInfo,
MVKSwapchain* swapchain,
uint32_t swapchainIndex) : MVKImage(device, pCreateInfo) {
_swapchain = swapchain;
_swapchainIndex = swapchainIndex;
}
MVKSwapchainImage::MVKSwapchainImage(MVKDevice* device,
const VkImageCreateInfo* pCreateInfo,
MVKSwapchain* swapchain) : MVKImage(device, pCreateInfo) {
_swapchain = swapchain;
_swapchainIndex = uint32_t(-1);
}
MVKSwapchainImage::~MVKSwapchainImage() {
resetMetalSurface(); // remove drawable from swapchain
}
#pragma mark -
#pragma mark MVKImageView
@ -1225,94 +1315,3 @@ void MVKSampler::initConstExprSampler(const VkSamplerCreateInfo* pCreateInfo) {
MVKSampler::~MVKSampler() {
[_mtlSamplerState release];
}
#pragma mark -
#pragma mark MVKSwapchainImage
VkResult MVKSwapchainImage::bindDeviceMemory(MVKDeviceMemory*, VkDeviceSize) {
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
}
VkResult MVKSwapchainImage::bindDeviceMemory2(const void* pBindInfo) {
const auto* imageInfo = (const VkBindImageMemoryInfo*)pBindInfo;
const VkBindImageMemorySwapchainInfoKHR* swapchainInfo = nullptr;
for (const auto* next = (const VkBaseInStructure*)imageInfo->pNext; next; next = next->pNext) {
switch (next->sType) {
case VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR:
swapchainInfo = (const VkBindImageMemorySwapchainInfoKHR*)next;
break;
default:
break;
}
if (swapchainInfo) { break; }
}
if (!swapchainInfo) {
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
}
_swapchainIndex = swapchainInfo->imageIndex;
return VK_SUCCESS;
}
#pragma mark Metal
// Creates and returns a retained Metal texture suitable for use in this instance.
// This implementation retrieves a MTLTexture from the CAMetalDrawable.
id<MTLTexture> MVKSwapchainImage::newMTLTexture() {
return [[getCAMetalDrawable() texture] retain];
}
id<CAMetalDrawable> MVKSwapchainImage::getCAMetalDrawable() {
id<CAMetalDrawable> mtlDrawable = _swapchain->getCAMetalDrawable(_swapchainIndex);
MVKAssert(mtlDrawable, "Could not acquire an available CAMetalDrawable from the CAMetalLayer in MVKSwapchain image: %p.", this);
return mtlDrawable;
}
// Present the drawable and make myself available only once the command buffer has completed.
void MVKSwapchainImage::presentCAMetalDrawable(id<MTLCommandBuffer> mtlCmdBuff) {
_swapchain->willPresentSurface(getMTLTexture(), mtlCmdBuff);
NSString* scName = _swapchain->getDebugName();
if (scName) { mvkPushDebugGroup(mtlCmdBuff, scName); }
[mtlCmdBuff presentDrawable: getCAMetalDrawable()];
if (scName) { mvkPopDebugGroup(mtlCmdBuff); }
resetMetalSurface();
_swapchain->signalPresentationSemaphore(_swapchainIndex, mtlCmdBuff);
retain(); // Ensure this image is not destroyed while awaiting MTLCommandBuffer completion
[mtlCmdBuff addCompletedHandler: ^(id<MTLCommandBuffer> mcb) {
_swapchain->makeAvailable(_swapchainIndex);
release();
}];
}
// Resets the MTLTexture and CAMetalDrawable underlying this image.
void MVKSwapchainImage::resetMetalSurface() {
resetMTLTexture(); // Release texture first so drawable will be last to release it
_swapchain->resetCAMetalDrawable(_swapchainIndex);
}
#pragma mark Construction
MVKSwapchainImage::MVKSwapchainImage(MVKDevice* device,
const VkImageCreateInfo* pCreateInfo,
MVKSwapchain* swapchain,
uint32_t swapchainIndex) : MVKImage(device, pCreateInfo) {
_swapchain = swapchain;
_swapchainIndex = swapchainIndex;
}
MVKSwapchainImage::MVKSwapchainImage(MVKDevice* device,
const VkImageCreateInfo* pCreateInfo,
MVKSwapchain* swapchain) : MVKImage(device, pCreateInfo) {
_swapchain = swapchain;
_swapchainIndex = uint32_t(-1);
}
MVKSwapchainImage::~MVKSwapchainImage() {
resetMetalSurface(); // remove drawable from swapchain
}