Skip to content

Commit

Permalink
Merge pull request #2086 from billhollings/VK_EXT_headless_surface
Browse files Browse the repository at this point in the history
Add support for extension VK_EXT_headless_surface.
  • Loading branch information
billhollings authored Dec 5, 2023
2 parents 8820c53 + 90eb1af commit e6a3886
Show file tree
Hide file tree
Showing 21 changed files with 312 additions and 236 deletions.
42 changes: 27 additions & 15 deletions Common/MVKOSExtensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
#include <limits>


#pragma mark -
#pragma mark Operating System versions

typedef float MVKOSVersion;

/*** Constant indicating unsupported functionality in an OS. */
Expand Down Expand Up @@ -66,20 +69,31 @@ static inline bool mvkOSVersionIsAtLeast(MVKOSVersion macOSMinVer,
#endif
}


#pragma mark -
#pragma mark Timestamps

/**
* Returns a monotonic timestamp value for use in Vulkan and performance timestamping.
* Returns a monotonic tick 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.
* 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.
*/
uint64_t mvkGetTimestamp();

/** Returns the number of nanoseconds between each increment of the value returned by mvkGetTimestamp(). */
double mvkGetTimestampPeriod();
/**
* 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();

/**
* Returns the number of nanoseconds elapsed between startTimestamp and endTimestamp,
Expand All @@ -97,12 +111,6 @@ uint64_t mvkGetElapsedNanoseconds(uint64_t startTimestamp = 0, uint64_t endTimes
*/
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);


#pragma mark -
#pragma mark Process environment
Expand Down Expand Up @@ -141,8 +149,12 @@ 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();

/** Ensures the block is executed on the main thread. */
void mvkDispatchToMainAndWait(dispatch_block_t block);
43 changes: 24 additions & 19 deletions Common/MVKOSExtensions.mm
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@

using namespace std;


#pragma mark -
#pragma mark Operating System versions

