Skip to content

Commit

Permalink
Add updated iOS App support to the Vulkan examples (#1119)
Browse files Browse the repository at this point in the history
* Fix clang Objective-C++ flags for macOS command line builds

* Fix getAssetPath() and getShaderBasePath() for macOS command line builds

* Protect debugUtilsMessageCallback() from failing when pMessageIdName is NULL

* Fix a few clang function override and mismatched type warnings

* Fix validation layer warnings on exit for computeraytracing example

* Fix regression in text visibility toggle for textOverlay example

* Support VK_USE_PLATFORM_METAL_EXT vs. deprecated VK_USE_PLATFORM_MACOS_MVK / DVK_USE_PLATFORM_IOS_MVK

* Check dynamic state features before enabling capabilities in dynamicstate example

* Fix vkCmdDraw() vertexCount argument (PARTICLE_COUNT) in particlesystem example

* Update examples list and restore benchmarking script (to top level)

* Fix validation warning in descriptorindexing example

* Fix device max recursion depth validation warnings in ray tracing examples

* Fix OpenMP build settings for texture3d example on all platforms

* Update and simplify build instructions for macOS

* Update CI script with correct library path for libomp on macOS x86_64

* Update CI scipt to install libomp prior to macOS builds

* Trying one more time to get the CI script working for macOS libomp

* Fix vertexCount argument using calculated size in particlesystem example

* Fix combined image descriptor offset calculation in descriptorbuffer example

* Add iOS App support for Vulkan examples on simulator and physical devices

* Add continuous integration (CI) script for iOS

* Update CI script to build iOS using Xcode 14 via macos-12 runner-image

* Update iOS project docs for Xcode 14 and rename ios folder to apple

* Update macOS docs and CI script to use LIBOMP_PREFIX for OpenMP library path

* Delete benchmark-all-validate.py

Delete benchmark script as per feedback from Sascha Willems

* Update debugprintf example documentation in examples.h
  • Loading branch information
SRSaunders authored May 22, 2024
1 parent 3d4446f commit ba927ea
Show file tree
Hide file tree
Showing 38 changed files with 2,755 additions and 9 deletions.
29 changes: 26 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
cmake --build .
build_macOS:
name: Build Mac
name: Build macOS
runs-on: macos-11
steps:
- uses: actions/checkout@v3
Expand All @@ -57,8 +57,31 @@ jobs:
cd ~/VulkanSDK/latest
sudo python ./install_vulkan.py
brew install libomp
brew --prefix libomp
- name: Build
run: |
cmake -G "Xcode" -DOpenMP_omp_LIBRARY=/usr/local/opt/libomp/lib/libomp.dylib
export LIBOMP_PREFIX=$(brew --prefix libomp)
cmake -G "Xcode" -DOpenMP_omp_LIBRARY=$LIBOMP_PREFIX/lib/libomp.dylib .
cmake --build .
build_iOS:
name: Build iOS
runs-on: macos-12
steps:
- uses: actions/checkout@v3
with:
submodules: "recursive"
- name: Setup
run: |
curl -L "https://sdk.lunarg.com/sdk/download/latest/mac/vulkan-sdk.dmg" -o /tmp/vulkan-sdk.dmg
hdiutil attach /tmp/vulkan-sdk.dmg -mountpoint /Volumes/vulkan-sdk
/Volumes/vulkan-sdk/InstallVulkan.app/Contents/MacOS/InstallVulkan \
--root ~/VulkanSDK/latest --accept-licenses --default-answer --confirm-command install
cd ~/VulkanSDK/latest
sudo python ./install_vulkan.py
- name: Build
run: |
cd apple
rm MoltenVK.xcframework
ln -s ~/VulkanSDK/latest/macOS/lib/MoltenVK.xcframework
xcodebuild -scheme examples-ios build CODE_SIGNING_ALLOWED=NO
xcodebuild -scheme examples-macos build
13 changes: 7 additions & 6 deletions BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,13 @@ Open **vulkan_sdk.dmg** and install the Vulkan SDK with *System Global Installat
Install **libomp** from [homebrew](https://brew.sh) using:
```brew install libomp```

Find the **libomp** path prefix using:
```brew --prefix libomp```

Use the **libomp** path prefix to adjust the path for ```-DOpenMP_omp_LIBRARY=``` in the cmake command below.
Define the **libomp** path prefix using:
```export LIBOMP_PREFIX=$(brew --prefix libomp)```

Use [CMake](https://cmake.org) to generate a build configuration for Xcode or your preferred build method (e.g. Unix Makefiles or Ninja).

Example of cmake generating for Xcode with **libomp** path defined for homebrew on Apple Silicon:
```cmake -G "Xcode" -DOpenMP_omp_LIBRARY=/opt/homebrew/opt/libomp/lib/libomp.dylib```
Example of cmake generating for Xcode with **libomp** library path defined:
```cmake -G "Xcode" -DOpenMP_omp_LIBRARY=$LIBOMP_PREFIX/lib/libomp.dylib .```

####iOS
Navigate to the [apple](apple/) folder and follow the instructions in [README\_MoltenVK_Examples.md](apple/README_MoltenVK_Examples.md)
135 changes: 135 additions & 0 deletions apple/MVKExample.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
* MVKExample.cpp
*
* Copyright (c) 2016-2017 The Brenwill Workshop Ltd.
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
*/


#include "MVKExample.h"
#include "examples.h"

void MVKExample::renderFrame() {
_vulkanExample->renderFrame();
}

void MVKExample::displayLinkOutputCb() { // SRS - expose VulkanExampleBase::displayLinkOutputCb() to DemoViewController
_vulkanExample->displayLinkOutputCb();
}

void MVKExample::keyPressed(uint32_t keyChar) { // SRS - handle keyboard key presses only (e.g. Pause, Space, etc)
switch (keyChar)
{
case KEY_P:
_vulkanExample->paused = !_vulkanExample->paused;
break;
case KEY_1: // SRS - support keyboards with no function keys
case KEY_F1:
_vulkanExample->UIOverlay.visible = !_vulkanExample->UIOverlay.visible;
_vulkanExample->UIOverlay.updated = true;
break;
default:
_vulkanExample->keyPressed(keyChar);
break;
}
}

void MVKExample::keyDown(uint32_t keyChar) { // SRS - handle physical keyboard key down/up actions and presses
switch (keyChar)
{
case KEY_W:
case KEY_Z: // for French AZERTY keyboards
_vulkanExample->camera.keys.up = true;
break;
case KEY_S:
_vulkanExample->camera.keys.down = true;
break;
case KEY_A:
case KEY_Q: // for French AZERTY keyboards
_vulkanExample->camera.keys.left = true;
break;
case KEY_D:
_vulkanExample->camera.keys.right = true;
break;
default:
MVKExample::keyPressed(keyChar);
break;
}
}

void MVKExample::keyUp(uint32_t keyChar) {
switch (keyChar)
{
case KEY_W:
case KEY_Z: // for French AZERTY keyboards
_vulkanExample->camera.keys.up = false;
break;
case KEY_S:
_vulkanExample->camera.keys.down = false;
break;
case KEY_A:
case KEY_Q: // for French AZERTY keyboards
_vulkanExample->camera.keys.left = false;
break;
case KEY_D:
_vulkanExample->camera.keys.right = false;
break;
default:
break;
}
}

void MVKExample::mouseDown(double x, double y) {
_vulkanExample->mouseState.position = glm::vec2(x, y);
_vulkanExample->mouseState.buttons.left = true;
}

void MVKExample::mouseUp() {
_vulkanExample->mouseState.buttons.left = false;
}

void MVKExample::rightMouseDown(double x, double y) {
_vulkanExample->mouseState.position = glm::vec2(x, y);
_vulkanExample->mouseState.buttons.right = true;
}

void MVKExample::rightMouseUp() {
_vulkanExample->mouseState.buttons.right = false;
}

void MVKExample::otherMouseDown(double x, double y) {
_vulkanExample->mouseState.position = glm::vec2(x, y);
_vulkanExample->mouseState.buttons.middle = true;
}

void MVKExample::otherMouseUp() {
_vulkanExample->mouseState.buttons.middle = false;
}

void MVKExample::mouseDragged(double x, double y) {
_vulkanExample->mouseDragged(x, y);
}

void MVKExample::scrollWheel(short wheelDelta) {
_vulkanExample->camera.translate(glm::vec3(0.0f, 0.0f, wheelDelta * 0.05f * _vulkanExample->camera.movementSpeed));
_vulkanExample->viewUpdated = true;
}

void MVKExample::fullScreen(bool fullscreen) {
_vulkanExample->settings.fullscreen = fullscreen;
}

MVKExample::MVKExample(void* view, double scaleUI) {
_vulkanExample = new VulkanExample();
_vulkanExample->initVulkan();
_vulkanExample->setupWindow(view);
_vulkanExample->settings.vsync = true; // SRS - set vsync flag since this iOS/macOS example app uses displayLink vsync rendering
_vulkanExample->UIOverlay.scale = scaleUI; // SRS - set UIOverlay scale to maintain relative proportions/readability on retina displays
_vulkanExample->prepare();
_vulkanExample->renderLoop(); // SRS - this inits destWidth/destHeight/lastTimestamp/tPrevEnd, then falls through and returns
}

MVKExample::~MVKExample() {
vkDeviceWaitIdle(_vulkanExample->vulkanDevice->logicalDevice);
delete(_vulkanExample);
}
42 changes: 42 additions & 0 deletions apple/MVKExample.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* MVKExample.h
*
* Copyright (c) 2016-2017 The Brenwill Workshop Ltd.
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
*/

#pragma once

#include "vulkanexamplebase.h"

// Wrapper class for the SW VulkanExample instance.
class MVKExample {

public:
void renderFrame();
void displayLinkOutputCb(); // SRS - expose VulkanExampleBase::displayLinkOutputCb() to DemoViewController

void keyPressed(uint32_t keyChar); // SRS - expose keyboard events to DemoViewController
void keyDown(uint32_t keyChar);
void keyUp(uint32_t keyChar);

void mouseDown(double x, double y); // SRS - expose mouse events to DemoViewController
void mouseUp();
void rightMouseDown(double x, double y);
void rightMouseUp();
void otherMouseDown(double x, double y);
void otherMouseUp();
void mouseDragged(double x, double y);
void scrollWheel(short wheelDelta);

void fullScreen(bool fullscreen); // SRS - expose VulkanExampleBase::settings.fullscreen to DemoView (macOS only)

MVKExample(void* view, double scaleUI); // SRS - support UIOverlay scaling parameter based on device and display type
~MVKExample();

protected:
VulkanExampleBase* _vulkanExample;
};



1 change: 1 addition & 0 deletions apple/MoltenVK.xcframework
73 changes: 73 additions & 0 deletions apple/README_MoltenVK_Examples.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<a class="site-logo" href="https://www.moltengl.com/moltenvk/" title="MoltenVK">
<img src="images/MoltenVK-Logo-Banner.png" alt="MoltenVK Home" style="width:256px;height:auto">
</a>

#MoltenVK Vulkan Examples

Copyright (c) 2016-2024 [The Brenwill Workshop Ltd.](http://www.brenwill.com).
This document is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)

*This document is written in [Markdown](http://en.wikipedia.org/wiki/Markdown) format.
For best results, use a Markdown reader.*


<a name="intro"></a>

Introduction
------------

The *Xcode* project in this folder builds and runs the *Vulkan* examples in this
repository on *iOS*, the *iOS Simulator*, and *macOS*, using the **MoltenVK** *Vulkan* driver.



<a name="installing-moltenvk"></a>

Installing MoltenVK
-------------------

These examples require **Vulkan SDK 1.3.275.0** or later.

Follow these instructions to install the latest Vulkan SDK containing **MoltenVK**:

1. [Download](https://sdk.lunarg.com/sdk/download/latest/mac/vulkan_sdk.dmg) the latest
**Vulkan SDK** for macOS. This includes the required **MoltenVK** library frameworks
for *iOS*, the *iOS Simulator*, and *macOS*. The latest getting started information can be found at [Getting Started](https://vulkan.lunarg.com/doc/sdk/latest/mac/getting_started.html).

2. Install the downloaded **vulkansdk-macos-*version*.dmg** package to the default location.

3. Open a *Terminal* session and navigate to the directory containing this document,
remove the existing `MoltenVK.xcframework` symbolic link in this directory, and create
a new symbolic link pointing to `MoltenVK.xcframework` within the **Vulkan SDK**:

cd path-to-this-directory
rm MoltenVK.xcframework
ln -s path-to-VulkanSDK/macOS/lib/MoltenVK.xcframework

<a name="running-examples"></a>

Running the Vulkan Examples
---------------------------

The single `examples.xcodeproj` *Xcode* project can be used to run any of the examples
in this repository on *iOS*, the *iOS Simulator*, or *macOS*. To do so, follow these instructions:

1. Open the `examples.xcodeproj` *Xcode* project using **Xcode 14** or later. <ins>Earlier versions of *Xcode* are not supported and will not successfully build this project</ins>.

2. Specify which of the many examples within this respository you wish to run, by opening
the `examples.h` file within *Xcode*, and following the instructions in the comments
within that file to indicate which of the examples you wish to run. Some examples may not be supported on *iOS* or *macOS* - please see the comments.

3. Run either the `examples-iOS` or `examples-macOS` *Xcode Scheme* to run the example in *iOS*, the *iOS Simulator*, or *macOS* respectively.

4. Many of the examples include an option to press keys to control the display of features
and scene components:

- On *iOS*, use one- and/or two-finger gestures to rotate, translate, or zoom the scene. On *macOS*, use the left/center/right mouse buttons or mouse wheel to rotate, translate, or zoom the scene.
- On the *iOS Simulator*, use the left mouse button to select or rotate the scene, Shift + Option + click and drag for translation, or Option + click and drag for zoom.
- On *iOS*, double tap on the scene to display the keyboard. Double tap again on the scene to hide the keyboard. On the *iOS Simulator* double click to show and hide the virtual keyboard (note: you may need to press ⌘(command) + ⇧(shift) + K to switch from the hardware keyboard to the virtual keyboard).
- On both *iOS* and *macOS*, use the numeric keys (*1, 2, 3...*) instead of function keys (*F1, F2, F3...*).
- On both *iOS* and *macOS*, use the regular keyboard *+* and *-* keys instead of the numpad *+* and *-* keys.
- On both *iOS* and *macOS*, use the keyboard *p* key to pause and resume animation.
- On both *iOS* and *macOS*, use the *delete* key instead of the *escape* key.

Loading

0 comments on commit ba927ea

Please sign in to comment.