Merge pull request #570 from billhollings/master

Update dependency libraries for SDK 1.1.106.
This commit is contained in:
Bill Hollings 2019-04-11 18:41:18 -04:00 committed by GitHub
commit d57704b69f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 2679 additions and 2512 deletions

View File

@ -18,8 +18,6 @@
#pragma once
#include "mvk_vulkan.h"
#include "MVKFoundation.h"
#include <dispatch/dispatch.h>
#include <string>
@ -111,32 +109,5 @@ bool mvkGetEnvVarBool(std::string varName, bool* pWasFound = nullptr);
bool wasFound = false; \
int64_t ev = mvkGetEnvVarInt64(#EV, &wasFound); \
int64_t val = wasFound ? ev : EV; \
cfgVal = (int32_t)mvkClamp(val, (int64_t)INT32_MIN, (int64_t)INT32_MAX); \
cfgVal = (int32_t)std::min(std::max(val, (int64_t)INT32_MIN), (int64_t)INT32_MAX); \
} while(false)
#ifdef __OBJC__
#import <Metal/Metal.h>
#pragma mark -
#pragma mark MTLDevice
/** Returns an approximation of how much memory, in bytes, the device can use with good performance. */
uint64_t mvkRecommendedMaxWorkingSetSize(id<MTLDevice> mtlDevice);
/** Populate the propertes with info about the GPU represented by the MTLDevice. */
void mvkPopulateGPUInfo(VkPhysicalDeviceProperties& devProps, id<MTLDevice> mtlDevice);
/** Returns the registry ID of the specified device, or zero if the device does not have a registry ID. */
uint64_t mvkGetRegistryID(id<MTLDevice> mtlDevice);
/**
* If the MTLDevice defines a texture memory alignment for the format, it is retrieved from
* the MTLDevice and returned, or returns zero if the MTLDevice does not define an alignment.
* The format must support linear texture memory (must not be depth, stencil, or compressed).
*/
VkDeviceSize mvkMTLPixelFormatLinearTextureAlignment(MTLPixelFormat mtlPixelFormat, id<MTLDevice> mtlDevice);
#endif // __OBJC__

96
Common/MVKOSExtensions.mm Normal file
View File