MVKOSVersion mvkOSVersion() {
static MVKOSVersion _mvkOSVersion = 0;
if ( !_mvkOSVersion ) {
Expand All @@ -38,43 +42,35 @@ MVKOSVersion mvkOSVersion() {
return _mvkOSVersion;
}

static uint64_t _mvkTimestampBase;
static double _mvkTimestampPeriod;

#pragma mark -
#pragma mark Timestamps

static mach_timebase_info_data_t _mvkMachTimebase;

uint64_t mvkGetTimestamp() { return mach_absolute_time() - _mvkTimestampBase; }
uint64_t mvkGetTimestamp() { return mach_absolute_time(); }

uint64_t mvkGetRuntimeNanoseconds() { return mach_absolute_time() * _mvkMachTimebase.numer / _mvkMachTimebase.denom; }

double mvkGetTimestampPeriod() { return _mvkTimestampPeriod; }
uint64_t mvkGetContinuousNanoseconds() { return mach_continuous_time() * _mvkMachTimebase.numer / _mvkMachTimebase.denom; }

uint64_t mvkGetElapsedNanoseconds(uint64_t startTimestamp, uint64_t endTimestamp) {
if (endTimestamp == 0) { endTimestamp = mvkGetTimestamp(); }
return (endTimestamp - startTimestamp) * _mvkTimestampPeriod;
return (endTimestamp - startTimestamp) * _mvkMachTimebase.numer / _mvkMachTimebase.denom;
}

double mvkGetElapsedMilliseconds(uint64_t startTimestamp, uint64_t endTimestamp) {
return mvkGetElapsedNanoseconds(startTimestamp, endTimestamp) / 1e6;
}

uint64_t mvkGetAbsoluteTime() { return mach_continuous_time() * _mvkMachTimebase.numer / _mvkMachTimebase.denom; }

// Initialize timestamping capabilities on app startup.
//Called automatically when the framework is loaded and initialized.
// Initialize timestamp capabilities on app startup.
// Called automatically when the framework is loaded and initialized.
static bool _mvkTimestampsInitialized = false;
__attribute__((constructor)) static void MVKInitTimestamps() {
if (_mvkTimestampsInitialized ) { return; }
_mvkTimestampsInitialized = true;

_mvkTimestampBase = mach_absolute_time();
mach_timebase_info(&_mvkMachTimebase);
_mvkTimestampPeriod = (double)_mvkMachTimebase.numer / (double)_mvkMachTimebase.denom;
}

void mvkDispatchToMainAndWait(dispatch_block_t block) {
if (NSThread.isMainThread) {
block();
} else {
dispatch_sync(dispatch_get_main_queue(), block);
}
}


Expand Down Expand Up @@ -145,10 +141,19 @@ uint64_t mvkGetUsedMemorySize() {

uint64_t mvkGetHostMemoryPageSize() { return sysconf(_SC_PAGESIZE); }


#pragma mark -
#pragma mark Threading

/** Returns the amount of avaliable CPU cores. */
uint32_t mvkGetAvaliableCPUCores() {
return (uint32_t)[[NSProcessInfo processInfo] activeProcessorCount];
}

void mvkDispatchToMainAndWait(dispatch_block_t block) {
if (NSThread.isMainThread) {
block();
} else {
dispatch_sync(dispatch_get_main_queue(), block);
}
}
3 changes: 3 additions & 0 deletions Docs/MoltenVK_Runtime_UserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,9 @@ In addition to core *Vulkan* functionality, **MoltenVK** also supports the foll
- `VK_EXT_external_memory_host`
- `VK_EXT_fragment_shader_interlock`
- *Requires Metal 2.0 and Raster Order Groups.*
- `VK_EXT_hdr_metadata`
- *macOS only.*
- `VK_EXT_headless_surface`
- `VK_EXT_host_query_reset`
- `VK_EXT_image_robustness`
- `VK_EXT_inline_uniform_block`
Expand Down
2 changes: 2 additions & 0 deletions Docs/Whats_New.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ Released TBD

- Add support for extensions:
- `VK_EXT_extended_dynamic_state3` *(Metal does not support `VK_POLYGON_MODE_POINT`)*
- `VK_EXT_headless_surface`
- Fix regression that broke `VK_POLYGON_MODE_LINE`.
- Fix regression in marking rendering state dirty after `vkCmdClearAttachments()`.
- Reduce disk space consumed after running `fetchDependencies` script by removing intermediate file caches.
- Fix rare deadlock during launch via `dlopen()`.
- Fix initial value of `VkPhysicalDeviceLimits::timestampPeriod` on non-Apple Silicon GPUs.
- Fix swapchain and surface bugs when windowing system is accessed from off the main thread.
- Update to latest SPIRV-Cross:
- MSL: Fix regression error in argument buffer runtime arrays.
- MSL: Work around broken cube texture gradients on Apple Silicon.
Expand Down
20 changes: 10 additions & 10 deletions MoltenVK/MoltenVK.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@
2FEA0AAF24902F9F00EEF3AD /* MVKLayers.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7A11C7DFB4800632CA3 /* MVKLayers.mm */; };
2FEA0AB024902F9F00EEF3AD /* MVKFramebuffer.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7881C7DFB4800632CA3 /* MVKFramebuffer.mm */; };
2FEA0AB124902F9F00EEF3AD /* MVKMTLBufferAllocation.mm in Sources */ = {isa = PBXBuildFile; fileRef = A9C96DCF1DDC20C20053187F /* MVKMTLBufferAllocation.mm */; };
2FEA0AB224902F9F00EEF3AD /* CAMetalLayer+MoltenVK.m in Sources */ = {isa = PBXBuildFile; fileRef = A9E53DD62100B197002781DD /* CAMetalLayer+MoltenVK.m */; };
2FEA0AB224902F9F00EEF3AD /* CAMetalLayer+MoltenVK.mm in Sources */ = {isa = PBXBuildFile; fileRef = A9E53DD62100B197002781DD /* CAMetalLayer+MoltenVK.mm */; };
2FEA0AB324902F9F00EEF3AD /* MVKCmdDispatch.mm in Sources */ = {isa = PBXBuildFile; fileRef = A9096E5D1F81E16300DFBEA6 /* MVKCmdDispatch.mm */; };
2FEA0AB424902F9F00EEF3AD /* MVKCmdDebug.mm in Sources */ = {isa = PBXBuildFile; fileRef = A99C90ED229455B300A061DA /* MVKCmdDebug.mm */; };
45003E73214AD4E500E989CB /* MVKExtensions.def in Headers */ = {isa = PBXBuildFile; fileRef = 45003E6F214AD4C900E989CB /* MVKExtensions.def */; };
Expand Down Expand Up @@ -360,8 +360,8 @@
A9E53DE62100B197002781DD /* NSString+MoltenVK.mm in Sources */ = {isa = PBXBuildFile; fileRef = A9E53DD42100B197002781DD /* NSString+MoltenVK.mm */; };
A9E53DE72100B197002781DD /* MTLTextureDescriptor+MoltenVK.m in Sources */ = {isa = PBXBuildFile; fileRef = A9E53DD52100B197002781DD /* MTLTextureDescriptor+MoltenVK.m */; };
A9E53DE82100B197002781DD /* MTLTextureDescriptor+MoltenVK.m in Sources */ = {isa = PBXBuildFile; fileRef = A9E53DD52100B197002781DD /* MTLTextureDescriptor+MoltenVK.m */; };
A9E53DE92100B197002781DD /* CAMetalLayer+MoltenVK.m in Sources */ = {isa = PBXBuildFile; fileRef = A9E53DD62100B197002781DD /* CAMetalLayer+MoltenVK.m */; };
A9E53DEA2100B197002781DD /* CAMetalLayer+MoltenVK.m in Sources */ = {isa = PBXBuildFile; fileRef = A9E53DD62100B197002781DD /* CAMetalLayer+MoltenVK.m */; };
A9E53DE92100B197002781DD /* CAMetalLayer+MoltenVK.mm in Sources */ = {isa = PBXBuildFile; fileRef = A9E53DD62100B197002781DD /* CAMetalLayer+MoltenVK.mm */; };
A9E53DEA2100B197002781DD /* CAMetalLayer+MoltenVK.mm in Sources */ = {isa = PBXBuildFile; fileRef = A9E53DD62100B197002781DD /* CAMetalLayer+MoltenVK.mm */; };
A9E53DF32100B302002781DD /* MTLRenderPassDescriptor+MoltenVK.h in Headers */ = {isa = PBXBuildFile; fileRef = A9E53DEE2100B302002781DD /* MTLRenderPassDescriptor+MoltenVK.h */; };
A9E53DF42100B302002781DD /* MTLRenderPassDescriptor+MoltenVK.h in Headers */ = {isa = PBXBuildFile; fileRef = A9E53DEE2100B302002781DD /* MTLRenderPassDescriptor+MoltenVK.h */; };
A9E53DF52100B302002781DD /* MTLRenderPassDescriptor+MoltenVK.m in Sources */ = {isa = PBXBuildFile; fileRef = A9E53DF22100B302002781DD /* MTLRenderPassDescriptor+MoltenVK.m */; };
Expand Down Expand Up @@ -495,7 +495,7 @@
DCFD7F572A45BC6E007BBBF7 /* MVKFramebuffer.mm in Sources */ = {isa = PBXBuildFile; fileRef = A94FB7881C7DFB4800632CA3 /* MVKFramebuffer.mm */; };
DCFD7F582A45BC6E007BBBF7 /* MTLRenderPassStencilAttachmentDescriptor+MoltenVK.m in Sources */ = {isa = PBXBuildFile; fileRef = 453638302508A4C6000EFFD3 /* MTLRenderPassStencilAttachmentDescriptor+MoltenVK.m */; };
DCFD7F592A45BC6E007BBBF7 /* MVKMTLBufferAllocation.mm in Sources */ = {isa = PBXBuildFile; fileRef = A9C96DCF1DDC20C20053187F /* MVKMTLBufferAllocation.mm */; };
DCFD7F5A2A45BC6E007BBBF7 /* CAMetalLayer+MoltenVK.m in Sources */ = {isa = PBXBuildFile; fileRef = A9E53DD62100B197002781DD /* CAMetalLayer+MoltenVK.m */; };
DCFD7F5A2A45BC6E007BBBF7 /* CAMetalLayer+MoltenVK.mm in Sources */ = {isa = PBXBuildFile; fileRef = A9E53DD62100B197002781DD /* CAMetalLayer+MoltenVK.mm */; };
DCFD7F5B2A45BC6E007BBBF7 /* MVKCmdDispatch.mm in Sources */ = {isa = PBXBuildFile; fileRef = A9096E5D1F81E16300DFBEA6 /* MVKCmdDispatch.mm */; };
DCFD7F5C2A45BC6E007BBBF7 /* MVKCmdDebug.mm in Sources */ = {isa = PBXBuildFile; fileRef = A99C90ED229455B300A061DA /* MVKCmdDebug.mm */; };
/* End PBXBuildFile section */
Expand Down Expand Up @@ -691,7 +691,7 @@
A9E53DD32100B197002781DD /* MTLSamplerDescriptor+MoltenVK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MTLSamplerDescriptor+MoltenVK.h"; sourceTree = "<group>"; };
A9E53DD42100B197002781DD /* NSString+MoltenVK.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSString+MoltenVK.mm"; sourceTree = "<group>"; };
A9E53DD52100B197002781DD /* MTLTextureDescriptor+MoltenVK.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MTLTextureDescriptor+MoltenVK.m"; sourceTree = "<group>"; };
A9E53DD62100B197002781DD /* CAMetalLayer+MoltenVK.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CAMetalLayer+MoltenVK.m"; sourceTree = "<group>"; };
A9E53DD62100B197002781DD /* CAMetalLayer+MoltenVK.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "CAMetalLayer+MoltenVK.mm"; sourceTree = "<group>"; };
A9E53DEE2100B302002781DD /* MTLRenderPassDescriptor+MoltenVK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MTLRenderPassDescriptor+MoltenVK.h"; sourceTree = "<group>"; };
A9E53DF22100B302002781DD /* MTLRenderPassDescriptor+MoltenVK.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MTLRenderPassDescriptor+MoltenVK.m"; sourceTree = "<group>"; };
A9E53DFA21064F84002781DD /* MTLRenderPipelineDescriptor+MoltenVK.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MTLRenderPipelineDescriptor+MoltenVK.m"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -889,7 +889,7 @@
isa = PBXGroup;
children = (
A9E53DD12100B197002781DD /* CAMetalLayer+MoltenVK.h */,
A9E53DD62100B197002781DD /* CAMetalLayer+MoltenVK.m */,
A9E53DD62100B197002781DD /* CAMetalLayer+MoltenVK.mm */,
453638312508A4C7000EFFD3 /* MTLRenderPassDepthAttachmentDescriptor+MoltenVK.h */,
4536382F2508A4C6000EFFD3 /* MTLRenderPassDepthAttachmentDescriptor+MoltenVK.m */,
A9E53DEE2100B302002781DD /* MTLRenderPassDescriptor+MoltenVK.h */,
Expand Down Expand Up @@ -1703,7 +1703,7 @@
2FEA0AAF24902F9F00EEF3AD /* MVKLayers.mm in Sources */,
2FEA0AB024902F9F00EEF3AD /* MVKFramebuffer.mm in Sources */,
2FEA0AB124902F9F00EEF3AD /* MVKMTLBufferAllocation.mm in Sources */,
2FEA0AB224902F9F00EEF3AD /* CAMetalLayer+MoltenVK.m in Sources */,
2FEA0AB224902F9F00EEF3AD /* CAMetalLayer+MoltenVK.mm in Sources */,
2FEA0AB324902F9F00EEF3AD /* MVKCmdDispatch.mm in Sources */,
2FEA0AB424902F9F00EEF3AD /* MVKCmdDebug.mm in Sources */,
);
Expand Down Expand Up @@ -1763,7 +1763,7 @@
A94FB7EE1C7DFB4800632CA3 /* MVKFramebuffer.mm in Sources */,
453638382508A4C7000EFFD3 /* MTLRenderPassStencilAttachmentDescriptor+MoltenVK.m in Sources */,
A9C96DD21DDC20C20053187F /* MVKMTLBufferAllocation.mm in Sources */,
A9E53DE92100B197002781DD /* CAMetalLayer+MoltenVK.m in Sources */,
A9E53DE92100B197002781DD /* CAMetalLayer+MoltenVK.mm in Sources */,
A9096E5E1F81E16300DFBEA6 /* MVKCmdDispatch.mm in Sources */,
A99C90F0229455B300A061DA /* MVKCmdDebug.mm in Sources */,
);
Expand Down Expand Up @@ -1823,7 +1823,7 @@
A94FB7EF1C7DFB4800632CA3 /* MVKFramebuffer.mm in Sources */,
4536383A2508A4C7000EFFD3 /* MTLRenderPassStencilAttachmentDescriptor+MoltenVK.m in Sources */,
A9C96DD31DDC20C20053187F /* MVKMTLBufferAllocation.mm in Sources */,
A9E53DEA2100B197002781DD /* CAMetalLayer+MoltenVK.m in Sources */,
A9E53DEA2100B197002781DD /* CAMetalLayer+MoltenVK.mm in Sources */,
A9096E5F1F81E16300DFBEA6 /* MVKCmdDispatch.mm in Sources */,
A99C90F1229455B300A061DA /* MVKCmdDebug.mm in Sources */,
);
Expand Down Expand Up @@ -1883,7 +1883,7 @@
DCFD7F572A45BC6E007BBBF7 /* MVKFramebuffer.mm in Sources */,
DCFD7F582A45BC6E007BBBF7 /* MTLRenderPassStencilAttachmentDescriptor+MoltenVK.m in Sources */,
DCFD7F592A45BC6E007BBBF7 /* MVKMTLBufferAllocation.mm in Sources */,
DCFD7F5A2A45BC6E007BBBF7 /* CAMetalLayer+MoltenVK.m in Sources */,
DCFD7F5A2A45BC6E007BBBF7 /* CAMetalLayer+MoltenVK.mm in Sources */,
DCFD7F5B2A45BC6E007BBBF7 /* MVKCmdDispatch.mm in Sources */,
DCFD7F5C2A45BC6E007BBBF7 /* MVKCmdDebug.mm in Sources */,
);
Expand Down
27 changes: 10 additions & 17 deletions MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1202,8 +1202,8 @@
isHeadless = getMTLDevice().isHeadless;
#endif

