Merge pull request #570 from billhollings/master
Update dependency libraries for SDK 1.1.106.
This commit is contained in:
commit
d57704b69f
@ -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
96
Common/MVKOSExtensions.mm
Normal 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;
|
||||
}
|
@ -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
@ -1 +1 @@
|
||||
4395339586c2eebc08e602d307aa5e750b736533
|
||||
ac5a9570a744eb72725c23c34f36fbc564c0bb51
|
||||
|
@ -1 +1 @@
|
||||
ebcf66aa429eceb3360008878fe2881c7f5b2b20
|
||||
08cbb5458f692d4778806775f65eb3dc642ddbbf
|
||||
|
@ -1 +1 @@
|
||||
d43b22f0859f42c5fd71a530278ffa504ce95b7f
|
||||
2abb69904b9ad017d39d3da1e7fc3dec1a584cd8
|
||||
|
@ -1 +1 @@
|
||||
9ce6ece9d86b9501c1a8a4adbd4e0e60a5ae8456
|
||||
07b1ccd82ff6b7e6369a0d8d6a5e5e4f7ba0b7d6
|
||||
|
@ -1 +1 @@
|
||||
5432f0dd8f331f15182681664d7486681e8514e6
|
||||
e06c7e9a515b716c731bda13f507546f107775d1
|
||||
|
@ -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 */,
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -111,6 +111,10 @@
|
||||
argument = "-l"
|
||||
isEnabled = "YES">
|
||||
</CommandLineArgument>
|
||||
<CommandLineArgument
|
||||
argument = "-p"
|
||||
isEnabled = "NO">
|
||||
</CommandLineArgument>
|
||||
</CommandLineArguments>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user