MVKDevice: Support capturing GPU traces to a file.

Use MVK_CONFIG_AUTO_GPU_CAPTURE_OUTPUT_FILE to set the destination file.
This is useful for capturing traces where the program in question cannot
be run under Xcode's control; the captured trace can then be inspected
later with Xcode.

This new feature requires Metal 3.0 (macOS 10.15, iOS 13).
This commit is contained in:
Chip Davis 2020-04-22 16:24:38 -05:00
parent b1b86654ed
commit 9260f5bfd5
6 changed files with 54 additions and 2 deletions

View File

@ -115,6 +115,13 @@ bool mvkGetEnvVarBool(std::string varName, bool* pWasFound = nullptr);
cfgVal = (int32_t)std::min(std::max(val, (int64_t)INT32_MIN), (int64_t)INT32_MAX); \
} while(false)
#define MVK_SET_FROM_ENV_OR_BUILD_STRING(cfgVal, EV) \
do { \
bool wasFound = false; \
std::string ev = mvkGetEnvVar(#EV, &wasFound); \
cfgVal = wasFound ? std::move(ev) : EV; \
} while(false)
#pragma mark -
#pragma mark System memory

View File

@ -128,7 +128,7 @@ typedef unsigned long MTLLanguageVersion;
* synchronization behaviour, by default.
*
* 5. The MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE runtime environment variable or MoltenVK compile-time
* build setting controls whether Xcode should run an automatic GPU capture without the user
* build setting controls whether Metal should run an automatic GPU capture without the user
* having to trigger it manually via the Xcode user interface, and controls the scope under
* which that GPU capture will occur. This is useful when trying to capture a one-shot GPU
* trace, such as when running a Vulkan CTS test case. For the automatic GPU capture to occur,
@ -137,6 +137,12 @@ typedef unsigned long MTLLanguageVersion;
* Xcode user interface.
* 0: No automatic GPU capture.
* 1: Capture all GPU commands issued during the lifetime of the VkDevice.
* If MVK_CONFIG_AUTO_GPU_CAPTURE_OUTPUT_FILE is also set, it is a filename where the automatic
* GPU capture should be saved. In this case, the Xcode scheme need not have Metal GPU capture
* enabled, and in fact the app need not be run under Xcode's control at all. This is useful
* in case the app cannot be run under Xcode's control. A path starting with '~' can be used
* to place it in a user's home directory, as in the shell. This feature requires Metal 3.0
* (macOS 10.15, iOS 13).
* If none of these is set, no automatic GPU capture will occur.
*
* 6. The MVK_CONFIG_TEXTURE_1D_AS_2D runtime environment variable or MoltenVK compile-time build

View File

@ -2613,7 +2613,33 @@ MVKDevice::MVKDevice(MVKPhysicalDevice* physicalDevice, const VkDeviceCreateInfo
initQueues(pCreateInfo);
if (getInstance()->_autoGPUCaptureScope == MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE_DEVICE) {
[[MTLCaptureManager sharedCaptureManager] startCaptureWithDevice: getMTLDevice()];
MTLCaptureManager *captureMgr = [MTLCaptureManager sharedCaptureManager];
if (!getInstance()->_autoGPUCaptureOutputFile.empty()) {
if ( ![captureMgr respondsToSelector: @selector(supportsDestination:)] ||
![captureMgr supportsDestination: MTLCaptureDestinationGPUTraceDocument] ) {
reportError(VK_ERROR_FEATURE_NOT_PRESENT, "Capturing GPU traces to a file requires macOS 10.15 or iOS 13.0. Falling back to Xcode GPU capture.");
[captureMgr startCaptureWithDevice: getMTLDevice()];
} else {
NSError *err = nil;
NSString *path, *expandedPath;
MTLCaptureDescriptor *captureDesc = [MTLCaptureDescriptor new];
captureDesc.captureObject = getMTLDevice();
captureDesc.destination = MTLCaptureDestinationGPUTraceDocument;
path = [NSString stringWithUTF8String: getInstance()->_autoGPUCaptureOutputFile.c_str()];
expandedPath = path.stringByExpandingTildeInPath;
captureDesc.outputURL = [NSURL fileURLWithPath: expandedPath];
if (![captureMgr startCaptureWithDescriptor: captureDesc error: &err]) {
reportError(VK_ERROR_INITIALIZATION_FAILED, "Failed to start GPU capture session to %s (Error code %li): %s", getInstance()->_autoGPUCaptureOutputFile.c_str(), (long)err.code, err.localizedDescription.UTF8String);
[err release];
}
[captureDesc.outputURL release];
[captureDesc release];
[expandedPath release];
[path release];
}
} else {
[captureMgr startCaptureWithDevice: getMTLDevice()];
}
}
MVKLogInfo("Created VkDevice to run on GPU %s with the following %d Vulkan extensions enabled:%s",

View File

@ -199,6 +199,7 @@ protected:
bool _useCreationCallbacks;
const char* _debugReportCallbackLayerPrefix;
int32_t _autoGPUCaptureScope;
std::string _autoGPUCaptureOutputFile;
};

View File

@ -666,6 +666,7 @@ void MVKInstance::initConfig() {
MVK_SET_FROM_ENV_OR_BUILD_BOOL( _mvkConfig.defaultGPUCaptureScopeQueueIndex, MVK_CONFIG_DEFAULT_GPU_CAPTURE_SCOPE_QUEUE_INDEX);
MVK_SET_FROM_ENV_OR_BUILD_INT32(_autoGPUCaptureScope, MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE);
MVK_SET_FROM_ENV_OR_BUILD_STRING(_autoGPUCaptureOutputFile, MVK_CONFIG_AUTO_GPU_CAPTURE_OUTPUT_FILE);
}
VkResult MVKInstance::verifyLayers(uint32_t count, const char* const* names) {

View File

@ -166,6 +166,17 @@
# define MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE MVK_CONFIG_AUTO_GPU_CAPTURE_SCOPE_NONE
#endif
/**
* The file to capture automatic GPU traces to, instead of capturing to Xcode. This is
* useful when trying to capture a one-shot trace, but the program cannot be run under
* Xcode's control. Tilde paths may be used to place the trace document in a user's home
* directory. This functionality requires macOS 10.15 or iOS 13. If left blank, automatic
* traces will be captured to Xcode.
*/
#ifndef MVK_CONFIG_AUTO_GPU_CAPTURE_OUTPUT_FILE
# define MVK_CONFIG_AUTO_GPU_CAPTURE_OUTPUT_FILE ""
#endif
/** Force the use of a low-power GPU if it exists. Disabled by default. */
#ifndef MVK_CONFIG_FORCE_LOW_POWER_GPU
# define MVK_CONFIG_FORCE_LOW_POWER_GPU 0