2017-11-17 11:14:29 -05:00
|
|
|
/*
|
|
|
|
* MVKOSExtensions.h
|
|
|
|
*
|
2024-01-04 14:51:53 -05:00
|
|
|
* Copyright (c) 2015-2024 The Brenwill Workshop Ltd. (http://www.brenwill.com)
|
2017-11-17 11:14:29 -05:00
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2020-06-11 12:43:38 -04:00
|
|
|
#include "MVKCommonEnvironment.h"
|
2019-02-11 10:49:58 -05:00
|
|
|
#include <dispatch/dispatch.h>
|
2019-01-09 16:59:04 -05:00
|
|
|
#include <string>
|
2020-06-11 12:43:38 -04:00
|
|
|
#include <limits>
|
2017-11-17 11:14:29 -05:00
|
|
|
|
|
|
|
|
2023-12-02 19:20:31 -05:00
|
|
|
#pragma mark -
|
|
|
|
#pragma mark Operating System versions
|
|
|
|
|
2017-11-17 11:14:29 -05:00
|
|
|
typedef float MVKOSVersion;
|
|
|
|
|
2020-06-11 12:43:38 -04:00
|
|
|
/*** Constant indicating unsupported functionality in an OS. */
|
|
|
|
static const MVKOSVersion kMVKOSVersionUnsupported = std::numeric_limits<MVKOSVersion>::max();
|
|
|
|
|
2017-11-17 11:14:29 -05:00
|
|
|
/**
|
|
|
|
* Returns the operating system version as an MVKOSVersion, which is a float in which the
|
|
|
|
* whole number portion indicates the major version, and the fractional portion indicates
|
|
|
|
* the minor and patch versions, associating 2 decimal places to each.
|
|
|
|
* - (10.12.3) => 10.1203
|
|
|
|
* - (8.0.2) => 8.0002
|
|
|
|
*/
|
2020-03-28 20:11:21 -04:00
|
|
|
MVKOSVersion mvkOSVersion();
|
|
|
|
|
2020-06-11 12:43:38 -04:00
|
|
|
/** Returns a MVKOSVersion built from the version components. */
|
2023-09-06 16:16:11 -04:00
|
|
|
static inline MVKOSVersion mvkMakeOSVersion(uint32_t major, uint32_t minor, uint32_t patch) {
|
2020-06-11 12:43:38 -04:00
|
|
|
return (float)major + ((float)minor / 100.0f) + ((float)patch / 10000.0f);
|
|
|
|
}
|
|
|
|
|
2020-03-28 20:11:21 -04:00
|
|
|
/** Returns whether the operating system version is at least minVer. */
|
2023-09-06 16:16:11 -04:00
|
|
|
static inline bool mvkOSVersionIsAtLeast(MVKOSVersion minVer) { return mvkOSVersion() >= minVer; }
|
2017-11-17 11:14:29 -05:00
|
|
|
|
2020-06-11 12:43:38 -04:00
|
|
|
/**
|
|
|
|
* Returns whether the operating system version is at least the appropriate min version.
|
2023-09-06 16:16:11 -04:00
|
|
|
* The constant kMVKOSVersionUnsupported can be used for any of the values to cause the test
|
2023-09-07 09:33:40 -04:00
|
|
|
* to always fail on that OS, which is useful for indicating that functionalty guarded by
|
2020-06-11 12:43:38 -04:00
|
|
|
* this test is not supported on that OS.
|
|
|
|
*/
|
2023-09-06 16:16:11 -04:00
|
|
|
static inline bool mvkOSVersionIsAtLeast(MVKOSVersion macOSMinVer,
|
|
|
|
MVKOSVersion iOSMinVer,
|
|
|
|
MVKOSVersion visionOSMinVer) {
|
2020-06-11 12:43:38 -04:00
|
|
|
#if MVK_MACOS
|
|
|
|
return mvkOSVersionIsAtLeast(macOSMinVer);
|
|
|
|
#endif
|
2023-09-06 16:16:11 -04:00
|
|
|
#if MVK_IOS_OR_TVOS
|
|
|
|
return mvkOSVersionIsAtLeast(iOSMinVer);
|
|
|
|
#endif
|
2023-06-23 10:24:35 -04:00
|
|
|
#if MVK_VISIONOS
|
|
|
|
return mvkOSVersionIsAtLeast(visionOSMinVer);
|
2020-06-11 12:43:38 -04:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2023-12-02 19:20:31 -05:00
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
#pragma mark Timestamps
|
|
|
|
|
2018-02-24 19:51:43 -05:00
|
|
|
/**
|
2023-12-02 19:20:31 -05:00
|
|
|
* Returns a monotonic tick value for use in Vulkan and performance timestamping.
|
2018-02-24 19:51:43 -05:00
|
|
|
*
|
2023-12-02 19:20:31 -05:00
|
|
|
* The returned value corresponds to the number of CPU ticks since an arbitrary
|
|
|
|
* point in the past, and does not increment while the system is asleep.
|
2018-02-24 19:51:43 -05:00
|
|
|
*/
|
|
|
|
uint64_t mvkGetTimestamp();
|
|
|
|
|
2023-12-02 19:20:31 -05:00
|
|
|
/**
|
|
|
|
* Returns the number of runtime nanoseconds since an arbitrary point in the past,
|
|
|
|
* excluding any time spent while the system is asleep.
|
|
|
|
*
|
|
|
|
* This value corresponds to the timestamps returned by Metal presentation timings.
|
|
|
|
*/
|
|
|
|
uint64_t mvkGetRuntimeNanoseconds();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the number of nanoseconds since an arbitrary point in the past,
|
|
|
|
* including any time spent while the system is asleep.
|
|
|
|
*/
|
|
|
|
uint64_t mvkGetContinuousNanoseconds();
|
2018-02-24 19:51:43 -05:00
|
|
|
|
Support the `VK_EXT_pipeline_creation_feedback` extension.
This provides feedback that indicates:
* how long it took to compile each shader stage and the pipeline as a
whole;
* whether or not the pipeline or any shader stage were found in any
supplied pipeline cache; and
* whether or not any supplied base pipeline were used to accelerate
pipeline creation.
This is similar to the performance statistics that MoltenVK already
collects.
Since we don't use any supplied base pipeline at all, this
implementation never sets
`VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT`. However,
I've identified several places where we could probably use the base
pipeline to accelerate pipeline creation. One day, I should probably
implement that.
Likewise, because we don't yet support using `MTLBinaryArchive`s,
`VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT` is
never set on the whole pipeline, though it *is* set for individual
stages, on the assumption that any shader found in a cache is likely to
be found in Metal's own implicit cache.
In this implementation, shader stage compilation time includes any time
needed to build the `MTLComputePipelineState`s needed for vertex and
tessellation control shaders in tessellated pipelines.
This patch also changes compilation of the vertex stage
`MTLComputePipelineState`s in tessellated pipelines to be eager instead
of lazy. We really ought to have been doing this anyway, in order to
report pipeline failures at creation time instead of draw time. I'm not
happy, though, that we now pay the cost of all three pipeline states all
the time, instead of just the ones that are used.
This also gets rid of some fields of `MVKGraphicsPipeline` that were
only used during pipeline construction, which should save some memory,
particularly for apps that create lots of pipelines.
2023-07-07 00:25:37 -07:00
|
|
|
/**
|
|
|
|
* Returns the number of nanoseconds elapsed between startTimestamp and endTimestamp,
|
|
|
|
* each of which should be a value returned by mvkGetTimestamp().
|
|
|
|
* If endTimestamp is zero or not supplied, it is taken to be the current time.
|
|
|
|
* If startTimestamp is zero or not supplied, it is taken to be the time the app was initialized.
|
|
|
|
*/
|
|
|
|
uint64_t mvkGetElapsedNanoseconds(uint64_t startTimestamp = 0, uint64_t endTimestamp = 0);
|
|
|
|
|
2018-02-24 19:51:43 -05:00
|
|
|
/**
|
|
|
|
* Returns the number of milliseconds elapsed between startTimestamp and endTimestamp,
|
|
|
|
* each of which should be a value returned by mvkGetTimestamp().
|
|
|
|
* If endTimestamp is zero or not supplied, it is taken to be the current time.
|
|
|
|
* If startTimestamp is zero or not supplied, it is taken to be the time the app was initialized.
|
|
|
|
*/
|
|
|
|
double mvkGetElapsedMilliseconds(uint64_t startTimestamp = 0, uint64_t endTimestamp = 0);
|
|
|
|
|
2017-11-17 11:14:29 -05:00
|
|
|
|
2019-01-09 16:59:04 -05:00
|
|
|
#pragma mark -
|
|
|
|
#pragma mark Process environment
|
|
|
|
|
|
|
|
/**
|
2023-09-11 20:14:23 -04:00
|
|
|
* Sets the value of the environment variable at the given name, into the
|
|
|
|
* std::string, and returns whether the environment variable was found.
|
2019-01-09 16:59:04 -05:00
|
|
|
*/
|
2023-09-11 20:14:23 -04:00
|
|
|
bool mvkGetEnvVar(const char* evName, std::string& evStr);
|
2019-01-09 16:59:04 -05:00
|
|
|
|
|
|
|
/**
|
2023-09-11 20:14:23 -04:00
|
|
|
* 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.
|
2019-01-09 16:59:04 -05:00
|
|
|
*/
|
2023-09-11 20:14:23 -04:00
|
|
|
const char* mvkGetEnvVarString(const char* evName, std::string& evStr, const char* defaultValue = "");
|
2019-01-09 16:59:04 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the value of the environment variable at the given name,
|
2023-09-11 20:14:23 -04:00
|
|
|
* or returns the default value if the environment variable was not set.
|
2019-01-09 16:59:04 -05:00
|
|
|
*/
|
2023-09-11 20:14:23 -04:00
|
|
|
double mvkGetEnvVarNumber(const char* evName, double defaultValue = 0.0);
|
2020-04-22 16:24:38 -05:00
|
|
|
|
2019-08-08 14:53:19 -05:00
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
#pragma mark System memory
|
|
|
|
|
|
|
|
/** Returns the total amount of physical RAM in the system. */
|
|
|
|
uint64_t mvkGetSystemMemorySize();
|
|
|
|
|
|
|
|
/** Returns the amount of memory available to this process. */
|
|
|
|
uint64_t mvkGetAvailableMemorySize();
|
|
|
|
|
|
|
|
/** Returns the amount of memory currently used by this process. */
|
|
|
|
uint64_t mvkGetUsedMemorySize();
|
|
|
|
|
2023-03-19 22:53:36 -04:00
|
|
|
/** Returns the size of a page of host memory on this platform. */
|
|
|
|
uint64_t mvkGetHostMemoryPageSize();
|
2023-06-20 10:19:29 -04:00
|
|
|
|
2023-12-02 19:20:31 -05:00
|
|
|
|
2023-06-20 10:19:29 -04:00
|
|
|
#pragma mark -
|
|
|
|
#pragma mark Threading
|
|
|
|
|
|
|
|
/** Returns the amount of avaliable CPU cores. */
|
|
|
|
uint32_t mvkGetAvaliableCPUCores();
|
2023-12-02 19:20:31 -05:00
|
|
|
|
|
|
|
/** Ensures the block is executed on the main thread. */
|
|
|
|
void mvkDispatchToMainAndWait(dispatch_block_t block);
|