Skip to content

Commit

Permalink
Merge branch 'main' into ue4-nastys-patch-env
Browse files Browse the repository at this point in the history
  • Loading branch information
italomandara committed Oct 4, 2023
2 parents 41571d6 + 568cc3a commit 611ae64
Show file tree
Hide file tree
Showing 72 changed files with 2,213 additions and 1,473 deletions.
73 changes: 18 additions & 55 deletions Common/MVKOSExtensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,27 +39,30 @@ static const MVKOSVersion kMVKOSVersionUnsupported = std::numeric_limits<MVKOSVe
MVKOSVersion mvkOSVersion();

/** Returns a MVKOSVersion built from the version components. */
inline MVKOSVersion mvkMakeOSVersion(uint32_t major, uint32_t minor, uint32_t patch) {
static inline MVKOSVersion mvkMakeOSVersion(uint32_t major, uint32_t minor, uint32_t patch) {
return (float)major + ((float)minor / 100.0f) + ((float)patch / 10000.0f);
}

/** Returns whether the operating system version is at least minVer. */
inline bool mvkOSVersionIsAtLeast(MVKOSVersion minVer) { return mvkOSVersion() >= minVer; }
static inline bool mvkOSVersionIsAtLeast(MVKOSVersion minVer) { return mvkOSVersion() >= minVer; }

/**
* Returns whether the operating system version is at least the appropriate min version.
* The constant kMVKOSVersionUnsupported can be used for either value to cause the test
* to always fail on that OS, which is useful for indidicating functionalty guarded by
* The constant kMVKOSVersionUnsupported can be used for any of the values to cause the test
* to always fail on that OS, which is useful for indicating that functionalty guarded by
* this test is not supported on that OS.
*/
inline bool mvkOSVersionIsAtLeast(MVKOSVersion macOSMinVer, MVKOSVersion iOSMinVer, MVKOSVersion visionOSMinVer) {
static inline bool mvkOSVersionIsAtLeast(MVKOSVersion macOSMinVer,
MVKOSVersion iOSMinVer,
MVKOSVersion visionOSMinVer) {
#if MVK_MACOS
return mvkOSVersionIsAtLeast(macOSMinVer);
#endif
#if MVK_IOS_OR_TVOS
return mvkOSVersionIsAtLeast(iOSMinVer);
#endif
#if MVK_VISIONOS
return mvkOSVersionIsAtLeast(visionOSMinVer);
#elif MVK_IOS_OR_TVOS
return mvkOSVersionIsAtLeast(iOSMinVer);
#endif
}

Expand Down Expand Up @@ -105,62 +108,22 @@ void mvkDispatchToMainAndWait(dispatch_block_t block);
#pragma mark Process environment

/**
* Returns the value of the environment variable at the given name,
* or an empty string if no environment variable with that name exists.
*
* If pWasFound is not null, its value is set to true if the environment
* variable exists, or false if not.
* Sets the value of the environment variable at the given name, into the
* std::string, and returns whether the environment variable was found.
*/
std::string mvkGetEnvVar(std::string varName, bool* pWasFound = nullptr);
bool mvkGetEnvVar(const char* evName, std::string& evStr);

/**
* Returns the value of the environment variable at the given name,
* or zero if no environment variable with that name exists.
*
* If pWasFound is not null, its value is set to true if the environment
* variable exists, or false if not.
* Returns a pointer to a string containing the value of the environment variable at
* the given name, or returns the default value if the environment variable was not set.
*/
int64_t mvkGetEnvVarInt64(std::string varName, bool* pWasFound = nullptr);
const char* mvkGetEnvVarString(const char* evName, std::string& evStr, const char* defaultValue = "");

/**
* Returns the value of the environment variable at the given name,
* or false if no environment variable with that name exists.
*
* If pWasFound is not null, its value is set to true if the environment
* variable exists, or false if not.
* or returns the default value if the environment variable was not set.
*/
bool mvkGetEnvVarBool(std::string varName, bool* pWasFound = nullptr);

#define MVK_SET_FROM_ENV_OR_BUILD_BOOL(cfgVal, EV) \
do { \
bool wasFound = false; \
bool ev = mvkGetEnvVarBool(#EV, &wasFound); \
cfgVal = wasFound ? ev : EV; \
} while(false)

#define MVK_SET_FROM_ENV_OR_BUILD_INT64(cfgVal, EV) \
do { \
bool wasFound = false; \
int64_t ev = mvkGetEnvVarInt64(#EV, &wasFound); \
cfgVal = wasFound ? ev : EV; \
} while(false)

// Pointer cast permits cfgVal to be an enum var
#define MVK_SET_FROM_ENV_OR_BUILD_INT32(cfgVal, EV) \
do { \
bool wasFound = false; \
int64_t ev = mvkGetEnvVarInt64(#EV, &wasFound); \
int64_t val = wasFound ? ev : EV; \
*(int32_t*)&cfgVal = (int32_t)std::min(std::max(val, (int64_t)INT32_MIN), (int64_t)INT32_MAX); \
} while(false)

#define MVK_SET_FROM_ENV_OR_BUILD_STRING(cfgVal, EV, strObj) \
do { \
bool wasFound = false; \
std::string ev = mvkGetEnvVar(#EV, &wasFound); \
strObj = wasFound ? std::move(ev) : EV; \
cfgVal = strObj.c_str(); \
} while(false)
double mvkGetEnvVarNumber(const char* evName, double defaultValue = 0.0);


#pragma mark -
Expand Down
17 changes: 9 additions & 8 deletions Common/MVKOSExtensions.mm
Original file line number Diff line number Diff line change
Expand Up @@ -81,21 +81,22 @@ void mvkDispatchToMainAndWait(dispatch_block_t block) {
#pragma mark -
#pragma mark Process environment

string mvkGetEnvVar(string varName, bool* pWasFound) {
bool mvkGetEnvVar(const char* varName, string& evStr) {
@autoreleasepool {
NSDictionary* nsEnv = [[NSProcessInfo processInfo] environment];
NSString* envStr = nsEnv[@(varName.c_str())];
if (pWasFound) { *pWasFound = envStr != nil; }
return envStr ? envStr.UTF8String : "";
NSString* nsStr = nsEnv[@(varName)];
if (nsStr) { evStr = nsStr.UTF8String; }
return nsStr != nil;
}
}

int64_t mvkGetEnvVarInt64(string varName, bool* pWasFound) {
return strtoll(mvkGetEnvVar(varName, pWasFound).c_str(), NULL, 0);
const char* mvkGetEnvVarString(const char* varName, string& evStr, const char* defaultValue) {
return mvkGetEnvVar(varName, evStr) ? evStr.c_str() : defaultValue;
}

bool mvkGetEnvVarBool(std::string varName, bool* pWasFound) {
return mvkGetEnvVarInt64(varName, pWasFound) != 0;
double mvkGetEnvVarNumber(const char* varName, double defaultValue) {
string evStr;
return mvkGetEnvVar(varName, evStr) ? strtod(evStr.c_str(), nullptr) : defaultValue;
}


Expand Down
2 changes: 1 addition & 1 deletion Demos/Cube/Cube.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 52;
objectVersion = 54;
objects = {

/* Begin PBXBuildFile section */
Expand Down
19 changes: 10 additions & 9 deletions Demos/Cube/iOS/DemoViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,9 @@ @implementation DemoViewController {
struct demo demo;
}

-(void) dealloc {
demo_cleanup(&demo);
[_displayLink release];
[super dealloc];
}

/** Since this is a single-view app, init Vulkan when the view is loaded. */
-(void) viewDidLoad {
[super viewDidLoad];
/** Since this is a single-view app, initialize Vulkan as view is appearing. */
-(void) viewWillAppear: (BOOL) animated {
[super viewWillAppear: animated];

self.view.contentScaleFactor = UIScreen.mainScreen.nativeScale;

Expand Down Expand Up @@ -68,6 +62,13 @@ -(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coord
demo_resize(&demo);
}

-(void) viewDidDisappear: (BOOL) animated {
[_displayLink invalidate];
[_displayLink release];
demo_cleanup(&demo);
[super viewDidDisappear: animated];
}

@end


Expand Down
64 changes: 45 additions & 19 deletions Demos/Cube/macOS/DemoViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#import "DemoViewController.h"
#import <QuartzCore/CAMetalLayer.h>
#import <CoreVideo/CVDisplayLink.h>

#include <MoltenVK/mvk_vulkan.h>
#include "../../Vulkan-Tools/cube/cube.c"
Expand All @@ -27,47 +28,68 @@
#pragma mark DemoViewController

@implementation DemoViewController {
CVDisplayLinkRef _displayLink;
CVDisplayLinkRef _displayLink;
struct demo demo;
uint32_t _maxFrameCount;
uint64_t _frameCount;
BOOL _stop;
BOOL _useDisplayLink;
}

-(void) dealloc {
demo_cleanup(&demo);
CVDisplayLinkRelease(_displayLink);
[super dealloc];
}

/** Since this is a single-view app, initialize Vulkan during view loading. */
-(void) viewDidLoad {
[super viewDidLoad];
/** Since this is a single-view app, initialize Vulkan as view is appearing. */
-(void) viewWillAppear {
[super viewWillAppear];

self.view.wantsLayer = YES; // Back the view with a layer created by the makeBackingLayer method.

// Enabling this will sync the rendering loop with the natural display link (60 fps).
// Disabling this will allow the rendering loop to run flat out, limited only by the rendering speed.
bool useDisplayLink = true;
// Enabling this will sync the rendering loop with the natural display link
// (monitor refresh rate, typically 60 fps). Disabling this will allow the
// rendering loop to run flat out, limited only by the rendering speed.
_useDisplayLink = YES;

VkPresentModeKHR vkPresentMode = useDisplayLink ? VK_PRESENT_MODE_FIFO_KHR : VK_PRESENT_MODE_IMMEDIATE_KHR;
// If this value is set to zero, the demo will render frames until the window is closed.
// If this value is not zero, it establishes a maximum number of frames that will be
// rendered, and once this count has been reached, the demo will stop rendering.
// Once rendering is finished, if _useDisplayLink is false, the demo will immediately
// clean up the Vulkan objects, or if _useDisplayLink is true, the demo will delay
// cleaning up Vulkan objects until the window is closed.
_maxFrameCount = 0;

VkPresentModeKHR vkPresentMode = _useDisplayLink ? VK_PRESENT_MODE_FIFO_KHR : VK_PRESENT_MODE_IMMEDIATE_KHR;
char vkPresentModeStr[64];
sprintf(vkPresentModeStr, "%d", vkPresentMode);

const char* argv[] = { "cube", "--present_mode", vkPresentModeStr };
int argc = sizeof(argv)/sizeof(char*);
demo_main(&demo, self.view.layer, argc, argv);

if (useDisplayLink) {
_stop = NO;
_frameCount = 0;
if (_useDisplayLink) {
CVDisplayLinkCreateWithActiveCGDisplays(&_displayLink);
CVDisplayLinkSetOutputCallback(_displayLink, &DisplayLinkCallback, &demo);
CVDisplayLinkSetOutputCallback(_displayLink, &DisplayLinkCallback, self);
CVDisplayLinkStart(_displayLink);
} else {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
while(true) {
do {
demo_draw(&demo);
}
_stop = _stop || (_maxFrameCount && ++_frameCount >= _maxFrameCount);
} while( !_stop );
demo_cleanup(&demo);
});
}
}

-(void) viewDidDisappear {
_stop = YES;
if (_useDisplayLink) {
CVDisplayLinkRelease(_displayLink);
demo_cleanup(&demo);
}

[super viewDidDisappear];
}


#pragma mark Display loop callback function

Expand All @@ -78,7 +100,11 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink,
CVOptionFlags flagsIn,
CVOptionFlags* flagsOut,
void* target) {
demo_draw((struct demo*)target);
DemoViewController* demoVC =(DemoViewController*)target;
if ( !demoVC->_stop ) {
demo_draw(&demoVC->demo);
demoVC->_stop = (demoVC->_maxFrameCount && ++demoVC->_frameCount >= demoVC->_maxFrameCount);
}
return kCVReturnSuccess;
}

Expand Down
22 changes: 20 additions & 2 deletions Docs/MoltenVK_Runtime_UserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Table of Contents
- [Performance Considerations](#performance)
- [Shader Loading Time](#shader_load_time)
- [Swapchains](#swapchains)
- [Timestamping](#timestamping)
- [Xcode Configuration](#xcode_config)
- [Metal System Trace Tool](#trace_tool)
- [Known **MoltenVK** Limitations](#limitations)
Expand Down Expand Up @@ -327,6 +328,7 @@ In addition to core *Vulkan* functionality, **MoltenVK** also supports the foll
- `VK_KHR_get_surface_capabilities2`
- `VK_KHR_imageless_framebuffer`
- `VK_KHR_image_format_list`
- `VK_KHR_incremental_present`
- `VK_KHR_maintenance1`
- `VK_KHR_maintenance2`
- `VK_KHR_maintenance3`
Expand All @@ -348,6 +350,7 @@ In addition to core *Vulkan* functionality, **MoltenVK** also supports the foll
- `VK_KHR_surface`
- `VK_KHR_swapchain`
- `VK_KHR_swapchain_mutable_format`
- `VK_KHR_synchronization2`
- `VK_KHR_timeline_semaphore`
- `VK_KHR_uniform_buffer_standard_layout`
- `VK_KHR_variable_pointers`
Expand All @@ -369,6 +372,7 @@ In addition to core *Vulkan* functionality, **MoltenVK** also supports the foll
- `VK_EXT_metal_objects`
- `VK_EXT_metal_surface`
- `VK_EXT_pipeline_creation_cache_control`
- `VK_EXT_pipeline_creation_feedback`
- `VK_EXT_post_depth_coverage` *(iOS and macOS, requires family 4 (A11) or better Apple GPU)*
- `VK_EXT_private_data `
- `VK_EXT_robustness2`
Expand Down Expand Up @@ -514,8 +518,8 @@ you can address the issue as follows:
- Errors encountered during **Runtime Shader Conversion** are logged to the console.

- To help understand conversion issues during **Runtime Shader Conversion**, you can enable the
logging of the *SPIR-V* and *MSL* shader source code during shader conversion, by turning on
the `MVKConfiguration::debugMode` configuration parameter, or setting the value of the `MVK_DEBUG`
logging of the *SPIR-V* and *MSL* shader source code during shader conversion, by turning on the
`MVKConfiguration::debugMode` configuration parameter, or setting the value of the `MVK_CONFIG_DEBUG`
runtime environment variable to `1`. See the [*MoltenVK Configuration*](#moltenvk_config)
description above.

Expand Down Expand Up @@ -581,6 +585,20 @@ than when using an internal compositor, which increases the risk that a swapchai
vailable when you request it, resulting in frame delays and visual stuttering.


<a name="timestamping"></a>
### Timestamping

On non-Apple Silicon devices (older Mac devices), the GPU can switch power and performance
states as required by usage. This affects the GPU timestamps retrievable through the Vulkan
API. As a result, the value of `VkPhysicalDeviceLimits::timestampPeriod` can vary over time.
Consider calling `vkGetPhysicalDeviceProperties()`, when needed, and retrieve the current
value of `VkPhysicalDeviceLimits::timestampPeriod`, to help you calibrate recent GPU
timestamps queried through the Vulkan API.

This is not needed on Apple Silicon devices, where all GPU timestamps are always returned
as nanoseconds, regardless of variations in power and performance states as the app runs.


<a name="xcode_config"></a>
### Xcode Configuration

Expand Down
Loading

0 comments on commit 611ae64

Please sign in to comment.