When creating a surface, accept either a CAMetalLayer or an

NSView/UIView in the pView member, and improve error logging.
This commit is contained in:
Bill Hollings 2018-09-16 12:39:03 -04:00
parent b543d08afe
commit e546b83852
5 changed files with 46 additions and 12 deletions

View File

@ -252,6 +252,17 @@ You can enable each of these extensions by defining the `VK_USE_PLATFORM_IOS_MVK
`VK_USE_PLATFORM_MACOS_MVK` guard macro in your compiler build settings. See the description
of the `mvk_vulkan.h` file below for a convenient way to enable these extensions automatically.
When using the `VK_MVK_macos_surface ` extension, the `pView` member of the `VkMacOSSurfaceCreateInfoMVK`
structure passed in the `vkCreateMacOSSurfaceMVK` function can be either an `NSView` whose layer is a
`CAMetalLayer`, or the `CAMetalLayer` itself. Passing the `CAMetalLayer` itself is recommended when calling
the `vkCreateMacOSSurfaceMVK` function from outside the main application thread, as `NSView` should only be
accessed from the main application thread.
When using the `VK_MVK_ios_surface ` extension, the `pView` member of the `VkIOSSurfaceCreateInfoMVK`
structure passed in the `vkCreateIOSSurfaceMVK` function can be either a `UIView` whose layer is a
`CAMetalLayer`, or the `CAMetalLayer` itself. Passing the `CAMetalLayer` itself is recommended when
calling the `vkCreateIOSSurfaceMVK ` function from outside the main application thread, as `UIView`
should only be accessed from the main application thread.
<a name="moltenvk_extension"></a>
### MoltenVK Extension

View File

@ -28,14 +28,14 @@
# define Vk_PLATFORM_SurfaceCreateInfoMVK VkIOSSurfaceCreateInfoMVK
# define PLATFORM_VIEW_CLASS UIView
# include <UIKit/UIView.h>
#endif // MVK_IOS
#endif
#ifdef VK_USE_PLATFORM_MACOS_MVK
# define vkCreate_PLATFORM_SurfaceMVK vkCreateMacOSSurfaceMVK
# define Vk_PLATFORM_SurfaceCreateInfoMVK VkMacOSSurfaceCreateInfoMVK
# define PLATFORM_VIEW_CLASS NSView
# include <AppKit/NSView.h>
#endif // MVK_MACOS
#endif
#import <Metal/Metal.h>
#import <QuartzCore/CAMetalLayer.h>

View File

@ -26,18 +26,41 @@
#pragma mark Construction
#ifdef VK_USE_PLATFORM_IOS_MVK
static const char* mvkSurfaceCreateFuncName = "vkCreateIOSSurfaceMVK";
static const char* mvkSurfaceCreateStructName = "VkIOSSurfaceCreateInfoMVK";
static const char* mvkViewClassName = "UIView";
#endif
#ifdef VK_USE_PLATFORM_MACOS_MVK
static const char* mvkSurfaceCreateFuncName = "vkCreateMacOSSurfaceMVK";
static const char* mvkSurfaceCreateStructName = "VkMacOSSurfaceCreateInfoMVK";
static const char* mvkViewClassName = "NSView";
#endif
// pCreateInfo->pView can be either a CAMetalLayer or a view (NSView/UIView).
MVKSurface::MVKSurface(MVKInstance* mvkInstance,
const Vk_PLATFORM_SurfaceCreateInfoMVK* pCreateInfo,
const VkAllocationCallbacks* pAllocator) {
__block CALayer* viewLayer = nil;
mvkDispatchToMainAndWait(^{ viewLayer = ((PLATFORM_VIEW_CLASS*)pCreateInfo->pView).layer; });
if ( [viewLayer isKindOfClass: [CAMetalLayer class]] ) {
_mtlCAMetalLayer = (CAMetalLayer*)[viewLayer retain]; // retained
} else {
setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_INITIALIZATION_FAILED, "On-screen rendering requires a view that is backed by a layer of type CAMetalLayer."));
_mtlCAMetalLayer = nil;
}
// Get the platform object contained in pView
id<NSObject> obj = (id<NSObject>)pCreateInfo->pView;
// If it's a view (NSView/UIView), extract the layer, otherwise assume it's already a CAMetalLayer.
if ([obj isKindOfClass: [PLATFORM_VIEW_CLASS class]]) {
if ( !NSThread.isMainThread ) {
MVKLogInfo("%s(): You are not calling this function from the main thread. %s should only be accessed from the main thread. When using this function outside the main thread, consider passing the CAMetalLayer itself in %s::pView, instead of the %s.", mvkSurfaceCreateFuncName, mvkViewClassName, mvkSurfaceCreateStructName, mvkViewClassName);
}
obj = ((PLATFORM_VIEW_CLASS*)obj).layer;
}
// Confirm that we were provided with a CAMetalLayer
if ([obj isKindOfClass: [CAMetalLayer class]]) {
_mtlCAMetalLayer = (CAMetalLayer*)[obj retain]; // retained
} else {
setConfigurationResult(mvkNotifyErrorWithText(VK_ERROR_INITIALIZATION_FAILED, "%s(): On-screen rendering requires a layer of type CAMetalLayer.", mvkSurfaceCreateFuncName));
_mtlCAMetalLayer = nil;
}
}
MVKSurface::~MVKSurface() {

View File

@ -26,7 +26,7 @@ clang \
-Wno-incompatible-sysroot \
-isysroot ${SDK_DIR} \
-iframework ${MVK_SYS_FWK_DIR} \
-framework Metal ${MVK_IOSURFACE_FWK} -framework UIKit -framework QuartzCore -framework Foundation \
-framework Metal ${MVK_IOSURFACE_FWK} -framework UIKit -framework QuartzCore -framework UIKit -framework Foundation \
--library-directory ${MVK_USR_LIB_DIR} \
-lSystem -lc++ \
-o "${MVK_BUILT_PROD_PATH}/${MVK_DYLIB_NAME}" \

View File

@ -17,7 +17,7 @@ clang \
-Wno-incompatible-sysroot \
-isysroot ${SDK_DIR} \
-iframework ${MVK_SYS_FWK_DIR} \
-framework Metal -framework IOSurface -framework IOKit -framework QuartzCore -framework Foundation \
-framework Metal -framework IOSurface -framework IOKit -framework QuartzCore -framework AppKit -framework Foundation \
--library-directory ${MVK_USR_LIB_DIR} \
-lSystem -lc++ \
-o "${MVK_BUILT_PROD_PATH}/${MVK_DYLIB_NAME}" \