moltenvk/Common/MVKOSExtensions.h

149 lines
5.4 KiB
C
Raw Normal View History

2017-11-17 11:14:29 -05:00
/*
* MVKOSExtensions.h
*
2023-01-13 12:19:37 -05:00
* Copyright (c) 2015-2023 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
#include "MVKCommonEnvironment.h"
#include <dispatch/dispatch.h>
#include <string>
#include <limits>
2017-11-17 11:14:29 -05:00
typedef float MVKOSVersion;
/*** 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
*/
MVKOSVersion mvkOSVersion();
/** Returns a MVKOSVersion built from the version components. */
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. */
static inline bool mvkOSVersionIsAtLeast(MVKOSVersion minVer) { return mvkOSVersion() >= minVer; }
2017-11-17 11:14:29 -05:00
/**
* Returns whether the operating system version is at least the appropriate min version.
* 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.
*/
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);
#endif
}
/**
* Returns a monotonic timestamp value for use in Vulkan and performance timestamping.
*
* The returned value corresponds to the number of CPU "ticks" since the app was initialized.
*
* Calling this value twice, subtracting the first value from the second, and then multiplying
* the result by the value returned by mvkGetTimestampPeriod() will provide an indication of the
* number of nanoseconds between the two calls. The convenience function mvkGetElapsedMilliseconds()
* can be used to perform this calculation.
*/
uint64_t mvkGetTimestamp();
/** Returns the number of nanoseconds between each increment of the value returned by mvkGetTimestamp(). */
double mvkGetTimestampPeriod();
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);
/**
* 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);
/** Returns the current absolute time in nanoseconds. */
uint64_t mvkGetAbsoluteTime();
/** Ensures the block is executed on the main thread. */
void mvkDispatchToMainAndWait(dispatch_block_t block);
2017-11-17 11:14:29 -05:00
#pragma mark -
#pragma mark Process environment
/**
* Sets the value of the environment variable at the given name, into the
* std::string, and returns whether the environment variable was found.
*/
bool mvkGetEnvVar(const char* evName, std::string& evStr);
/**
* 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.
*/
const char* mvkGetEnvVarString(const char* evName, std::string& evStr, const char* defaultValue = "");
/**
* Returns the value of the environment variable at the given name,
* or returns the default value if the environment variable was not set.
*/
double mvkGetEnvVarNumber(const char* evName, double defaultValue = 0.0);
#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();
/** Returns the size of a page of host memory on this platform. */
uint64_t mvkGetHostMemoryPageSize();
#pragma mark -
#pragma mark Threading
/** Returns the amount of avaliable CPU cores. */
uint32_t mvkGetAvaliableCPUCores();