@ -0,0 +1,96 @@
/*
* MVKOSExtensions.mm
*
* Copyright (c) 2014-2019 The Brenwill Workshop Ltd. (http://www.brenwill.com)
*
* 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.
*/
#include "MVKOSExtensions.h"
#include "MVKLogging.h"
#include <mach/mach_time.h>
#import <Foundation/Foundation.h>
using namespace std;
static const MVKOSVersion kMVKOSVersionUnknown = 0.0f;
static MVKOSVersion _mvkOSVersion = kMVKOSVersionUnknown;
MVKOSVersion mvkOSVersion() {
if (_mvkOSVersion == kMVKOSVersionUnknown) {
NSOperatingSystemVersion osVer = [[NSProcessInfo processInfo] operatingSystemVersion];
float maj = osVer.majorVersion;
float min = osVer.minorVersion;
float pat = osVer.patchVersion;
_mvkOSVersion = maj + (min / 100.0f) + + (pat / 10000.0f);
}
return _mvkOSVersion;
}
static uint64_t _mvkTimestampBase;
static double _mvkTimestampPeriod;
uint64_t mvkGetTimestamp() { return mach_absolute_time() - _mvkTimestampBase; }
double mvkGetTimestampPeriod() { return _mvkTimestampPeriod; }
double mvkGetElapsedMilliseconds(uint64_t startTimestamp, uint64_t endTimestamp) {
if (endTimestamp == 0) { endTimestamp = mvkGetTimestamp(); }
return (double)(endTimestamp - startTimestamp) * _mvkTimestampPeriod / 1e6;
}
/**
* Initialize timestamping 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_data_t timebase;
mach_timebase_info(&timebase);
_mvkTimestampPeriod = (double)timebase.numer / (double)timebase.denom;
MVKLogDebug("Initializing MoltenVK timestamping. Mach time: %llu. Time period: %d / %d = %.6f.",
_mvkTimestampBase, timebase.numer, timebase.denom, _mvkTimestampPeriod);
}
void mvkDispatchToMainAndWait(dispatch_block_t block) {
if (NSThread.isMainThread) {
block();
} else {
dispatch_sync(dispatch_get_main_queue(), block);
}
}
#pragma mark -
#pragma mark Process environment
string mvkGetEnvVar(string varName, bool* pWasFound) {
NSDictionary* env = [[NSProcessInfo processInfo] environment];
NSString* envStr = env[@(varName.c_str())];
if (pWasFound) { *pWasFound = envStr != nil; }
return envStr ? envStr.UTF8String : "";
}
int64_t mvkGetEnvVarInt64(string varName, bool* pWasFound) {
return strtoll(mvkGetEnvVar(varName, pWasFound).c_str(), NULL, 0);
}
bool mvkGetEnvVarBool(std::string varName, bool* pWasFound) {
return mvkGetEnvVarInt64(varName, pWasFound) != 0;
}

View File

@ -16,21 +16,20 @@ For best results, use a Markdown reader.*
MoltenVK 1.0.34
---------------
Released TBD
Released 2019-04-12
- Add support for tessellation.
- Add correct function entry point handling.
- Add support for `VK_KHR_get_surface_capabilities2` extension.
- Implement newer `VK_KHR_swapchain` extension functions.
- Support the `VK_EXT_host_query_reset` extension.
- Add support for tracking device features enabled during `vkCreateDevice()`.
- Handle surface loss due to window moved between screens or a window style change.
- Allow zero offset and stride combo in `VkVertexInputBindingDescription`.
- API: Add MVKPhysicalDeviceMetalFeatures::depthSampleCompare.
- API: Add `MVKPhysicalDeviceMetalFeatures::depthSampleCompare`.
- Fix conditions under which functions return `VK_INCOMPLETE`.
- Fix potential memory leak on synchronous command buffer submission.
- Increase shader float constant accuracy beyond 6 digits of precision.
- MoltenVKShaderConverter tool support cs & csh for compute shader file extensions.
- MoltenVKShaderConverter tool validates converted MSL with a test compilation.
- `fetchDependencies`: Stop on first error.
- Clean up behaviour of sparse binding functions.
- Fix a possible race condition around `MVKMTLBufferAllocation`.
@ -39,32 +38,61 @@ Released TBD
- Fix wrong offset for `vkCmdFillBuffer()` on `VK_WHOLE_SIZE`.
- Fixed crash within `MVKPushConstantsCommandEncoderState` when accessing absent
graphics pipeline during a compute stage.
- Fixed crash when `MTLRenderPassDescriptor renderTargetWidth` & `renderTargetHeight`
set on older devices.
- Renderpass width/height clamped to the `renderArea` includes `offset`, not just `extent`,
and are set only when layered rendering is supported on device.
- Set options properly on a buffer view's `MTLTextureDescriptor`.
- Don't set `MTLSamplerDescriptor.compareFunction` on devices that don't support it.
- Disable the `shaderStorageImageArrayDynamicIndexing` feature on iOS.
- Debug build mode includes `dSYM` file for each `dylib` file.
- Explicitly build dSYM files in `BUILT_PRODUCTS_DIR` to avoid conflict between
macOS and iOS build locations.
- `Makefile` supports `install` target to install `MoltenVK.framework`
- `Makefile` supports `install` target to install `MoltenVK.framework`.
into `/Library/Frameworks/`.
- Add `MVK_CONFIG_TRACE_VULKAN_CALLS` env var and build setting to log Vulkan calls made by application.
- Log shader performance statistics in any runtime if `MVKConfiguration::performanceLoggingFrameCount` non-zero.
- Suppress visibility warning spam when building Debug macOS from SPIRV-Cross Release build.
- Support Xcode 10.2.
- Update `VK_MVK_MOLTENVK_SPEC_VERSION` to 19.
- MoltenVKShaderConverter tool:
- Support `cs` & `csh` for compute shader file extensions.
- Validate converted MSL with a test compilation.
- Add option to log shader conversion performance.
- Update to latest SPIRV-Cross version:
- MSL: Add support for Metal 2 indirect argument buffers.
- MSL: Add support for tessellation control & evaluation shaders.
- MSL: Support `VK_KHR_push_descriptor`.
- MSL: Force unnamed array builtin attributes to have a name.
- MSL: Set location of builtins based on client input.
- MSL: Ignore duplicate builtin vertex attributes.
- MSL: Fix crash where variable storage buffer pointers are passed down.
- MSL: Fix depth2d 4-component fixup.
- MSL: Fix infinite CAS loop on atomic_compare_exchange_weak_explicit().
- MSL: Fix `depth2d` 4-component fixup.
- MSL: Expand quad `gl_TessCoord` to a float3.
- MSL: Fix depth textures which are sampled and compared against.
- MSL: Emit proper name for optimized UBO/SSBO arrays.
- MSL: Support emit two layers of address space.
- MSL: Declare `gl_WorkGroupSize` constant with `[[maybe_unused]]`.
- MSL: Fix OpLoad of array which is forced to a temporary.
- Add stable C API and ABI.
- Performance improvements & reduce pressure on global allocation.
- Fix case where a struct is loaded which contains a row-major matrix.
- Fix edge case where opaque types can be declared on stack.
- Ensure locale handling is safe for multi-threading.
- Add support for sanitizing address and threads.
- Add support for `SPV_NV_ray_tracing`.
- Support -1 index in `OpVectorShuffle`.
- Deal more flexibly with for-loop & while-loop variations.
- Detect invalid DoWhileLoop early.
- Force complex loop in certain rare access chain scenarios.
- Make locale handling threadsafe.
- Support do-while where test is negative.
- Emit loop header variables even for while and dowhile.
- Properly deal with sign-dependent GLSL opcodes.
- Deal with mismatched signs in S/U/F conversion opcodes.
- Rewrite how we deal with locales and decimal point.
- Fix crash when `backend.int16_t_literal_suffix` set to null.
- Introduce customizable SPIRV-Cross namespaces and use `MVK_spirv_cross` in MoltenVK.

File diff suppressed because it is too large Load Diff

View File

@ -1 +1 @@
4395339586c2eebc08e602d307aa5e750b736533
ac5a9570a744eb72725c23c34f36fbc564c0bb51

View File

@ -1 +1 @@
ebcf66aa429eceb3360008878fe2881c7f5b2b20
08cbb5458f692d4778806775f65eb3dc642ddbbf

View File

@ -1 +1 @@
d43b22f0859f42c5fd71a530278ffa504ce95b7f
2abb69904b9ad017d39d3da1e7fc3dec1a584cd8

View File

@ -1 +1 @@
9ce6ece9d86b9501c1a8a4adbd4e0e60a5ae8456
07b1ccd82ff6b7e6369a0d8d6a5e5e4f7ba0b7d6

View File

@ -1 +1 @@
5432f0dd8f331f15182681664d7486681e8514e6
e06c7e9a515b716c731bda13f507546f107775d1

View File

@ -179,6 +179,10 @@
A98149641FB6A3F7005F00B4 /* MVKWatermarkTextureContent.h in Headers */ = {isa = PBXBuildFile; fileRef = A981494C1FB6A3F7005F00B4 /* MVKWatermarkTextureContent.h */; };
A981496B1FB6A998005F00B4 /* MVKStrings.h in Headers */ = {isa = PBXBuildFile; fileRef = A981496A1FB6A998005F00B4 /* MVKStrings.h */; };
A981496C1FB6A998005F00B4 /* MVKStrings.h in Headers */ = {isa = PBXBuildFile; fileRef = A981496A1FB6A998005F00B4 /* MVKStrings.h */; };
A9B51BD7225E986A00AC74D2 /* MVKOSExtensions.mm in Sources */ = {isa = PBXBuildFile; fileRef = A9B51BD2225E986A00AC74D2 /* MVKOSExtensions.mm */; };
A9B51BD8225E986A00AC74D2 /* MVKOSExtensions.mm in Sources */ = {isa = PBXBuildFile; fileRef = A9B51BD2225E986A00AC74D2 /* MVKOSExtensions.mm */; };
A9B51BD9225E986A00AC74D2 /* MVKOSExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = A9B51BD6225E986A00AC74D2 /* MVKOSExtensions.h */; };
A9B51BDA225E986A00AC74D2 /* MVKOSExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = A9B51BD6225E986A00AC74D2 /* MVKOSExtensions.h */; };
A9C96DD01DDC20C20053187F /* MVKMTLBufferAllocation.h in Headers */ = {isa = PBXBuildFile; fileRef = A9C96DCE1DDC20C20053187F /* MVKMTLBufferAllocation.h */; };
A9C96DD11DDC20C20053187F /* MVKMTLBufferAllocation.h in Headers */ = {isa = PBXBuildFile; fileRef = A9C96DCE1DDC20C20053187F /* MVKMTLBufferAllocation.h */; };
A9C96DD21DDC20C20053187F /* MVKMTLBufferAllocation.mm in Sources */ = {isa = PBXBuildFile; fileRef = A9C96DCF1DDC20C20053187F /* MVKMTLBufferAllocation.mm */; };
@ -189,10 +193,6 @@
A9E4B78A1E1D8AF10046A4CE /* MVKMTLResourceBindings.h in Headers */ = {isa = PBXBuildFile; fileRef = A9E4B7881E1D8AF10046A4CE /* MVKMTLResourceBindings.h */; };
A9E53DD72100B197002781DD /* MTLSamplerDescriptor+MoltenVK.m in Sources */ = {isa = PBXBuildFile; fileRef = A9E53DCD2100B197002781DD /* MTLSamplerDescriptor+MoltenVK.m */; };
A9E53DD82100B197002781DD /* MTLSamplerDescriptor+MoltenVK.m in Sources */ = {isa = PBXBuildFile; fileRef = A9E53DCD2100B197002781DD /* MTLSamplerDescriptor+MoltenVK.m */; };
A9E53DD92100B197002781DD /* MVKOSExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = A9E53DCE2100B197002781DD /* MVKOSExtensions.h */; };
A9E53DDA2100B197002781DD /* MVKOSExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = A9E53DCE2100B197002781DD /* MVKOSExtensions.h */; };
A9E53DDB2100B197002781DD /* MVKOSExtensions.mm in Sources */ = {isa = PBXBuildFile; fileRef = A9E53DCF2100B197002781DD /* MVKOSExtensions.mm */; };
A9E53DDC2100B197002781DD /* MVKOSExtensions.mm in Sources */ = {isa = PBXBuildFile; fileRef = A9E53DCF2100B197002781DD /* MVKOSExtensions.mm */; };
A9E53DDD2100B197002781DD /* MTLTextureDescriptor+MoltenVK.h in Headers */ = {isa = PBXBuildFile; fileRef = A9E53DD02100B197002781DD /* MTLTextureDescriptor+MoltenVK.h */; };
A9E53DDE2100B197002781DD /* MTLTextureDescriptor+MoltenVK.h in Headers */ = {isa = PBXBuildFile; fileRef = A9E53DD02100B197002781DD /* MTLTextureDescriptor+MoltenVK.h */; };
A9E53DDF2100B197002781DD /* CAMetalLayer+MoltenVK.h in Headers */ = {isa = PBXBuildFile; fileRef = A9E53DD12100B197002781DD /* CAMetalLayer+MoltenVK.h */; };
@ -363,6 +363,8 @@
A981494C1FB6A3F7005F00B4 /* MVKWatermarkTextureContent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKWatermarkTextureContent.h; sourceTree = "<group>"; };
A981496A1FB6A998005F00B4 /* MVKStrings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKStrings.h; sourceTree = "<group>"; };
A9AD67C72054DD6C00ED3C08 /* vulkan */ = {isa = PBXFileReference; lastKnownFileType = folder; path = vulkan; sourceTree = "<group>"; };
A9B51BD2225E986A00AC74D2 /* MVKOSExtensions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKOSExtensions.mm; sourceTree = "<group>"; };
A9B51BD6225E986A00AC74D2 /* MVKOSExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKOSExtensions.h; sourceTree = "<group>"; };
A9B8EE0A1A98D796009C5A02 /* libMoltenVK.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libMoltenVK.a; sourceTree = BUILT_PRODUCTS_DIR; };
A9C86CB61C55B8350096CAF2 /* MoltenVKShaderConverter.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = MoltenVKShaderConverter.xcodeproj; path = ../MoltenVKShaderConverter/MoltenVKShaderConverter.xcodeproj; sourceTree = "<group>"; };
A9C96DCE1DDC20C20053187F /* MVKMTLBufferAllocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKMTLBufferAllocation.h; sourceTree = "<group>"; };
@ -372,8 +374,6 @@
A9E337B1220129DD00363D2A /* MVKLogging.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MVKLogging.cpp; sourceTree = "<group>"; };
A9E4B7881E1D8AF10046A4CE /* MVKMTLResourceBindings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKMTLResourceBindings.h; sourceTree = "<group>"; };
A9E53DCD2100B197002781DD /* MTLSamplerDescriptor+MoltenVK.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MTLSamplerDescriptor+MoltenVK.m"; sourceTree = "<group>"; };
A9E53DCE2100B197002781DD /* MVKOSExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKOSExtensions.h; sourceTree = "<group>"; };
A9E53DCF2100B197002781DD /* MVKOSExtensions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKOSExtensions.mm; sourceTree = "<group>"; };
A9E53DD02100B197002781DD /* MTLTextureDescriptor+MoltenVK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MTLTextureDescriptor+MoltenVK.h"; sourceTree = "<group>"; };
A9E53DD12100B197002781DD /* CAMetalLayer+MoltenVK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CAMetalLayer+MoltenVK.h"; sourceTree = "<group>"; };
A9E53DD22100B197002781DD /* NSString+MoltenVK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+MoltenVK.h"; sourceTree = "<group>"; };
@ -571,8 +571,6 @@
A9E53DD52100B197002781DD /* MTLTextureDescriptor+MoltenVK.m */,
A93E832E2121C5D3001FEBD4 /* MVKGPUCapture.h */,
A93E83342121F0C8001FEBD4 /* MVKGPUCapture.mm */,
A9E53DCE2100B197002781DD /* MVKOSExtensions.h */,
A9E53DCF2100B197002781DD /* MVKOSExtensions.mm */,
A9E53DD22100B197002781DD /* NSString+MoltenVK.h */,
A9E53DD42100B197002781DD /* NSString+MoltenVK.mm */,
);
@ -585,6 +583,8 @@
A9F0429D1FB4CF82009FCCB8 /* MVKCommonEnvironment.h */,
A9E337B1220129DD00363D2A /* MVKLogging.cpp */,
A9F0429E1FB4CF82009FCCB8 /* MVKLogging.h */,
A9B51BD6225E986A00AC74D2 /* MVKOSExtensions.h */,
A9B51BD2225E986A00AC74D2 /* MVKOSExtensions.mm */,
A981496A1FB6A998005F00B4 /* MVKStrings.h */,
);
name = Common;
@ -628,7 +628,6 @@
A9E53E0121064F84002781DD /* MTLRenderPipelineDescriptor+MoltenVK.h in Headers */,
A94FB7F41C7DFB4800632CA3 /* MVKInstance.h in Headers */,
A95870F81C90D29F009EB096 /* MVKCommandResourceFactory.h in Headers */,
A9E53DD92100B197002781DD /* MVKOSExtensions.h in Headers */,
A94FB7FC1C7DFB4800632CA3 /* MVKQueryPool.h in Headers */,
A95B7D691D3EE486003183D3 /* MVKCommandEncoderState.h in Headers */,
A94FB7D81C7DFB4800632CA3 /* MVKCommandPipelineStateFactoryShaderSource.h in Headers */,
@ -658,6 +657,7 @@
A94FB7DC1C7DFB4800632CA3 /* MVKBuffer.h in Headers */,
A9F042A41FB4CF83009FCCB8 /* MVKCommonEnvironment.h in Headers */,
A981495D1FB6A3F7005F00B4 /* MVKWatermark.h in Headers */,
A9B51BD9225E986A00AC74D2 /* MVKOSExtensions.h in Headers */,
A94FB7C41C7DFB4800632CA3 /* MVKCmdRenderPass.h in Headers */,
A94FB7BC1C7DFB4800632CA3 /* MVKCmdPipeline.h in Headers */,
A94FB7F81C7DFB4800632CA3 /* MVKPipeline.h in Headers */,
@ -693,7 +693,6 @@
A9E53E0221064F84002781DD /* MTLRenderPipelineDescriptor+MoltenVK.h in Headers */,
A94FB7F51C7DFB4800632CA3 /* MVKInstance.h in Headers */,
A95870F91C90D29F009EB096 /* MVKCommandResourceFactory.h in Headers */,
A9E53DDA2100B197002781DD /* MVKOSExtensions.h in Headers */,
A94FB7FD1C7DFB4800632CA3 /* MVKQueryPool.h in Headers */,
A95B7D6A1D3EE486003183D3 /* MVKCommandEncoderState.h in Headers */,
A94FB7D91C7DFB4800632CA3 /* MVKCommandPipelineStateFactoryShaderSource.h in Headers */,
@ -723,6 +722,7 @@
A94FB7DD1C7DFB4800632CA3 /* MVKBuffer.h in Headers */,
A9F042A51FB4CF83009FCCB8 /* MVKCommonEnvironment.h in Headers */,
A981495E1FB6A3F7005F00B4 /* MVKWatermark.h in Headers */,
A9B51BDA225E986A00AC74D2 /* MVKOSExtensions.h in Headers */,
A94FB7C51C7DFB4800632CA3 /* MVKCmdRenderPass.h in Headers */,
A94FB7BD1C7DFB4800632CA3 /* MVKCmdPipeline.h in Headers */,
A94FB7F91C7DFB4800632CA3 /* MVKPipeline.h in Headers */,
@ -949,7 +949,6 @@
A981495F1FB6A3F7005F00B4 /* MVKWatermark.mm in Sources */,
A981494D1FB6A3F7005F00B4 /* MVKBaseObject.cpp in Sources */,
A9E53DE52100B197002781DD /* NSString+MoltenVK.mm in Sources */,
A9E53DDB2100B197002781DD /* MVKOSExtensions.mm in Sources */,
A94FB8321C7DFB4800632CA3 /* vulkan.mm in Sources */,
A94FB8121C7DFB4800632CA3 /* MVKSurface.mm in Sources */,
A94FB7FE1C7DFB4800632CA3 /* MVKQueryPool.mm in Sources */,
@ -977,6 +976,7 @@
A95B7D6B1D3EE486003183D3 /* MVKCommandEncoderState.mm in Sources */,
A9E337B5220129DD00363D2A /* MVKLogging.cpp in Sources */,
A93E83352121F0C8001FEBD4 /* MVKGPUCapture.mm in Sources */,
A9B51BD7225E986A00AC74D2 /* MVKOSExtensions.mm in Sources */,
A94FB7CE1C7DFB4800632CA3 /* MVKCommand.mm in Sources */,
A94FB80E1C7DFB4800632CA3 /* MVKShaderModule.mm in Sources */,
A94FB81A1C7DFB4800632CA3 /* MVKSync.mm in Sources */,
@ -1004,7 +1004,6 @@
A98149601FB6A3F7005F00B4 /* MVKWatermark.mm in Sources */,
A981494E1FB6A3F7005F00B4 /* MVKBaseObject.cpp in Sources */,
A9E53DE62100B197002781DD /* NSString+MoltenVK.mm in Sources */,
A9E53DDC2100B197002781DD /* MVKOSExtensions.mm in Sources */,
A94FB8331C7DFB4800632CA3 /* vulkan.mm in Sources */,
A94FB8131C7DFB4800632CA3 /* MVKSurface.mm in Sources */,
A94FB7FF1C7DFB4800632CA3 /* MVKQueryPool.mm in Sources */,
@ -1032,6 +1031,7 @@
A95B7D6C1D3EE486003183D3 /* MVKCommandEncoderState.mm in Sources */,
A9E337B6220129DD00363D2A /* MVKLogging.cpp in Sources */,
A93E83362121F0C8001FEBD4 /* MVKGPUCapture.mm in Sources */,
A9B51BD8225E986A00AC74D2 /* MVKOSExtensions.mm in Sources */,
A94FB7CF1C7DFB4800632CA3 /* MVKCommand.mm in Sources */,
A94FB80F1C7DFB4800632CA3 /* MVKShaderModule.mm in Sources */,
A94FB81B1C7DFB4800632CA3 /* MVKSync.mm in Sources */,

