Merge pull request #654 from billhollings/master
Support VK_EXT_metal_surface extension.
This commit is contained in:
commit
46bea62230
@ -32,7 +32,7 @@ static UIView* sampleView; // Global variable to pass UIView to LunarG sample c
|
||||
* Initialize sample from view, and resize view in accordance with the sample.
|
||||
*/
|
||||
void init_window(struct sample_info &info) {
|
||||
info.window = sampleView;
|
||||
info.window = sampleView.layer;
|
||||
sampleView.bounds = CGRectMake(0, 0, info.width, info.height);
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ static NSView* sampleView; // Global variable to pass NSView to LunarG sample c
|
||||
* Initialize sample from view, and resize view in accordance with the sample.
|
||||
*/
|
||||
void init_window(struct sample_info &info) {
|
||||
info.window = sampleView;
|
||||
info.window = sampleView.layer;
|
||||
sampleView.bounds = CGRectMake(0, 0, info.width, info.height);
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@
|
||||
self.view.contentScaleFactor = UIScreen.mainScreen.nativeScale;
|
||||
|
||||
const char* arg = "cube";
|
||||
demo_main(&demo, self.view, 1, &arg);
|
||||
demo_main(&demo, self.view.layer, 1, &arg);
|
||||
demo_draw(&demo);
|
||||
|
||||
uint32_t fps = 60;
|
||||
|
@ -43,7 +43,7 @@
|
||||
|
||||
self.view.wantsLayer = YES; // Back the view with a layer created by the makeBackingLayer method.
|
||||
const char* arg = "cube";
|
||||
demo_main(&demo, self.view, 1, &arg);
|
||||
demo_main(&demo, self.view.layer, 1, &arg);
|
||||
|
||||
CVDisplayLinkCreateWithActiveCGDisplays(&_displayLink);
|
||||
CVDisplayLinkSetOutputCallback(_displayLink, &DisplayLinkCallback, &demo);
|
||||
|
@ -48,12 +48,7 @@ ShellMVK::ShellMVK(Game& game) : Shell(game)
|
||||
_profile_start_time = _current_time;
|
||||
_profile_present_count = 0;
|
||||
|
||||
#ifdef VK_USE_PLATFORM_IOS_MVK
|
||||
instance_extensions_.push_back(VK_MVK_IOS_SURFACE_EXTENSION_NAME);
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_MACOS_MVK
|
||||
instance_extensions_.push_back(VK_MVK_MACOS_SURFACE_EXTENSION_NAME);
|
||||
#endif
|
||||
instance_extensions_.push_back(VK_EXT_METAL_SURFACE_EXTENSION_NAME);
|
||||
|
||||
init_vk();
|
||||
}
|
||||
@ -78,22 +73,12 @@ VkSurfaceKHR ShellMVK::create_surface(VkInstance instance) {
|
||||
VkSurfaceKHR surface;
|
||||
|
||||
VkResult err;
|
||||
#ifdef VK_USE_PLATFORM_IOS_MVK
|
||||
VkIOSSurfaceCreateInfoMVK surface_info;
|
||||
surface_info.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK;
|
||||
VkMetalSurfaceCreateInfoEXT surface_info;
|
||||
surface_info.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT;
|
||||
surface_info.pNext = NULL;
|
||||
surface_info.flags = 0;
|
||||
surface_info.pView = _view;
|
||||
err = vkCreateIOSSurfaceMVK(instance, &surface_info, NULL, &surface);
|
||||
#endif
|
||||
#ifdef VK_USE_PLATFORM_MACOS_MVK
|
||||
VkMacOSSurfaceCreateInfoMVK surface_info;
|
||||
surface_info.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
|
||||
surface_info.pNext = NULL;
|
||||
surface_info.flags = 0;
|
||||
surface_info.pView = _view;
|
||||
err = vkCreateMacOSSurfaceMVK(instance, &surface_info, NULL, &surface);
|
||||
#endif
|
||||
surface_info.pLayer = _caMetalLayer;
|
||||
err = vkCreateMetalSurfaceEXT(instance, &surface_info, NULL, &surface);
|
||||
assert(!err);
|
||||
|
||||
return surface;
|
||||
@ -124,8 +109,8 @@ void ShellMVK::update_and_draw() {
|
||||
}
|
||||
}
|
||||
|
||||
void ShellMVK::run(void* view) {
|
||||
_view = view; // not retained
|
||||
void ShellMVK::run(void* caMetalLayer) {
|
||||
_caMetalLayer = caMetalLayer; // not retained
|
||||
create_context();
|
||||
resize_swapchain(settings_.initial_width, settings_.initial_height);
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ public:
|
||||
void quit() { }
|
||||
|
||||
protected:
|
||||
void* _view;
|
||||
void* _caMetalLayer;
|
||||
PosixTimer _timer;
|
||||
double _current_time;
|
||||
double _profile_start_time;
|
||||
|
@ -45,12 +45,12 @@
|
||||
self.view.contentScaleFactor = UIScreen.mainScreen.nativeScale;
|
||||
|
||||
std::vector<std::string> args;
|
||||
args.push_back("-p"); // Use push constants
|
||||
args.push_back("-p"); // Use push constants
|
||||
// args.push_back("-s"); // Use a single thread
|
||||
_game = new Hologram(args);
|
||||
|
||||
_shell = new ShellMVK(*_game);
|
||||
_shell->run(self.view);
|
||||
_shell->run(self.view.layer);
|
||||
|
||||
uint32_t fps = 60;
|
||||
_displayLink = [CADisplayLink displayLinkWithTarget: self selector: @selector(renderLoop)];
|
||||
|
@ -46,12 +46,12 @@
|
||||
self.view.wantsLayer = YES; // Back the view with a layer created by the makeBackingLayer method.
|
||||
|
||||
std::vector<std::string> args;
|
||||
// args.push_back("-p"); // Uncomment to use push constants
|
||||
args.push_back("-p"); // Uncomment to use push constants
|
||||
// args.push_back("-s"); // Uncomment to use a single thread
|
||||
_game = new Hologram(args);
|
||||
|
||||
_shell = new ShellMVK(*_game);
|
||||
_shell->run(self.view);
|
||||
_shell->run(self.view.layer);
|
||||
|
||||
CVDisplayLinkCreateWithActiveCGDisplays(&_displayLink);
|
||||
CVDisplayLinkSetOutputCallback(_displayLink, &DisplayLinkCallback, _shell);
|
||||
|
@ -253,36 +253,23 @@ In addition to the core *Vulkan* API, **MoltenVK** also supports the following
|
||||
- `VK_EXT_debug_utils`
|
||||
- `VK_EXT_host_query_reset`
|
||||
- `VK_EXT_memory_budget`
|
||||
- `VK_EXT_metal_surface`
|
||||
- `VK_EXT_shader_viewport_index_layer`
|
||||
- `VK_EXT_vertex_attribute_divisor`
|
||||
- `VK_EXTX_portability_subset`
|
||||
- `VK_MVK_ios_surface` (iOS)
|
||||
- `VK_MVK_macos_surface` (macOS)
|
||||
- `VK_MVK_ios_surface` *(iOS) (Obsolete. Use `VK_EXT_metal_surface` instead.)*
|
||||
- `VK_MVK_macos_surface` *(macOS) (Obsolete. Use `VK_EXT_metal_surface` instead.)*
|
||||
- `VK_MVK_moltenvk`
|
||||
- `VK_AMD_gpu_shader_half_float`
|
||||
- `VK_AMD_negative_viewport_height`
|
||||
- `VK_IMG_format_pvrtc` (iOS)
|
||||
- `VK_IMG_format_pvrtc` *(iOS)*
|
||||
- `VK_NV_glsl_shader`
|
||||
|
||||
In order to visibly display your content on *iOS* or *macOS*, you must enable the `VK_MVK_ios_surface`
|
||||
or `VK_MVK_macos_surface` extension, respectively, and use the functions defined for that extension
|
||||
to create a *Vulkan* rendering surface.
|
||||
|
||||
You can enable each of these extensions by defining the `VK_USE_PLATFORM_IOS_MVK` or
|
||||
`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.
|
||||
In order to visibly display your content on *iOS* or *macOS*, you must enable the `VK_EXT_metal_surface`
|
||||
extension, and use the function defined in that extension to create a *Vulkan* rendering surface.
|
||||
You can enable the `VK_EXT_metal_surface` extension by defining the `VK_USE_PLATFORM_METAL_EXT`
|
||||
guard macro in your compiler build settings. See the description of the `mvk_vulkan.h` file below for
|
||||
a convenient way to enable this extension automatically.
|
||||
|
||||
|
||||
<a name="moltenvk_extension"></a>
|
||||
@ -308,10 +295,8 @@ where `HEADER_FILE` is one of the following:
|
||||
enabled for *iOS* or *macOS*. Use this header file in place of the `vulkan.h` header file,
|
||||
where access to a **MoltenVK** platform surface extension is required.
|
||||
|
||||
- When building for *iOS*, the `mvk_vulkan.h` header file automatically enables the
|
||||
`VK_USE_PLATFORM_IOS_MVK` build setting and `VK_MVK_ios_surface` *Vulkan* extension.
|
||||
- When building for *macOS*, the `mvk_vulkan.h` header file automatically enables the
|
||||
`VK_USE_PLATFORM_MACOS_MVK` build setting and `VK_MVK_macos_surface` *Vulkan* extension.
|
||||
The `mvk_vulkan.h` header file automatically enables the `VK_USE_PLATFORM_METAL_EXT`
|
||||
build setting and `VK_EXT_metal_surface` *Vulkan* extension.
|
||||
|
||||
- `mvk_datatypes.h` - Contains helpful functions for converting between *Vulkan* and *Metal* data types.
|
||||
You do not need to use this functionality to use **MoltenVK**, as **MoltenVK** converts between
|
||||
|
@ -18,6 +18,8 @@ MoltenVK 1.0.36
|
||||
|
||||
Released TBD
|
||||
|
||||
- Add support for extensions:
|
||||
- `VK_EXT_metal_surface`
|
||||
- For shaders created directly from MSL, set function name from
|
||||
`VkPipelineShaderStageCreateInfo::pName`.
|
||||
- On iOS GPU family 2 and earlier, support immutable depth-compare samplers
|
||||
|
@ -18,11 +18,13 @@
|
||||
|
||||
|
||||
/**
|
||||
* This is a convenience header file that loads vulkan.h with the appropriate MoltenVK
|
||||
* Vulkan platform extensions automatically enabled for iOS or macOS.
|
||||
* This is a convenience header file that loads vulkan.h with the appropriate Vulkan platform extensions.
|
||||
*
|
||||
* When building for iOS, this header automatically enables the VK_MVK_ios_surface Vulkan extension.
|
||||
* When building for macOS, this header automatically enables the VK_MVK_macos_surface Vulkan extension.
|
||||
* This header automatically enables the VK_EXT_metal_surface Vulkan extension.
|
||||
*
|
||||
* When building for iOS, this header also automatically enables the obsolete VK_MVK_ios_surface Vulkan extension.
|
||||
* When building for macOS, this header also automatically enables the obsolete VK_MVK_macos_surface Vulkan extension.
|
||||
* Both of these extensions are obsolete. Consider using the portable VK_EXT_metal_surface extension instead.
|
||||
*/
|
||||
|
||||
#ifndef __mvk_vulkan_h_
|
||||
@ -31,6 +33,8 @@
|
||||
|
||||
#include <Availability.h>
|
||||
|
||||
#define VK_USE_PLATFORM_METAL_EXT 1
|
||||
|
||||
#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
|
||||
# define VK_USE_PLATFORM_IOS_MVK 1
|
||||
#endif
|
||||
|
@ -88,6 +88,9 @@ public:
|
||||
/** Returns the driver layer. */
|
||||
MVKLayer* getDriverLayer() { return MVKLayerManager::globalManager()->getDriverLayer(); }
|
||||
|
||||
MVKSurface* createSurface(const VkMetalSurfaceCreateInfoEXT* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator);
|
||||
|
||||
MVKSurface* createSurface(const Vk_PLATFORM_SurfaceCreateInfoMVK* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator);
|
||||
|
||||
|
@ -70,6 +70,11 @@ VkResult MVKInstance::getPhysicalDevices(uint32_t* pCount, VkPhysicalDevice* pPh
|
||||
return result;
|
||||
}
|
||||
|
||||
MVKSurface* MVKInstance::createSurface(const VkMetalSurfaceCreateInfoEXT* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator) {
|
||||
return new MVKSurface(this, pCreateInfo, pAllocator);
|
||||
}
|
||||
|
||||
MVKSurface* MVKInstance::createSurface(const Vk_PLATFORM_SurfaceCreateInfoMVK* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator) {
|
||||
return new MVKSurface(this, pCreateInfo, pAllocator);
|
||||
@ -540,6 +545,7 @@ void MVKInstance::initProcAddrs() {
|
||||
ADD_INST_EXT_ENTRY_POINT(vkCreateDebugUtilsMessengerEXT, EXT_DEBUG_UTILS);
|
||||
ADD_INST_EXT_ENTRY_POINT(vkDestroyDebugUtilsMessengerEXT, EXT_DEBUG_UTILS);
|
||||
ADD_INST_EXT_ENTRY_POINT(vkSubmitDebugUtilsMessageEXT, EXT_DEBUG_UTILS);
|
||||
ADD_INST_EXT_ENTRY_POINT(vkCreateMetalSurfaceEXT, EXT_METAL_SURFACE);
|
||||
|
||||
#ifdef VK_USE_PLATFORM_IOS_MVK
|
||||
ADD_INST_EXT_ENTRY_POINT(vkCreateIOSSurfaceMVK, MVK_IOS_SURFACE);
|
||||
|
@ -65,6 +65,10 @@ public:
|
||||
|
||||
#pragma mark Construction
|
||||
|
||||
MVKSurface(MVKInstance* mvkInstance,
|
||||
const VkMetalSurfaceCreateInfoEXT* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator);
|
||||
|
||||
MVKSurface(MVKInstance* mvkInstance,
|
||||
const Vk_PLATFORM_SurfaceCreateInfoMVK* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator);
|
||||
@ -73,6 +77,7 @@ public:
|
||||
|
||||
protected:
|
||||
void propogateDebugName() override {}
|
||||
void initLayerObserver();
|
||||
|
||||
MVKInstance* _mvkInstance;
|
||||
CAMetalLayer* _mtlCAMetalLayer;
|
||||
|
@ -23,16 +23,28 @@
|
||||
#include "MVKOSExtensions.h"
|
||||
#import "MVKBlockObserver.h"
|
||||
|
||||
#define STR(NAME) #NAME
|
||||
// We need to double-dereference the name to first convert to the platform symbol, then to a string.
|
||||
#define STR_PLATFORM(NAME) #NAME
|
||||
#define STR(NAME) STR_PLATFORM(NAME)
|
||||
|
||||
|
||||
#pragma mark MVKSurface
|
||||
|
||||
MVKSurface::MVKSurface(MVKInstance* mvkInstance,
|
||||
const VkMetalSurfaceCreateInfoEXT* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator) : _mvkInstance(mvkInstance) {
|
||||
|
||||
_mtlCAMetalLayer = (CAMetalLayer*)[pCreateInfo->pLayer retain];
|
||||
initLayerObserver();
|
||||
}
|
||||
|
||||
// pCreateInfo->pView can be either a CAMetalLayer or a view (NSView/UIView).
|
||||
MVKSurface::MVKSurface(MVKInstance* mvkInstance,
|
||||
const Vk_PLATFORM_SurfaceCreateInfoMVK* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator) : _mvkInstance(mvkInstance) {
|
||||
|
||||
MVKLogInfo("%s(): This function is obsolete. Consider using the vkCreateMetalSurfaceEXT() function from the VK_EXT_metal_surface extension instead.", STR(vkCreate_PLATFORM_SurfaceMVK));
|
||||
|
||||
// Get the platform object contained in pView
|
||||
id<NSObject> obj = (id<NSObject>)pCreateInfo->pView;
|
||||
|
||||
@ -45,30 +57,34 @@ MVKSurface::MVKSurface(MVKInstance* mvkInstance,
|
||||
obj = ((PLATFORM_VIEW_CLASS*)obj).layer;
|
||||
}
|
||||
|
||||
_layerObserver = nil;
|
||||
|
||||
// Confirm that we were provided with a CAMetalLayer
|
||||
if ([obj isKindOfClass: [CAMetalLayer class]]) {
|
||||
_mtlCAMetalLayer = (CAMetalLayer*)[obj retain]; // retained
|
||||
if ([_mtlCAMetalLayer.delegate isKindOfClass: [PLATFORM_VIEW_CLASS class]]) {
|
||||
// Sometimes, the owning view can replace its CAMetalLayer. In that case, the client
|
||||
// needs to recreate the surface.
|
||||
_layerObserver = [MVKBlockObserver observerWithBlock: ^(NSString* path, id, NSDictionary*, void*) {
|
||||
if ( ![path isEqualToString: @"layer"] ) { return; }
|
||||
std::lock_guard<std::mutex> lock(this->_lock);
|
||||
[this->_mtlCAMetalLayer release];
|
||||
this->_mtlCAMetalLayer = nil;
|
||||
this->setConfigurationResult(VK_ERROR_SURFACE_LOST_KHR);
|
||||
[this->_layerObserver release];
|
||||
this->_layerObserver = nil;
|
||||
} forObject: _mtlCAMetalLayer.delegate atKeyPath: @"layer"];
|
||||
}
|
||||
} else {
|
||||
setConfigurationResult(reportError(VK_ERROR_INITIALIZATION_FAILED,
|
||||
"%s(): On-screen rendering requires a layer of type CAMetalLayer.",
|
||||
STR(vkCreate_PLATFORM_SurfaceMVK)));
|
||||
_mtlCAMetalLayer = nil;
|
||||
}
|
||||
|
||||
initLayerObserver();
|
||||
}
|
||||
|
||||
// Sometimes, the owning view can replace its CAMetalLayer. In that case, the client needs to recreate the surface.
|
||||
void MVKSurface::initLayerObserver() {
|
||||
|
||||
_layerObserver = nil;
|
||||
if ( ![_mtlCAMetalLayer.delegate isKindOfClass: [PLATFORM_VIEW_CLASS class]] ) { return; }
|
||||
|
||||
_layerObserver = [MVKBlockObserver observerWithBlock: ^(NSString* path, id, NSDictionary*, void*) {
|
||||
if ( ![path isEqualToString: @"layer"] ) { return; }
|
||||
std::lock_guard<std::mutex> lock(this->_lock);
|
||||
[this->_mtlCAMetalLayer release];
|
||||
this->_mtlCAMetalLayer = nil;
|
||||
this->setConfigurationResult(VK_ERROR_SURFACE_LOST_KHR);
|
||||
[this->_layerObserver release];
|
||||
this->_layerObserver = nil;
|
||||
} forObject: _mtlCAMetalLayer.delegate atKeyPath: @"layer"];
|
||||
}
|
||||
|
||||
MVKSurface::~MVKSurface() {
|
||||
|
@ -57,6 +57,7 @@ MVK_EXTENSION(EXT_debug_report, EXT_DEBUG_REPORT)
|
||||
MVK_EXTENSION(EXT_debug_utils, EXT_DEBUG_UTILS)
|
||||
MVK_EXTENSION(EXT_host_query_reset, EXT_HOST_QUERY_RESET)
|
||||
MVK_EXTENSION(EXT_memory_budget, EXT_MEMORY_BUDGET)
|
||||
MVK_EXTENSION(EXT_metal_surface, EXT_METAL_SURFACE)
|
||||
MVK_EXTENSION(EXT_shader_viewport_index_layer, EXT_SHADER_VIEWPORT_INDEX_LAYER)
|
||||
MVK_EXTENSION(EXT_vertex_attribute_divisor, EXT_VERTEX_ATTRIBUTE_DIVISOR)
|
||||
MVK_EXTENSION(EXTX_portability_subset, EXTX_PORTABILITY_SUBSET)
|
||||
|
@ -2608,6 +2608,23 @@ MVK_PUBLIC_SYMBOL void vkSubmitDebugUtilsMessageEXT(
|
||||
MVKTraceVulkanCallEnd();
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark VK_EXT_metal_surface extension
|
||||
|
||||
MVK_PUBLIC_SYMBOL VkResult vkCreateMetalSurfaceEXT(
|
||||
VkInstance instance,
|
||||
const VkMetalSurfaceCreateInfoEXT* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkSurfaceKHR* pSurface) {
|
||||
|
||||
MVKTraceVulkanCallStart();
|
||||
MVKInstance* mvkInst = MVKInstance::getMVKInstance(instance);
|
||||
MVKSurface* mvkSrfc = mvkInst->createSurface(pCreateInfo, pAllocator);
|
||||
*pSurface = (VkSurfaceKHR)mvkSrfc;
|
||||
VkResult rslt = mvkSrfc->getConfigurationResult();
|
||||
MVKTraceVulkanCallEnd();
|
||||
return rslt;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark iOS & macOS surface extensions
|
||||
|
Loading…
x
Reference in New Issue
Block a user