// If this device is headless or the surface does not have a CAMetalLayer, it is not supported.
*pSupported = !(isHeadless || (surface->getCAMetalLayer() == nil));
// If this device is headless, the surface must be headless.
*pSupported = isHeadless ? surface->isHeadless() : wasConfigurationSuccessful();
return *pSupported ? VK_SUCCESS : surface->getConfigurationResult();
}

Expand Down Expand Up @@ -1262,13 +1262,12 @@

// The CAlayer underlying the surface must be a CAMetalLayer.
MVKSurface* surface = (MVKSurface*)pSurfaceInfo->surface;
CAMetalLayer* mtlLayer = surface->getCAMetalLayer();
if ( !mtlLayer ) { return surface->getConfigurationResult(); }
if ( !surface->wasConfigurationSuccessful() ) { return surface->getConfigurationResult(); }

VkSurfaceCapabilitiesKHR& surfCaps = pSurfaceCapabilities->surfaceCapabilities;
surfCaps.minImageCount = _metalFeatures.minSwapchainImageCount;
surfCaps.maxImageCount = _metalFeatures.maxSwapchainImageCount;
surfCaps.currentExtent = mvkGetNaturalExtent(mtlLayer);
surfCaps.currentExtent = surface->getNaturalExtent();
surfCaps.minImageExtent = { 1, 1 };
surfCaps.maxImageExtent = { _properties.limits.maxImageDimension2D, _properties.limits.maxImageDimension2D };
surfCaps.maxImageArrayLayers = 1;
Expand Down Expand Up @@ -1347,9 +1346,7 @@
uint32_t* pCount,
VkSurfaceFormatKHR* pSurfaceFormats) {

// The layer underlying the surface view must be a CAMetalLayer.
CAMetalLayer* mtlLayer = surface->getCAMetalLayer();
if ( !mtlLayer ) { return surface->getConfigurationResult(); }
if ( !surface->wasConfigurationSuccessful() ) { return surface->getConfigurationResult(); }

#define addSurfFmt(MTL_FMT) \
do { \
Expand Down Expand Up @@ -1472,9 +1469,7 @@
uint32_t* pCount,
VkPresentModeKHR* pPresentModes) {

// The layer underlying the surface view must be a CAMetalLayer.
CAMetalLayer* mtlLayer = surface->getCAMetalLayer();
if ( !mtlLayer ) { return surface->getConfigurationResult(); }
if ( !surface->wasConfigurationSuccessful() ) { return surface->getConfigurationResult(); }

#define ADD_VK_PRESENT_MODE(VK_PM) \
do { \
Expand Down Expand Up @@ -1502,9 +1497,7 @@
uint32_t* pRectCount,
VkRect2D* pRects) {

// The layer underlying the surface view must be a CAMetalLayer.
CAMetalLayer* mtlLayer = surface->getCAMetalLayer();
if ( !mtlLayer ) { return surface->getConfigurationResult(); }
if ( !surface->wasConfigurationSuccessful() ) { return surface->getConfigurationResult(); }

if ( !pRects ) {
*pRectCount = 1;
Expand All @@ -1516,7 +1509,7 @@
*pRectCount = 1;

pRects[0].offset = { 0, 0 };
pRects[0].extent = mvkGetNaturalExtent(mtlLayer);
pRects[0].extent = surface->getNaturalExtent();

return VK_SUCCESS;
}
Expand Down Expand Up @@ -3672,14 +3665,14 @@ static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef prope
MTLTimestamp cpuStamp, gpuStamp;
uint64_t cpuStart, cpuEnd;

cpuStart = mvkGetAbsoluteTime();
cpuStart = mvkGetContinuousNanoseconds();
[getMTLDevice() sampleTimestamps: &cpuStamp gpuTimestamp: &gpuStamp];
// Sample again to calculate the maximum deviation. Note that the
// -[MTLDevice sampleTimestamps:gpuTimestamp:] method guarantees that CPU
// timestamps are in nanoseconds. We don't want to call the method again,
// because that could result in an expensive syscall to query the GPU time-
// stamp.
cpuEnd = mvkGetAbsoluteTime();
cpuEnd = mvkGetContinuousNanoseconds();
for (uint32_t tsIdx = 0; tsIdx < timestampCount; ++tsIdx) {
switch (pTimestampInfos[tsIdx].timeDomain) {
case VK_TIME_DOMAIN_DEVICE_EXT:
Expand Down
Loading

0 comments on commit e6a3886

Please sign in to comment.