View File

@ -290,9 +290,11 @@ typedef struct {
uint64_t metalCompileTimeout;
/**
* If enabled, per-frame performance statistics are tracked, optionally logged, and can be
* retrieved via the vkGetSwapchainPerformanceMVK() function, and various performance statistics
* are tracked, logged, and can be retrieved via the vkGetPerformanceStatisticsMVK() function.
* If enabled, performance statistics, as defined by the MVKPerformanceStatistics structure,
* are collected, and can be retrieved via the vkGetPerformanceStatisticsMVK() function.
*
* You can also use the performanceLoggingFrameCount parameter to automatically log the
* performance statistics collected by this parameter.
*
* The value of this parameter may be changed at any time during application runtime,
* and the changed value will immediately effect subsequent MoltenVK behaviour.
@ -305,8 +307,12 @@ typedef struct {
VkBool32 performanceTracking;
/**
* If non-zero, performance statistics will be periodically logged to the console, on a repeating
* cycle of this many frames per swapchain. The performanceTracking capability must also be enabled.
* If non-zero, performance statistics, as defined by the MVKPerformanceStatistics structure,
* will be logged to the console. Frame-based statistics will be logged, on a repeating cycle,
* once per this many frames. Non-frame-based statistics will be logged as they occur.
*
* The performanceTracking parameter must also be enabled. If this parameter is zero, or
* the performanceTracking parameter is disabled, no performance statistics will be logged.
*
* The value of this parameter may be changed at any time during application runtime,
* and the changed value will immediately effect subsequent MoltenVK behaviour.

View File

@ -793,3 +793,21 @@ protected:
};
#pragma mark -
#pragma mark Support functions
/** Returns an approximation of how much memory, in bytes, the device can use with good performance. */
uint64_t mvkRecommendedMaxWorkingSetSize(id<MTLDevice> mtlDevice);
/** Populate the propertes with info about the GPU represented by the MTLDevice. */
void mvkPopulateGPUInfo(VkPhysicalDeviceProperties& devProps, id<MTLDevice> mtlDevice);
/** Returns the registry ID of the specified device, or zero if the device does not have a registry ID. */
uint64_t mvkGetRegistryID(id<MTLDevice> mtlDevice);
/**
* If the MTLDevice defines a texture memory alignment for the format, it is retrieved from
* the MTLDevice and returned, or returns zero if the MTLDevice does not define an alignment.
* The format must support linear texture memory (must not be depth, stencil, or compressed).
*/
VkDeviceSize mvkMTLPixelFormatLinearTextureAlignment(MTLPixelFormat mtlPixelFormat, id<MTLDevice> mtlDevice);

View File

@ -35,6 +35,7 @@
#include "MVKOSExtensions.h"
#include <MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.h>
#include "vk_mvk_moltenvk.h"
#include <mach/mach_host.h>
#import "CAMetalLayer+MoltenVK.h"
@ -1947,13 +1948,15 @@ void MVKDevice::addActivityPerformanceImpl(MVKPerformanceTracker& shaderCompilat
double totalInterval = (shaderCompilationEvent.averageDuration * shaderCompilationEvent.count++) + currInterval;
shaderCompilationEvent.averageDuration = totalInterval / shaderCompilationEvent.count;
MVKLogDebug("Performance to %s curr: %.3f ms, avg: %.3f ms, min: %.3f ms, max: %.3f ms, count: %d",
getActivityPerformanceDescription(shaderCompilationEvent),
currInterval,
shaderCompilationEvent.averageDuration,
shaderCompilationEvent.minimumDuration,
shaderCompilationEvent.maximumDuration,
shaderCompilationEvent.count);
if (_pMVKConfig->performanceLoggingFrameCount) {
MVKLogInfo("Performance to %s count: %d curr: %.3f ms, min: %.3f ms, max: %.3f ms, avg: %.3f ms",
getActivityPerformanceDescription(shaderCompilationEvent),
shaderCompilationEvent.count,
currInterval,
shaderCompilationEvent.minimumDuration,
shaderCompilationEvent.maximumDuration,
shaderCompilationEvent.averageDuration);
}
}
const char* MVKDevice::getActivityPerformanceDescription(MVKPerformanceTracker& shaderCompilationEvent) {
@ -2308,3 +2311,142 @@ bool MVKRefCountedDeviceObject::markDestroyed() {
}
#pragma mark -
#pragma mark Support functions
uint64_t mvkRecommendedMaxWorkingSetSize(id<MTLDevice> mtlDevice) {
#if MVK_MACOS
if ( [mtlDevice respondsToSelector: @selector(recommendedMaxWorkingSetSize)]) {
return mtlDevice.recommendedMaxWorkingSetSize;
}
#endif
#if MVK_IOS
// GPU and CPU use shared memory. Estimate the current free memory in the system.
mach_port_t host_port;
mach_msg_type_number_t host_size;
vm_size_t pagesize;
host_port = mach_host_self();
host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
host_page_size(host_port, &pagesize);
vm_statistics_data_t vm_stat;
if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) == KERN_SUCCESS ) {
return vm_stat.free_count * pagesize;
}
#endif
return 128 * MEBI; // Conservative minimum for macOS GPU's & iOS shared memory
}
#if MVK_MACOS
static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef propertyName) {
uint32_t value = 0;
CFTypeRef cfProp = IORegistryEntrySearchCFProperty(entry,
kIOServicePlane,
propertyName,
kCFAllocatorDefault,
kIORegistryIterateRecursively |
kIORegistryIterateParents);
if (cfProp) {
const uint32_t* pValue = reinterpret_cast<const uint32_t*>(CFDataGetBytePtr((CFDataRef)cfProp));
if (pValue) { value = *pValue; }
CFRelease(cfProp);
}
return value;
}
void mvkPopulateGPUInfo(VkPhysicalDeviceProperties& devProps, id<MTLDevice> mtlDevice) {
static const uint32_t kIntelVendorId = 0x8086;
bool isFound = false;
bool isIntegrated = mtlDevice.isLowPower;
devProps.deviceType = isIntegrated ? VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU : VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
strlcpy(devProps.deviceName, mtlDevice.name.UTF8String, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
// If the device has an associated registry ID, we can use that to get the associated IOKit node.
// The match dictionary is consumed by IOServiceGetMatchingServices and does not need to be released.
io_registry_entry_t entry;
uint64_t regID = mvkGetRegistryID(mtlDevice);
if (regID) {
entry = IOServiceGetMatchingService(kIOMasterPortDefault, IORegistryEntryIDMatching(regID));
if (entry) {
// That returned the IOGraphicsAccelerator nub. Its parent, then, is the actual
// PCI device.
io_registry_entry_t parent;
if (IORegistryEntryGetParentEntry(entry, kIOServicePlane, &parent) == kIOReturnSuccess) {
isFound = true;
devProps.vendorID = mvkGetEntryProperty(parent, CFSTR("vendor-id"));
devProps.deviceID = mvkGetEntryProperty(parent, CFSTR("device-id"));
IOObjectRelease(parent);
}
IOObjectRelease(entry);
}
}
// Iterate all GPU's, looking for a match.
// The match dictionary is consumed by IOServiceGetMatchingServices and does not need to be released.
io_iterator_t entryIterator;
if (!isFound && IOServiceGetMatchingServices(kIOMasterPortDefault,
IOServiceMatching("IOPCIDevice"),
&entryIterator) == kIOReturnSuccess) {
while ( !isFound && (entry = IOIteratorNext(entryIterator)) ) {
if (mvkGetEntryProperty(entry, CFSTR("class-code")) == 0x30000) { // 0x30000 : DISPLAY_VGA
// The Intel GPU will always be marked as integrated.
// Return on a match of either Intel && low power, or non-Intel and non-low-power.
uint32_t vendorID = mvkGetEntryProperty(entry, CFSTR("vendor-id"));
if ( (vendorID == kIntelVendorId) == isIntegrated) {
isFound = true;
devProps.vendorID = vendorID;
devProps.deviceID = mvkGetEntryProperty(entry, CFSTR("device-id"));
}
}
}
IOObjectRelease(entryIterator);
}
}
#endif //MVK_MACOS
#if MVK_IOS
void mvkPopulateGPUInfo(VkPhysicalDeviceProperties& devProps, id<MTLDevice> mtlDevice) {
// For iOS devices, the Device ID is the SoC model (A8, A10X...), in the hex form 0xaMMX, where
//"a" is the Apple brand, MM is the SoC model number (8, 10...) and X is 1 for X version, 0 for other.
NSUInteger coreCnt = NSProcessInfo.processInfo.processorCount;
uint32_t devID = 0xa070;
if ([mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily5_v1]) {
devID = 0xa120;
} else if ([mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily4_v1]) {
devID = 0xa110;
} else if ([mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily3_v1]) {
devID = coreCnt > 2 ? 0xa101 : 0xa100;
} else if ([mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily2_v1]) {
devID = coreCnt > 2 ? 0xa081 : 0xa080;
}
devProps.vendorID = 0x0000106b; // Apple's PCI ID
devProps.deviceID = devID;
devProps.deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
strlcpy(devProps.deviceName, mtlDevice.name.UTF8String, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
}
#endif //MVK_IOS
uint64_t mvkGetRegistryID(id<MTLDevice> mtlDevice) {
return [mtlDevice respondsToSelector: @selector(registryID)] ? mtlDevice.registryID : 0;
}
VkDeviceSize mvkMTLPixelFormatLinearTextureAlignment(MTLPixelFormat mtlPixelFormat,
id<MTLDevice> mtlDevice) {
if ([mtlDevice respondsToSelector: @selector(minimumLinearTextureAlignmentForPixelFormat:)]) {
return [mtlDevice minimumLinearTextureAlignmentForPixelFormat: mtlPixelFormat];
} else {
return 0;
}
}

View File

@ -1,245 +0,0 @@
/*
* MVKOSExtensions.mm
*
* Copyright (c) 2014-2019 The Brenwill Workshop Ltd. (http://www.brenwill.com)
*
* 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.
*/
#include "MVKOSExtensions.h"
#include "MVKFoundation.h"
#include "MVKCommonEnvironment.h"
#include <vector>
#include <mach/mach_host.h>
#include <mach/mach_time.h>
#if MVK_MACOS
# import <CoreFoundation/CFData.h>
# import <IOKit/IOKitLib.h>
# import <IOKit/IOKitKeys.h>
#endif
#if MVK_IOS
# import <UIKit/UIDevice.h>
#endif
using namespace std;
static const MVKOSVersion kMVKOSVersionUnknown = 0.0f;
static MVKOSVersion _mvkOSVersion = kMVKOSVersionUnknown;
MVKOSVersion mvkOSVersion() {
if (_mvkOSVersion == kMVKOSVersionUnknown) {
NSOperatingSystemVersion osVer = [[NSProcessInfo processInfo] operatingSystemVersion];
float maj = osVer.majorVersion;
float min = osVer.minorVersion;
float pat = osVer.patchVersion;
_mvkOSVersion = maj + (min / 100.0f) + + (pat / 10000.0f);
}
return _mvkOSVersion;
}
static uint64_t _mvkTimestampBase;
static double _mvkTimestampPeriod;
uint64_t mvkGetTimestamp() { return mach_absolute_time() - _mvkTimestampBase; }
double mvkGetTimestampPeriod() { return _mvkTimestampPeriod; }
double mvkGetElapsedMilliseconds(uint64_t startTimestamp, uint64_t endTimestamp) {
if (endTimestamp == 0) { endTimestamp = mvkGetTimestamp(); }
return (double)(endTimestamp - startTimestamp) * _mvkTimestampPeriod / 1e6;
}
/**
* Initialize timestamping 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_data_t timebase;
mach_timebase_info(&timebase);
_mvkTimestampPeriod = (double)timebase.numer / (double)timebase.denom;
MVKLogDebug("Initializing MoltenVK timestamping. Mach time: %llu. Time period: %d / %d = %.6f.", _mvkTimestampBase, timebase.numer, timebase.denom, _mvkTimestampPeriod);
}
void mvkDispatchToMainAndWait(dispatch_block_t block) {
if (NSThread.isMainThread) {
block();
} else {
dispatch_sync(dispatch_get_main_queue(), block);
}
}
#pragma mark -
#pragma mark Process environment
string mvkGetEnvVar(string varName, bool* pWasFound) {
NSDictionary* env = [[NSProcessInfo processInfo] environment];
NSString* envStr = env[@(varName.c_str())];
if (pWasFound) { *pWasFound = envStr != nil; }
return envStr ? envStr.UTF8String : "";
}
int64_t mvkGetEnvVarInt64(string varName, bool* pWasFound) {
return strtoll(mvkGetEnvVar(varName, pWasFound).c_str(), NULL, 0);
}
bool mvkGetEnvVarBool(std::string varName, bool* pWasFound) {
return mvkGetEnvVarInt64(varName, pWasFound) != 0;
}
#pragma mark -
#pragma mark MTLDevice
uint64_t mvkRecommendedMaxWorkingSetSize(id<MTLDevice> mtlDevice) {
#if MVK_MACOS
if ( [mtlDevice respondsToSelector: @selector(recommendedMaxWorkingSetSize)]) {
return mtlDevice.recommendedMaxWorkingSetSize;
}
#endif
#if MVK_IOS
// GPU and CPU use shared memory. Estimate the current free memory in the system.
mach_port_t host_port;
mach_msg_type_number_t host_size;
vm_size_t pagesize;
host_port = mach_host_self();
host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
host_page_size(host_port, &pagesize);
vm_statistics_data_t vm_stat;
if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) == KERN_SUCCESS ) {
return vm_stat.free_count * pagesize;
}
#endif
return 128 * MEBI; // Conservative minimum for macOS GPU's & iOS shared memory
}
#if MVK_MACOS
static uint32_t mvkGetEntryProperty(io_registry_entry_t entry, CFStringRef propertyName) {
uint32_t value = 0;
CFTypeRef cfProp = IORegistryEntrySearchCFProperty(entry,
kIOServicePlane,
propertyName,
kCFAllocatorDefault,
kIORegistryIterateRecursively |
kIORegistryIterateParents);
if (cfProp) {
const uint32_t* pValue = reinterpret_cast<const uint32_t*>(CFDataGetBytePtr((CFDataRef)cfProp));
if (pValue) { value = *pValue; }
CFRelease(cfProp);
}
return value;
}
void mvkPopulateGPUInfo(VkPhysicalDeviceProperties& devProps, id<MTLDevice> mtlDevice) {
static const uint32_t kIntelVendorId = 0x8086;
bool isFound = false;
bool isIntegrated = mtlDevice.isLowPower;
devProps.deviceType = isIntegrated ? VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU : VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
strlcpy(devProps.deviceName, mtlDevice.name.UTF8String, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
// If the device has an associated registry ID, we can use that to get the associated IOKit node.
// The match dictionary is consumed by IOServiceGetMatchingServices and does not need to be released.
io_registry_entry_t entry;
uint64_t regID = mvkGetRegistryID(mtlDevice);
if (regID) {
entry = IOServiceGetMatchingService(kIOMasterPortDefault, IORegistryEntryIDMatching(regID));
if (entry) {
// That returned the IOGraphicsAccelerator nub. Its parent, then, is the actual
// PCI device.
io_registry_entry_t parent;
if (IORegistryEntryGetParentEntry(entry, kIOServicePlane, &parent) == kIOReturnSuccess) {
isFound = true;
devProps.vendorID = mvkGetEntryProperty(parent, CFSTR("vendor-id"));
devProps.deviceID = mvkGetEntryProperty(parent, CFSTR("device-id"));
IOObjectRelease(parent);
}
IOObjectRelease(entry);
}
}
// Iterate all GPU's, looking for a match.
// The match dictionary is consumed by IOServiceGetMatchingServices and does not need to be released.
io_iterator_t entryIterator;
if (!isFound && IOServiceGetMatchingServices(kIOMasterPortDefault,
IOServiceMatching("IOPCIDevice"),
&entryIterator) == kIOReturnSuccess) {
while ( !isFound && (entry = IOIteratorNext(entryIterator)) ) {
if (mvkGetEntryProperty(entry, CFSTR("class-code")) == 0x30000) { // 0x30000 : DISPLAY_VGA
// The Intel GPU will always be marked as integrated.
// Return on a match of either Intel && low power, or non-Intel and non-low-power.
uint32_t vendorID = mvkGetEntryProperty(entry, CFSTR("vendor-id"));
if ( (vendorID == kIntelVendorId) == isIntegrated) {
isFound = true;
devProps.vendorID = vendorID;
devProps.deviceID = mvkGetEntryProperty(entry, CFSTR("device-id"));
}
}
}
IOObjectRelease(entryIterator);
}
}
#endif //MVK_MACOS
#if MVK_IOS
void mvkPopulateGPUInfo(VkPhysicalDeviceProperties& devProps, id<MTLDevice> mtlDevice) {
// For iOS devices, the Device ID is the SoC model (A8, A10X...), in the hex form 0xaMMX, where
//"a" is the Apple brand, MM is the SoC model number (8, 10...) and X is 1 for X version, 0 for other.
NSUInteger coreCnt = NSProcessInfo.processInfo.processorCount;
uint32_t devID = 0xa070;
if ([mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily5_v1]) {
devID = 0xa120;
} else if ([mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily4_v1]) {
devID = 0xa110;
} else if ([mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily3_v1]) {
devID = coreCnt > 2 ? 0xa101 : 0xa100;
} else if ([mtlDevice supportsFeatureSet: MTLFeatureSet_iOS_GPUFamily2_v1]) {
devID = coreCnt > 2 ? 0xa081 : 0xa080;
}
devProps.vendorID = 0x0000106b; // Apple's PCI ID
devProps.deviceID = devID;
devProps.deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
strlcpy(devProps.deviceName, mtlDevice.name.UTF8String, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
}
#endif //MVK_IOS
uint64_t mvkGetRegistryID(id<MTLDevice> mtlDevice) {
return [mtlDevice respondsToSelector: @selector(registryID)] ? mtlDevice.registryID : 0;
}
VkDeviceSize mvkMTLPixelFormatLinearTextureAlignment(MTLPixelFormat mtlPixelFormat,
id<MTLDevice> mtlDevice) {
if ([mtlDevice respondsToSelector: @selector(minimumLinearTextureAlignmentForPixelFormat:)]) {
return [mtlDevice minimumLinearTextureAlignmentForPixelFormat: mtlPixelFormat];
} else {
return 0;
}
}

View File

@ -45,6 +45,7 @@
A98149681FB6A98A005F00B4 /* MVKStrings.h in Headers */ = {isa = PBXBuildFile; fileRef = A98149651FB6A98A005F00B4 /* MVKStrings.h */; };
A98149691FB6A98A005F00B4 /* MVKStrings.h in Headers */ = {isa = PBXBuildFile; fileRef = A98149651FB6A98A005F00B4 /* MVKStrings.h */; };
A9A14E332244388700C080F3 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A9A14E322244388700C080F3 /* Metal.framework */; };
A9B51BDD225E98BB00AC74D2 /* MVKOSExtensions.mm in Sources */ = {isa = PBXBuildFile; fileRef = A9B51BDB225E98BB00AC74D2 /* MVKOSExtensions.mm */; };
A9C70F5A221B2F6500FBA31A /* libSPIRVTools.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A972AD3021CEE7040013AB25 /* libSPIRVTools.a */; };
A9C70F5B221B2F8100FBA31A /* libSPIRVTools.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A972AD3421CEE7330013AB25 /* libSPIRVTools.a */; };
A9C70F5F221B321700FBA31A /* SPIRVSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = A9C70F5D221B321600FBA31A /* SPIRVSupport.h */; };
@ -115,6 +116,8 @@
A97CC73F1C7527F3004A5C7E /* MoltenVKShaderConverterTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MoltenVKShaderConverterTool.h; sourceTree = "<group>"; };
A98149651FB6A98A005F00B4 /* MVKStrings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKStrings.h; sourceTree = "<group>"; };
A9A14E322244388700C080F3 /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; };
A9B51BDB225E98BB00AC74D2 /* MVKOSExtensions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MVKOSExtensions.mm; sourceTree = "<group>"; };
A9B51BDC225E98BB00AC74D2 /* MVKOSExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVKOSExtensions.h; sourceTree = "<group>"; };
A9C70F5D221B321600FBA31A /* SPIRVSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SPIRVSupport.h; path = Common/SPIRVSupport.h; sourceTree = SOURCE_ROOT; };
A9C70F5E221B321700FBA31A /* SPIRVSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SPIRVSupport.cpp; path = Common/SPIRVSupport.cpp; sourceTree = SOURCE_ROOT; };
A9E337B7220129ED00363D2A /* MVKLogging.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MVKLogging.cpp; sourceTree = "<group>"; };
@ -243,6 +246,8 @@
A9F042AA1FB4D060009FCCB8 /* MVKCommonEnvironment.h */,
A9E337B7220129ED00363D2A /* MVKLogging.cpp */,
A9F042AB1FB4D060009FCCB8 /* MVKLogging.h */,
A9B51BDC225E98BB00AC74D2 /* MVKOSExtensions.h */,
A9B51BDB225E98BB00AC74D2 /* MVKOSExtensions.mm */,
A98149651FB6A98A005F00B4 /* MVKStrings.h */,
A9C70F5E221B321700FBA31A /* SPIRVSupport.cpp */,
A9C70F5D221B321600FBA31A /* SPIRVSupport.h */,
@ -624,6 +629,7 @@
A97CC7411C7527F3004A5C7E /* MoltenVKShaderConverterTool.cpp in Sources */,
A9C70F63221B321700FBA31A /* SPIRVSupport.cpp in Sources */,
A95096BF2003D32400F10950 /* OSSupport.mm in Sources */,
A9B51BDD225E98BB00AC74D2 /* MVKOSExtensions.mm in Sources */,
A97CC7401C7527F3004A5C7E /* main.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;

View File

@ -111,6 +111,10 @@
argument = "-l"
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument
argument = "-p"
isEnabled = "NO">
</CommandLineArgument>
</CommandLineArguments>
<AdditionalOptions>
</AdditionalOptions>

View File

@ -22,6 +22,7 @@
#include "GLSLToSPIRVConverter.h"
#include "SPIRVToMSLConverter.h"
#include "SPIRVSupport.h"
#include "MVKOSExtensions.h"
using namespace std;
using namespace mvk;
@ -40,6 +41,17 @@ static const char* _defaultCompShaderExtns = "cs csh cp cmp comp compute kn kl k
static const char* _defaultSPIRVShaderExtns = "spv spirv";
uint64_t MVKPerformanceTracker::getTimestamp() { return mvkGetTimestamp(); }
void MVKPerformanceTracker::accumulate(uint64_t startTime, uint64_t endTime) {
double currInterval = mvkGetElapsedMilliseconds(startTime, endTime);
minimumDuration = min(currInterval, minimumDuration);
maximumDuration = max(currInterval, maximumDuration);
double totalInterval = (averageDuration * count++) + currInterval;
averageDuration = totalInterval / count;
}
#pragma mark -
#pragma mark MoltenVKShaderConverterTool
@ -59,6 +71,8 @@ int MoltenVKShaderConverterTool::run() {
showUsage();
}
}
reportPerformance();
return success ? EXIT_SUCCESS : EXIT_FAILURE;
}
@ -117,7 +131,12 @@ bool MoltenVKShaderConverterTool::convertGLSL(string& glslInFile,
// Convert GLSL to SPIR-V
GLSLToSPIRVConverter glslConverter;
glslConverter.setGLSL(glslCode);
if (glslConverter.convert(shaderStage, _shouldLogConversions, _shouldLogConversions)) {
uint64_t startTime = _glslConversionPerformance.getTimestamp();
bool wasConverted = glslConverter.convert(shaderStage, _shouldLogConversions, _shouldLogConversions);
_glslConversionPerformance.accumulate(startTime);
if (wasConverted) {
if (_shouldLogConversions) { log(glslConverter.getResultLog().data()); }
} else {
string logMsg = "Could not convert GLSL in file: " + absolutePath(path);
@ -188,7 +207,12 @@ bool MoltenVKShaderConverterTool::convertSPIRV(const vector<uint32_t>& spv,
SPIRVToMSLConverter spvConverter;
spvConverter.setSPIRV(spv);
if (spvConverter.convert(mslContext, shouldLogSPV, _shouldLogConversions, (_shouldLogConversions && shouldLogSPV))) {
uint64_t startTime = _spvConversionPerformance.getTimestamp();
bool wasConverted = spvConverter.convert(mslContext, shouldLogSPV, _shouldLogConversions, (_shouldLogConversions && shouldLogSPV));
_spvConversionPerformance.accumulate(startTime);
if (wasConverted) {
if (_shouldLogConversions) { log(spvConverter.getResultLog().data()); }
} else {
string errMsg = "Could not convert SPIR-V in file: " + absolutePath(inFile);
@ -302,9 +326,33 @@ void MoltenVKShaderConverterTool::showUsage() {
log(" -sx \"fileExtns\" - List of SPIR-V shader file extensions.");
log(" May be omitted for defaults (\"spv spirv\").");
log(" -l - Log the conversion results to the console (to aid debugging).");
log(" -p - Log the performance of the shader conversions.");
log("");
}
void MoltenVKShaderConverterTool::reportPerformance() {
if ( !_shouldReportPerformance ) { return; }
if (_shouldReadGLSL) { reportPerformance(_glslConversionPerformance, "GLSL to SPIR-V"); }
reportPerformance(_spvConversionPerformance, "SPIR-V to MSL");
}
void MoltenVKShaderConverterTool::reportPerformance(MVKPerformanceTracker& shaderCompilationEvent, string eventDescription) {
string logMsg;
logMsg += "Performance to convert ";
logMsg += eventDescription;
logMsg += " count: ";
logMsg += to_string(shaderCompilationEvent.count);
logMsg += ", min: ";
logMsg += to_string(shaderCompilationEvent.minimumDuration);
logMsg += " ms, max: ";
logMsg += to_string(shaderCompilationEvent.maximumDuration);
logMsg += " ms, avg: ";
logMsg += to_string(shaderCompilationEvent.averageDuration);
logMsg += " ms.\n";
log(logMsg.c_str());
}
#pragma mark Construction
@ -325,6 +373,7 @@ MoltenVKShaderConverterTool::MoltenVKShaderConverterTool(int argc, const char* a
_shouldFlipVertexY = true;
_shouldIncludeOrigPathExtn = true;
_shouldLogConversions = false;
_shouldReportPerformance = false;
_isActive = parseArgs(argc, argv);
if ( !_isActive ) { showUsage(); }
@ -463,6 +512,11 @@ bool MoltenVKShaderConverterTool::parseArgs(int argc, const char* argv[]) {
continue;
}
if(equal(arg, "-p", true)) {
_shouldReportPerformance = true;
continue;
}
}
return true;

View File

@ -26,6 +26,15 @@
namespace mvk {
typedef struct {
uint32_t count = 0;
double averageDuration = 0;
double minimumDuration = std::numeric_limits<double>::max();
double maximumDuration = 0;
uint64_t getTimestamp();
void accumulate(uint64_t startTime, uint64_t endTime = 0);
} MVKPerformanceTracker;
#pragma mark -
#pragma mark MoltenVKShaderConverterTool
@ -75,6 +84,9 @@ namespace mvk {
int optionArgIndex,
int argc,
const char* argv[]);
void reportPerformance();
void reportPerformance(MVKPerformanceTracker& shaderCompilationEvent,
std::string eventDescription);
std::string _processName;
std::string _directoryPath;
@ -88,6 +100,8 @@ namespace mvk {
std::vector<std::string> _glslCompFileExtns;
std::vector<std::string> _spvFileExtns;
MVKShaderStage _shaderStage;
MVKPerformanceTracker _glslConversionPerformance;
MVKPerformanceTracker _spvConversionPerformance;
bool _isActive;
bool _shouldUseDirectoryRecursion;
bool _shouldReadGLSL;
@ -98,6 +112,7 @@ namespace mvk {
bool _shouldFlipVertexY;
bool _shouldIncludeOrigPathExtn;
bool _shouldLogConversions;
bool _shouldReportPerformance;
};